@williamthorsen/nmr 0.38.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.meta/changelog.json +212 -4
- package/.readyup/kits/default.js +124 -104
- package/.readyup/manifest.json +12 -7
- package/CHANGELOG.md +108 -0
- package/README.md +41 -47
- package/agents/README.md +8 -8
- package/agents/guidance/rulebooks/nmr.md +8 -8
- package/bin/ensure-prepublish-hooks.js +1 -1
- package/bin/nmr-clean.js +1 -1
- package/bin/nmr-compile.js +1 -1
- package/bin/nmr-fmt.js +1 -1
- package/bin/nmr-report-catalog.js +1 -1
- package/bin/nmr-report-overrides.js +1 -1
- package/bin/nmr-taze.js +1 -1
- package/bin/nmr.js +1 -1
- package/dist/esm/UserError.d.ts +1 -2
- package/dist/esm/check-cache.d.ts +61 -63
- package/dist/esm/check-cache.js +24 -24
- package/dist/esm/cli-ensure-prepublish-hooks.js +4 -4
- package/dist/esm/commands/build-output.d.ts +37 -38
- package/dist/esm/commands/build-output.js +9 -9
- package/dist/esm/commands/build.d.ts +13 -14
- package/dist/esm/commands/build.js +67 -65
- package/dist/esm/commands/clean.d.ts +6 -6
- package/dist/esm/commands/clean.js +11 -11
- package/dist/esm/commands/ensure-prepublish-hooks.d.ts +7 -7
- package/dist/esm/commands/ensure-prepublish-hooks.js +41 -41
- package/dist/esm/commands/fmt.d.ts +8 -8
- package/dist/esm/commands/fmt.js +33 -33
- package/dist/esm/commands/report-catalog.d.ts +5 -7
- package/dist/esm/commands/report-catalog.js +10 -8
- package/dist/esm/commands/report-overrides.d.ts +0 -2
- package/dist/esm/commands/report-overrides.js +8 -8
- package/dist/esm/commands/taze.d.ts +9 -8
- package/dist/esm/config.d.ts +5 -5
- package/dist/esm/config.js +27 -27
- package/dist/esm/context.d.ts +1 -2
- package/dist/esm/context.js +8 -8
- package/dist/esm/default-scripts.d.ts +5 -6
- package/dist/esm/defineConfig.d.ts +1 -1
- package/dist/esm/git-ignored-paths.d.ts +9 -0
- package/dist/esm/git-ignored-paths.js +10 -0
- package/dist/esm/glyphs.d.ts +3 -3
- package/dist/esm/help.d.ts +4 -4
- package/dist/esm/help.js +21 -21
- package/dist/esm/helpers/clampToBytes.d.ts +4 -5
- package/dist/esm/helpers/clampToBytes.js +3 -3
- package/dist/esm/helpers/config-path.d.ts +0 -2
- package/dist/esm/helpers/createBoundedBuffer.d.ts +3 -3
- package/dist/esm/helpers/createBoundedBuffer.js +2 -2
- package/dist/esm/helpers/deriveExcerpt.d.ts +4 -5
- package/dist/esm/helpers/duration.d.ts +10 -11
- package/dist/esm/helpers/duration.js +7 -7
- package/dist/esm/helpers/filter-selection.d.ts +19 -19
- package/dist/esm/helpers/filter-selection.js +12 -12
- package/dist/esm/helpers/findClosestName.d.ts +1 -1
- package/dist/esm/helpers/findClosestName.js +15 -15
- package/dist/esm/helpers/hook-name.d.ts +2 -5
- package/dist/esm/helpers/package-json.d.ts +11 -10
- package/dist/esm/helpers/package-json.js +26 -25
- package/dist/esm/helpers/readStringValues.d.ts +2 -3
- package/dist/esm/helpers/reportClosing.d.ts +8 -9
- package/dist/esm/helpers/transcript.d.ts +15 -15
- package/dist/esm/helpers/transcript.js +14 -14
- package/dist/esm/helpers/type-guards.d.ts +1 -0
- package/dist/esm/output-style.d.ts +12 -13
- package/dist/esm/prettier.d.ts +2 -2
- package/dist/esm/prettier.js +5 -5
- package/dist/esm/recording.d.ts +25 -20
- package/dist/esm/recording.js +28 -21
- package/dist/esm/replay-assembly.d.ts +10 -10
- package/dist/esm/report-format.d.ts +15 -20
- package/dist/esm/report-format.js +7 -7
- package/dist/esm/reportCliFailure.d.ts +2 -3
- package/dist/esm/resolve-scripts.d.ts +4 -5
- package/dist/esm/resolveBinStyles.d.ts +4 -5
- package/dist/esm/resolveBinStyles.js +3 -3
- package/dist/esm/resolver.d.ts +16 -20
- package/dist/esm/resolver.js +15 -15
- package/dist/esm/runCli.d.ts +6 -6
- package/dist/esm/runCli.js +261 -195
- package/dist/esm/runner.d.ts +20 -20
- package/dist/esm/runner.js +18 -18
- package/dist/esm/steps.d.ts +51 -38
- package/dist/esm/steps.js +32 -27
- package/dist/esm/taze.d.ts +1 -1
- package/dist/esm/tests.d.ts +23 -18
- package/dist/esm/tests.js +21 -9
- package/dist/esm/tiers.d.ts +28 -24
- package/dist/esm/tiers.js +13 -9
- package/dist/esm/types.d.ts +5 -5
- package/dist/esm/verbosity.d.ts +23 -21
- package/dist/esm/verbosity.js +7 -7
- package/dist/esm/verdict.d.ts +39 -32
- package/dist/esm/verdict.js +63 -50
- package/dist/esm/vitest-source-resolution.d.ts +11 -11
- package/dist/esm/vitest-source-resolution.js +49 -47
- package/dist/esm/vitest.d.ts +27 -26
- package/dist/esm/vitest.js +90 -33
- package/dist/esm/workspace.d.ts +6 -22
- package/dist/esm/workspace.js +9 -67
- package/docs/check-cache.md +57 -57
- package/docs/prettier.md +10 -10
- package/docs/reporting.md +48 -44
- package/docs/scripts.md +29 -29
- package/docs/upgrades.md +18 -18
- package/docs/utilities.md +13 -13
- package/docs/vitest.md +68 -66
- package/docs/workspace.md +27 -4
- package/package.json +6 -6
- package/dist/esm/helpers/workspace-patterns.d.ts +0 -8
- package/dist/esm/helpers/workspace-patterns.js +0 -29
package/dist/esm/resolver.d.ts
CHANGED
|
@@ -2,22 +2,22 @@ import { type ScriptRegistry, type ScriptValue } from './resolve-scripts.js';
|
|
|
2
2
|
import { type Step } from './steps.js';
|
|
3
3
|
import type { NmrConfig } from './types.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Replaces the first token of a command with a `devBin` substitute.
|
|
6
6
|
* Relative paths in the replacement are resolved from `monorepoRoot`.
|
|
7
7
|
*/
|
|
8
8
|
export declare function applyDevBin(command: string, devBin: Record<string, string> | undefined, monorepoRoot: string): string;
|
|
9
9
|
/**
|
|
10
10
|
* Applies a `devBin` substitution to each opaque step, leaving nmr's own compositions alone.
|
|
11
11
|
*
|
|
12
|
-
* A structural step names a command nmr resolves for itself, so substituting its first token would replace
|
|
13
|
-
* `nmr` that
|
|
12
|
+
* A structural step names a command that nmr resolves for itself, so substituting its first token would replace
|
|
13
|
+
* the `nmr` that runs the composite rather than the leaf tool that `devBin` documents replacing.
|
|
14
14
|
*/
|
|
15
15
|
export declare function applyDevBinToSteps(steps: readonly Step[], devBin: Record<string, string> | undefined, monorepoRoot: string): readonly Step[];
|
|
16
16
|
/**
|
|
17
17
|
* Where a resolved script was read from.
|
|
18
18
|
*
|
|
19
19
|
* `registry` covers the built-in defaults and the repo-wide config together, which resolution cannot tell
|
|
20
|
-
* apart:
|
|
20
|
+
* apart: It receives the two already merged. A caller that has the config refines the two.
|
|
21
21
|
*/
|
|
22
22
|
export type ScriptOrigin = {
|
|
23
23
|
tier: 'registry';
|
|
@@ -32,13 +32,13 @@ export interface ResolvedScript {
|
|
|
32
32
|
steps: readonly Step[];
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* Expands a script value into the ordered steps it runs as: a string is one opaque step, and an array is one
|
|
35
|
+
* Expands a script value into the ordered steps that it runs as: a string is one opaque step, and an array is one
|
|
36
36
|
* structural step per element.
|
|
37
37
|
*
|
|
38
38
|
* A bare string element and the `{ run }` spec compose the same step. The spec's only addition is the
|
|
39
|
-
* declaration of what the step does with the invocation's trailing arguments, which position cannot
|
|
39
|
+
* declaration of what the step does with the invocation's trailing arguments, which position cannot express.
|
|
40
40
|
*/
|
|
41
|
-
export declare function expandScript(script: ScriptValue,
|
|
41
|
+
export declare function expandScript(script: ScriptValue, isWorkspaceRoot: boolean): readonly Step[];
|
|
42
42
|
/**
|
|
43
43
|
* Returns a description of a script for help output.
|
|
44
44
|
*/
|
|
@@ -47,8 +47,7 @@ export declare function describeScript(script: ScriptValue): string;
|
|
|
47
47
|
* Reads a package.json's `scripts`, rejecting any value that is not a string.
|
|
48
48
|
*
|
|
49
49
|
* npm and pnpm read a script as a string too, so a value of any other type is malformed however it got there.
|
|
50
|
-
* Dropping one silently would run the registry's entry in its place
|
|
51
|
-
* being told a step list resolves a shelled-nmr crossing would otherwise do.
|
|
50
|
+
* Dropping one silently would run the registry's entry in its place.
|
|
52
51
|
*/
|
|
53
52
|
export declare function readPackageJsonScripts(packageDir: string): Record<string, string> | undefined;
|
|
54
53
|
/**
|
|
@@ -62,20 +61,17 @@ export declare function buildWorkspaceRegistry(config: NmrConfig): ScriptRegistr
|
|
|
62
61
|
*/
|
|
63
62
|
export declare function buildRootRegistry(config: NmrConfig): ScriptRegistry;
|
|
64
63
|
/**
|
|
65
|
-
* Returns a `package.json` entry that re-invokes the command it is declared
|
|
66
|
-
* `undefined`
|
|
64
|
+
* Returns a `package.json` entry that re-invokes the command under which it is declared alongside other steps,
|
|
65
|
+
* or `undefined` when the entry does not.
|
|
67
66
|
*
|
|
68
|
-
* Resolution discards a self-referential entry however it reads, so an entry that chains loses the steps it
|
|
67
|
+
* Resolution discards a self-referential entry however it reads, so an entry that chains loses the steps that it
|
|
69
68
|
* chained. This is what an invocation rejects on, read where the command runs rather than raised from
|
|
70
|
-
* resolution:
|
|
69
|
+
* resolution: The same scripts are resolved speculatively, for packages that nobody named.
|
|
71
70
|
*/
|
|
72
71
|
export declare function findChainedSelfReference(packageDir: string | undefined, commandName: string): string | undefined;
|
|
73
72
|
/**
|
|
74
|
-
* Reports whether a `package.json` entry re-invokes the command it is declared
|
|
75
|
-
* re-invocation
|
|
76
|
-
*
|
|
77
|
-
* Honouring one spawns a shell that runs the same command in the same directory, reaching the same entry
|
|
78
|
-
* again without bound, so resolution discards it.
|
|
73
|
+
* Reports whether a `package.json` entry re-invokes the command under which it is declared, wherever the
|
|
74
|
+
* re-invocation appears in it, e.g. `"build": "nmr build"` or `"build": "rdy compile && nmr build"`.
|
|
79
75
|
*/
|
|
80
76
|
export declare function isSelfReferential(script: string, commandName: string, packageDir: string): boolean;
|
|
81
77
|
/**
|
|
@@ -85,6 +81,6 @@ export declare function isSelfReferential(script: string, commandName: string, p
|
|
|
85
81
|
* 3. Per-package overrides (package.json scripts)
|
|
86
82
|
*
|
|
87
83
|
* Returns undefined if the command is not found in the registry. A package.json override of `""` (indicating
|
|
88
|
-
* skip) resolves to a single opaque step
|
|
84
|
+
* skip) resolves to a single opaque step containing it, which renders back to the empty string.
|
|
89
85
|
*/
|
|
90
|
-
export declare function resolveScript(commandName: string, registry: ScriptRegistry, packageDir: string | undefined,
|
|
86
|
+
export declare function resolveScript(commandName: string, registry: ScriptRegistry, packageDir: string | undefined, isWorkspaceRoot: boolean): ResolvedScript | undefined;
|
package/dist/esm/resolver.js
CHANGED
|
@@ -12,13 +12,13 @@ export function applyDevBin(command, devBin, monorepoRoot) {
|
|
|
12
12
|
}
|
|
13
13
|
const spaceIndex = command.indexOf(' ');
|
|
14
14
|
const firstToken = spaceIndex === -1 ? command : command.slice(0, spaceIndex);
|
|
15
|
-
const
|
|
15
|
+
const restOfCommand = spaceIndex === -1 ? '' : command.slice(spaceIndex);
|
|
16
16
|
const replacement = devBin[firstToken];
|
|
17
17
|
if (replacement === undefined) {
|
|
18
18
|
return command;
|
|
19
19
|
}
|
|
20
20
|
const resolvedReplacement = resolveReplacementPaths(replacement, monorepoRoot);
|
|
21
|
-
return resolvedReplacement +
|
|
21
|
+
return resolvedReplacement + restOfCommand;
|
|
22
22
|
}
|
|
23
23
|
export function applyDevBinToSteps(steps, devBin, monorepoRoot) {
|
|
24
24
|
if (!devBin) {
|
|
@@ -40,13 +40,13 @@ function resolveReplacementPaths(replacement, monorepoRoot) {
|
|
|
40
40
|
})
|
|
41
41
|
.join(' ');
|
|
42
42
|
}
|
|
43
|
-
export function expandScript(script,
|
|
43
|
+
export function expandScript(script, isWorkspaceRoot) {
|
|
44
44
|
if (typeof script === 'string') {
|
|
45
45
|
return [{ kind: 'opaque', command: script }];
|
|
46
46
|
}
|
|
47
47
|
return script.map((element) => typeof element === 'string'
|
|
48
|
-
? composeNmrStep(element,
|
|
49
|
-
: composeNmrStep(element.run,
|
|
48
|
+
? composeNmrStep(element, isWorkspaceRoot)
|
|
49
|
+
: composeNmrStep(element.run, isWorkspaceRoot, element.shouldDeclineArguments));
|
|
50
50
|
}
|
|
51
51
|
export function describeScript(script) {
|
|
52
52
|
return typeof script === 'string' ? script : `[${script.map(describeElement).join(', ')}]`;
|
|
@@ -59,9 +59,9 @@ function describeElement(element) {
|
|
|
59
59
|
}
|
|
60
60
|
export function readPackageJsonScripts(packageDir) {
|
|
61
61
|
const file = resolvePackageJsonPath(packageDir);
|
|
62
|
-
let
|
|
62
|
+
let rawText;
|
|
63
63
|
try {
|
|
64
|
-
|
|
64
|
+
rawText = readFileSync(file, 'utf8');
|
|
65
65
|
}
|
|
66
66
|
catch (error) {
|
|
67
67
|
if (hasErrnoCode(error, 'ENOENT')) {
|
|
@@ -69,10 +69,10 @@ export function readPackageJsonScripts(packageDir) {
|
|
|
69
69
|
}
|
|
70
70
|
throw error;
|
|
71
71
|
}
|
|
72
|
-
const
|
|
73
|
-
if (!isObject(
|
|
72
|
+
const parsedManifest = parsePackageJson(rawText, file);
|
|
73
|
+
if (!isObject(parsedManifest))
|
|
74
74
|
return undefined;
|
|
75
|
-
const scripts =
|
|
75
|
+
const scripts = parsedManifest['scripts'];
|
|
76
76
|
if (!isObject(scripts))
|
|
77
77
|
return undefined;
|
|
78
78
|
return readScriptRecord(packageDir, scripts);
|
|
@@ -108,15 +108,15 @@ export function findChainedSelfReference(packageDir, commandName) {
|
|
|
108
108
|
export function isSelfReferential(script, commandName, packageDir) {
|
|
109
109
|
return readSelfReference({ anchoredAtRoot: isMonorepoRoot(packageDir), commandName, script }) !== undefined;
|
|
110
110
|
}
|
|
111
|
-
export function resolveScript(commandName, registry, packageDir,
|
|
111
|
+
export function resolveScript(commandName, registry, packageDir, isWorkspaceRoot) {
|
|
112
112
|
if (packageDir) {
|
|
113
113
|
const pkgScripts = readPackageJsonScripts(packageDir);
|
|
114
114
|
if (pkgScripts && Object.hasOwn(pkgScripts, commandName)) {
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
115
|
+
const overrideCommand = pkgScripts[commandName];
|
|
116
|
+
if (overrideCommand !== undefined && !isSelfReferential(overrideCommand, commandName, packageDir)) {
|
|
117
117
|
return {
|
|
118
118
|
origin: { tier: 'package', file: resolvePackageJsonPath(packageDir), key: commandName },
|
|
119
|
-
steps: [{ kind: 'opaque', command:
|
|
119
|
+
steps: [{ kind: 'opaque', command: overrideCommand }],
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -128,5 +128,5 @@ export function resolveScript(commandName, registry, packageDir, workspaceRoot)
|
|
|
128
128
|
if (registryEntry === undefined) {
|
|
129
129
|
return undefined;
|
|
130
130
|
}
|
|
131
|
-
return { origin: { tier: 'registry', key: commandName }, steps: expandScript(registryEntry,
|
|
131
|
+
return { origin: { tier: 'registry', key: commandName }, steps: expandScript(registryEntry, isWorkspaceRoot) };
|
|
132
132
|
}
|
package/dist/esm/runCli.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Writable } from 'node:stream';
|
|
2
2
|
/**
|
|
3
|
-
* Marks a run made on a delegating caller's behalf,
|
|
4
|
-
* rather than failing.
|
|
3
|
+
* Marks a run made on a delegating caller's behalf, in which a command that the registry does not define, and a
|
|
4
|
+
* `--log` with nothing to show, exit 0 rather than failing.
|
|
5
5
|
*/
|
|
6
6
|
export declare const RUN_IF_PRESENT_ENV_VAR = "NMR_RUN_IF_PRESENT";
|
|
7
7
|
/** @internal */
|
|
@@ -10,11 +10,11 @@ export interface RunCliOptions {
|
|
|
10
10
|
args: string[];
|
|
11
11
|
/** Working directory used to resolve the nmr execution context. */
|
|
12
12
|
cwd: string;
|
|
13
|
-
/** Environment
|
|
13
|
+
/** Environment from which `runCli` reads its settings, and the base of the one that its children inherit. */
|
|
14
14
|
env: NodeJS.ProcessEnv;
|
|
15
|
-
/** Stream for normal output
|
|
15
|
+
/** Stream for normal output: help, version, verdicts, recordings, and override notices. */
|
|
16
16
|
stdout: Writable;
|
|
17
|
-
/** Stream for
|
|
17
|
+
/** Stream for errors, warnings, and debug notes. */
|
|
18
18
|
stderr: Writable;
|
|
19
19
|
}
|
|
20
20
|
/** @internal */
|
|
@@ -23,7 +23,7 @@ export interface RunCliResult {
|
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Executes the nmr CLI flow in-process and returns the resulting exit code.
|
|
26
|
-
*
|
|
26
|
+
* Does not hold global state, does not read `process.*` globals, and never calls `process.exit`.
|
|
27
27
|
*
|
|
28
28
|
* @internal
|
|
29
29
|
*/
|