@nifrajs/cli 3.3.0 → 4.0.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/README.md +42 -3
- package/dist/app-files.d.ts +11 -0
- package/dist/app-files.d.ts.map +1 -0
- package/dist/app-files.js +34 -0
- package/dist/app-files.js.map +1 -0
- package/dist/assure-hydration.d.ts +7 -1
- package/dist/assure-hydration.d.ts.map +1 -1
- package/dist/assure-hydration.js +128 -43
- package/dist/assure-hydration.js.map +1 -1
- package/dist/assure.d.ts.map +1 -1
- package/dist/assure.js +16 -2
- package/dist/assure.js.map +1 -1
- package/dist/capabilities-tool.d.ts +5 -1
- package/dist/capabilities-tool.d.ts.map +1 -1
- package/dist/capabilities-tool.js +32 -10
- package/dist/capabilities-tool.js.map +1 -1
- package/dist/cdn-check.d.ts +41 -0
- package/dist/cdn-check.d.ts.map +1 -0
- package/dist/cdn-check.js +207 -0
- package/dist/cdn-check.js.map +1 -0
- package/dist/check-diagnostics.d.ts +7 -15
- package/dist/check-diagnostics.d.ts.map +1 -1
- package/dist/check-diagnostics.js +162 -713
- package/dist/check-diagnostics.js.map +1 -1
- package/dist/check-scan.d.ts +58 -7
- package/dist/check-scan.d.ts.map +1 -1
- package/dist/check-scan.js +323 -62
- package/dist/check-scan.js.map +1 -1
- package/dist/check.d.ts +1 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +145 -54
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts +42 -16
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +306 -87
- package/dist/cli.js.map +1 -1
- package/dist/command-catalog.d.ts +60 -5
- package/dist/command-catalog.d.ts.map +1 -1
- package/dist/command-catalog.js +298 -33
- package/dist/command-catalog.js.map +1 -1
- package/dist/config-target.d.ts +8 -0
- package/dist/config-target.d.ts.map +1 -0
- package/dist/config-target.js +45 -0
- package/dist/config-target.js.map +1 -0
- package/dist/contracts.d.ts +3 -2
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +56 -16
- package/dist/contracts.js.map +1 -1
- package/dist/db-audit.d.ts +37 -0
- package/dist/db-audit.d.ts.map +1 -0
- package/dist/db-audit.js +99 -0
- package/dist/db-audit.js.map +1 -0
- package/dist/db-child.d.ts +64 -0
- package/dist/db-child.d.ts.map +1 -0
- package/dist/db-child.js +213 -0
- package/dist/db-child.js.map +1 -0
- package/dist/db-config.d.ts +60 -0
- package/dist/db-config.d.ts.map +1 -0
- package/dist/db-config.js +176 -0
- package/dist/db-config.js.map +1 -0
- package/dist/db-tool.d.ts +84 -0
- package/dist/db-tool.d.ts.map +1 -0
- package/dist/db-tool.js +537 -0
- package/dist/db-tool.js.map +1 -0
- package/dist/dev-bun-config.d.ts +20 -13
- package/dist/dev-bun-config.d.ts.map +1 -1
- package/dist/dev-bun-config.js +98 -41
- package/dist/dev-bun-config.js.map +1 -1
- package/dist/dev-feed-tool.d.ts +106 -0
- package/dist/dev-feed-tool.d.ts.map +1 -0
- package/dist/dev-feed-tool.js +713 -0
- package/dist/dev-feed-tool.js.map +1 -0
- package/dist/dev-server-client.d.ts +67 -0
- package/dist/dev-server-client.d.ts.map +1 -0
- package/dist/dev-server-client.js +195 -0
- package/dist/dev-server-client.js.map +1 -0
- package/dist/diagnostics.d.ts +86 -0
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +85 -0
- package/dist/diagnostics.js.map +1 -1
- package/dist/diff-tool.d.ts +3 -3
- package/dist/diff-tool.d.ts.map +1 -1
- package/dist/diff-tool.js +6 -5
- package/dist/diff-tool.js.map +1 -1
- package/dist/docs-search.d.ts.map +1 -1
- package/dist/docs-search.js +12 -4
- package/dist/docs-search.js.map +1 -1
- package/dist/doctor.d.ts +17 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +76 -15
- package/dist/doctor.js.map +1 -1
- package/dist/env-file.d.ts +15 -0
- package/dist/env-file.d.ts.map +1 -1
- package/dist/env-file.js +73 -1
- package/dist/env-file.js.map +1 -1
- package/dist/fix-recipes.d.ts.map +1 -1
- package/dist/fix-recipes.js +41 -21
- package/dist/fix-recipes.js.map +1 -1
- package/dist/frontend-guidance.js +5 -5
- package/dist/frontend-guidance.js.map +1 -1
- package/dist/i18n-check.d.ts +16 -0
- package/dist/i18n-check.d.ts.map +1 -0
- package/dist/i18n-check.js +154 -0
- package/dist/i18n-check.js.map +1 -0
- package/dist/init-agents.d.ts +49 -13
- package/dist/init-agents.d.ts.map +1 -1
- package/dist/init-agents.js +239 -34
- package/dist/init-agents.js.map +1 -1
- package/dist/internal/code-unit-order.d.ts +4 -0
- package/dist/internal/code-unit-order.d.ts.map +1 -0
- package/dist/internal/code-unit-order.js +6 -0
- package/dist/internal/code-unit-order.js.map +1 -0
- package/dist/internal/script-kind.d.ts +7 -0
- package/dist/internal/script-kind.d.ts.map +1 -0
- package/dist/internal/script-kind.js +12 -0
- package/dist/internal/script-kind.js.map +1 -0
- package/dist/internal/source-facts.d.ts +5 -0
- package/dist/internal/source-facts.d.ts.map +1 -1
- package/dist/internal/source-facts.js +61 -5
- package/dist/internal/source-facts.js.map +1 -1
- package/dist/internal/typescript-import.d.ts +49 -24
- package/dist/internal/typescript-import.d.ts.map +1 -1
- package/dist/internal/typescript-import.js +507 -67
- package/dist/internal/typescript-import.js.map +1 -1
- package/dist/introspect.d.ts +6 -4
- package/dist/introspect.d.ts.map +1 -1
- package/dist/introspect.js +93 -74
- package/dist/introspect.js.map +1 -1
- package/dist/learn.js +3 -3
- package/dist/learn.js.map +1 -1
- package/dist/levels-tool.d.ts +10 -0
- package/dist/levels-tool.d.ts.map +1 -1
- package/dist/levels-tool.js +33 -3
- package/dist/levels-tool.js.map +1 -1
- package/dist/load.d.ts +71 -16
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js +78 -18
- package/dist/load.js.map +1 -1
- package/dist/manifest-tool.d.ts.map +1 -1
- package/dist/manifest-tool.js +3 -2
- package/dist/manifest-tool.js.map +1 -1
- package/dist/mcp-app-tool.d.ts.map +1 -1
- package/dist/mcp-app-tool.js +2 -0
- package/dist/mcp-app-tool.js.map +1 -1
- package/dist/mcp-context.d.ts.map +1 -1
- package/dist/mcp-context.js +5 -6
- package/dist/mcp-context.js.map +1 -1
- package/dist/mcp-delegate.d.ts +57 -0
- package/dist/mcp-delegate.d.ts.map +1 -0
- package/dist/mcp-delegate.js +130 -0
- package/dist/mcp-delegate.js.map +1 -0
- package/dist/mcp-docs-tools.d.ts.map +1 -1
- package/dist/mcp-docs-tools.js +23 -5
- package/dist/mcp-docs-tools.js.map +1 -1
- package/dist/mcp-exec.d.ts +3 -0
- package/dist/mcp-exec.d.ts.map +1 -1
- package/dist/mcp-exec.js +263 -131
- package/dist/mcp-exec.js.map +1 -1
- package/dist/mcp-http.d.ts.map +1 -1
- package/dist/mcp-http.js +20 -5
- package/dist/mcp-http.js.map +1 -1
- package/dist/mcp-io.d.ts +26 -0
- package/dist/mcp-io.d.ts.map +1 -1
- package/dist/mcp-io.js +113 -0
- package/dist/mcp-io.js.map +1 -1
- package/dist/mcp-isolate.d.ts +48 -0
- package/dist/mcp-isolate.d.ts.map +1 -0
- package/dist/mcp-isolate.js +222 -0
- package/dist/mcp-isolate.js.map +1 -0
- package/dist/mcp-path.d.ts +10 -0
- package/dist/mcp-path.d.ts.map +1 -0
- package/dist/mcp-path.js +51 -0
- package/dist/mcp-path.js.map +1 -0
- package/dist/mcp-project-child.d.ts +74 -0
- package/dist/mcp-project-child.d.ts.map +1 -0
- package/dist/mcp-project-child.js +130 -0
- package/dist/mcp-project-child.js.map +1 -0
- package/dist/mcp-reflect.d.ts.map +1 -1
- package/dist/mcp-reflect.js +2 -2
- package/dist/mcp-reflect.js.map +1 -1
- package/dist/mcp-render.d.ts.map +1 -1
- package/dist/mcp-render.js +64 -45
- package/dist/mcp-render.js.map +1 -1
- package/dist/mcp-root.d.ts +37 -9
- package/dist/mcp-root.d.ts.map +1 -1
- package/dist/mcp-root.js +124 -25
- package/dist/mcp-root.js.map +1 -1
- package/dist/mcp-run.d.ts +18 -1
- package/dist/mcp-run.d.ts.map +1 -1
- package/dist/mcp-run.js +159 -55
- package/dist/mcp-run.js.map +1 -1
- package/dist/mcp-ws.js +4 -1
- package/dist/mcp-ws.js.map +1 -1
- package/dist/mcp.d.ts +18 -5
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +165 -82
- package/dist/mcp.js.map +1 -1
- package/dist/migrate-layout.d.ts +44 -0
- package/dist/migrate-layout.d.ts.map +1 -0
- package/dist/migrate-layout.js +982 -0
- package/dist/migrate-layout.js.map +1 -0
- package/dist/openapi-tool.d.ts +2 -2
- package/dist/openapi-tool.d.ts.map +1 -1
- package/dist/openapi-tool.js.map +1 -1
- package/dist/openapi-types.d.ts +2 -1
- package/dist/openapi-types.d.ts.map +1 -1
- package/dist/openapi-types.js +240 -12
- package/dist/openapi-types.js.map +1 -1
- package/dist/pipeline-report.d.ts +3 -2
- package/dist/pipeline-report.d.ts.map +1 -1
- package/dist/pipeline-report.js +19 -16
- package/dist/pipeline-report.js.map +1 -1
- package/dist/port.d.ts +5 -4
- package/dist/port.d.ts.map +1 -1
- package/dist/port.js +46 -29
- package/dist/port.js.map +1 -1
- package/dist/project-facts.d.ts +28 -4
- package/dist/project-facts.d.ts.map +1 -1
- package/dist/project-facts.js +12 -2
- package/dist/project-facts.js.map +1 -1
- package/dist/recipes/4.0.0.d.ts +9 -0
- package/dist/recipes/4.0.0.d.ts.map +1 -0
- package/dist/recipes/4.0.0.js +34 -0
- package/dist/recipes/4.0.0.js.map +1 -0
- package/dist/recipes/index.d.ts.map +1 -1
- package/dist/recipes/index.js +2 -0
- package/dist/recipes/index.js.map +1 -1
- package/dist/release-verification.d.ts +11 -1
- package/dist/release-verification.d.ts.map +1 -1
- package/dist/release-verification.js +47 -4
- package/dist/release-verification.js.map +1 -1
- package/dist/review.d.ts +21 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +823 -0
- package/dist/review.js.map +1 -0
- package/dist/route-types.d.ts +28 -0
- package/dist/route-types.d.ts.map +1 -0
- package/dist/route-types.js +106 -0
- package/dist/route-types.js.map +1 -0
- package/dist/rules/codes.d.ts +9 -0
- package/dist/rules/codes.d.ts.map +1 -1
- package/dist/rules/codes.js +9 -0
- package/dist/rules/codes.js.map +1 -1
- package/dist/rules/data-guard.d.ts +12 -0
- package/dist/rules/data-guard.d.ts.map +1 -0
- package/dist/rules/data-guard.js +213 -0
- package/dist/rules/data-guard.js.map +1 -0
- package/dist/rules/index.d.ts +3 -0
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +17 -5
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/islands.d.ts.map +1 -1
- package/dist/rules/islands.js +7 -4
- package/dist/rules/islands.js.map +1 -1
- package/dist/rules/legacy.d.ts +3 -1
- package/dist/rules/legacy.d.ts.map +1 -1
- package/dist/rules/legacy.js +829 -34
- package/dist/rules/legacy.js.map +1 -1
- package/dist/rules/nano.d.ts.map +1 -1
- package/dist/rules/nano.js +15 -6
- package/dist/rules/nano.js.map +1 -1
- package/dist/rules/pages.d.ts +15 -0
- package/dist/rules/pages.d.ts.map +1 -0
- package/dist/rules/pages.js +88 -0
- package/dist/rules/pages.js.map +1 -0
- package/dist/rules/routes.d.ts +11 -0
- package/dist/rules/routes.d.ts.map +1 -1
- package/dist/rules/routes.js +180 -2
- package/dist/rules/routes.js.map +1 -1
- package/dist/rules/secrets.d.ts +10 -0
- package/dist/rules/secrets.d.ts.map +1 -0
- package/dist/rules/secrets.js +169 -0
- package/dist/rules/secrets.js.map +1 -0
- package/dist/rules/security.d.ts +7 -0
- package/dist/rules/security.d.ts.map +1 -1
- package/dist/rules/security.js +171 -65
- package/dist/rules/security.js.map +1 -1
- package/dist/rules/typescript.d.ts +16 -0
- package/dist/rules/typescript.d.ts.map +1 -0
- package/dist/rules/typescript.js +59 -0
- package/dist/rules/typescript.js.map +1 -0
- package/dist/rules/zones.d.ts +17 -0
- package/dist/rules/zones.d.ts.map +1 -0
- package/dist/rules/zones.js +174 -0
- package/dist/rules/zones.js.map +1 -0
- package/dist/scaffold.d.ts +25 -12
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +154 -90
- package/dist/scaffold.js.map +1 -1
- package/dist/sdk.d.ts +17 -3
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +941 -153
- package/dist/sdk.js.map +1 -1
- package/dist/search-terms.d.ts +2 -0
- package/dist/search-terms.d.ts.map +1 -1
- package/dist/search-terms.js +23 -8
- package/dist/search-terms.js.map +1 -1
- package/dist/smoke.d.ts +79 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/smoke.js +494 -0
- package/dist/smoke.js.map +1 -0
- package/dist/sync-manifest.d.ts.map +1 -1
- package/dist/sync-manifest.js +2 -1
- package/dist/sync-manifest.js.map +1 -1
- package/dist/sync-routes.d.ts +4 -3
- package/dist/sync-routes.d.ts.map +1 -1
- package/dist/sync-routes.js +4 -3
- package/dist/sync-routes.js.map +1 -1
- package/dist/test-tool.d.ts.map +1 -1
- package/dist/test-tool.js +30 -11
- package/dist/test-tool.js.map +1 -1
- package/dist/types-search.d.ts.map +1 -1
- package/dist/types-search.js +11 -5
- package/dist/types-search.js.map +1 -1
- package/dist/upgrade.d.ts +36 -6
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +167 -29
- package/dist/upgrade.js.map +1 -1
- package/dist/verification-plan.d.ts.map +1 -1
- package/dist/verification-plan.js +8 -0
- package/dist/verification-plan.js.map +1 -1
- package/dist/verification.d.ts.map +1 -1
- package/dist/verification.js +45 -12
- package/dist/verification.js.map +1 -1
- package/dist/web-app-options.d.ts +19 -0
- package/dist/web-app-options.d.ts.map +1 -0
- package/dist/web-app-options.js +49 -0
- package/dist/web-app-options.js.map +1 -0
- package/dist/work-graph.d.ts +3 -0
- package/dist/work-graph.d.ts.map +1 -1
- package/dist/work-graph.js +33 -16
- package/dist/work-graph.js.map +1 -1
- package/docs/examples.json +185 -29
- package/docs/llms-full.txt +4123 -548
- package/docs/types.json +14391 -10060
- package/package.json +19 -11
- package/src/app-files.ts +40 -0
- package/src/assure-hydration.ts +139 -46
- package/src/assure.ts +17 -2
- package/src/capabilities-tool.ts +35 -9
- package/src/cdn-check.ts +268 -0
- package/src/check-diagnostics.ts +199 -797
- package/src/check-scan.ts +394 -63
- package/src/check.ts +146 -58
- package/src/cli.ts +347 -92
- package/src/command-catalog.ts +407 -45
- package/src/config-target.ts +47 -0
- package/src/contracts.ts +66 -15
- package/src/db-audit.ts +128 -0
- package/src/db-child.ts +285 -0
- package/src/db-config.ts +224 -0
- package/src/db-tool.ts +690 -0
- package/src/dev-bun-config.ts +116 -40
- package/src/dev-feed-tool.ts +912 -0
- package/src/dev-server-client.ts +267 -0
- package/src/diagnostics.ts +179 -0
- package/src/diff-tool.ts +6 -5
- package/src/docs-search.ts +10 -3
- package/src/doctor.ts +98 -15
- package/src/env-file.ts +78 -1
- package/src/fix-recipes.ts +44 -31
- package/src/frontend-guidance.ts +5 -5
- package/src/i18n-check.ts +179 -0
- package/src/init-agents.ts +301 -38
- package/src/internal/code-unit-order.ts +5 -0
- package/src/internal/script-kind.ts +11 -0
- package/src/internal/source-facts.ts +96 -22
- package/src/internal/typescript-import.ts +663 -68
- package/src/introspect.ts +93 -82
- package/src/learn.ts +3 -3
- package/src/levels-tool.ts +47 -2
- package/src/load.ts +144 -32
- package/src/manifest-tool.ts +3 -2
- package/src/mcp-app-tool.ts +2 -0
- package/src/mcp-context.ts +5 -7
- package/src/mcp-delegate.ts +162 -0
- package/src/mcp-docs-tools.ts +23 -5
- package/src/mcp-exec.ts +301 -161
- package/src/mcp-http.ts +22 -5
- package/src/mcp-io.ts +130 -0
- package/src/mcp-isolate.ts +287 -0
- package/src/mcp-path.ts +50 -0
- package/src/mcp-project-child.ts +182 -0
- package/src/mcp-reflect.ts +3 -2
- package/src/mcp-render.ts +72 -42
- package/src/mcp-root.ts +130 -24
- package/src/mcp-run.ts +190 -56
- package/src/mcp-ws.ts +4 -1
- package/src/mcp.ts +193 -91
- package/src/migrate-layout.ts +1121 -0
- package/src/openapi-tool.ts +7 -3
- package/src/openapi-types.ts +315 -13
- package/src/pipeline-report.ts +22 -18
- package/src/port.ts +53 -30
- package/src/project-facts.ts +42 -8
- package/src/recipes/4.0.0.ts +35 -0
- package/src/recipes/index.ts +2 -0
- package/src/release-verification.ts +74 -5
- package/src/review.ts +988 -0
- package/src/route-types.ts +133 -0
- package/src/rules/codes.ts +9 -0
- package/src/rules/data-guard.ts +230 -0
- package/src/rules/index.ts +18 -5
- package/src/rules/islands.ts +12 -4
- package/src/rules/legacy.ts +947 -35
- package/src/rules/nano.ts +18 -6
- package/src/rules/pages.ts +99 -0
- package/src/rules/routes.ts +181 -2
- package/src/rules/secrets.ts +174 -0
- package/src/rules/security.ts +198 -70
- package/src/rules/typescript.ts +77 -0
- package/src/rules/zones.ts +195 -0
- package/src/scaffold.ts +175 -98
- package/src/sdk.ts +1215 -158
- package/src/search-terms.ts +24 -7
- package/src/smoke.ts +607 -0
- package/src/sync-manifest.ts +2 -1
- package/src/sync-routes.ts +4 -3
- package/src/test-tool.ts +32 -11
- package/src/types-search.ts +11 -4
- package/src/upgrade.ts +205 -25
- package/src/verification-plan.ts +27 -0
- package/src/verification.ts +50 -12
- package/src/web-app-options.ts +57 -0
- package/src/work-graph.ts +40 -16
package/dist/test-tool.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { readHeadTail } from "./mcp-io.js";
|
|
2
|
+
import { mcpProjectPathError, resolveMcpProjectPath } from "./mcp-path.js";
|
|
1
3
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
2
4
|
const MAX_TIMEOUT_MS = 300_000;
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
+
const HEAD_CHARS = 4_000;
|
|
6
|
+
const TAIL_CHARS = 8_000;
|
|
7
|
+
const MAX_OUTPUT_CHARS = HEAD_CHARS + TAIL_CHARS;
|
|
8
|
+
function normalizePattern(value, root) {
|
|
5
9
|
if (value === undefined || value === null)
|
|
6
10
|
return undefined;
|
|
7
11
|
if (typeof value !== "string")
|
|
@@ -17,6 +21,9 @@ function normalizePattern(value) {
|
|
|
17
21
|
// `pattern` narrows test files; it is not a remote flag injection surface.
|
|
18
22
|
if (pattern.startsWith("-"))
|
|
19
23
|
throw new Error("pattern must be a file/path pattern, not a CLI flag");
|
|
24
|
+
// `bun test` runs any `./`, `../` or absolute path it is given, so a pattern stays inside the project.
|
|
25
|
+
if (resolveMcpProjectPath(root, pattern) === null)
|
|
26
|
+
throw new Error(mcpProjectPathError("pattern", pattern));
|
|
20
27
|
return pattern;
|
|
21
28
|
}
|
|
22
29
|
function normalizeTimeout(value) {
|
|
@@ -28,11 +35,17 @@ function normalizeTimeout(value) {
|
|
|
28
35
|
return Math.min(Math.max(Math.trunc(value), 1_000), MAX_TIMEOUT_MS);
|
|
29
36
|
}
|
|
30
37
|
const ANSI = new RegExp(`${String.fromCharCode(27)}\\[[0-?]*[ -/]*[@-~]`, "g");
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
// A UTF-8 character is at most four bytes, so these hold every character the result can show.
|
|
39
|
+
const HEAD_BYTES = HEAD_CHARS * 4;
|
|
40
|
+
const TAIL_BYTES = TAIL_CHARS * 4;
|
|
41
|
+
function clean(output) {
|
|
42
|
+
const strip = (text) => text.replace(ANSI, "");
|
|
43
|
+
if (output.droppedBytes > 0)
|
|
44
|
+
return `${strip(output.head).slice(0, HEAD_CHARS)}\n…(trimmed more than ${output.droppedBytes} bytes)…\n${strip(output.tail).slice(-TAIL_CHARS)}`;
|
|
45
|
+
const stripped = strip(output.head + output.tail);
|
|
33
46
|
return stripped.length <= MAX_OUTPUT_CHARS
|
|
34
47
|
? stripped
|
|
35
|
-
: `${stripped.slice(0,
|
|
48
|
+
: `${stripped.slice(0, HEAD_CHARS)}\n…(trimmed ${stripped.length - MAX_OUTPUT_CHARS} chars)…\n${stripped.slice(-TAIL_CHARS)}`;
|
|
36
49
|
}
|
|
37
50
|
function firstNumber(pattern, text) {
|
|
38
51
|
const match = pattern.exec(text);
|
|
@@ -58,7 +71,7 @@ export async function collectTestResult(cwd, args = {}, opts = {}) {
|
|
|
58
71
|
let pattern;
|
|
59
72
|
let timeoutMs;
|
|
60
73
|
try {
|
|
61
|
-
pattern = normalizePattern(args.pattern);
|
|
74
|
+
pattern = normalizePattern(args.pattern, cwd);
|
|
62
75
|
timeoutMs = normalizeTimeout(args.timeoutMs);
|
|
63
76
|
}
|
|
64
77
|
catch (err) {
|
|
@@ -92,8 +105,11 @@ export async function collectTestResult(cwd, args = {}, opts = {}) {
|
|
|
92
105
|
: "cancelled",
|
|
93
106
|
};
|
|
94
107
|
}
|
|
95
|
-
|
|
108
|
+
// The running Bun, not the first `bun` on PATH: an MCP client may start the server with no `bun` there.
|
|
109
|
+
const proc = Bun.spawn([process.execPath, ...command.slice(1)], {
|
|
96
110
|
cwd,
|
|
111
|
+
// Explicit: without `env`, Bun passes the environment it started with, missing `--env-file` values.
|
|
112
|
+
env: process.env,
|
|
97
113
|
stdout: "pipe",
|
|
98
114
|
stderr: "pipe",
|
|
99
115
|
});
|
|
@@ -108,13 +124,16 @@ export async function collectTestResult(cwd, args = {}, opts = {}) {
|
|
|
108
124
|
timedOut = true;
|
|
109
125
|
proc.kill();
|
|
110
126
|
}, timeoutMs);
|
|
111
|
-
|
|
112
|
-
let
|
|
127
|
+
const empty = { head: "", tail: "", droppedBytes: 0 };
|
|
128
|
+
let stdoutRaw = empty;
|
|
129
|
+
let stderrRaw = empty;
|
|
113
130
|
let exitCode = null;
|
|
114
131
|
try {
|
|
132
|
+
// Drained to the end but held to what the result shows, so a test run that prints without limit
|
|
133
|
+
// cannot grow the server's memory with it.
|
|
115
134
|
const result = await Promise.all([
|
|
116
|
-
|
|
117
|
-
|
|
135
|
+
readHeadTail(proc.stdout, HEAD_BYTES, TAIL_BYTES),
|
|
136
|
+
readHeadTail(proc.stderr, HEAD_BYTES, TAIL_BYTES),
|
|
118
137
|
proc.exited,
|
|
119
138
|
]);
|
|
120
139
|
stdoutRaw = result[0];
|
package/dist/test-tool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-tool.js","sourceRoot":"","sources":["../src/test-tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test-tool.js","sourceRoot":"","sources":["../src/test-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-search.d.ts","sourceRoot":"","sources":["../src/types-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"types-search.d.ts","sourceRoot":"","sources":["../src/types-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAA;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAqBD;6BAC6B;AAC7B,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAGjF;AAED,oGAAoG;AACpG,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,UAAU,EAAE,CAoBd;AAuDD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,MAAM,EACb,IAAI,UAAQ,GACX,MAAM,CA2BR;AAMD,iGAAiG;AACjG,wBAAgB,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,CAalE"}
|
package/dist/types-search.js
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* Lookup by `name` is exact (case-insensitive); `query` keyword-scores over the name (heavy) + the
|
|
9
9
|
* signature/doc body; no args → a per-package index of the available type names.
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { codeUnitOrder } from "./internal/code-unit-order.js";
|
|
12
|
+
import { countBodyHits, queryTermGroups, tokenize, tokenSetScore } from "./search-terms.js";
|
|
12
13
|
const preparedTypesCache = new WeakMap();
|
|
13
14
|
const prepareTypes = (types) => {
|
|
14
15
|
const cached = preparedTypesCache.get(types);
|
|
@@ -37,15 +38,20 @@ export function searchTypes(types, query, limit) {
|
|
|
37
38
|
for (const prepared of prepareTypes(types)) {
|
|
38
39
|
const t = prepared.type;
|
|
39
40
|
let score = 0;
|
|
41
|
+
let nameTermMatches = 0;
|
|
40
42
|
for (const term of terms) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
const nameScore = tokenSetScore(prepared.nameTokens, term);
|
|
44
|
+
if (nameScore > 0) {
|
|
45
|
+
nameTermMatches += 1;
|
|
46
|
+
score += 8 + nameScore * 4;
|
|
47
|
+
}
|
|
43
48
|
score += countBodyHits(prepared.bodyLower, term, 4);
|
|
44
49
|
}
|
|
50
|
+
score += nameTermMatches * 4;
|
|
45
51
|
if (score > 0)
|
|
46
52
|
scored.push({ ...t, score });
|
|
47
53
|
}
|
|
48
|
-
return scored.sort((a, b) => b.score - a.score || a.name
|
|
54
|
+
return scored.sort((a, b) => b.score - a.score || codeUnitOrder(a.name, b.name)).slice(0, limit);
|
|
49
55
|
}
|
|
50
56
|
function renderEntry(t) {
|
|
51
57
|
const head = `## ${t.name} - ${t.kind}, \`${t.package}\``;
|
|
@@ -124,7 +130,7 @@ export function renderTypesResult(types, name, query, limit, full = false) {
|
|
|
124
130
|
byPkg.set(t.package, list);
|
|
125
131
|
}
|
|
126
132
|
const index = [...byPkg.entries()]
|
|
127
|
-
.sort(([a], [b]) => a
|
|
133
|
+
.sort(([a], [b]) => codeUnitOrder(a, b))
|
|
128
134
|
.map(([pkg, names]) => `- **${pkg}**: ${names.sort().join(", ")}`)
|
|
129
135
|
.join("\n");
|
|
130
136
|
return `# nifra types - index (${types.length} exported symbols; pass \`name\` for the exact declaration, or \`query\` to search)\n\nSignatures are generated from the built \`.d.ts\` - authoritative + complete. Use this instead of reading any \`.d.ts\` file.\n\n${index}`;
|
package/dist/types-search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-search.js","sourceRoot":"","sources":["../src/types-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"types-search.js","sourceRoot":"","sources":["../src/types-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAsB3F,MAAM,kBAAkB,GAAG,IAAI,OAAO,EAAiD,CAAA;AACvF,MAAM,YAAY,GAAG,CAAC,KAA2B,EAA2B,EAAE;IAC5E,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IAC5C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAA;IACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI;QACJ,UAAU,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,SAAS,EAAE,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE;KAC/D,CAAC,CAAC,CAAA;IACH,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACvC,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED;6BAC6B;AAC7B,MAAM,UAAU,UAAU,CAAC,KAA2B,EAAE,IAAY;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACxC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAA;AAC7D,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CACzB,KAA2B,EAC3B,KAAa,EACb,KAAa;IAEb,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IACjC,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,KAAK,MAAM,QAAQ,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAA;QACvB,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,IAAI,eAAe,GAAG,CAAC,CAAA;QACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;YAC1D,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,eAAe,IAAI,CAAC,CAAA;gBACpB,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC,CAAA;YAC5B,CAAC;YACD,KAAK,IAAI,aAAa,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACrD,CAAC;QACD,KAAK,IAAI,eAAe,GAAG,CAAC,CAAA;QAC5B,IAAI,KAAK,GAAG,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;AAClG,CAAC;AAED,SAAS,WAAW,CAAC,CAAY;IAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,IAAI,CAAA;IACzD,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;IACrC,OAAO,GAAG,IAAI,iBAAiB,GAAG,GAAG,CAAC,CAAC,SAAS,UAAU,CAAA;AAC5D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAAG,GAAG,CAAA;AAEhC,kGAAkG;AAClG,SAAS,SAAS,CAAC,GAAuB;IACxC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IAChC,MAAM,IAAI,GAAG,GAAG;SACb,OAAO,CAAC,sBAAsB,EAAE,GAAG,CAAC;SACpC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAA;IACT,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACnC,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAA;IAC3D,OAAO,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC1E,CAAC;AAED,0EAA0E;AAC1E,SAAS,iBAAiB,CAAC,SAAiB;IAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACnC,IAAI,IAAI,KAAK,CAAC,CAAC;QAAE,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,GAAG,CAAA;IACtE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAClC,8FAA8F;IAC9F,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAA;IACjF,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,OAAO,cAAc,CAAA;AACxE,CAAC;AAED,iEAAiE;AACjE,SAAS,eAAe,CAAC,CAAY;IACnC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,IAAI,CAAA;IACzD,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,SAAS,GACb,CAAC,CAAC,SAAS,CAAC,MAAM,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAC3F,MAAM,IAAI,GACR,CAAC,CAAC,SAAS,CAAC,MAAM,IAAI,oBAAoB;QACxC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,iBAAiB,CAAC,CAAC,SAAS,CAAC,MAAM,wCAAwC,CAAC,CAAC,IAAI,mCAAmC,CAAA;IAC1H,OAAO,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,eAAe,SAAS,WAAW,IAAI,EAAE,CAAA;AAC7F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAA2B,EAC3B,IAAwB,EACxB,KAAyB,EACzB,KAAa,EACb,IAAI,GAAG,KAAK;IAEZ,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,0BAA0B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,sHAAsH,CAAA;QAC7K,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IAClD,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;QAChD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,oBAAoB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,mFAAmF,CAAA;QACrI,CAAC;QACD,qFAAqF;QACrF,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IAC9E,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAA;IACzC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QACvC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACjB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAC5B,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;SAC/B,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SACvC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;SACjE,IAAI,CAAC,IAAI,CAAC,CAAA;IACb,OAAO,0BAA0B,KAAK,CAAC,MAAM,2NAA2N,KAAK,EAAE,CAAA;AACjR,CAAC;AAED;iDACiD;AACjD,IAAI,kBAAgE,CAAA;AAEpE,iGAAiG;AACjG,MAAM,UAAU,eAAe;IAC7B,kBAAkB,KAAK,CAAC,KAAK,IAAI,EAAE;QACjC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC1D,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;YACvC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAA;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAA;YAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;QACxE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC,CAAC,EAAE,CAAA;IACJ,OAAO,kBAAkB,CAAA;AAC3B,CAAC"}
|
package/dist/upgrade.d.ts
CHANGED
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
* 3. **import moves** - rewrite exact import specifiers to their updated module paths.
|
|
11
11
|
* 4. **verify** - reuse the existing `nifra check` gate; no new verification surface.
|
|
12
12
|
*
|
|
13
|
+
* Upgrading across several releases runs every recipe between the installed version (the lowest
|
|
14
|
+
* fixed-group version the workspace declares) and the target, oldest first, then pins the target. A
|
|
15
|
+
* target newer than this CLI prints the newer CLI's command instead of guessing at recipes it does not
|
|
16
|
+
* carry; nothing is downloaded or run on the user's behalf.
|
|
17
|
+
*
|
|
13
18
|
* Dry-run by default (prints the plan, writes nothing); `--write` applies. Fail-closed on an unknown
|
|
14
19
|
* target version or a missing package.json, and deterministic (same repo + target → same edits).
|
|
15
20
|
*
|
|
@@ -30,6 +35,10 @@ export interface UpgradeOptions {
|
|
|
30
35
|
readonly verify?: boolean;
|
|
31
36
|
/** Permit a target BELOW the installed version (a rollback). Default false → fail-closed. */
|
|
32
37
|
readonly allowDowngrade?: boolean;
|
|
38
|
+
/** Pin the exact target (`3.6.0`), dropping the `^`/`~` a spec used. Default false → keep it. */
|
|
39
|
+
readonly exact?: boolean;
|
|
40
|
+
/** The running CLI's version: the newest target it applies. Default: its newest recipe. */
|
|
41
|
+
readonly cliVersion?: string;
|
|
33
42
|
}
|
|
34
43
|
export interface PinChange {
|
|
35
44
|
readonly file: string;
|
|
@@ -63,10 +72,13 @@ export interface UpgradePlan {
|
|
|
63
72
|
readonly notes: readonly string[];
|
|
64
73
|
}
|
|
65
74
|
/**
|
|
66
|
-
* Rewrite a dependency version spec to `toVersion`, preserving the range operator (`^`, `~`, …)
|
|
67
|
-
* Returns null when the spec is not a plain semver spec (→ skip it) or
|
|
75
|
+
* Rewrite a dependency version spec to `toVersion`, preserving the range operator (`^`, `~`, …), or
|
|
76
|
+
* dropping it when `exact`. Returns null when the spec is not a plain semver spec (→ skip it) or
|
|
77
|
+
* already equals the target.
|
|
68
78
|
*/
|
|
69
|
-
export declare function rewriteVersionSpec(spec: string, toVersion: string): string | null;
|
|
79
|
+
export declare function rewriteVersionSpec(spec: string, toVersion: string, exact?: boolean): string | null;
|
|
80
|
+
/** The version a plain semver spec names (`^2.4.1` → `2.4.1`), or null for any other spec. */
|
|
81
|
+
export declare function specVersion(spec: string): string | null;
|
|
70
82
|
/** Numeric core (major, minor, patch) of a semver spec, ignoring the range operator + prerelease/build. */
|
|
71
83
|
export declare function specVersionTuple(spec: string): readonly [number, number, number] | null;
|
|
72
84
|
/** Compare two semver cores: <0 when a<b, 0 equal, >0 when a>b. */
|
|
@@ -81,7 +93,7 @@ export declare function compareSemverSpec(a: string, b: string): number;
|
|
|
81
93
|
export declare function pinSweepText(text: string, rules: readonly {
|
|
82
94
|
match: string;
|
|
83
95
|
to: string;
|
|
84
|
-
}[], allowDowngrade?: boolean): {
|
|
96
|
+
}[], allowDowngrade?: boolean, exact?: boolean): {
|
|
85
97
|
text: string;
|
|
86
98
|
changes: Array<Omit<PinChange, "file">>;
|
|
87
99
|
downgrades: Array<Omit<PinChange, "file">>;
|
|
@@ -91,7 +103,7 @@ export declare function moveDependenciesText(text: string, moves: readonly {
|
|
|
91
103
|
from: string;
|
|
92
104
|
to: string;
|
|
93
105
|
toVersion: string;
|
|
94
|
-
}[]): {
|
|
106
|
+
}[], exact?: boolean): {
|
|
95
107
|
text: string;
|
|
96
108
|
changes: Array<Omit<DependencyMoveChange, "file">>;
|
|
97
109
|
};
|
|
@@ -107,8 +119,26 @@ export declare function applyImportMoves(text: string, moves: readonly {
|
|
|
107
119
|
count: number;
|
|
108
120
|
}>;
|
|
109
121
|
};
|
|
122
|
+
/**
|
|
123
|
+
* The lowest fixed-group version any package.json under `cwd` declares with a plain semver spec, or
|
|
124
|
+
* null when none does. Recipes newer than it still have edits to make somewhere in the workspace.
|
|
125
|
+
*/
|
|
126
|
+
export declare function installedGroupVersion(cwd: string): string | null;
|
|
127
|
+
/** One recipe that applies every release recipe after `installed` up to `target`, oldest first. */
|
|
128
|
+
export interface ChainedRecipe extends UpgradeRecipe {
|
|
129
|
+
/** The release recipes it applies, oldest first. */
|
|
130
|
+
readonly steps: readonly string[];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Chain the recipes after `installed` (exclusive) up to `target` (inclusive): their dependency and
|
|
134
|
+
* import moves in release order, their notes labeled by release, and the fixed group pinned to
|
|
135
|
+
* `target`. Without a known installed version only the target's own recipe applies.
|
|
136
|
+
*/
|
|
137
|
+
export declare function chainRecipes(target: string, installed: string | null): ChainedRecipe;
|
|
110
138
|
/** Compute the plan (and, when `write`, apply it) for a target recipe against `cwd`. */
|
|
111
|
-
export declare function computeUpgrade(cwd: string, recipe: UpgradeRecipe, write: boolean, allowDowngrade?: boolean): UpgradePlan;
|
|
139
|
+
export declare function computeUpgrade(cwd: string, recipe: UpgradeRecipe, write: boolean, allowDowngrade?: boolean, exact?: boolean): UpgradePlan;
|
|
140
|
+
/** The targets this CLI applies: each release recipe up to its own version, and that version. */
|
|
141
|
+
export declare function upgradeTargets(cliVersion: string): string[];
|
|
112
142
|
/** CLI entry. Returns false (→ non-zero exit) on an unknown version, no project, or a failed verify. */
|
|
113
143
|
export declare function runUpgrade(cwd: string, options: UpgradeOptions): Promise<boolean>;
|
|
114
144
|
//# sourceMappingURL=upgrade.d.ts.map
|
package/dist/upgrade.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"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"}
|
package/dist/upgrade.js
CHANGED
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
* 3. **import moves** - rewrite exact import specifiers to their updated module paths.
|
|
11
11
|
* 4. **verify** - reuse the existing `nifra check` gate; no new verification surface.
|
|
12
12
|
*
|
|
13
|
+
* Upgrading across several releases runs every recipe between the installed version (the lowest
|
|
14
|
+
* fixed-group version the workspace declares) and the target, oldest first, then pins the target. A
|
|
15
|
+
* target newer than this CLI prints the newer CLI's command instead of guessing at recipes it does not
|
|
16
|
+
* carry; nothing is downloaded or run on the user's behalf.
|
|
17
|
+
*
|
|
13
18
|
* Dry-run by default (prints the plan, writes nothing); `--write` applies. Fail-closed on an unknown
|
|
14
19
|
* target version or a missing package.json, and deterministic (same repo + target → same edits).
|
|
15
20
|
*
|
|
@@ -30,17 +35,27 @@ const DEP_FIELDS = [
|
|
|
30
35
|
// urls, "*", "latest", or a multi-part range - is intentionally left untouched (skipped, not guessed).
|
|
31
36
|
const SEMVER_SPEC = /^([\^~]|>=|<=|>|<|=)?\s*(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
32
37
|
/**
|
|
33
|
-
* Rewrite a dependency version spec to `toVersion`, preserving the range operator (`^`, `~`, …)
|
|
34
|
-
* Returns null when the spec is not a plain semver spec (→ skip it) or
|
|
38
|
+
* Rewrite a dependency version spec to `toVersion`, preserving the range operator (`^`, `~`, …), or
|
|
39
|
+
* dropping it when `exact`. Returns null when the spec is not a plain semver spec (→ skip it) or
|
|
40
|
+
* already equals the target.
|
|
35
41
|
*/
|
|
36
|
-
export function rewriteVersionSpec(spec, toVersion) {
|
|
42
|
+
export function rewriteVersionSpec(spec, toVersion, exact = false) {
|
|
37
43
|
const match = SEMVER_SPEC.exec(spec.trim());
|
|
38
44
|
if (!match)
|
|
39
45
|
return null;
|
|
40
|
-
const operator = match[1] ?? "";
|
|
46
|
+
const operator = exact ? "" : (match[1] ?? "");
|
|
41
47
|
const next = `${operator}${toVersion}`;
|
|
42
48
|
return next === spec ? null : next;
|
|
43
49
|
}
|
|
50
|
+
/** The version a plain semver spec names (`^2.4.1` → `2.4.1`), or null for any other spec. */
|
|
51
|
+
export function specVersion(spec) {
|
|
52
|
+
const match = SEMVER_SPEC.exec(spec.trim());
|
|
53
|
+
if (!match)
|
|
54
|
+
return null;
|
|
55
|
+
return `${match[2]}.${match[3]}.${match[4]}${match[5] === undefined ? "" : `-${match[5]}`}`;
|
|
56
|
+
}
|
|
57
|
+
// A release target: a bare version, never a range, so it can be pinned and printed in a command.
|
|
58
|
+
const RELEASE_VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
|
|
44
59
|
/** Numeric core (major, minor, patch) of a semver spec, ignoring the range operator + prerelease/build. */
|
|
45
60
|
export function specVersionTuple(spec) {
|
|
46
61
|
const match = SEMVER_SPEC.exec(spec.trim());
|
|
@@ -105,7 +120,7 @@ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
|
105
120
|
* JSON re-serialize that would reorder keys or drop comments-as-formatting). Returns the new text and
|
|
106
121
|
* the changes made.
|
|
107
122
|
*/
|
|
108
|
-
export function pinSweepText(text, rules, allowDowngrade = false) {
|
|
123
|
+
export function pinSweepText(text, rules, allowDowngrade = false, exact = false) {
|
|
109
124
|
let parsed;
|
|
110
125
|
try {
|
|
111
126
|
parsed = JSON.parse(text);
|
|
@@ -126,7 +141,7 @@ export function pinSweepText(text, rules, allowDowngrade = false) {
|
|
|
126
141
|
const rule = rules.find((r) => name === r.match || (r.match.endsWith("/") && name.startsWith(r.match)));
|
|
127
142
|
if (!rule)
|
|
128
143
|
continue;
|
|
129
|
-
const next = rewriteVersionSpec(rawSpec, rule.to);
|
|
144
|
+
const next = rewriteVersionSpec(rawSpec, rule.to, exact);
|
|
130
145
|
if (next === null)
|
|
131
146
|
continue;
|
|
132
147
|
// Refuse a rollback: `upgrade <version>` pins an exact target, so an OLD target on a newer install
|
|
@@ -201,14 +216,14 @@ function rewriteDependencyEntry(text, field, from, fromVersion, to, toVersion) {
|
|
|
201
216
|
let start = match.index;
|
|
202
217
|
let end = match.index + match[0].length;
|
|
203
218
|
let after = end;
|
|
204
|
-
while (
|
|
219
|
+
while (/\s/.test(body[after] ?? ""))
|
|
205
220
|
after++;
|
|
206
221
|
if (body[after] === ",") {
|
|
207
222
|
end = after + 1;
|
|
208
223
|
}
|
|
209
224
|
else {
|
|
210
225
|
let before = start - 1;
|
|
211
|
-
while (before >= 0 &&
|
|
226
|
+
while (before >= 0 && /\s/.test(body[before] ?? ""))
|
|
212
227
|
before--;
|
|
213
228
|
if (body[before] === ",")
|
|
214
229
|
start = before;
|
|
@@ -218,7 +233,7 @@ function rewriteDependencyEntry(text, field, from, fromVersion, to, toVersion) {
|
|
|
218
233
|
return text.slice(0, range.start) + nextBody + text.slice(range.end);
|
|
219
234
|
}
|
|
220
235
|
/** Move removed package dependencies without reserializing or reordering package.json. */
|
|
221
|
-
export function moveDependenciesText(text, moves) {
|
|
236
|
+
export function moveDependenciesText(text, moves, exact = false) {
|
|
222
237
|
let out = text;
|
|
223
238
|
const changes = [];
|
|
224
239
|
for (const move of moves) {
|
|
@@ -239,7 +254,7 @@ export function moveDependenciesText(text, moves) {
|
|
|
239
254
|
const fromVersion = dependencyMap[move.from];
|
|
240
255
|
if (typeof fromVersion !== "string")
|
|
241
256
|
continue;
|
|
242
|
-
const movedVersion = rewriteVersionSpec(fromVersion, move.toVersion) ?? fromVersion;
|
|
257
|
+
const movedVersion = rewriteVersionSpec(fromVersion, move.toVersion, exact) ?? fromVersion;
|
|
243
258
|
// Dependency fields have different install semantics. A devDependency does not satisfy a runtime
|
|
244
259
|
// dependency, so only deduplicate the successor inside the same field.
|
|
245
260
|
const targetExists = Object.hasOwn(dependencyMap, move.to);
|
|
@@ -258,6 +273,13 @@ export function moveDependenciesText(text, moves) {
|
|
|
258
273
|
});
|
|
259
274
|
}
|
|
260
275
|
}
|
|
276
|
+
// The edit is textual; a result that no longer parses is never written.
|
|
277
|
+
try {
|
|
278
|
+
JSON.parse(out);
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
return { text, changes: [] };
|
|
282
|
+
}
|
|
261
283
|
return { text: out, changes };
|
|
262
284
|
}
|
|
263
285
|
const IMPORT_SPEC = (from) => new RegExp(`(\\bfrom\\s*|\\bimport\\s*\\(\\s*|\\brequire\\s*\\(\\s*|\\bimport\\s+)(['"])${escapeRegExp(from)}(['"])`, "g");
|
|
@@ -279,8 +301,13 @@ export function applyImportMoves(text, moves) {
|
|
|
279
301
|
return { text: out, changes };
|
|
280
302
|
}
|
|
281
303
|
const SOURCE_GLOB = "**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}";
|
|
282
|
-
const
|
|
283
|
-
|
|
304
|
+
const IGNORED_DIRECTORIES = new Set(["node_modules", "dist", "build", ".git", "coverage", ".next"]);
|
|
305
|
+
// Any directory on the path counts, the top-level one included (`dist/index.js`). Bun's glob yields
|
|
306
|
+
// `dist\index.js` on Windows.
|
|
307
|
+
const isIgnored = (path) => path
|
|
308
|
+
.split(/[\\/]/)
|
|
309
|
+
.slice(0, -1)
|
|
310
|
+
.some((segment) => IGNORED_DIRECTORIES.has(segment));
|
|
284
311
|
function scan(cwd, pattern) {
|
|
285
312
|
const glob = new Glob(pattern);
|
|
286
313
|
const out = [];
|
|
@@ -290,8 +317,73 @@ function scan(cwd, pattern) {
|
|
|
290
317
|
}
|
|
291
318
|
return out.sort(); // deterministic order
|
|
292
319
|
}
|
|
320
|
+
// The fixed version group: every package released together at one version.
|
|
321
|
+
const isFixedGroup = (name) => name.startsWith("@nifrajs/") || name === "nifra" || name === "create-nifra";
|
|
322
|
+
const groupPins = (version) => [
|
|
323
|
+
{ match: "@nifrajs/", to: version },
|
|
324
|
+
{ match: "create-nifra", to: version },
|
|
325
|
+
{ match: "nifra", to: version },
|
|
326
|
+
];
|
|
327
|
+
/**
|
|
328
|
+
* The lowest fixed-group version any package.json under `cwd` declares with a plain semver spec, or
|
|
329
|
+
* null when none does. Recipes newer than it still have edits to make somewhere in the workspace.
|
|
330
|
+
*/
|
|
331
|
+
export function installedGroupVersion(cwd) {
|
|
332
|
+
let lowest = null;
|
|
333
|
+
for (const rel of scan(cwd, "**/package.json")) {
|
|
334
|
+
let parsed;
|
|
335
|
+
try {
|
|
336
|
+
parsed = JSON.parse(readFileSync(join(cwd, rel), "utf8"));
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
for (const field of DEP_FIELDS) {
|
|
342
|
+
const deps = parsed[field];
|
|
343
|
+
if (typeof deps !== "object" || deps === null)
|
|
344
|
+
continue;
|
|
345
|
+
for (const [name, spec] of Object.entries(deps)) {
|
|
346
|
+
if (!isFixedGroup(name) || typeof spec !== "string")
|
|
347
|
+
continue;
|
|
348
|
+
const version = specVersion(spec);
|
|
349
|
+
if (version !== null && (lowest === null || compareSemverSpec(version, lowest) < 0)) {
|
|
350
|
+
lowest = version;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return lowest;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Chain the recipes after `installed` (exclusive) up to `target` (inclusive): their dependency and
|
|
359
|
+
* import moves in release order, their notes labeled by release, and the fixed group pinned to
|
|
360
|
+
* `target`. Without a known installed version only the target's own recipe applies.
|
|
361
|
+
*/
|
|
362
|
+
export function chainRecipes(target, installed) {
|
|
363
|
+
const steps = installed === null
|
|
364
|
+
? getRecipe(target) === undefined
|
|
365
|
+
? []
|
|
366
|
+
: [target]
|
|
367
|
+
: listRecipeVersions().filter((version) => compareSemverSpec(version, installed) > 0 && compareSemverSpec(version, target) <= 0);
|
|
368
|
+
const recipes = steps.flatMap((version) => getRecipe(version) ?? []);
|
|
369
|
+
// A later rule for the same match replaces an earlier one; the target's pins win last.
|
|
370
|
+
const pins = new Map();
|
|
371
|
+
for (const recipe of recipes)
|
|
372
|
+
for (const rule of recipe.pins)
|
|
373
|
+
pins.set(rule.match, rule.to);
|
|
374
|
+
for (const rule of getRecipe(target)?.pins ?? groupPins(target))
|
|
375
|
+
pins.set(rule.match, rule.to);
|
|
376
|
+
return {
|
|
377
|
+
version: target,
|
|
378
|
+
steps,
|
|
379
|
+
pins: [...pins].map(([match, to]) => ({ match, to })),
|
|
380
|
+
dependencyMoves: recipes.flatMap((recipe) => recipe.dependencyMoves ?? []),
|
|
381
|
+
importMoves: recipes.flatMap((recipe) => recipe.importMoves),
|
|
382
|
+
notes: recipes.flatMap((recipe) => (recipe.notes ?? []).map((note) => `${recipe.version}: ${note}`)),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
293
385
|
/** Compute the plan (and, when `write`, apply it) for a target recipe against `cwd`. */
|
|
294
|
-
export function computeUpgrade(cwd, recipe, write, allowDowngrade = false) {
|
|
386
|
+
export function computeUpgrade(cwd, recipe, write, allowDowngrade = false, exact = false) {
|
|
295
387
|
const pins = [];
|
|
296
388
|
const dependencyMoves = [];
|
|
297
389
|
const importMoves = [];
|
|
@@ -300,10 +392,10 @@ export function computeUpgrade(cwd, recipe, write, allowDowngrade = false) {
|
|
|
300
392
|
for (const rel of scan(cwd, "**/package.json")) {
|
|
301
393
|
const abs = join(cwd, rel);
|
|
302
394
|
const original = readFileSync(abs, "utf8");
|
|
303
|
-
const moved = moveDependenciesText(original, recipe.dependencyMoves ?? []);
|
|
395
|
+
const moved = moveDependenciesText(original, recipe.dependencyMoves ?? [], exact);
|
|
304
396
|
for (const change of moved.changes)
|
|
305
397
|
dependencyMoves.push({ file: rel, ...change });
|
|
306
|
-
const pinned = pinSweepText(moved.text, recipe.pins, allowDowngrade);
|
|
398
|
+
const pinned = pinSweepText(moved.text, recipe.pins, allowDowngrade, exact);
|
|
307
399
|
for (const change of pinned.changes)
|
|
308
400
|
pins.push({ file: rel, ...change });
|
|
309
401
|
for (const d of pinned.downgrades)
|
|
@@ -334,10 +426,15 @@ export function computeUpgrade(cwd, recipe, write, allowDowngrade = false) {
|
|
|
334
426
|
notes: recipe.notes ?? [],
|
|
335
427
|
};
|
|
336
428
|
}
|
|
337
|
-
function renderPlan(plan, write) {
|
|
429
|
+
function renderPlan(plan, write, from, steps) {
|
|
338
430
|
const lines = [];
|
|
339
431
|
const verb = write ? "Applied" : "Planned";
|
|
340
432
|
lines.push(`nifra upgrade → ${plan.version} (${write ? "write" : "dry-run"})`);
|
|
433
|
+
if (from !== null) {
|
|
434
|
+
lines.push(steps.length === 0
|
|
435
|
+
? `From ${from}; no release recipe in between.`
|
|
436
|
+
: `From ${from}, applying the ${steps.join(", ")} recipe${steps.length === 1 ? "" : "s"}.`);
|
|
437
|
+
}
|
|
341
438
|
lines.push("");
|
|
342
439
|
if (plan.pins.length === 0 &&
|
|
343
440
|
plan.dependencyMoves.length === 0 &&
|
|
@@ -386,24 +483,62 @@ function renderDowngradeRefusal(version, downgrades) {
|
|
|
386
483
|
"installed one, or pass --allow-downgrade if the rollback is intended.",
|
|
387
484
|
].join("\n");
|
|
388
485
|
}
|
|
486
|
+
/** The targets this CLI applies: each release recipe up to its own version, and that version. */
|
|
487
|
+
export function upgradeTargets(cliVersion) {
|
|
488
|
+
const versions = listRecipeVersions().filter((version) => compareSemverSpec(version, cliVersion) <= 0);
|
|
489
|
+
if (!versions.includes(cliVersion))
|
|
490
|
+
versions.push(cliVersion);
|
|
491
|
+
return versions.sort(compareSemverSpec);
|
|
492
|
+
}
|
|
493
|
+
/** The command that runs `version`'s own CLI with the same flags. `version` is a validated release. */
|
|
494
|
+
function newerCliCommand(version, options) {
|
|
495
|
+
const flags = [
|
|
496
|
+
options.write === true ? "--write" : "",
|
|
497
|
+
options.exact === true ? "--exact" : "",
|
|
498
|
+
options.allowDowngrade === true ? "--allow-downgrade" : "",
|
|
499
|
+
options.verify === false ? "--no-verify" : "",
|
|
500
|
+
options.json === true ? "--json" : "",
|
|
501
|
+
].filter((flag) => flag !== "");
|
|
502
|
+
return ["bunx", `@nifrajs/cli@${version}`, "upgrade", version, ...flags].join(" ");
|
|
503
|
+
}
|
|
389
504
|
/** CLI entry. Returns false (→ non-zero exit) on an unknown version, no project, or a failed verify. */
|
|
390
505
|
export async function runUpgrade(cwd, options) {
|
|
506
|
+
const cliVersion = options.cliVersion ?? listRecipeVersions().at(-1) ?? "0.0.0";
|
|
507
|
+
const targets = upgradeTargets(cliVersion);
|
|
391
508
|
if (options.list) {
|
|
392
|
-
const versions = listRecipeVersions();
|
|
393
509
|
if (options.json)
|
|
394
|
-
console.log(JSON.stringify({ versions }, null, 2));
|
|
395
|
-
else
|
|
396
|
-
console.log(`available upgrade targets:\n${
|
|
510
|
+
console.log(JSON.stringify({ versions: targets, cliVersion }, null, 2));
|
|
511
|
+
else {
|
|
512
|
+
console.log(`available upgrade targets:\n${targets.map((v) => ` ${v}`).join("\n")}\n\n` +
|
|
513
|
+
`A newer release upgrades with its own CLI: bunx @nifrajs/cli@<version> upgrade <version>`);
|
|
514
|
+
}
|
|
397
515
|
return true;
|
|
398
516
|
}
|
|
399
517
|
const { version } = options;
|
|
400
518
|
if (version === undefined) {
|
|
401
|
-
console.error(
|
|
519
|
+
console.error(`[nifra] upgrade needs a target version, e.g. \`nifra upgrade ${cliVersion}\` (or --list)`);
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
if (!RELEASE_VERSION.test(version)) {
|
|
523
|
+
console.error(`[nifra] ${JSON.stringify(version)} is not a release version, e.g. ${cliVersion}`);
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
if (compareSemverSpec(version, cliVersion) > 0) {
|
|
527
|
+
// Recipes ship with the CLI: only the target release's CLI knows every recipe up to it. Print its
|
|
528
|
+
// command rather than downloading and running code on the user's behalf.
|
|
529
|
+
const command = newerCliCommand(version, options);
|
|
530
|
+
if (options.json) {
|
|
531
|
+
console.log(JSON.stringify({ version, cliVersion, refused: "newer-than-cli", command }, null, 2));
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
console.error(`nifra upgrade → ${version}: this CLI is ${cliVersion} and carries the recipes up to it.\n` +
|
|
535
|
+
`Run the ${version} CLI, which carries every recipe up to ${version}:\n\n ${command}`);
|
|
536
|
+
}
|
|
402
537
|
return false;
|
|
403
538
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
539
|
+
if (!targets.includes(version)) {
|
|
540
|
+
console.error(`[nifra] no upgrade recipe for ${version}. This CLI upgrades to: ${targets.join(", ")}. ` +
|
|
541
|
+
`For ${version} itself, run: ${newerCliCommand(version, options)}`);
|
|
407
542
|
return false;
|
|
408
543
|
}
|
|
409
544
|
// Detect: the cwd must be a project (or workspace) root.
|
|
@@ -416,23 +551,26 @@ export async function runUpgrade(cwd, options) {
|
|
|
416
551
|
}
|
|
417
552
|
const write = options.write === true;
|
|
418
553
|
const allowDowngrade = options.allowDowngrade === true;
|
|
554
|
+
const exact = options.exact === true;
|
|
555
|
+
const from = installedGroupVersion(cwd);
|
|
556
|
+
const recipe = chainRecipes(version, from);
|
|
419
557
|
// Fail-closed on rollback: a dry pass writes nothing, so we can refuse before any package.json is touched.
|
|
420
|
-
const preview = computeUpgrade(cwd, recipe, false, allowDowngrade);
|
|
558
|
+
const preview = computeUpgrade(cwd, recipe, false, allowDowngrade, exact);
|
|
421
559
|
if (preview.downgrades.length > 0) {
|
|
422
560
|
if (options.json) {
|
|
423
|
-
console.log(JSON.stringify({ ...preview, write: false, refused: "downgrade" }, null, 2));
|
|
561
|
+
console.log(JSON.stringify({ ...preview, from, steps: recipe.steps, write: false, refused: "downgrade" }, null, 2));
|
|
424
562
|
}
|
|
425
563
|
else {
|
|
426
564
|
console.error(renderDowngradeRefusal(recipe.version, preview.downgrades));
|
|
427
565
|
}
|
|
428
566
|
return false;
|
|
429
567
|
}
|
|
430
|
-
const plan = write ? computeUpgrade(cwd, recipe, true, allowDowngrade) : preview;
|
|
568
|
+
const plan = write ? computeUpgrade(cwd, recipe, true, allowDowngrade, exact) : preview;
|
|
431
569
|
if (options.json) {
|
|
432
|
-
console.log(JSON.stringify({ ...plan, write }, null, 2));
|
|
570
|
+
console.log(JSON.stringify({ ...plan, from, steps: recipe.steps, write }, null, 2));
|
|
433
571
|
}
|
|
434
572
|
else {
|
|
435
|
-
console.log(renderPlan(plan, write));
|
|
573
|
+
console.log(renderPlan(plan, write, from, recipe.steps));
|
|
436
574
|
}
|
|
437
575
|
// Verify only makes sense once edits are on disk. Default on after --write; opt out with --no-verify.
|
|
438
576
|
if (write && options.verify !== false) {
|