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.
Files changed (274) hide show
  1. package/dist/bin/init-local.js +11 -20
  2. package/dist/bin/nx.d.ts +1 -0
  3. package/dist/bin/nx.js +28 -2
  4. package/dist/plugins/package-json.js +4 -2
  5. package/dist/src/adapter/ngcli-adapter.d.ts +2 -1
  6. package/dist/src/adapter/ngcli-adapter.js +25 -2
  7. package/dist/src/ai/clone-ai-config-repo.js +20 -3
  8. package/dist/src/analytics/analytics.js +10 -1
  9. package/dist/src/command-line/add/completion.d.ts +1 -0
  10. package/dist/src/command-line/add/completion.js +15 -0
  11. package/dist/src/command-line/affected/completion.d.ts +1 -0
  12. package/dist/src/command-line/affected/completion.js +15 -0
  13. package/dist/src/command-line/completion/argv-layout.d.ts +6 -0
  14. package/dist/src/command-line/completion/argv-layout.js +19 -0
  15. package/dist/src/command-line/completion/command-completions.d.ts +19 -0
  16. package/dist/src/command-line/completion/command-completions.js +120 -0
  17. package/dist/src/command-line/completion/command-handlers.d.ts +30 -0
  18. package/dist/src/command-line/completion/command-handlers.js +69 -0
  19. package/dist/src/command-line/completion/command-object.d.ts +10 -0
  20. package/dist/src/command-line/completion/command-object.js +95 -0
  21. package/dist/src/command-line/completion/completion-providers.d.ts +21 -0
  22. package/dist/src/command-line/completion/completion-providers.js +194 -0
  23. package/dist/src/command-line/completion/infix-targets.d.ts +1 -0
  24. package/dist/src/command-line/completion/infix-targets.js +48 -0
  25. package/dist/src/command-line/completion/metadata.d.ts +22 -0
  26. package/dist/src/command-line/completion/metadata.js +71 -0
  27. package/dist/src/command-line/completion/registrations.d.ts +9 -0
  28. package/dist/src/command-line/completion/registrations.js +16 -0
  29. package/dist/src/command-line/completion/scripts/bash.sh +51 -0
  30. package/dist/src/command-line/completion/scripts/fish.fish +47 -0
  31. package/dist/src/command-line/completion/scripts/powershell.ps1 +52 -0
  32. package/dist/src/command-line/completion/scripts/zsh.zsh +69 -0
  33. package/dist/src/command-line/completion/scripts.d.ts +18 -0
  34. package/dist/src/command-line/completion/scripts.js +140 -0
  35. package/dist/src/command-line/completion/trigger.d.ts +3 -0
  36. package/dist/src/command-line/completion/trigger.js +21 -0
  37. package/dist/src/command-line/completion/value-completions.d.ts +3 -0
  38. package/dist/src/command-line/completion/value-completions.js +21 -0
  39. package/dist/src/command-line/examples.js +1 -1
  40. package/dist/src/command-line/format/format.js +15 -5
  41. package/dist/src/command-line/generate/completion.d.ts +1 -0
  42. package/dist/src/command-line/generate/completion.js +9 -0
  43. package/dist/src/command-line/graph/completion.d.ts +1 -0
  44. package/dist/src/command-line/graph/completion.js +13 -0
  45. package/dist/src/command-line/init/implementation/angular/standalone-workspace.js +14 -18
  46. package/dist/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +1 -0
  47. package/dist/src/command-line/init/implementation/utils.d.ts +7 -1
  48. package/dist/src/command-line/init/implementation/utils.js +51 -14
  49. package/dist/src/command-line/migrate/agentic/capture-generator-output.d.ts +22 -0
  50. package/dist/src/command-line/migrate/agentic/capture-generator-output.js +100 -0
  51. package/dist/src/command-line/migrate/agentic/cli-args.d.ts +12 -0
  52. package/dist/src/command-line/migrate/agentic/cli-args.js +38 -0
  53. package/dist/src/command-line/migrate/agentic/definitions.d.ts +6 -0
  54. package/dist/src/command-line/migrate/agentic/definitions.js +98 -0
  55. package/dist/src/command-line/migrate/agentic/detect-installed.d.ts +10 -0
  56. package/dist/src/command-line/migrate/agentic/detect-installed.js +68 -0
  57. package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +46 -0
  58. package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +87 -0
  59. package/dist/src/command-line/migrate/agentic/handoff.d.ts +63 -0
  60. package/dist/src/command-line/migrate/agentic/handoff.js +183 -0
  61. package/dist/src/command-line/migrate/agentic/inception.d.ts +9 -0
  62. package/dist/src/command-line/migrate/agentic/inception.js +15 -0
  63. package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.d.ts +22 -0
  64. package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.js +50 -0
  65. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.d.ts +51 -0
  66. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +65 -0
  67. package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.d.ts +44 -0
  68. package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.js +52 -0
  69. package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.d.ts +21 -0
  70. package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.js +26 -0
  71. package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.d.ts +18 -0
  72. package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.js +130 -0
  73. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +46 -0
  74. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +88 -0
  75. package/dist/src/command-line/migrate/agentic/run-step.d.ts +51 -0
  76. package/dist/src/command-line/migrate/agentic/run-step.js +121 -0
  77. package/dist/src/command-line/migrate/agentic/runner.d.ts +33 -0
  78. package/dist/src/command-line/migrate/agentic/runner.js +442 -0
  79. package/dist/src/command-line/migrate/agentic/select.d.ts +14 -0
  80. package/dist/src/command-line/migrate/agentic/select.js +150 -0
  81. package/dist/src/command-line/migrate/agentic/types.d.ts +102 -0
  82. package/dist/src/command-line/migrate/agentic/types.js +2 -0
  83. package/dist/src/command-line/migrate/command-object.d.ts +1 -0
  84. package/dist/src/command-line/migrate/command-object.js +32 -7
  85. package/dist/src/command-line/migrate/migrate-commits.d.ts +50 -0
  86. package/dist/src/command-line/migrate/migrate-commits.js +102 -0
  87. package/dist/src/command-line/migrate/migrate-output.d.ts +180 -0
  88. package/dist/src/command-line/migrate/migrate-output.js +258 -0
  89. package/dist/src/command-line/migrate/migrate.d.ts +122 -12
  90. package/dist/src/command-line/migrate/migrate.js +1036 -217
  91. package/dist/src/command-line/migrate/migration-shape.d.ts +8 -0
  92. package/dist/src/command-line/migrate/migration-shape.js +13 -0
  93. package/dist/src/command-line/migrate/multi-major.d.ts +30 -0
  94. package/dist/src/command-line/migrate/multi-major.js +185 -0
  95. package/dist/src/command-line/migrate/prompt-files.d.ts +31 -0
  96. package/dist/src/command-line/migrate/prompt-files.js +141 -0
  97. package/dist/src/command-line/migrate/run-migration-process.js +28 -6
  98. package/dist/src/command-line/migrate/safe-prompt.d.ts +28 -0
  99. package/dist/src/command-line/migrate/safe-prompt.js +49 -0
  100. package/dist/src/command-line/migrate/update-filters.d.ts +11 -0
  101. package/dist/src/command-line/migrate/update-filters.js +44 -0
  102. package/dist/src/command-line/migrate/version-utils.d.ts +6 -0
  103. package/dist/src/command-line/migrate/version-utils.js +59 -0
  104. package/dist/src/command-line/nx-commands.js +9 -0
  105. package/dist/src/command-line/release/config/config.d.ts +3 -6
  106. package/dist/src/command-line/release/config/config.js +77 -45
  107. package/dist/src/command-line/release/config/use-legacy-versioning.d.ts +2 -0
  108. package/dist/src/command-line/release/config/use-legacy-versioning.js +8 -0
  109. package/dist/src/command-line/release/utils/release-graph.js +2 -3
  110. package/dist/src/command-line/release/utils/repository-git-tags.js +1 -1
  111. package/dist/src/command-line/release/utils/resolve-changelog-renderer.js +7 -19
  112. package/dist/src/command-line/release/version/resolve-current-version.js +1 -1
  113. package/dist/src/command-line/release/version/version-actions.js +3 -7
  114. package/dist/src/command-line/report/report.js +2 -2
  115. package/dist/src/command-line/run/completion.d.ts +1 -0
  116. package/dist/src/command-line/run/completion.js +7 -0
  117. package/dist/src/command-line/run-many/completion.d.ts +1 -0
  118. package/dist/src/command-line/run-many/completion.js +13 -0
  119. package/dist/src/command-line/show/completion.d.ts +1 -0
  120. package/dist/src/command-line/show/completion.js +27 -0
  121. package/dist/src/command-line/show/show-target/info.d.ts +1 -0
  122. package/dist/src/command-line/show/show-target/info.js +100 -19
  123. package/dist/src/command-line/watch/command-object.js +24 -4
  124. package/dist/src/command-line/watch/completion.d.ts +1 -0
  125. package/dist/src/command-line/watch/completion.js +10 -0
  126. package/dist/src/command-line/watch/watch.d.ts +7 -0
  127. package/dist/src/command-line/watch/watch.js +1 -1
  128. package/dist/src/config/misc-interfaces.d.ts +25 -2
  129. package/dist/src/config/nx-json.d.ts +43 -56
  130. package/dist/src/config/schema-utils.d.ts +21 -0
  131. package/dist/src/config/schema-utils.js +92 -18
  132. package/dist/src/config/task-graph.d.ts +4 -107
  133. package/dist/src/core/graph/main.js +1 -1
  134. package/dist/src/core/graph/styles.css +2 -3
  135. package/dist/src/core/graph/styles.js +1 -1
  136. package/dist/src/daemon/client/client.d.ts +1 -1
  137. package/dist/src/daemon/server/file-watching/file-watcher-sockets.d.ts +1 -1
  138. package/dist/src/daemon/server/file-watching/file-watcher-sockets.js +1 -1
  139. package/dist/src/daemon/server/file-watching/route-workspace-changes.d.ts +9 -0
  140. package/dist/src/daemon/server/file-watching/route-workspace-changes.js +76 -0
  141. package/dist/src/daemon/server/project-graph-incremental-recomputation.js +45 -11
  142. package/dist/src/daemon/server/server.js +4 -43
  143. package/dist/src/daemon/server/start.d.ts +1 -1
  144. package/dist/src/daemon/server/start.js +2 -0
  145. package/dist/src/devkit-exports.d.ts +2 -2
  146. package/dist/src/devkit-internals.d.ts +5 -1
  147. package/dist/src/devkit-internals.js +17 -1
  148. package/dist/src/executors/run-commands/running-tasks.d.ts +7 -0
  149. package/dist/src/executors/run-commands/running-tasks.js +178 -105
  150. package/dist/src/executors/run-script/run-script.impl.js +3 -10
  151. package/dist/src/executors/utils/convert-nx-executor.js +1 -1
  152. package/dist/src/hasher/hash-plan-inspector.d.ts +1 -1
  153. package/dist/src/hasher/task-hasher.js +6 -4
  154. package/dist/src/index.d.ts +1 -1
  155. package/dist/src/index.js +0 -3
  156. package/dist/src/migrations/update-16-2-0/remove-run-commands-output-path.js +6 -2
  157. package/dist/src/migrations/update-17-0-0/move-cache-directory.md +31 -0
  158. package/dist/src/migrations/update-17-0-0/use-minimal-config-for-tasks-runner-options.js +20 -4
  159. package/dist/src/migrations/update-20-0-0/move-use-daemon-process.md +27 -0
  160. package/dist/src/migrations/update-20-0-1/use-legacy-cache.md +24 -0
  161. package/dist/src/migrations/update-21-0-0/release-changelog-config-changes.md +49 -0
  162. package/dist/src/migrations/update-21-0-0/release-version-config-changes.md +54 -0
  163. package/dist/src/migrations/update-21-0-0/remove-custom-tasks-runner.md +28 -0
  164. package/dist/src/migrations/update-21-0-0/remove-legacy-cache.md +22 -0
  165. package/dist/src/migrations/update-22-2-0/add-self-healing-to-gitignore.md +11 -0
  166. package/dist/src/migrations/update-23-0-0/add-migrate-runs-to-git-ignore.d.ts +2 -0
  167. package/dist/src/migrations/update-23-0-0/add-migrate-runs-to-git-ignore.js +16 -0
  168. package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.d.ts +9 -0
  169. package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.js +18 -0
  170. package/dist/src/migrations/update-23-0-0/convert-target-defaults-to-array.d.ts +35 -0
  171. package/dist/src/migrations/update-23-0-0/convert-target-defaults-to-array.js +139 -0
  172. package/dist/src/migrations/update-23-0-0/convert-target-defaults-to-array.md +66 -0
  173. package/dist/src/native/index.d.ts +79 -2
  174. package/dist/src/native/native-bindings.js +3 -0
  175. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  176. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  177. package/dist/src/plugins/js/lock-file/npm-parser.js +37 -19
  178. package/dist/src/plugins/js/lock-file/pnpm-parser.js +51 -4
  179. package/dist/src/plugins/js/lock-file/project-graph-pruning.js +12 -4
  180. package/dist/src/plugins/js/utils/packages.js +1 -1
  181. package/dist/src/plugins/js/utils/register.d.ts +103 -14
  182. package/dist/src/plugins/js/utils/register.js +434 -39
  183. package/dist/src/plugins/js/utils/typescript.d.ts +7 -0
  184. package/dist/src/plugins/js/utils/typescript.js +39 -0
  185. package/dist/src/plugins/package-json/create-nodes.d.ts +3 -2
  186. package/dist/src/plugins/package-json/create-nodes.js +7 -5
  187. package/dist/src/project-graph/affected/locators/project-glob-changes.js +2 -1
  188. package/dist/src/project-graph/build-project-graph.d.ts +5 -0
  189. package/dist/src/project-graph/build-project-graph.js +6 -2
  190. package/dist/src/project-graph/file-map-utils.d.ts +5 -0
  191. package/dist/src/project-graph/file-map-utils.js +10 -1
  192. package/dist/src/project-graph/plugins/get-plugins.d.ts +7 -2
  193. package/dist/src/project-graph/plugins/get-plugins.js +8 -5
  194. package/dist/src/project-graph/plugins/isolation/plugin-worker.d.ts +1 -0
  195. package/dist/src/project-graph/plugins/isolation/plugin-worker.js +2 -0
  196. package/dist/src/project-graph/plugins/resolve-plugin.d.ts +7 -4
  197. package/dist/src/project-graph/plugins/resolve-plugin.js +152 -33
  198. package/dist/src/project-graph/plugins/tasks-execution-hooks.js +4 -2
  199. package/dist/src/project-graph/plugins/transpiler.d.ts +12 -0
  200. package/dist/src/project-graph/plugins/transpiler.js +37 -0
  201. package/dist/src/project-graph/plugins/utils.js +13 -7
  202. package/dist/src/project-graph/project-graph.js +1 -1
  203. package/dist/src/project-graph/utils/project-configuration/target-defaults.d.ts +95 -4
  204. package/dist/src/project-graph/utils/project-configuration/target-defaults.js +515 -68
  205. package/dist/src/project-graph/utils/project-configuration-utils.d.ts +13 -5
  206. package/dist/src/project-graph/utils/project-configuration-utils.js +14 -6
  207. package/dist/src/project-graph/utils/retrieve-workspace-files.js +1 -1
  208. package/dist/src/tasks-runner/create-task-graph.d.ts +4 -4
  209. package/dist/src/tasks-runner/create-task-graph.js +1 -1
  210. package/dist/src/tasks-runner/default-tasks-runner.d.ts +0 -2
  211. package/dist/src/tasks-runner/forked-process-task-runner.d.ts +1 -1
  212. package/dist/src/tasks-runner/forked-process-task-runner.js +11 -6
  213. package/dist/src/tasks-runner/init-tasks-runner.d.ts +0 -15
  214. package/dist/src/tasks-runner/init-tasks-runner.js +0 -63
  215. package/dist/src/tasks-runner/legacy-depends-on-warning.d.ts +18 -0
  216. package/dist/src/tasks-runner/legacy-depends-on-warning.js +109 -0
  217. package/dist/src/tasks-runner/life-cycle.d.ts +7 -8
  218. package/dist/src/tasks-runner/life-cycles/invoke-runner-terminal-output-life-cycle.js +6 -6
  219. package/dist/src/tasks-runner/life-cycles/task-history-life-cycle-old.js +13 -2
  220. package/dist/src/tasks-runner/life-cycles/task-history-life-cycle.js +16 -5
  221. package/dist/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +11 -2
  222. package/dist/src/tasks-runner/pseudo-terminal.d.ts +1 -1
  223. package/dist/src/tasks-runner/pseudo-terminal.js +22 -10
  224. package/dist/src/tasks-runner/run-command.js +8 -11
  225. package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +1 -1
  226. package/dist/src/tasks-runner/running-tasks/batch-process.js +3 -5
  227. package/dist/src/tasks-runner/running-tasks/node-child-process.d.ts +2 -2
  228. package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -7
  229. package/dist/src/tasks-runner/task-env.d.ts +1 -1
  230. package/dist/src/tasks-runner/task-env.js +6 -1
  231. package/dist/src/tasks-runner/task-orchestrator.d.ts +11 -1
  232. package/dist/src/tasks-runner/task-orchestrator.js +112 -38
  233. package/dist/src/tasks-runner/tasks-schedule.js +3 -3
  234. package/dist/src/tasks-runner/utils.d.ts +7 -8
  235. package/dist/src/tasks-runner/utils.js +23 -27
  236. package/dist/src/utils/child-process.js +2 -2
  237. package/dist/src/utils/compile-cache.d.ts +24 -0
  238. package/dist/src/utils/compile-cache.js +49 -0
  239. package/dist/src/utils/enable-compile-cache.d.ts +1 -0
  240. package/dist/src/utils/enable-compile-cache.js +7 -0
  241. package/dist/src/utils/fileutils.d.ts +0 -8
  242. package/dist/src/utils/fileutils.js +0 -40
  243. package/dist/src/utils/git-utils.d.ts +15 -0
  244. package/dist/src/utils/git-utils.js +138 -0
  245. package/dist/src/utils/handle-import.d.ts +4 -1
  246. package/dist/src/utils/handle-import.js +56 -2
  247. package/dist/src/utils/has-nx-js-plugin.d.ts +9 -0
  248. package/dist/src/utils/has-nx-js-plugin.js +24 -0
  249. package/dist/src/utils/installed-nx-version.d.ts +14 -4
  250. package/dist/src/utils/installed-nx-version.js +54 -7
  251. package/dist/src/utils/logger.d.ts +12 -1
  252. package/dist/src/utils/logger.js +57 -36
  253. package/dist/src/utils/nx-key.d.ts +0 -1
  254. package/dist/src/utils/nx-key.js +20 -23
  255. package/dist/src/utils/nx-package-group.d.ts +8 -0
  256. package/dist/src/utils/nx-package-group.js +15 -0
  257. package/dist/src/utils/output.d.ts +3 -2
  258. package/dist/src/utils/output.js +29 -28
  259. package/dist/src/utils/package-json.d.ts +14 -1
  260. package/dist/src/utils/package-json.js +20 -21
  261. package/dist/src/utils/perf-logging.js +3 -1
  262. package/dist/src/utils/plugin-cache-utils.d.ts +13 -4
  263. package/dist/src/utils/plugin-cache-utils.js +23 -13
  264. package/dist/src/utils/plugins/local-plugins.d.ts +18 -0
  265. package/dist/src/utils/plugins/local-plugins.js +30 -0
  266. package/dist/src/utils/tar.d.ts +8 -0
  267. package/dist/src/utils/tar.js +44 -0
  268. package/migrations.json +16 -0
  269. package/package.json +28 -28
  270. package/schemas/nx-schema.json +114 -80
  271. package/dist/src/plugins/js/project-graph/build-dependencies/strip-source-code.d.ts +0 -7
  272. package/dist/src/plugins/js/project-graph/build-dependencies/strip-source-code.js +0 -155
  273. package/dist/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.d.ts +0 -16
  274. package/dist/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.js +0 -121
@@ -0,0 +1,8 @@
1
+ interface MigrationShape {
2
+ prompt?: string;
3
+ implementation?: string;
4
+ factory?: string;
5
+ }
6
+ export declare function isPromptOnlyMigration(m: MigrationShape): boolean;
7
+ export declare function isHybridMigration(m: MigrationShape): boolean;
8
+ export {};
@@ -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
+ }