nx 23.0.0-beta.2 → 23.0.0-beta.21
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/dist/bin/init-local.js +11 -20
- package/dist/bin/nx.d.ts +1 -0
- package/dist/bin/nx.js +28 -2
- package/dist/plugins/package-json.js +4 -2
- package/dist/src/adapter/ngcli-adapter.d.ts +2 -1
- package/dist/src/adapter/ngcli-adapter.js +25 -2
- package/dist/src/ai/clone-ai-config-repo.js +20 -3
- package/dist/src/analytics/analytics.js +10 -1
- package/dist/src/command-line/add/completion.d.ts +1 -0
- package/dist/src/command-line/add/completion.js +15 -0
- package/dist/src/command-line/affected/completion.d.ts +1 -0
- package/dist/src/command-line/affected/completion.js +15 -0
- package/dist/src/command-line/completion/argv-layout.d.ts +6 -0
- package/dist/src/command-line/completion/argv-layout.js +19 -0
- package/dist/src/command-line/completion/command-completions.d.ts +19 -0
- package/dist/src/command-line/completion/command-completions.js +120 -0
- package/dist/src/command-line/completion/command-handlers.d.ts +30 -0
- package/dist/src/command-line/completion/command-handlers.js +69 -0
- package/dist/src/command-line/completion/command-object.d.ts +10 -0
- package/dist/src/command-line/completion/command-object.js +95 -0
- package/dist/src/command-line/completion/completion-providers.d.ts +21 -0
- package/dist/src/command-line/completion/completion-providers.js +194 -0
- package/dist/src/command-line/completion/infix-targets.d.ts +1 -0
- package/dist/src/command-line/completion/infix-targets.js +48 -0
- package/dist/src/command-line/completion/metadata.d.ts +22 -0
- package/dist/src/command-line/completion/metadata.js +71 -0
- package/dist/src/command-line/completion/registrations.d.ts +9 -0
- package/dist/src/command-line/completion/registrations.js +16 -0
- package/dist/src/command-line/completion/scripts/bash.sh +51 -0
- package/dist/src/command-line/completion/scripts/fish.fish +47 -0
- package/dist/src/command-line/completion/scripts/powershell.ps1 +52 -0
- package/dist/src/command-line/completion/scripts/zsh.zsh +69 -0
- package/dist/src/command-line/completion/scripts.d.ts +18 -0
- package/dist/src/command-line/completion/scripts.js +140 -0
- package/dist/src/command-line/completion/trigger.d.ts +3 -0
- package/dist/src/command-line/completion/trigger.js +21 -0
- package/dist/src/command-line/completion/value-completions.d.ts +3 -0
- package/dist/src/command-line/completion/value-completions.js +21 -0
- package/dist/src/command-line/examples.js +1 -1
- package/dist/src/command-line/format/format.js +15 -5
- package/dist/src/command-line/generate/completion.d.ts +1 -0
- package/dist/src/command-line/generate/completion.js +9 -0
- package/dist/src/command-line/graph/completion.d.ts +1 -0
- package/dist/src/command-line/graph/completion.js +13 -0
- package/dist/src/command-line/init/implementation/angular/standalone-workspace.js +14 -18
- package/dist/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +1 -0
- package/dist/src/command-line/init/implementation/utils.d.ts +7 -1
- package/dist/src/command-line/init/implementation/utils.js +51 -14
- package/dist/src/command-line/migrate/agentic/capture-generator-output.d.ts +22 -0
- package/dist/src/command-line/migrate/agentic/capture-generator-output.js +100 -0
- package/dist/src/command-line/migrate/agentic/cli-args.d.ts +12 -0
- package/dist/src/command-line/migrate/agentic/cli-args.js +38 -0
- package/dist/src/command-line/migrate/agentic/definitions.d.ts +6 -0
- package/dist/src/command-line/migrate/agentic/definitions.js +98 -0
- package/dist/src/command-line/migrate/agentic/detect-installed.d.ts +10 -0
- package/dist/src/command-line/migrate/agentic/detect-installed.js +68 -0
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +46 -0
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +87 -0
- package/dist/src/command-line/migrate/agentic/handoff.d.ts +63 -0
- package/dist/src/command-line/migrate/agentic/handoff.js +183 -0
- package/dist/src/command-line/migrate/agentic/inception.d.ts +9 -0
- package/dist/src/command-line/migrate/agentic/inception.js +15 -0
- package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.d.ts +22 -0
- package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.js +50 -0
- package/dist/src/command-line/migrate/agentic/prompts/generic-validation.d.ts +51 -0
- package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +65 -0
- package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.d.ts +44 -0
- package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.js +52 -0
- package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.d.ts +21 -0
- package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.js +26 -0
- package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.d.ts +18 -0
- package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.js +130 -0
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +46 -0
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +88 -0
- package/dist/src/command-line/migrate/agentic/run-step.d.ts +51 -0
- package/dist/src/command-line/migrate/agentic/run-step.js +121 -0
- package/dist/src/command-line/migrate/agentic/runner.d.ts +33 -0
- package/dist/src/command-line/migrate/agentic/runner.js +442 -0
- package/dist/src/command-line/migrate/agentic/select.d.ts +14 -0
- package/dist/src/command-line/migrate/agentic/select.js +150 -0
- package/dist/src/command-line/migrate/agentic/types.d.ts +102 -0
- package/dist/src/command-line/migrate/agentic/types.js +2 -0
- package/dist/src/command-line/migrate/command-object.d.ts +1 -0
- package/dist/src/command-line/migrate/command-object.js +32 -7
- package/dist/src/command-line/migrate/migrate-commits.d.ts +50 -0
- package/dist/src/command-line/migrate/migrate-commits.js +102 -0
- package/dist/src/command-line/migrate/migrate-output.d.ts +180 -0
- package/dist/src/command-line/migrate/migrate-output.js +258 -0
- package/dist/src/command-line/migrate/migrate.d.ts +122 -12
- package/dist/src/command-line/migrate/migrate.js +1036 -217
- package/dist/src/command-line/migrate/migration-shape.d.ts +8 -0
- package/dist/src/command-line/migrate/migration-shape.js +13 -0
- package/dist/src/command-line/migrate/multi-major.d.ts +30 -0
- package/dist/src/command-line/migrate/multi-major.js +185 -0
- package/dist/src/command-line/migrate/prompt-files.d.ts +31 -0
- package/dist/src/command-line/migrate/prompt-files.js +141 -0
- package/dist/src/command-line/migrate/run-migration-process.js +28 -6
- package/dist/src/command-line/migrate/safe-prompt.d.ts +28 -0
- package/dist/src/command-line/migrate/safe-prompt.js +49 -0
- package/dist/src/command-line/migrate/update-filters.d.ts +11 -0
- package/dist/src/command-line/migrate/update-filters.js +44 -0
- package/dist/src/command-line/migrate/version-utils.d.ts +6 -0
- package/dist/src/command-line/migrate/version-utils.js +59 -0
- package/dist/src/command-line/nx-commands.js +9 -0
- package/dist/src/command-line/release/config/config.d.ts +3 -6
- package/dist/src/command-line/release/config/config.js +77 -45
- package/dist/src/command-line/release/config/use-legacy-versioning.d.ts +2 -0
- package/dist/src/command-line/release/config/use-legacy-versioning.js +8 -0
- package/dist/src/command-line/release/utils/release-graph.js +2 -3
- package/dist/src/command-line/release/utils/repository-git-tags.js +1 -1
- package/dist/src/command-line/release/utils/resolve-changelog-renderer.js +7 -19
- package/dist/src/command-line/release/version/resolve-current-version.js +1 -1
- package/dist/src/command-line/release/version/version-actions.js +3 -7
- package/dist/src/command-line/report/report.js +2 -2
- package/dist/src/command-line/run/completion.d.ts +1 -0
- package/dist/src/command-line/run/completion.js +7 -0
- package/dist/src/command-line/run-many/completion.d.ts +1 -0
- package/dist/src/command-line/run-many/completion.js +13 -0
- package/dist/src/command-line/show/completion.d.ts +1 -0
- package/dist/src/command-line/show/completion.js +27 -0
- package/dist/src/command-line/show/show-target/info.d.ts +1 -0
- package/dist/src/command-line/show/show-target/info.js +100 -19
- package/dist/src/command-line/watch/command-object.js +24 -4
- package/dist/src/command-line/watch/completion.d.ts +1 -0
- package/dist/src/command-line/watch/completion.js +10 -0
- package/dist/src/command-line/watch/watch.d.ts +7 -0
- package/dist/src/command-line/watch/watch.js +1 -1
- package/dist/src/config/misc-interfaces.d.ts +25 -2
- package/dist/src/config/nx-json.d.ts +43 -56
- package/dist/src/config/schema-utils.d.ts +21 -0
- package/dist/src/config/schema-utils.js +92 -18
- package/dist/src/config/task-graph.d.ts +4 -107
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/core/graph/styles.css +2 -3
- package/dist/src/core/graph/styles.js +1 -1
- package/dist/src/daemon/client/client.d.ts +1 -1
- package/dist/src/daemon/server/file-watching/file-watcher-sockets.d.ts +1 -1
- package/dist/src/daemon/server/file-watching/file-watcher-sockets.js +1 -1
- package/dist/src/daemon/server/file-watching/route-workspace-changes.d.ts +9 -0
- package/dist/src/daemon/server/file-watching/route-workspace-changes.js +76 -0
- package/dist/src/daemon/server/project-graph-incremental-recomputation.js +45 -11
- package/dist/src/daemon/server/server.js +4 -43
- package/dist/src/daemon/server/start.d.ts +1 -1
- package/dist/src/daemon/server/start.js +2 -0
- package/dist/src/devkit-exports.d.ts +2 -2
- package/dist/src/devkit-internals.d.ts +5 -1
- package/dist/src/devkit-internals.js +17 -1
- package/dist/src/executors/run-commands/running-tasks.d.ts +7 -0
- package/dist/src/executors/run-commands/running-tasks.js +178 -105
- package/dist/src/executors/run-script/run-script.impl.js +3 -10
- package/dist/src/executors/utils/convert-nx-executor.js +1 -1
- package/dist/src/hasher/hash-plan-inspector.d.ts +1 -1
- package/dist/src/hasher/task-hasher.js +6 -4
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +0 -3
- package/dist/src/migrations/update-16-2-0/remove-run-commands-output-path.js +6 -2
- package/dist/src/migrations/update-17-0-0/move-cache-directory.md +31 -0
- package/dist/src/migrations/update-17-0-0/use-minimal-config-for-tasks-runner-options.js +20 -4
- package/dist/src/migrations/update-20-0-0/move-use-daemon-process.md +27 -0
- package/dist/src/migrations/update-20-0-1/use-legacy-cache.md +24 -0
- package/dist/src/migrations/update-21-0-0/release-changelog-config-changes.md +49 -0
- package/dist/src/migrations/update-21-0-0/release-version-config-changes.md +54 -0
- package/dist/src/migrations/update-21-0-0/remove-custom-tasks-runner.md +28 -0
- package/dist/src/migrations/update-21-0-0/remove-legacy-cache.md +22 -0
- package/dist/src/migrations/update-22-2-0/add-self-healing-to-gitignore.md +11 -0
- package/dist/src/migrations/update-23-0-0/add-migrate-runs-to-git-ignore.d.ts +2 -0
- package/dist/src/migrations/update-23-0-0/add-migrate-runs-to-git-ignore.js +16 -0
- package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.d.ts +9 -0
- package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.js +18 -0
- package/dist/src/migrations/update-23-0-0/convert-target-defaults-to-array.d.ts +35 -0
- package/dist/src/migrations/update-23-0-0/convert-target-defaults-to-array.js +139 -0
- package/dist/src/migrations/update-23-0-0/convert-target-defaults-to-array.md +66 -0
- package/dist/src/native/index.d.ts +79 -2
- package/dist/src/native/native-bindings.js +3 -0
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/plugins/js/lock-file/npm-parser.js +37 -19
- package/dist/src/plugins/js/lock-file/pnpm-parser.js +51 -4
- package/dist/src/plugins/js/lock-file/project-graph-pruning.js +12 -4
- package/dist/src/plugins/js/utils/packages.js +1 -1
- package/dist/src/plugins/js/utils/register.d.ts +103 -14
- package/dist/src/plugins/js/utils/register.js +434 -39
- package/dist/src/plugins/js/utils/typescript.d.ts +7 -0
- package/dist/src/plugins/js/utils/typescript.js +39 -0
- package/dist/src/plugins/package-json/create-nodes.d.ts +3 -2
- package/dist/src/plugins/package-json/create-nodes.js +7 -5
- package/dist/src/project-graph/affected/locators/project-glob-changes.js +2 -1
- package/dist/src/project-graph/build-project-graph.d.ts +5 -0
- package/dist/src/project-graph/build-project-graph.js +6 -2
- package/dist/src/project-graph/file-map-utils.d.ts +5 -0
- package/dist/src/project-graph/file-map-utils.js +10 -1
- package/dist/src/project-graph/plugins/get-plugins.d.ts +7 -2
- package/dist/src/project-graph/plugins/get-plugins.js +8 -5
- package/dist/src/project-graph/plugins/isolation/plugin-worker.d.ts +1 -0
- package/dist/src/project-graph/plugins/isolation/plugin-worker.js +2 -0
- package/dist/src/project-graph/plugins/resolve-plugin.d.ts +7 -4
- package/dist/src/project-graph/plugins/resolve-plugin.js +152 -33
- package/dist/src/project-graph/plugins/tasks-execution-hooks.js +4 -2
- package/dist/src/project-graph/plugins/transpiler.d.ts +12 -0
- package/dist/src/project-graph/plugins/transpiler.js +37 -0
- package/dist/src/project-graph/plugins/utils.js +13 -7
- package/dist/src/project-graph/project-graph.js +1 -1
- package/dist/src/project-graph/utils/project-configuration/target-defaults.d.ts +95 -4
- package/dist/src/project-graph/utils/project-configuration/target-defaults.js +515 -68
- package/dist/src/project-graph/utils/project-configuration-utils.d.ts +13 -5
- package/dist/src/project-graph/utils/project-configuration-utils.js +14 -6
- package/dist/src/project-graph/utils/retrieve-workspace-files.js +1 -1
- package/dist/src/tasks-runner/create-task-graph.d.ts +4 -4
- package/dist/src/tasks-runner/create-task-graph.js +1 -1
- package/dist/src/tasks-runner/default-tasks-runner.d.ts +0 -2
- package/dist/src/tasks-runner/forked-process-task-runner.d.ts +1 -1
- package/dist/src/tasks-runner/forked-process-task-runner.js +11 -6
- package/dist/src/tasks-runner/init-tasks-runner.d.ts +0 -15
- package/dist/src/tasks-runner/init-tasks-runner.js +0 -63
- package/dist/src/tasks-runner/legacy-depends-on-warning.d.ts +18 -0
- package/dist/src/tasks-runner/legacy-depends-on-warning.js +109 -0
- package/dist/src/tasks-runner/life-cycle.d.ts +7 -8
- package/dist/src/tasks-runner/life-cycles/invoke-runner-terminal-output-life-cycle.js +6 -6
- package/dist/src/tasks-runner/life-cycles/task-history-life-cycle-old.js +13 -2
- package/dist/src/tasks-runner/life-cycles/task-history-life-cycle.js +16 -5
- package/dist/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +11 -2
- package/dist/src/tasks-runner/pseudo-terminal.d.ts +1 -1
- package/dist/src/tasks-runner/pseudo-terminal.js +22 -10
- package/dist/src/tasks-runner/run-command.js +8 -11
- package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +1 -1
- package/dist/src/tasks-runner/running-tasks/batch-process.js +3 -5
- package/dist/src/tasks-runner/running-tasks/node-child-process.d.ts +2 -2
- package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -7
- package/dist/src/tasks-runner/task-env.d.ts +1 -1
- package/dist/src/tasks-runner/task-env.js +6 -1
- package/dist/src/tasks-runner/task-orchestrator.d.ts +11 -1
- package/dist/src/tasks-runner/task-orchestrator.js +112 -38
- package/dist/src/tasks-runner/tasks-schedule.js +3 -3
- package/dist/src/tasks-runner/utils.d.ts +7 -8
- package/dist/src/tasks-runner/utils.js +23 -27
- package/dist/src/utils/child-process.js +2 -2
- package/dist/src/utils/compile-cache.d.ts +24 -0
- package/dist/src/utils/compile-cache.js +49 -0
- package/dist/src/utils/enable-compile-cache.d.ts +1 -0
- package/dist/src/utils/enable-compile-cache.js +7 -0
- package/dist/src/utils/fileutils.d.ts +0 -8
- package/dist/src/utils/fileutils.js +0 -40
- package/dist/src/utils/git-utils.d.ts +15 -0
- package/dist/src/utils/git-utils.js +138 -0
- package/dist/src/utils/handle-import.d.ts +4 -1
- package/dist/src/utils/handle-import.js +56 -2
- package/dist/src/utils/has-nx-js-plugin.d.ts +9 -0
- package/dist/src/utils/has-nx-js-plugin.js +24 -0
- package/dist/src/utils/installed-nx-version.d.ts +14 -4
- package/dist/src/utils/installed-nx-version.js +54 -7
- package/dist/src/utils/logger.d.ts +12 -1
- package/dist/src/utils/logger.js +57 -36
- package/dist/src/utils/nx-key.d.ts +0 -1
- package/dist/src/utils/nx-key.js +20 -23
- package/dist/src/utils/nx-package-group.d.ts +8 -0
- package/dist/src/utils/nx-package-group.js +15 -0
- package/dist/src/utils/output.d.ts +3 -2
- package/dist/src/utils/output.js +29 -28
- package/dist/src/utils/package-json.d.ts +14 -1
- package/dist/src/utils/package-json.js +20 -21
- package/dist/src/utils/perf-logging.js +3 -1
- package/dist/src/utils/plugin-cache-utils.d.ts +13 -4
- package/dist/src/utils/plugin-cache-utils.js +23 -13
- package/dist/src/utils/plugins/local-plugins.d.ts +18 -0
- package/dist/src/utils/plugins/local-plugins.js +30 -0
- package/dist/src/utils/tar.d.ts +8 -0
- package/dist/src/utils/tar.js +44 -0
- package/migrations.json +16 -0
- package/package.json +28 -28
- package/schemas/nx-schema.json +114 -80
- package/dist/src/plugins/js/project-graph/build-dependencies/strip-source-code.d.ts +0 -7
- package/dist/src/plugins/js/project-graph/build-dependencies/strip-source-code.js +0 -155
- package/dist/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.d.ts +0 -16
- package/dist/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.js +0 -121
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isPromptOnlyMigration = isPromptOnlyMigration;
|
|
4
|
+
exports.isHybridMigration = isHybridMigration;
|
|
5
|
+
function hasDeterministicImplementation(m) {
|
|
6
|
+
return !!(m.implementation || m.factory);
|
|
7
|
+
}
|
|
8
|
+
function isPromptOnlyMigration(m) {
|
|
9
|
+
return !!m.prompt && !hasDeterministicImplementation(m);
|
|
10
|
+
}
|
|
11
|
+
function isHybridMigration(m) {
|
|
12
|
+
return !!m.prompt && hasDeterministicImplementation(m);
|
|
13
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { MigrateMode } from './migrate';
|
|
2
|
+
export declare const MULTI_MAJOR_MODE_FLAG = "--multi-major-mode";
|
|
3
|
+
export type MultiMajorMode = 'direct' | 'gradual';
|
|
4
|
+
/**
|
|
5
|
+
* Result of running the multi-major check.
|
|
6
|
+
*
|
|
7
|
+
* - `chosen`: the version to actually migrate to (always concrete semver when
|
|
8
|
+
* the function ran past the dist-tag resolution; otherwise the input value).
|
|
9
|
+
* - `originalTarget`: set only when an actual redirect happened (gradual mode
|
|
10
|
+
* auto-picked a smaller step, OR the interactive prompt returned a version
|
|
11
|
+
* different from the resolved target). Holds the concrete resolved target
|
|
12
|
+
* so callers can suggest re-running toward it.
|
|
13
|
+
* - `gradual`: set only when the redirect came from gradual mode (flag or
|
|
14
|
+
* env). Tells callers it's safe to propagate `--multi-major-mode=gradual`
|
|
15
|
+
* to a continuation command; left unset when the redirect came from the
|
|
16
|
+
* interactive prompt so the user isn't silently locked into gradual.
|
|
17
|
+
*/
|
|
18
|
+
export type MultiMajorResult = {
|
|
19
|
+
chosen: string;
|
|
20
|
+
originalTarget?: string;
|
|
21
|
+
gradual?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare function maybePromptOrWarnMultiMajorMigration(args: {
|
|
24
|
+
mode: MigrateMode;
|
|
25
|
+
options: {
|
|
26
|
+
multiMajorMode?: MultiMajorMode;
|
|
27
|
+
};
|
|
28
|
+
targetPackage: string;
|
|
29
|
+
targetVersion: string;
|
|
30
|
+
}): Promise<MultiMajorResult>;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MULTI_MAJOR_MODE_FLAG = void 0;
|
|
4
|
+
exports.maybePromptOrWarnMultiMajorMigration = maybePromptOrWarnMultiMajorMigration;
|
|
5
|
+
const safe_prompt_1 = require("./safe-prompt");
|
|
6
|
+
const semver_1 = require("semver");
|
|
7
|
+
const is_ci_1 = require("../../utils/is-ci");
|
|
8
|
+
const installed_nx_version_1 = require("../../utils/installed-nx-version");
|
|
9
|
+
const output_1 = require("../../utils/output");
|
|
10
|
+
const package_manager_1 = require("../../utils/package-manager");
|
|
11
|
+
const version_utils_1 = require("./version-utils");
|
|
12
|
+
const INCREMENTAL_UPDATE_GUIDE_URL = 'https://nx.dev/docs/guides/tips-n-tricks/advanced-update#one-major-version-at-a-time-small-steps';
|
|
13
|
+
exports.MULTI_MAJOR_MODE_FLAG = '--multi-major-mode';
|
|
14
|
+
const MULTI_MAJOR_MODE_ENV = 'NX_MULTI_MAJOR_MODE';
|
|
15
|
+
// Caret-major (`^X.0.0`) excludes prereleases per semver, so
|
|
16
|
+
// `resolvePackageVersionUsingRegistry` returns the highest stable in major X.
|
|
17
|
+
async function resolveLatestStableInMajor(packageName, majorVersion) {
|
|
18
|
+
try {
|
|
19
|
+
const resolved = await (0, package_manager_1.resolvePackageVersionUsingRegistry)(packageName, `^${majorVersion}.0.0`);
|
|
20
|
+
return (0, semver_1.valid)(resolved) ? resolved : null;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const multiMajorHeader = (pkg, installed, target) => `Migrating across multiple major versions: ${pkg}@${installed} → ${pkg}@${target}.`;
|
|
27
|
+
const multiMajorBodyLines = [
|
|
28
|
+
`The recommended process is to update one major version at a time, in small steps.`,
|
|
29
|
+
`See ${INCREMENTAL_UPDATE_GUIDE_URL}`,
|
|
30
|
+
];
|
|
31
|
+
function warnMultiMajorMigration(targetPackage, installed, target) {
|
|
32
|
+
output_1.output.warn({
|
|
33
|
+
title: multiMajorHeader(targetPackage, installed, target),
|
|
34
|
+
bodyLines: [
|
|
35
|
+
...multiMajorBodyLines,
|
|
36
|
+
`Pass ${exports.MULTI_MAJOR_MODE_FLAG}=direct (or =gradual) or set ${MULTI_MAJOR_MODE_ENV} to silence this warning.`,
|
|
37
|
+
],
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function logGradualStep(targetPackage, step, target) {
|
|
41
|
+
// Status-only announcement. The follow-up instruction ("re-run `nx migrate`
|
|
42
|
+
// to continue toward the original target") lives in the Next Steps block at
|
|
43
|
+
// the end of the run, where it's adjacent to the other re-run guidance and
|
|
44
|
+
// not scrolled out of view by the migration output.
|
|
45
|
+
output_1.output.log({
|
|
46
|
+
title: `Migrating to ${targetPackage}@${step} (one step toward ${targetPackage}@${target}).`,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function warnGradualUnavailable(targetPackage, target, reason) {
|
|
50
|
+
output_1.output.warn({
|
|
51
|
+
title: `Could not look up incremental migration options for ${exports.MULTI_MAJOR_MODE_FLAG}=gradual. Proceeding directly to ${targetPackage}@${target}.`,
|
|
52
|
+
bodyLines: [reason],
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Returns the chosen target version. Caller replaces `targetVersion` with it.
|
|
56
|
+
// At least one of `latestInCurrent`/`latestInNext` must be present.
|
|
57
|
+
async function promptMultiMajorMigration(args) {
|
|
58
|
+
const choices = [];
|
|
59
|
+
let recommendedMarked = false;
|
|
60
|
+
if (args.latestInCurrent) {
|
|
61
|
+
choices.push({
|
|
62
|
+
name: args.latestInCurrent,
|
|
63
|
+
message: `Migrate to ${args.targetPackage}@${args.latestInCurrent} (latest in current major) [recommended]`,
|
|
64
|
+
});
|
|
65
|
+
recommendedMarked = true;
|
|
66
|
+
}
|
|
67
|
+
if (args.latestInNext) {
|
|
68
|
+
choices.push({
|
|
69
|
+
name: args.latestInNext,
|
|
70
|
+
message: `Migrate to ${args.targetPackage}@${args.latestInNext} (next major)${recommendedMarked ? '' : ' [recommended]'}`,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
choices.push({
|
|
74
|
+
name: args.target,
|
|
75
|
+
message: `Migrate directly to ${args.targetPackage}@${args.target}`,
|
|
76
|
+
});
|
|
77
|
+
output_1.output.log({
|
|
78
|
+
title: multiMajorHeader(args.targetPackage, args.installed, args.target),
|
|
79
|
+
bodyLines: multiMajorBodyLines,
|
|
80
|
+
});
|
|
81
|
+
const { chosen } = await (0, safe_prompt_1.migratePrompt)({
|
|
82
|
+
type: 'select',
|
|
83
|
+
name: 'chosen',
|
|
84
|
+
message: 'How would you like to proceed?',
|
|
85
|
+
choices,
|
|
86
|
+
});
|
|
87
|
+
return chosen;
|
|
88
|
+
}
|
|
89
|
+
// Flag wins over env var; only the two literal values are honoured.
|
|
90
|
+
function resolveMultiMajorMode(options) {
|
|
91
|
+
if (options.multiMajorMode === 'direct' ||
|
|
92
|
+
options.multiMajorMode === 'gradual') {
|
|
93
|
+
return options.multiMajorMode;
|
|
94
|
+
}
|
|
95
|
+
const env = process.env[MULTI_MAJOR_MODE_ENV];
|
|
96
|
+
if (env === 'direct' || env === 'gradual')
|
|
97
|
+
return env;
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
async function maybePromptOrWarnMultiMajorMigration(args) {
|
|
101
|
+
const { mode, options, targetPackage } = args;
|
|
102
|
+
let { targetVersion } = args;
|
|
103
|
+
if (mode === 'third-party')
|
|
104
|
+
return { chosen: targetVersion };
|
|
105
|
+
const multiMajorMode = resolveMultiMajorMode(options);
|
|
106
|
+
if (multiMajorMode === 'direct')
|
|
107
|
+
return { chosen: targetVersion };
|
|
108
|
+
if (!(0, version_utils_1.isNxEquivalentTarget)(targetPackage, targetVersion)) {
|
|
109
|
+
return { chosen: targetVersion };
|
|
110
|
+
}
|
|
111
|
+
// Bare-package-name positionals (e.g. `nx migrate nx`, `nx migrate
|
|
112
|
+
// @nx/workspace`) leave `targetVersion` as the literal `'latest'` because
|
|
113
|
+
// `parseTargetPackageAndVersion` only resolves dist-tags via the registry
|
|
114
|
+
// when they appear standalone or after `@`. Resolve here so the remaining
|
|
115
|
+
// semver gates (and the subsequent walk) see a concrete version.
|
|
116
|
+
if (version_utils_1.DIST_TAGS.includes(targetVersion)) {
|
|
117
|
+
try {
|
|
118
|
+
targetVersion = await (0, version_utils_1.normalizeVersionWithTagCheck)(targetPackage, targetVersion);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
if (multiMajorMode === 'gradual') {
|
|
122
|
+
warnGradualUnavailable(targetPackage, targetVersion, `Failed to resolve the '${targetVersion}' dist-tag against the registry.`);
|
|
123
|
+
}
|
|
124
|
+
return { chosen: targetVersion };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (!(0, semver_1.valid)(targetVersion) || (0, version_utils_1.isLegacyEra)(targetVersion)) {
|
|
128
|
+
return { chosen: targetVersion };
|
|
129
|
+
}
|
|
130
|
+
const installed = (0, installed_nx_version_1.getInstalledNxVersion)();
|
|
131
|
+
if (!installed || !(0, semver_1.valid)(installed))
|
|
132
|
+
return { chosen: targetVersion };
|
|
133
|
+
// Legacy-era installs are out of scope for the multi-major check.
|
|
134
|
+
if ((0, version_utils_1.isLegacyEra)(installed))
|
|
135
|
+
return { chosen: targetVersion };
|
|
136
|
+
const installedMajor = (0, semver_1.major)(installed);
|
|
137
|
+
if ((0, semver_1.major)(targetVersion) - installedMajor < 2) {
|
|
138
|
+
return { chosen: targetVersion };
|
|
139
|
+
}
|
|
140
|
+
const interactive = !!process.stdin.isTTY && !(0, is_ci_1.isCI)();
|
|
141
|
+
// Non-TTY without gradual opt-in stays on the warn-only path; avoid the
|
|
142
|
+
// registry round-trip used to look up incremental migration options.
|
|
143
|
+
if (!interactive && multiMajorMode !== 'gradual') {
|
|
144
|
+
warnMultiMajorMigration(targetPackage, installed, targetVersion);
|
|
145
|
+
return { chosen: targetVersion };
|
|
146
|
+
}
|
|
147
|
+
const [latestInCurrent, latestInNext] = await Promise.all([
|
|
148
|
+
resolveLatestStableInMajor(targetPackage, installedMajor),
|
|
149
|
+
resolveLatestStableInMajor(targetPackage, installedMajor + 1),
|
|
150
|
+
]);
|
|
151
|
+
// Only suggest the current-major latest when there's at least a minor
|
|
152
|
+
// delta — a same-minor patch bump isn't a meaningful incremental step.
|
|
153
|
+
const showCurrent = latestInCurrent &&
|
|
154
|
+
(0, semver_1.gt)(latestInCurrent, installed) &&
|
|
155
|
+
(0, semver_1.minor)(latestInCurrent) > (0, semver_1.minor)(installed)
|
|
156
|
+
? latestInCurrent
|
|
157
|
+
: null;
|
|
158
|
+
if (multiMajorMode === 'gradual') {
|
|
159
|
+
const step = showCurrent ?? latestInNext;
|
|
160
|
+
if (step) {
|
|
161
|
+
logGradualStep(targetPackage, step, targetVersion);
|
|
162
|
+
return { chosen: step, originalTarget: targetVersion, gradual: true };
|
|
163
|
+
}
|
|
164
|
+
// Registry returned no eligible incremental version (or the lookup
|
|
165
|
+
// failed); without a step to land on, gradual silently degrades to direct.
|
|
166
|
+
// Surface that explicitly so the safety rail the user opted into isn't
|
|
167
|
+
// invisibly disabled.
|
|
168
|
+
warnGradualUnavailable(targetPackage, targetVersion, `Could not find an eligible version in major ${installedMajor} or ${installedMajor + 1} (registry lookup returned no result or failed).`);
|
|
169
|
+
return { chosen: targetVersion };
|
|
170
|
+
}
|
|
171
|
+
if (interactive && (showCurrent || latestInNext)) {
|
|
172
|
+
const chosen = await promptMultiMajorMigration({
|
|
173
|
+
targetPackage,
|
|
174
|
+
installed,
|
|
175
|
+
target: targetVersion,
|
|
176
|
+
latestInCurrent: showCurrent,
|
|
177
|
+
latestInNext,
|
|
178
|
+
});
|
|
179
|
+
return chosen !== targetVersion
|
|
180
|
+
? { chosen, originalTarget: targetVersion }
|
|
181
|
+
: { chosen };
|
|
182
|
+
}
|
|
183
|
+
warnMultiMajorMigration(targetPackage, installed, targetVersion);
|
|
184
|
+
return { chosen: targetVersion };
|
|
185
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { MigrationsJson } from '../../config/misc-interfaces';
|
|
2
|
+
export declare const AI_MIGRATIONS_DIR: string;
|
|
3
|
+
export declare function promptContentKey(packageName: string, promptRelPath: string): string;
|
|
4
|
+
export declare function validateMigrationEntries(packageName: string, packageVersion: string, migrations: MigrationsJson): void;
|
|
5
|
+
/**
|
|
6
|
+
* Thrown when the markdown prompt file referenced by a migration cannot be
|
|
7
|
+
* resolved.
|
|
8
|
+
*/
|
|
9
|
+
export declare class PromptResolutionError extends Error {
|
|
10
|
+
readonly promptPath: string;
|
|
11
|
+
readonly migrationsDir: string;
|
|
12
|
+
constructor(promptPath: string, migrationsDir: string, options?: {
|
|
13
|
+
cause?: unknown;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolves a migration prompt file path to an absolute path. Prompt paths are
|
|
18
|
+
* plain markdown files referenced relative to the directory containing the
|
|
19
|
+
* `migrations.json` - unlike schemas, they are not resolved through package
|
|
20
|
+
* exports or `require.resolve`. The path must stay within the migrations
|
|
21
|
+
* directory and point at an existing file.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolvePrompt(promptPath: string, migrationsDir: string): string;
|
|
24
|
+
export declare function extractPromptFilesFromTarball(packageName: string, packageVersion: string, migrations: MigrationsJson, migrationsFilePath: string, fullTarballPath: string, destDir: string): Promise<Record<string, string> | undefined>;
|
|
25
|
+
export declare function readPromptFilesFromInstall(packageName: string, packageVersion: string, migrations: MigrationsJson, migrationsFilePath: string): Promise<Record<string, string> | undefined>;
|
|
26
|
+
export declare function writePromptMigrationFiles(root: string, migrations: {
|
|
27
|
+
package: string;
|
|
28
|
+
name: string;
|
|
29
|
+
version: string;
|
|
30
|
+
prompt?: string;
|
|
31
|
+
}[], promptContents: Record<string, string>, targetVersion: string): string[];
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PromptResolutionError = exports.AI_MIGRATIONS_DIR = void 0;
|
|
4
|
+
exports.promptContentKey = promptContentKey;
|
|
5
|
+
exports.validateMigrationEntries = validateMigrationEntries;
|
|
6
|
+
exports.resolvePrompt = resolvePrompt;
|
|
7
|
+
exports.extractPromptFilesFromTarball = extractPromptFilesFromTarball;
|
|
8
|
+
exports.readPromptFilesFromInstall = readPromptFilesFromInstall;
|
|
9
|
+
exports.writePromptMigrationFiles = writePromptMigrationFiles;
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const path_1 = require("path");
|
|
12
|
+
const tar_1 = require("../../utils/tar");
|
|
13
|
+
const path_2 = require("../../utils/path");
|
|
14
|
+
exports.AI_MIGRATIONS_DIR = (0, path_2.joinPathFragments)('tools', 'ai-migrations');
|
|
15
|
+
function promptContentKey(packageName, promptRelPath) {
|
|
16
|
+
return `${packageName}::${promptRelPath}`;
|
|
17
|
+
}
|
|
18
|
+
function* iterateMigrationEntries(migrations) {
|
|
19
|
+
const merged = { ...migrations.schematics, ...migrations.generators };
|
|
20
|
+
yield* Object.entries(merged);
|
|
21
|
+
}
|
|
22
|
+
function validateMigrationEntries(packageName, packageVersion, migrations) {
|
|
23
|
+
for (const [migrationName, entry] of iterateMigrationEntries(migrations)) {
|
|
24
|
+
if (!entry.implementation && !entry.factory && !entry.prompt) {
|
|
25
|
+
throw new Error(`Invalid migration "${migrationName}" in package "${packageName}@${packageVersion}": migration entries must have at least one of "implementation", "factory", or "prompt".`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function resolvePromptFiles(packageName, packageVersion, migrations, migrationsDir, resolveContent) {
|
|
30
|
+
const resolvedPromptFiles = {};
|
|
31
|
+
for (const [migrationName, entry] of iterateMigrationEntries(migrations)) {
|
|
32
|
+
if (!entry.prompt || resolvedPromptFiles[entry.prompt] !== undefined) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
assertPromptPathWithinMigrationsDir(migrationsDir, entry.prompt, packageName, packageVersion);
|
|
36
|
+
try {
|
|
37
|
+
resolvedPromptFiles[entry.prompt] = await resolveContent(entry.prompt);
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
throw new Error(`Could not find prompt file "${entry.prompt}" for migration "${migrationName}" in package "${packageName}@${packageVersion}".`, { cause: e });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return Object.keys(resolvedPromptFiles).length > 0
|
|
44
|
+
? resolvedPromptFiles
|
|
45
|
+
: undefined;
|
|
46
|
+
}
|
|
47
|
+
function isPromptPathWithinMigrationsDir(migrationsDir, promptRelPath) {
|
|
48
|
+
const rel = (0, path_1.relative)(migrationsDir, (0, path_1.join)(migrationsDir, promptRelPath));
|
|
49
|
+
return !((0, path_1.isAbsolute)(promptRelPath) ||
|
|
50
|
+
rel === '..' ||
|
|
51
|
+
rel.startsWith(`..${path_1.sep}`) ||
|
|
52
|
+
rel.startsWith(`..${path_1.posix.sep}`));
|
|
53
|
+
}
|
|
54
|
+
function assertPromptPathWithinMigrationsDir(migrationsDir, promptRelPath, packageName, packageVersion) {
|
|
55
|
+
if (!isPromptPathWithinMigrationsDir(migrationsDir, promptRelPath)) {
|
|
56
|
+
throw new Error(`Invalid prompt path "${promptRelPath}" in package "${packageName}@${packageVersion}": prompt paths must be relative and resolve within the package's migrations directory.`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Thrown when the markdown prompt file referenced by a migration cannot be
|
|
61
|
+
* resolved.
|
|
62
|
+
*/
|
|
63
|
+
class PromptResolutionError extends Error {
|
|
64
|
+
constructor(promptPath, migrationsDir, options) {
|
|
65
|
+
super(`Could not resolve prompt "${promptPath}" from "${migrationsDir}".`, options);
|
|
66
|
+
this.promptPath = promptPath;
|
|
67
|
+
this.migrationsDir = migrationsDir;
|
|
68
|
+
this.name = 'PromptResolutionError';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.PromptResolutionError = PromptResolutionError;
|
|
72
|
+
/**
|
|
73
|
+
* Resolves a migration prompt file path to an absolute path. Prompt paths are
|
|
74
|
+
* plain markdown files referenced relative to the directory containing the
|
|
75
|
+
* `migrations.json` - unlike schemas, they are not resolved through package
|
|
76
|
+
* exports or `require.resolve`. The path must stay within the migrations
|
|
77
|
+
* directory and point at an existing file.
|
|
78
|
+
*/
|
|
79
|
+
function resolvePrompt(promptPath, migrationsDir) {
|
|
80
|
+
if (!isPromptPathWithinMigrationsDir(migrationsDir, promptPath)) {
|
|
81
|
+
throw new PromptResolutionError(promptPath, migrationsDir);
|
|
82
|
+
}
|
|
83
|
+
const resolvedPath = (0, path_1.join)(migrationsDir, promptPath);
|
|
84
|
+
if (!(0, fs_1.existsSync)(resolvedPath)) {
|
|
85
|
+
throw new PromptResolutionError(promptPath, migrationsDir);
|
|
86
|
+
}
|
|
87
|
+
return resolvedPath;
|
|
88
|
+
}
|
|
89
|
+
function extractPromptFilesFromTarball(packageName, packageVersion, migrations, migrationsFilePath, fullTarballPath, destDir) {
|
|
90
|
+
const migrationsDir = (0, path_1.dirname)(migrationsFilePath);
|
|
91
|
+
return resolvePromptFiles(packageName, packageVersion, migrations, migrationsDir, async (promptRelPath) => {
|
|
92
|
+
const promptInTarball = (0, path_2.joinPathFragments)('package', migrationsDir, promptRelPath);
|
|
93
|
+
const promptDest = (0, path_1.join)(destDir, migrationsDir, promptRelPath);
|
|
94
|
+
await (0, tar_1.extractFileFromTarball)(fullTarballPath, promptInTarball, promptDest);
|
|
95
|
+
return (0, fs_1.readFileSync)(promptDest, 'utf-8');
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function readPromptFilesFromInstall(packageName, packageVersion, migrations, migrationsFilePath) {
|
|
99
|
+
const migrationsDir = (0, path_1.dirname)(migrationsFilePath);
|
|
100
|
+
return resolvePromptFiles(packageName, packageVersion, migrations, migrationsDir, (promptRelPath) => (0, fs_1.readFileSync)((0, path_1.join)(migrationsDir, promptRelPath), 'utf-8'));
|
|
101
|
+
}
|
|
102
|
+
function writePromptMigrationFiles(root, migrations, promptContents, targetVersion) {
|
|
103
|
+
const sourceToChosen = new Map();
|
|
104
|
+
const result = [];
|
|
105
|
+
for (const migration of migrations) {
|
|
106
|
+
if (!migration.prompt)
|
|
107
|
+
continue;
|
|
108
|
+
const sourceKey = promptContentKey(migration.package, migration.prompt);
|
|
109
|
+
const content = promptContents[sourceKey];
|
|
110
|
+
if (content === undefined)
|
|
111
|
+
continue;
|
|
112
|
+
const cached = sourceToChosen.get(sourceKey);
|
|
113
|
+
if (cached !== undefined) {
|
|
114
|
+
migration.prompt = cached;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const baseName = path_1.posix.basename(migration.prompt);
|
|
118
|
+
const ext = path_1.posix.extname(baseName);
|
|
119
|
+
const stem = ext ? baseName.slice(0, -ext.length) : baseName;
|
|
120
|
+
const destDir = (0, path_2.joinPathFragments)(exports.AI_MIGRATIONS_DIR, migration.package, targetVersion);
|
|
121
|
+
let chosenPath;
|
|
122
|
+
for (let n = 0;; n++) {
|
|
123
|
+
const candidate = (0, path_2.joinPathFragments)(destDir, n === 0 ? baseName : `${stem}-${n}${ext}`);
|
|
124
|
+
const absCandidate = (0, path_1.join)(root, candidate);
|
|
125
|
+
if (!(0, fs_1.existsSync)(absCandidate)) {
|
|
126
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(absCandidate), { recursive: true });
|
|
127
|
+
(0, fs_1.writeFileSync)(absCandidate, content);
|
|
128
|
+
result.push(candidate);
|
|
129
|
+
chosenPath = candidate;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
if ((0, fs_1.readFileSync)(absCandidate, 'utf-8') === content) {
|
|
133
|
+
chosenPath = candidate;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
sourceToChosen.set(sourceKey, chosenPath);
|
|
138
|
+
migration.prompt = chosenPath;
|
|
139
|
+
}
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const { runNxOrAngularMigration } = require('./migrate');
|
|
1
|
+
const { runNxOrAngularMigration, ChangedDepInstaller } = require('./migrate');
|
|
2
|
+
const { commitMigrationIfRequested } = require('./migrate-commits');
|
|
2
3
|
const { execSync } = require('child_process');
|
|
3
4
|
|
|
4
5
|
async function runMigrationProcess() {
|
|
@@ -33,16 +34,37 @@ async function runMigrationProcess() {
|
|
|
33
34
|
windowsHide: true,
|
|
34
35
|
}).trim();
|
|
35
36
|
|
|
37
|
+
// Snapshot package.json deps now so we can detect post-migration drift
|
|
38
|
+
// and run a single install, whether commits are on or off.
|
|
39
|
+
const installer = new ChangedDepInstaller(workspacePath);
|
|
40
|
+
const installDepsIfChanged = () => installer.installDepsIfChanged();
|
|
41
|
+
|
|
36
42
|
const { changes: fileChanges, nextSteps } = await runNxOrAngularMigration(
|
|
37
43
|
workspacePath,
|
|
38
44
|
migration,
|
|
39
|
-
false
|
|
40
|
-
configuration.createCommits,
|
|
41
|
-
configuration.commitPrefix,
|
|
42
|
-
undefined,
|
|
43
|
-
true
|
|
45
|
+
false
|
|
44
46
|
);
|
|
45
47
|
|
|
48
|
+
if (configuration.createCommits) {
|
|
49
|
+
const commitResult = await commitMigrationIfRequested(
|
|
50
|
+
workspacePath,
|
|
51
|
+
migration,
|
|
52
|
+
true,
|
|
53
|
+
configuration.commitPrefix,
|
|
54
|
+
installDepsIfChanged
|
|
55
|
+
);
|
|
56
|
+
if (commitResult.status === 'failed') {
|
|
57
|
+
// Single-migration UI child surfaces the failure via stdout (logged
|
|
58
|
+
// inside commitMigrationIfRequested) and continues with success-
|
|
59
|
+
// with-warning. The executor's absorption flow does not apply here:
|
|
60
|
+
// there is no later migration that could pick up this migration's
|
|
61
|
+
// diff, so the working tree is left in its post-migration state
|
|
62
|
+
// for the user to commit or revert through the UI.
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
await installDepsIfChanged();
|
|
66
|
+
}
|
|
67
|
+
|
|
46
68
|
const gitRefAfter = execSync('git rev-parse HEAD', {
|
|
47
69
|
cwd: workspacePath,
|
|
48
70
|
encoding: 'utf-8',
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { prompt as enquirerPrompt } from 'enquirer';
|
|
2
|
+
/**
|
|
3
|
+
* Drop-in replacement for enquirer's `prompt()` that hardens cancel
|
|
4
|
+
* handling for every interactive prompt under `nx migrate`.
|
|
5
|
+
*
|
|
6
|
+
* Why: enquirer's built-in cancel path (`Prompt.cancel` → `close` →
|
|
7
|
+
* `keypress.js` `off` → `readline.pause`) races on `Interface.pause()`
|
|
8
|
+
* when triggered more than once in quick succession (mashed Ctrl+C),
|
|
9
|
+
* throwing `ERR_USE_AFTER_CLOSE` from an unhandled async chain that
|
|
10
|
+
* `await prompt(...)` cannot catch.
|
|
11
|
+
*
|
|
12
|
+
* In raw mode, Ctrl+C does NOT generate a SIGINT signal (the kernel's
|
|
13
|
+
* `ISIG` flag is cleared while enquirer's keypress listener is active);
|
|
14
|
+
* instead the 0x03 byte flows through `combos.js` and dispatches the
|
|
15
|
+
* `cancel` action. So a `process.on('SIGINT', ...)` handler is the wrong
|
|
16
|
+
* mechanism here — it never fires.
|
|
17
|
+
*
|
|
18
|
+
* The right hook is enquirer's per-prompt `options.cancel` override. When
|
|
19
|
+
* present, `Prompt.keypress` (lib/prompt.js:42) calls our handler INSTEAD
|
|
20
|
+
* of `this.cancel`, so enquirer's broken cleanup never runs. Both Ctrl+C
|
|
21
|
+
* (byte 0x03) and Esc map to the `cancel` action, so this single override
|
|
22
|
+
* covers both paths.
|
|
23
|
+
*
|
|
24
|
+
* The handler emits a single-line notice via `output.warn` and exits with
|
|
25
|
+
* POSIX status 130 (128 + SIGINT). Synchronous exit is correct here: the
|
|
26
|
+
* user explicitly asked to abort, there's no recovery state to preserve.
|
|
27
|
+
*/
|
|
28
|
+
export declare function migratePrompt<T = any>(questions: Parameters<typeof enquirerPrompt>[0]): Promise<T>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migratePrompt = migratePrompt;
|
|
4
|
+
const enquirer_1 = require("enquirer");
|
|
5
|
+
const output_1 = require("../../utils/output");
|
|
6
|
+
/**
|
|
7
|
+
* Drop-in replacement for enquirer's `prompt()` that hardens cancel
|
|
8
|
+
* handling for every interactive prompt under `nx migrate`.
|
|
9
|
+
*
|
|
10
|
+
* Why: enquirer's built-in cancel path (`Prompt.cancel` → `close` →
|
|
11
|
+
* `keypress.js` `off` → `readline.pause`) races on `Interface.pause()`
|
|
12
|
+
* when triggered more than once in quick succession (mashed Ctrl+C),
|
|
13
|
+
* throwing `ERR_USE_AFTER_CLOSE` from an unhandled async chain that
|
|
14
|
+
* `await prompt(...)` cannot catch.
|
|
15
|
+
*
|
|
16
|
+
* In raw mode, Ctrl+C does NOT generate a SIGINT signal (the kernel's
|
|
17
|
+
* `ISIG` flag is cleared while enquirer's keypress listener is active);
|
|
18
|
+
* instead the 0x03 byte flows through `combos.js` and dispatches the
|
|
19
|
+
* `cancel` action. So a `process.on('SIGINT', ...)` handler is the wrong
|
|
20
|
+
* mechanism here — it never fires.
|
|
21
|
+
*
|
|
22
|
+
* The right hook is enquirer's per-prompt `options.cancel` override. When
|
|
23
|
+
* present, `Prompt.keypress` (lib/prompt.js:42) calls our handler INSTEAD
|
|
24
|
+
* of `this.cancel`, so enquirer's broken cleanup never runs. Both Ctrl+C
|
|
25
|
+
* (byte 0x03) and Esc map to the `cancel` action, so this single override
|
|
26
|
+
* covers both paths.
|
|
27
|
+
*
|
|
28
|
+
* The handler emits a single-line notice via `output.warn` and exits with
|
|
29
|
+
* POSIX status 130 (128 + SIGINT). Synchronous exit is correct here: the
|
|
30
|
+
* user explicitly asked to abort, there's no recovery state to preserve.
|
|
31
|
+
*/
|
|
32
|
+
async function migratePrompt(questions) {
|
|
33
|
+
const cancel = () => {
|
|
34
|
+
// `\n\r` → next line at column 0 (enquirer left the TTY in raw mode,
|
|
35
|
+
// so a bare LF would not carry an implicit CR).
|
|
36
|
+
// `\x1B[J` → clear from cursor to end of screen. Wipes enquirer's
|
|
37
|
+
// leftover choice / input rendering below the row where we'll
|
|
38
|
+
// write our message so the exit output isn't shadowed by orphaned
|
|
39
|
+
// prompt fragments.
|
|
40
|
+
process.stdout.write('\n\r\x1B[J');
|
|
41
|
+
output_1.output.warn({ title: 'nx migrate interrupted by user.' });
|
|
42
|
+
process.exit(130);
|
|
43
|
+
};
|
|
44
|
+
const withCancel = (q) => ({ ...q, cancel });
|
|
45
|
+
const injected = Array.isArray(questions)
|
|
46
|
+
? questions.map(withCancel)
|
|
47
|
+
: withCancel(questions);
|
|
48
|
+
return (await (0, enquirer_1.prompt)(injected));
|
|
49
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PackageJsonUpdateForPackage as PackageUpdate } from '../../config/misc-interfaces';
|
|
2
|
+
import type { PackageJson } from '../../utils/package-json';
|
|
3
|
+
/**
|
|
4
|
+
* Drop entries from `packageUpdates` that would either downgrade the package
|
|
5
|
+
* (move resolved version backward) or rewrite a specifier that is already
|
|
6
|
+
* exactly pinned to the resolved version (a no-op write). Keep genuine
|
|
7
|
+
* upgrades and narrowing rewrites where the user's range covers a version
|
|
8
|
+
* lower than what's resolved (the migrator's traditional "lock to recommended
|
|
9
|
+
* exact pin" behavior).
|
|
10
|
+
*/
|
|
11
|
+
export declare function filterDowngradedUpdates(packageUpdates: Record<string, PackageUpdate>, packageJson: PackageJson | null, getInstalledVersion: (packageName: string) => string | null): Record<string, PackageUpdate>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filterDowngradedUpdates = filterDowngradedUpdates;
|
|
4
|
+
const semver_1 = require("semver");
|
|
5
|
+
const version_utils_1 = require("./version-utils");
|
|
6
|
+
/**
|
|
7
|
+
* Drop entries from `packageUpdates` that would either downgrade the package
|
|
8
|
+
* (move resolved version backward) or rewrite a specifier that is already
|
|
9
|
+
* exactly pinned to the resolved version (a no-op write). Keep genuine
|
|
10
|
+
* upgrades and narrowing rewrites where the user's range covers a version
|
|
11
|
+
* lower than what's resolved (the migrator's traditional "lock to recommended
|
|
12
|
+
* exact pin" behavior).
|
|
13
|
+
*/
|
|
14
|
+
function filterDowngradedUpdates(packageUpdates, packageJson, getInstalledVersion) {
|
|
15
|
+
const result = {};
|
|
16
|
+
for (const [name, update] of Object.entries(packageUpdates)) {
|
|
17
|
+
const resolved = getInstalledVersion(name);
|
|
18
|
+
if (!resolved) {
|
|
19
|
+
// Not installed; let downstream logic decide whether to add it.
|
|
20
|
+
result[name] = update;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const proposed = (0, version_utils_1.normalizeVersion)(update.version);
|
|
24
|
+
const resolvedNorm = (0, version_utils_1.normalizeVersion)(resolved);
|
|
25
|
+
if ((0, semver_1.gt)(proposed, resolvedNorm)) {
|
|
26
|
+
result[name] = update;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if ((0, semver_1.lt)(proposed, resolvedNorm)) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
// proposed === resolved: keep when narrowing a looser specifier to an
|
|
33
|
+
// exact pin; drop when the specifier is already exact at resolved.
|
|
34
|
+
const specifier = packageJson?.dependencies?.[name] ?? packageJson?.devDependencies?.[name];
|
|
35
|
+
if (!specifier) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const floor = (0, semver_1.minVersion)(specifier);
|
|
39
|
+
if (floor && (0, semver_1.lt)(floor.version, resolvedNorm)) {
|
|
40
|
+
result[name] = update;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const DIST_TAGS: readonly ["latest", "next", "canary"];
|
|
2
|
+
export type DistTag = (typeof DIST_TAGS)[number];
|
|
3
|
+
export declare function isLegacyEra(targetVersion: string): boolean;
|
|
4
|
+
export declare function normalizeVersion(version: string): string;
|
|
5
|
+
export declare function normalizeVersionWithTagCheck(pkg: string, version: string): Promise<string>;
|
|
6
|
+
export declare function isNxEquivalentTarget(targetPackage: string, targetVersion: string): boolean;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DIST_TAGS = void 0;
|
|
4
|
+
exports.isLegacyEra = isLegacyEra;
|
|
5
|
+
exports.normalizeVersion = normalizeVersion;
|
|
6
|
+
exports.normalizeVersionWithTagCheck = normalizeVersionWithTagCheck;
|
|
7
|
+
exports.isNxEquivalentTarget = isNxEquivalentTarget;
|
|
8
|
+
const semver_1 = require("semver");
|
|
9
|
+
const package_manager_1 = require("../../utils/package-manager");
|
|
10
|
+
exports.DIST_TAGS = ['latest', 'next', 'canary'];
|
|
11
|
+
const LEGACY_ERA_BOUNDARY = '14.0.0-beta.0';
|
|
12
|
+
// Pre-14 (legacy) installs used `@nrwl/workspace` as the canonical Nx package.
|
|
13
|
+
// Non-semver values (e.g. dist-tags or the literal `'latest'` sentinel before
|
|
14
|
+
// tag resolution) are treated as modern era.
|
|
15
|
+
function isLegacyEra(targetVersion) {
|
|
16
|
+
return (0, semver_1.valid)(targetVersion) && (0, semver_1.lt)(targetVersion, LEGACY_ERA_BOUNDARY);
|
|
17
|
+
}
|
|
18
|
+
function normalizeVersion(version) {
|
|
19
|
+
const [semver, ...prereleaseTagParts] = version.split('-');
|
|
20
|
+
// Handle versions like 1.0.0-beta-next.2
|
|
21
|
+
const prereleaseTag = prereleaseTagParts.join('-');
|
|
22
|
+
const [major, minor, patch] = semver.split('.');
|
|
23
|
+
const newSemver = `${major || 0}.${minor || 0}.${patch || 0}`;
|
|
24
|
+
const newVersion = prereleaseTag
|
|
25
|
+
? `${newSemver}-${prereleaseTag}`
|
|
26
|
+
: newSemver;
|
|
27
|
+
const withoutPatch = `${major || 0}.${minor || 0}.0`;
|
|
28
|
+
const withoutPatchAndMinor = `${major || 0}.0.0`;
|
|
29
|
+
const variationsToCheck = [
|
|
30
|
+
newVersion,
|
|
31
|
+
newSemver,
|
|
32
|
+
withoutPatch,
|
|
33
|
+
withoutPatchAndMinor,
|
|
34
|
+
];
|
|
35
|
+
for (const variation of variationsToCheck) {
|
|
36
|
+
try {
|
|
37
|
+
if ((0, semver_1.gt)(variation, '0.0.0')) {
|
|
38
|
+
return variation;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
}
|
|
43
|
+
return '0.0.0';
|
|
44
|
+
}
|
|
45
|
+
async function normalizeVersionWithTagCheck(pkg, version) {
|
|
46
|
+
// Treat non-parseable inputs (e.g. dist-tags like `latest`/`next`) as
|
|
47
|
+
// registry references and resolve them. Throws on registry failure;
|
|
48
|
+
// callers that need to tolerate registry outages must wrap.
|
|
49
|
+
if (version && !(0, semver_1.parse)(version)) {
|
|
50
|
+
return (0, package_manager_1.resolvePackageVersionUsingRegistry)(pkg, version);
|
|
51
|
+
}
|
|
52
|
+
return normalizeVersion(version);
|
|
53
|
+
}
|
|
54
|
+
function isNxEquivalentTarget(targetPackage, targetVersion) {
|
|
55
|
+
if (isLegacyEra(targetVersion)) {
|
|
56
|
+
return targetPackage === '@nrwl/workspace';
|
|
57
|
+
}
|
|
58
|
+
return targetPackage === 'nx' || targetPackage === '@nx/workspace';
|
|
59
|
+
}
|