@arethetypeswrong/cli
Advanced tools
Comparing version 0.5.0 to 0.6.0
@@ -18,3 +18,3 @@ #!/usr/bin/env node | ||
const version = packageJson.version; | ||
const formats = ["table", "table-flipped", "ascii", "json"]; | ||
const formats = ["auto", "table", "table-flipped", "ascii", "json"]; | ||
program | ||
@@ -28,11 +28,16 @@ .addHelpText("before", `ATTW CLI (v${version})\n`) | ||
.argument("[file-directory-or-package-spec]", "the packed .tgz, or directory containing package.json with --pack, or package spec with --from-npm") | ||
.option("-P, --pack", "run `npm pack` in the specified directory and delete the resulting .tgz file afterwards") | ||
.option("-p, --from-npm", "read from the npm registry instead of a local file") | ||
.addOption(new Option("-f, --format <format>", "specify the print format").choices(formats).default("table")) | ||
.option("-q, --quiet", "don't print anything to STDOUT (overrides all other options)") | ||
.addOption(new Option("--ignore-rules <rules...>", "specify rules to ignore").choices(Object.values(problemFlags)).default([])) | ||
.option("--summary, --no-summary", "whether to print summary information about the different errors") | ||
.option("--emoji, --no-emoji", "whether to use any emojis") | ||
.option("--color, --no-color", "whether to use any colors (the FORCE_COLOR env variable is also available)") | ||
.option("--config-path <path>", "path to config file (default: ./.attw.json)") | ||
.option("-P, --pack", "Run `npm pack` in the specified directory and delete the resulting .tgz file afterwards") | ||
.option("-p, --from-npm", "Read from the npm registry instead of a local file") | ||
.addOption(new Option("-f, --format <format>", "Specify the print format").choices(formats).default("auto")) | ||
.option("-q, --quiet", "Don't print anything to STDOUT (overrides all other options)") | ||
.option("--entrypoints <entrypoints...>", "Specify an exhaustive list of entrypoints to check. " + | ||
'The package root is `"." Specifying this option disables automatic entrypoint discovery, ' + | ||
"and overrides the `--include-entrypoints` and `--exclude-entrypoints` options.") | ||
.option("--include-entrypoints <entrypoints...>", "Specify entrypoints to check in addition to automatically discovered ones.") | ||
.option("--exclude-entrypoints <entrypoints...>", "Specify entrypoints to exclude from checking.") | ||
.addOption(new Option("--ignore-rules <rules...>", "Specify rules to ignore").choices(Object.values(problemFlags)).default([])) | ||
.option("--summary, --no-summary", "Whether to print summary information about the different errors") | ||
.option("--emoji, --no-emoji", "Whether to use any emojis") | ||
.option("--color, --no-color", "Whether to use any colors (the FORCE_COLOR env variable is also available)") | ||
.option("--config-path <path>", "Path to config file (default: ./.attw.json)") | ||
.action(async (fileOrDirectory = ".") => { | ||
@@ -61,3 +66,7 @@ var _a; | ||
else { | ||
analysis = await core.checkPackage(await core.createPackageFromNpm(`${result.data.name}@${result.data.version}`)); | ||
analysis = await core.checkPackage(await core.createPackageFromNpm(`${result.data.name}@${result.data.version}`), { | ||
entrypoints: opts.entrypoints, | ||
includeEntrypoints: opts.includeEntrypoints, | ||
excludeEntrypoints: opts.excludeEntrypoints, | ||
}); | ||
} | ||
@@ -98,3 +107,7 @@ } | ||
const data = new Uint8Array(file); | ||
analysis = await core.checkPackage(await core.createPackageFromTarballData(data)); | ||
analysis = await core.checkPackage(await core.createPackageFromTarballData(data), { | ||
entrypoints: opts.entrypoints, | ||
includeEntrypoints: opts.includeEntrypoints, | ||
excludeEntrypoints: opts.excludeEntrypoints, | ||
}); | ||
} | ||
@@ -138,1 +151,2 @@ catch (error) { | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -26,1 +26,2 @@ import * as core from "@arethetypeswrong/core"; | ||
}; | ||
//# sourceMappingURL=problemUtils.js.map |
@@ -41,1 +41,2 @@ import { Command } from "commander"; | ||
} | ||
//# sourceMappingURL=readConfig.js.map |
export * from './typed.js'; | ||
export * from './untyped.js'; | ||
//# sourceMappingURL=index.js.map |
@@ -8,3 +8,3 @@ import * as core from "@arethetypeswrong/core"; | ||
import { moduleKinds, problemFlags, resolutionKinds } from "../problemUtils.js"; | ||
import { tableFlipped } from "./tableFlipped.js"; | ||
import { asciiTable } from "./asciiTable.js"; | ||
import TerminalRenderer from "marked-terminal"; | ||
@@ -14,3 +14,3 @@ export async function typed(analysis, opts) { | ||
const grouped = groupProblemsByKind(problems); | ||
const subpaths = Object.keys(analysis.entrypoints); | ||
const entrypoints = Object.keys(analysis.entrypoints); | ||
marked.setOptions({ | ||
@@ -37,65 +37,81 @@ // @ts-expect-error the types are wrong (haha) | ||
} | ||
const entrypoints = subpaths.map((s) => { | ||
const entrypointNames = entrypoints.map((s) => `"${s === "." ? analysis.packageName : `${analysis.packageName}/${s.substring(2)}`}"`); | ||
const entrypointHeaders = entrypoints.map((s, i) => { | ||
const hasProblems = problems.some((p) => problemAffectsEntrypoint(p, s, analysis)); | ||
const color = hasProblems ? "redBright" : "greenBright"; | ||
if (s === ".") | ||
return chalk.bold[color](`"${analysis.packageName}"`); | ||
else | ||
return chalk.bold[color](`"${analysis.packageName}/${s.substring(2)}"`); | ||
return chalk.bold[color](entrypointNames[i]); | ||
}); | ||
if (opts.format === "table-flipped") { | ||
const table = new Table({ | ||
const getCellContents = memo((entrypoint, resolutionKind) => { | ||
var _a; | ||
const problemsForCell = groupProblemsByKind(filterProblems(problems, analysis, { entrypoint, resolutionKind })); | ||
const resolution = analysis.entrypoints[entrypoint].resolutions[resolutionKind].resolution; | ||
const kinds = Object.keys(problemsForCell); | ||
if (kinds.length) { | ||
return kinds | ||
.map((kind) => (opts.emoji ? `${problemKindInfo[kind].emoji} ` : "") + problemKindInfo[kind].shortDescription) | ||
.join("\n"); | ||
} | ||
const jsonResult = !opts.emoji ? "OK (JSON)" : "🟢 (JSON)"; | ||
const moduleResult = (!opts.emoji ? "OK " : "🟢 ") + moduleKinds[((_a = resolution === null || resolution === void 0 ? void 0 : resolution.moduleKind) === null || _a === void 0 ? void 0 : _a.detectedKind) || ""]; | ||
return (resolution === null || resolution === void 0 ? void 0 : resolution.isJson) ? jsonResult : moduleResult; | ||
}); | ||
const flippedTable = opts.format === "auto" || opts.format === "table-flipped" | ||
? new Table({ | ||
head: ["", ...allResolutionKinds.map((kind) => chalk.reset(resolutionKinds[kind]))], | ||
colWidths: [20, ...allResolutionKinds.map(() => 25)], | ||
}) | ||
: undefined; | ||
if (flippedTable) { | ||
entrypoints.forEach((subpath, i) => { | ||
flippedTable.push([ | ||
entrypointHeaders[i], | ||
...allResolutionKinds.map((resolutionKind) => getCellContents(subpath, resolutionKind)), | ||
]); | ||
}); | ||
subpaths.forEach((subpath, i) => { | ||
const point = entrypoints[i]; | ||
let row = [point]; | ||
row = row.concat(allResolutionKinds.map((kind) => { | ||
var _a; | ||
const problemsForCell = groupProblemsByKind(filterProblems(problems, analysis, { entrypoint: subpath, resolutionKind: kind })); | ||
const resolution = analysis.entrypoints[subpath].resolutions[kind].resolution; | ||
const kinds = Object.keys(problemsForCell); | ||
if (kinds.length) { | ||
return kinds | ||
.map((kind) => (opts.emoji ? `${problemKindInfo[kind].emoji} ` : "") + problemKindInfo[kind].shortDescription) | ||
.join("\n"); | ||
} | ||
const jsonResult = !opts.emoji ? "OK (JSON)" : "🟢 (JSON)"; | ||
const moduleResult = (!opts.emoji ? "OK " : "🟢 ") + moduleKinds[((_a = resolution === null || resolution === void 0 ? void 0 : resolution.moduleKind) === null || _a === void 0 ? void 0 : _a.detectedKind) || ""]; | ||
return (resolution === null || resolution === void 0 ? void 0 : resolution.isJson) ? jsonResult : moduleResult; | ||
})); | ||
table.push(row); | ||
} | ||
const table = opts.format === "auto" || !flippedTable | ||
? new Table({ | ||
head: ["", ...entrypointHeaders], | ||
}) | ||
: undefined; | ||
if (table) { | ||
allResolutionKinds.forEach((kind) => { | ||
table.push([resolutionKinds[kind], ...entrypoints.map((entrypoint) => getCellContents(entrypoint, kind))]); | ||
}); | ||
console.log(table.toString()); | ||
return; | ||
} | ||
const table = new Table({ | ||
head: ["", ...entrypoints], | ||
colWidths: [20, ...entrypoints.map(() => 35)], | ||
}); | ||
allResolutionKinds.forEach((kind) => { | ||
let row = [resolutionKinds[kind]]; | ||
row = row.concat(subpaths.map((subpath) => { | ||
var _a; | ||
const problemsForCell = groupProblemsByKind(filterProblems(problems, analysis, { entrypoint: subpath, resolutionKind: kind })); | ||
const resolution = analysis.entrypoints[subpath].resolutions[kind].resolution; | ||
const kinds = Object.keys(problemsForCell); | ||
if (kinds.length) { | ||
return kinds | ||
.map((kind) => (opts.emoji ? `${problemKindInfo[kind].emoji} ` : "") + problemKindInfo[kind].shortDescription) | ||
.join("\n"); | ||
switch (opts.format) { | ||
case "table": | ||
console.log(table.toString()); | ||
break; | ||
case "table-flipped": | ||
console.log(flippedTable.toString()); | ||
break; | ||
case "ascii": | ||
console.log(asciiTable(table)); | ||
break; | ||
case "auto": | ||
const terminalWidth = process.stdout.columns || 133; // This looks like GitHub Actions' width | ||
if (table.width <= terminalWidth) { | ||
console.log(table.toString()); | ||
} | ||
const jsonResult = !opts.emoji ? "OK (JSON)" : "🟢 (JSON)"; | ||
const moduleResult = (!opts.emoji ? "OK " : "🟢 ") + moduleKinds[((_a = resolution === null || resolution === void 0 ? void 0 : resolution.moduleKind) === null || _a === void 0 ? void 0 : _a.detectedKind) || ""]; | ||
return (resolution === null || resolution === void 0 ? void 0 : resolution.isJson) ? jsonResult : moduleResult; | ||
})); | ||
table.push(row); | ||
}); | ||
if (opts.format === "ascii") { | ||
console.log(tableFlipped(table)); | ||
else if (flippedTable.width <= terminalWidth) { | ||
console.log(flippedTable.toString()); | ||
} | ||
else { | ||
console.log(asciiTable(table)); | ||
} | ||
break; | ||
} | ||
else { | ||
console.log(table.toString()); | ||
} | ||
} | ||
function memo(fn) { | ||
const cache = new Map(); | ||
return (...args) => { | ||
const key = "" + args; | ||
if (cache.has(key)) { | ||
return cache.get(key); | ||
} | ||
const result = fn(...args); | ||
cache.set(key, result); | ||
return result; | ||
}; | ||
} | ||
//# sourceMappingURL=typed.js.map |
@@ -5,1 +5,2 @@ import * as core from "@arethetypeswrong/core"; | ||
} | ||
//# sourceMappingURL=untyped.js.map |
{ | ||
"name": "@arethetypeswrong/cli", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"description": "A CLI tool for arethetypeswrong.github.io", | ||
@@ -23,3 +23,3 @@ "author": "Andrew Branch & ej-shafran", | ||
"files": [ | ||
"dist" | ||
"dist/**/*.js" | ||
], | ||
@@ -49,3 +49,3 @@ "bin": { | ||
"dependencies": { | ||
"@arethetypeswrong/core": "0.5.0", | ||
"@arethetypeswrong/core": "0.6.0", | ||
"chalk": "^4.1.2", | ||
@@ -52,0 +52,0 @@ "cli-table3": "^0.6.3", |
@@ -21,11 +21,23 @@ # arethetypeswrong/cli | ||
The usage is: | ||
The CLI can check an `npm pack`ed tarball: | ||
```shell | ||
npm pack | ||
attw [options] <file-name> | ||
attw cool-package-1.0.0.tgz | ||
# or | ||
attw $(npm pack) | ||
``` | ||
Where `<file-name>` is a required positional argument (the path to a local `.tar.gz` file from `npm pack`). | ||
or pack one in-place by specifying `--pack` and a directory: | ||
```shell | ||
attw --pack . | ||
``` | ||
or check a package from npm: | ||
```shell | ||
attw --from-npm @arethetypeswrong/cli | ||
``` | ||
## Configuration | ||
@@ -35,4 +47,2 @@ | ||
Note that the `--config-path` option cannot be set from the config file :upside_down_face: | ||
### Options | ||
@@ -60,11 +70,33 @@ | ||
### Pack | ||
Specify a directory to run `npm pack` in (instead of specifying a tarball filename), analyze the resulting tarball, and delete it afterwards. | ||
```shell | ||
attw --pack . | ||
``` | ||
#### From NPM | ||
Specify the name (and, optionally, version range) of a package from the NPM registry instead of a local tarball filename. | ||
In the CLI: `--from-npm`, `-p` | ||
```shell | ||
attw --from-npm <package-name> | ||
``` | ||
In the config file, `fromNpm` can be a boolean value. | ||
#### Format | ||
The format to print the output in. Defaults to `table`. | ||
The format to print the output in. Defaults to `auto`. | ||
The available values are: | ||
- `table` | ||
- `table-flipped`, where the resolution kinds are the table's head, and the entry points label the table's rows | ||
- `table`, where columns are entrypoints and rows are resolution kinds | ||
- `table-flipped`, where columns are resolution kinds and rows are entrypoints | ||
- `ascii`, for large tables where the output is clunky | ||
- `raw`, outputs the raw JSON data (overriding all other rendering options) | ||
- `auto`, which picks whichever of the above best fits the terminal width | ||
- `json` outputs the raw JSON data (overriding all other rendering options) | ||
@@ -79,14 +111,12 @@ In the CLI: `--format`, `-f` | ||
#### From NPM | ||
#### Entrypoints | ||
Treat `<file-name>` as the name (and, optionally, version) of a package from the NPM registry. | ||
`attw` automatically discovers package entrypoints by looking at package.json `exports` and subdirectories with additional package.json files. This automatic discovery process can be overridden with the `--entrypoints` option, or altered with the `--include-entrypoints` and `--exclude-entrypoints` options: | ||
In the CLI: `--from-npm`, `-p` | ||
```shell | ||
attw --from-npm <package-name> | ||
attw --pack . --entrypoints . one two three # Just ".", "./one", "./two", "./three" | ||
attw --pack . --include-entrypoints added # Auto-discovered entyrpoints plus "./added" | ||
attw --pack . --exclude-entrypoints styles.css # Auto-discovered entrypoints except "./styles.css" | ||
``` | ||
In the config file, `fromNpm` can be a boolean value. | ||
#### Ignore Rules | ||
@@ -97,2 +127,3 @@ | ||
The available values are: | ||
- `wildcard` | ||
@@ -179,2 +210,1 @@ - `no-resolution` | ||
Cannot be set from within the config file itself. | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22158
347
205
+ Added@arethetypeswrong/core@0.6.0(transitive)
- Removed@arethetypeswrong/core@0.5.0(transitive)
Updated@arethetypeswrong/core@0.6.0