nx 23.1.0 → 23.1.1

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 (126) hide show
  1. package/dist/bin/nx.js +2 -1
  2. package/dist/src/ai/configure-ai-agents-disclaimer.d.ts +5 -0
  3. package/dist/src/ai/configure-ai-agents-disclaimer.js +31 -0
  4. package/dist/src/analytics/analytics.d.ts +6 -0
  5. package/dist/src/analytics/analytics.js +16 -8
  6. package/dist/src/analytics/index.d.ts +1 -1
  7. package/dist/src/analytics/index.js +2 -1
  8. package/dist/src/command-line/add/add.js +8 -1
  9. package/dist/src/command-line/graph/graph.d.ts +1 -0
  10. package/dist/src/command-line/graph/graph.js +15 -6
  11. package/dist/src/command-line/import/import.js +1 -1
  12. package/dist/src/command-line/init/ai-agent-prompts.d.ts +1 -1
  13. package/dist/src/command-line/init/ai-agent-prompts.js +7 -6
  14. package/dist/src/command-line/init/command-object.js +10 -2
  15. package/dist/src/command-line/init/configure-plugins.js +3 -2
  16. package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +4 -2
  17. package/dist/src/command-line/init/implementation/add-nx-to-nest.js +4 -3
  18. package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +4 -3
  19. package/dist/src/command-line/init/implementation/add-nx-to-turborepo.js +4 -3
  20. package/dist/src/command-line/init/implementation/angular/index.js +4 -2
  21. package/dist/src/command-line/init/implementation/angular/integrated-workspace.js +2 -5
  22. package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +3 -0
  23. package/dist/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +4 -1
  24. package/dist/src/command-line/init/implementation/utils.d.ts +3 -3
  25. package/dist/src/command-line/init/implementation/utils.js +22 -3
  26. package/dist/src/command-line/migrate/execute-migration.d.ts +72 -0
  27. package/dist/src/command-line/migrate/execute-migration.js +389 -0
  28. package/dist/src/command-line/migrate/migrate-ui-api.js +17 -12
  29. package/dist/src/command-line/migrate/migrate.d.ts +1 -45
  30. package/dist/src/command-line/migrate/migrate.js +33 -376
  31. package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +1 -1
  32. package/dist/src/command-line/nx-cloud/connect/view-logs.js +2 -0
  33. package/dist/src/command-line/release/utils/git.js +6 -2
  34. package/dist/src/command-line/release/utils/release-graph.d.ts +2 -2
  35. package/dist/src/command-line/release/utils/remote-release-clients/github.js +1 -1
  36. package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +1 -1
  37. package/dist/src/command-line/release/utils/shared.d.ts +2 -2
  38. package/dist/src/command-line/show/show-target/info.js +11 -2
  39. package/dist/src/command-line/show/show-target/inputs.js +50 -153
  40. package/dist/src/command-line/show/show-target/outputs.js +48 -173
  41. package/dist/src/command-line/show/show-target/utils.d.ts +28 -0
  42. package/dist/src/command-line/show/show-target/utils.js +83 -3
  43. package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
  44. package/dist/src/commands-runner/create-command-graph.js +5 -0
  45. package/dist/src/config/nx-json.d.ts +5 -3
  46. package/dist/src/core/graph/main.js +1 -1
  47. package/dist/src/daemon/client/client.d.ts +0 -2
  48. package/dist/src/daemon/client/client.js +17 -19
  49. package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +1 -1
  50. package/dist/src/daemon/server/server.js +7 -4
  51. package/dist/src/devkit-internals.d.ts +3 -0
  52. package/dist/src/devkit-internals.js +10 -1
  53. package/dist/src/generators/utils/nx-json.js +13 -3
  54. package/dist/src/hasher/check-task-files.d.ts +86 -0
  55. package/dist/src/hasher/check-task-files.js +378 -0
  56. package/dist/src/native/index.d.ts +21 -2
  57. package/dist/src/native/native-bindings.js +2 -0
  58. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  59. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  60. package/dist/src/plugins/js/lock-file/npm-parser.js +71 -27
  61. package/dist/src/plugins/js/lock-file/pnpm-parser.js +50 -17
  62. package/dist/src/plugins/js/lock-file/project-graph-pruning.js +1 -1
  63. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +3 -0
  64. package/dist/src/plugins/js/lock-file/yarn-parser.js +32 -5
  65. package/dist/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +12 -4
  66. package/dist/src/plugins/js/utils/register.d.ts +18 -0
  67. package/dist/src/plugins/js/utils/register.js +81 -0
  68. package/dist/src/plugins/js/utils/typescript.d.ts +9 -0
  69. package/dist/src/plugins/js/utils/typescript.js +15 -0
  70. package/dist/src/project-graph/build-project-graph.js +7 -1
  71. package/dist/src/project-graph/error-types.js +41 -1
  72. package/dist/src/project-graph/file-utils.js +6 -1
  73. package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +4 -0
  74. package/dist/src/project-graph/plugins/loaded-nx-plugin.js +1 -0
  75. package/dist/src/project-graph/plugins/transpiler.js +4 -0
  76. package/dist/src/project-graph/project-graph.js +3 -0
  77. package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.d.ts +10 -12
  78. package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.js +93 -63
  79. package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.d.ts +5 -8
  80. package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.js +11 -14
  81. package/dist/src/project-graph/utils/project-configuration/source-maps.d.ts +12 -5
  82. package/dist/src/project-graph/utils/project-configuration/source-maps.js +21 -7
  83. package/dist/src/project-graph/utils/project-configuration/target-defaults.d.ts +1 -1
  84. package/dist/src/project-graph/utils/project-configuration/target-defaults.js +26 -27
  85. package/dist/src/project-graph/utils/project-configuration/target-merging.js +50 -8
  86. package/dist/src/project-graph/utils/project-configuration/target-normalization.js +16 -3
  87. package/dist/src/project-graph/utils/project-configuration/utils.d.ts +15 -0
  88. package/dist/src/project-graph/utils/project-configuration/utils.js +42 -6
  89. package/dist/src/project-graph/utils/project-configuration-utils.d.ts +15 -12
  90. package/dist/src/project-graph/utils/project-configuration-utils.js +79 -101
  91. package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +11 -4
  92. package/dist/src/tasks-runner/life-cycles/performance-analysis.js +15 -6
  93. package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +5 -4
  94. package/dist/src/tasks-runner/life-cycles/performance-report.d.ts +18 -8
  95. package/dist/src/tasks-runner/life-cycles/performance-report.js +66 -29
  96. package/dist/src/tasks-runner/run-command.js +4 -2
  97. package/dist/src/tasks-runner/task-env.d.ts +9 -0
  98. package/dist/src/tasks-runner/task-env.js +26 -2
  99. package/dist/src/tasks-runner/task-orchestrator.d.ts +4 -1
  100. package/dist/src/tasks-runner/task-orchestrator.js +23 -10
  101. package/dist/src/utils/acknowledge-build-scripts.d.ts +13 -0
  102. package/dist/src/utils/acknowledge-build-scripts.js +102 -0
  103. package/dist/src/utils/analytics-prompt.d.ts +0 -6
  104. package/dist/src/utils/analytics-prompt.js +0 -51
  105. package/dist/src/utils/catalog/manager-utils.d.ts +1 -2
  106. package/dist/src/utils/catalog/manager-utils.js +22 -5
  107. package/dist/src/utils/catalog/pnpm-manager.d.ts +1 -0
  108. package/dist/src/utils/catalog/pnpm-manager.js +3 -15
  109. package/dist/src/utils/catalog/yarn-manager.d.ts +1 -0
  110. package/dist/src/utils/catalog/yarn-manager.js +3 -15
  111. package/dist/src/utils/command-line-utils.js +30 -20
  112. package/dist/src/utils/git-revision.d.ts +12 -0
  113. package/dist/src/utils/git-revision.js +25 -0
  114. package/dist/src/utils/git-utils.d.ts +16 -3
  115. package/dist/src/utils/git-utils.js +146 -52
  116. package/dist/src/utils/min-release-age/behavior/pnpm.js +9 -7
  117. package/dist/src/utils/package-json.js +11 -7
  118. package/dist/src/utils/package-manager.d.ts +3 -1
  119. package/dist/src/utils/package-manager.js +28 -4
  120. package/dist/src/utils/provenance.js +12 -2
  121. package/dist/src/utils/workspace-id.d.ts +20 -0
  122. package/dist/src/utils/workspace-id.js +54 -0
  123. package/migrations.json +7 -1
  124. package/package.json +22 -17
  125. package/dist/src/migrations/update-17-3-0/nx-release-path.d.ts +0 -3
  126. package/dist/src/migrations/update-17-3-0/nx-release-path.js +0 -47
@@ -1,24 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChangedDepInstaller = exports.isHybridMigration = exports.isPromptOnlyMigration = exports.filterDowngradedUpdates = exports.Migrator = exports.normalizeVersion = void 0;
3
+ exports.isHybridMigration = exports.isPromptOnlyMigration = exports.filterDowngradedUpdates = exports.Migrator = exports.normalizeVersion = void 0;
4
4
  exports.formatCommandFailure = formatCommandFailure;
5
5
  exports.resolveCanonicalNxPackage = resolveCanonicalNxPackage;
6
6
  exports.resolveInclude = resolveInclude;
7
7
  exports.parseMigrationsOptions = parseMigrationsOptions;
8
8
  exports.createFetcher = createFetcher;
9
9
  exports.generateMigrationsJsonAndUpdatePackageJson = generateMigrationsJsonAndUpdatePackageJson;
10
- exports.isNpmPeerDepsError = isNpmPeerDepsError;
11
10
  exports.resolveAgenticRunId = resolveAgenticRunId;
12
11
  exports.formatSkippedPromptsNextStep = formatSkippedPromptsNextStep;
13
12
  exports.resolveCreateCommits = resolveCreateCommits;
14
13
  exports.resolveShouldRunValidation = resolveShouldRunValidation;
15
14
  exports.executeMigrations = executeMigrations;
16
- exports.runNxOrAngularMigration = runNxOrAngularMigration;
17
- exports.parseMigrationReturn = parseMigrationReturn;
18
15
  exports.migrate = migrate;
19
16
  exports.runMigration = runMigration;
20
- exports.readMigrationCollection = readMigrationCollection;
21
- exports.getImplementationPath = getImplementationPath;
22
17
  exports.resolveMigrationForRun = resolveMigrationForRun;
23
18
  exports.resolveDocumentationFileToWorkspacePath = resolveDocumentationFileToWorkspacePath;
24
19
  exports.nxCliPath = nxCliPath;
@@ -26,14 +21,12 @@ const tslib_1 = require("tslib");
26
21
  const pc = tslib_1.__importStar(require("picocolors"));
27
22
  const child_process_1 = require("child_process");
28
23
  const safe_prompt_1 = require("./safe-prompt");
29
- const handle_import_1 = require("../../utils/handle-import");
30
24
  const path_1 = require("path");
31
25
  const module_1 = require("module");
32
26
  const path_2 = require("../../utils/path");
33
27
  const semver_1 = require("semver");
34
28
  const node_url_1 = require("node:url");
35
29
  const util_1 = require("util");
36
- const tree_1 = require("../../generators/tree");
37
30
  const fileutils_1 = require("../../utils/fileutils");
38
31
  const tar_1 = require("../../utils/tar");
39
32
  const write_formatted_json_file_1 = require("../../utils/write-formatted-json-file");
@@ -55,7 +48,6 @@ const configuration_1 = require("../../config/configuration");
55
48
  const child_process_2 = require("../../utils/child-process");
56
49
  const client_1 = require("../../daemon/client/client");
57
50
  const nx_cloud_utils_1 = require("../../utils/nx-cloud-utils");
58
- const project_graph_1 = require("../../project-graph/project-graph");
59
51
  const format_changed_files_with_prettier_if_available_1 = require("../../generators/internal-utils/format-changed-files-with-prettier-if-available");
60
52
  const provenance_1 = require("../../utils/provenance");
61
53
  const catalog_1 = require("../../utils/catalog");
@@ -74,6 +66,8 @@ const update_filters_1 = require("./update-filters");
74
66
  Object.defineProperty(exports, "filterDowngradedUpdates", { enumerable: true, get: function () { return update_filters_1.filterDowngradedUpdates; } });
75
67
  const version_utils_1 = require("./version-utils");
76
68
  Object.defineProperty(exports, "normalizeVersion", { enumerable: true, get: function () { return version_utils_1.normalizeVersion; } });
69
+ const execute_migration_1 = require("./execute-migration");
70
+ tslib_1.__exportStar(require("./execute-migration"), exports);
77
71
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
78
72
  function formatCommandFailure(command, error) {
79
73
  const normalizeCommandOutput = (output) => {
@@ -1051,6 +1045,15 @@ function createFetcher(pmc) {
1051
1045
  migrationsCache[packageName + '-' + packageVersion] = migrations;
1052
1046
  }
1053
1047
  migrations = fetchMigrations(packageName, packageVersion, setCache).then((result) => {
1048
+ // An exact requested version must come back verbatim; a mismatch means
1049
+ // a config surface (registry proxy, override, cooldown gate) silently
1050
+ // substituted another version, which would corrupt the whole plan.
1051
+ if ((0, semver_1.valid)(packageVersion) &&
1052
+ result.version &&
1053
+ result.version !== packageVersion) {
1054
+ throw new Error(`Fetching ${packageName}@${packageVersion} resolved to version ${result.version}. ` +
1055
+ `Check for registry, override, or minimum-release-age configuration that hides the requested version.`);
1056
+ }
1054
1057
  if (result.schematics) {
1055
1058
  result.generators = { ...result.schematics, ...result.generators };
1056
1059
  delete result.schematics;
@@ -1111,7 +1114,13 @@ async function downloadPackageMigrationsFromRegistry(packageName, packageVersion
1111
1114
  const { dir, cleanup } = (0, package_manager_1.createTempNpmDirectory)();
1112
1115
  let result;
1113
1116
  try {
1114
- const { tarballPath } = await (0, package_manager_1.packageRegistryPack)(dir, packageName, packageVersion);
1117
+ const { tarballPath } = await (0, package_manager_1.packageRegistryPack)(dir, packageName, packageVersion,
1118
+ // packageVersion is exact and already resolved through the workspace
1119
+ // package manager's min-release-age policy by the fetcher. In an npm
1120
+ // workspace the pack gate IS that policy, so leave it enforcing; for
1121
+ // other package managers npm's gate is foreign config with no
1122
+ // exclusions and would wrongly re-judge the vetted version.
1123
+ { bypassMinReleaseAge: (0, package_manager_1.detectPackageManager)() !== 'npm' });
1115
1124
  const fullTarballPath = (0, path_1.join)(dir, tarballPath);
1116
1125
  let migrations;
1117
1126
  try {
@@ -1189,7 +1198,7 @@ async function getPackageMigrationsUsingInstallImpl(packageName, packageVersion,
1189
1198
  // as-is by the outer catch instead of being mislabeled as install failures.
1190
1199
  throw new Error(formatCommandFailure(addCommand, e));
1191
1200
  }
1192
- const { migrations: migrationsFilePath, packageGroup, supportsOptionalMigrations, packageJson, } = readPackageMigrationConfig(packageName, dir);
1201
+ const { migrations: migrationsFilePath, packageGroup, supportsOptionalMigrations, packageJson, } = (0, execute_migration_1.readPackageMigrationConfig)(packageName, dir);
1193
1202
  let migrations = undefined;
1194
1203
  let resolvedPromptFiles;
1195
1204
  if (migrationsFilePath) {
@@ -1216,32 +1225,6 @@ async function getPackageMigrationsUsingInstallImpl(packageName, packageVersion,
1216
1225
  }
1217
1226
  return result;
1218
1227
  }
1219
- function readPackageMigrationConfig(packageName, dir) {
1220
- const { path: packageJsonPath, packageJson: json } = (0, package_json_1.readModulePackageJson)(packageName, (0, installation_directory_1.getNxRequirePaths)(dir));
1221
- const config = (0, package_json_1.readNxMigrateConfig)(json);
1222
- if (!config) {
1223
- return { packageJson: json, migrations: null, packageGroup: [] };
1224
- }
1225
- try {
1226
- const migrationFile = require.resolve(config.migrations, {
1227
- paths: [(0, path_1.dirname)(packageJsonPath)],
1228
- });
1229
- return {
1230
- packageJson: json,
1231
- migrations: migrationFile,
1232
- packageGroup: config.packageGroup,
1233
- supportsOptionalMigrations: config.supportsOptionalMigrations,
1234
- };
1235
- }
1236
- catch {
1237
- return {
1238
- packageJson: json,
1239
- migrations: null,
1240
- packageGroup: config.packageGroup,
1241
- supportsOptionalMigrations: config.supportsOptionalMigrations,
1242
- };
1243
- }
1244
- }
1245
1228
  async function createMigrationsFile(root, migrations) {
1246
1229
  await (0, write_formatted_json_file_1.writeFormattedJsonFile)((0, path_1.join)(root, 'migrations.json'), { migrations });
1247
1230
  }
@@ -1608,118 +1591,6 @@ function showConnectToCloudMessage() {
1608
1591
  return false;
1609
1592
  }
1610
1593
  }
1611
- function runInstall(nxWorkspaceRoot, phase = 'pre-migration') {
1612
- const cwd = nxWorkspaceRoot ?? process.cwd();
1613
- const packageManager = (0, package_manager_1.detectPackageManager)(cwd);
1614
- const pmCommands = (0, package_manager_1.getPackageManagerCommand)(packageManager, cwd);
1615
- const installCommand = `${pmCommands.install} ${pmCommands.ignoreScriptsFlag ?? ''}`;
1616
- output_1.output.log({
1617
- title: `Running '${installCommand}' to make sure necessary packages are installed`,
1618
- });
1619
- return new Promise((resolve, reject) => {
1620
- // For npm, pipe stderr so we can detect peer dependency errors while still
1621
- // mirroring it live to the user's terminal. Other package managers inherit
1622
- // stderr directly since we don't need to inspect their output.
1623
- const shouldCaptureStderr = packageManager === 'npm';
1624
- const child = (0, child_process_1.spawn)(installCommand, {
1625
- shell: true,
1626
- stdio: ['inherit', 'inherit', shouldCaptureStderr ? 'pipe' : 'inherit'],
1627
- windowsHide: true,
1628
- cwd,
1629
- });
1630
- const stderrChunks = [];
1631
- child.stderr?.on('data', (chunk) => {
1632
- process.stderr.write(chunk);
1633
- stderrChunks.push(chunk);
1634
- });
1635
- child.on('error', reject);
1636
- child.on('close', (code) => {
1637
- if (code === 0) {
1638
- resolve();
1639
- return;
1640
- }
1641
- if (shouldCaptureStderr) {
1642
- const stderr = Buffer.concat(stderrChunks).toString().trim();
1643
- if (isNpmPeerDepsError(stderr)) {
1644
- // Log the remediation guidance here so every caller of `runInstall`
1645
- // (CLI migrate, `nx repair`, single-migration runner, etc.) surfaces
1646
- // it consistently. Top-level callers catch `NpmPeerDepsInstallError`
1647
- // and return a non-zero exit code without re-logging.
1648
- logNpmPeerDepsError(phase);
1649
- reject(new NpmPeerDepsInstallError());
1650
- return;
1651
- }
1652
- }
1653
- reject(new Error(`Command failed: ${installCommand}`));
1654
- });
1655
- });
1656
- }
1657
- class NpmPeerDepsInstallError extends Error {
1658
- constructor() {
1659
- super('npm install failed due to peer dependency conflicts.');
1660
- this.name = 'NpmPeerDepsInstallError';
1661
- }
1662
- }
1663
- /**
1664
- * Detects npm peer-dependency resolution failures. Keyed on the `ERESOLVE`
1665
- * error code, which npm consistently emits for this class of failure across
1666
- * v7+ (`npm ERR! code ERESOLVE` / `npm error code ERESOLVE`). Falls back to a
1667
- * small set of stable phrases in case the code line is missing from the
1668
- * captured output.
1669
- */
1670
- function isNpmPeerDepsError(stderr) {
1671
- if (/\bERESOLVE\b/.test(stderr)) {
1672
- return true;
1673
- }
1674
- const lowerStderr = stderr.toLowerCase();
1675
- return (lowerStderr.includes('unable to resolve dependency tree') ||
1676
- lowerStderr.includes('could not resolve dependency') ||
1677
- lowerStderr.includes('conflicting peer dependency'));
1678
- }
1679
- function logNpmPeerDepsError(phase) {
1680
- const peerDepsResolutionSteps = [
1681
- 'Recommended approaches (in order of preference):',
1682
- '',
1683
- '1. Use "overrides" in package.json to force compatible versions across the dependency tree.',
1684
- ' See https://docs.npmjs.com/cli/configuring-npm/package-json#overrides',
1685
- '2. Persist legacy peer deps resolution in the project ".npmrc":',
1686
- ' npm config set legacy-peer-deps=true --location=project',
1687
- ' (bypasses peer dependency resolution; use with caution)',
1688
- '3. As a last resort, force the installation by running "npm install --force".',
1689
- ' (does not persist and may produce broken installs)',
1690
- ];
1691
- const manualInstallHint = [
1692
- 'If you installed the dependencies manually, pass "--skip-install" to avoid re-installing them:',
1693
- ' nx migrate --run-migrations --skip-install',
1694
- ];
1695
- if (phase === 'pre-migration') {
1696
- output_1.output.error({
1697
- title: 'You need to resolve the peer dependency conflicts before the migration can continue',
1698
- bodyLines: [
1699
- ...peerDepsResolutionSteps,
1700
- '',
1701
- 'Once the conflicts are resolved, re-run the migrations:',
1702
- ' nx migrate --run-migrations',
1703
- '',
1704
- ...manualInstallHint,
1705
- ],
1706
- });
1707
- }
1708
- else {
1709
- output_1.output.error({
1710
- title: 'Some migrations have been applied, but installing the updated dependencies failed',
1711
- bodyLines: [
1712
- ...peerDepsResolutionSteps,
1713
- '',
1714
- 'Once the conflicts are resolved, run "npm install" to install the updated dependencies.',
1715
- 'If the migration was interrupted before completing, re-run the remaining migrations:',
1716
- ' nx migrate --run-migrations',
1717
- '',
1718
- ...manualInstallHint,
1719
- ],
1720
- });
1721
- }
1722
- }
1723
1594
  function resolveAgenticRunId(migrations) {
1724
1595
  return (0, semver_1.rsort)(migrations.map((m) => (0, version_utils_1.normalizeVersion)(m.version)))[0];
1725
1596
  }
@@ -1797,7 +1668,7 @@ function resolveShouldRunValidation(args) {
1797
1668
  return args.validate !== false && args.agenticKind === 'enabled';
1798
1669
  }
1799
1670
  async function executeMigrations(root, migrations, isVerbose, shouldCreateCommits, commitPrefix, shouldSkipInstall = false, agentic, agenticHasDiffContext = false, shouldRunValidation = false) {
1800
- const changedDepInstaller = new ChangedDepInstaller(root, shouldSkipInstall);
1671
+ const changedDepInstaller = new execute_migration_1.ChangedDepInstaller(root, shouldSkipInstall);
1801
1672
  const migrationsWithNoChanges = [];
1802
1673
  const sortedMigrations = migrations.sort((a, b) => {
1803
1674
  // Under `--agentic`, hoist the v23 migration that ignores
@@ -1957,7 +1828,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
1957
1828
  }
1958
1829
  }
1959
1830
  else if ((0, migration_shape_1.isHybridMigration)(m)) {
1960
- const { changes, nextSteps, agentContext, logs, madeChanges } = await runNxOrAngularMigration(root, m, isVerbose,
1831
+ const { changes, nextSteps, agentContext, logs, madeChanges } = await (0, execute_migration_1.runNxOrAngularMigration)(root, m, isVerbose,
1961
1832
  /* captureGeneratorOutput: */ !!agenticRun, resolvedCollection);
1962
1833
  migrationEmittedNextSteps.push(...nextSteps);
1963
1834
  if (agenticRun) {
@@ -2021,7 +1892,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
2021
1892
  // Defer commit until validation succeeds; failed validation leaves
2022
1893
  // changes uncommitted in the working tree for the user to review.
2023
1894
  const validationRun = agenticRun && shouldRunValidation ? agenticRun : undefined;
2024
- const { changes, nextSteps, agentContext, logs, madeChanges } = await runNxOrAngularMigration(root, m, isVerbose,
1895
+ const { changes, nextSteps, agentContext, logs, madeChanges } = await (0, execute_migration_1.runNxOrAngularMigration)(root, m, isVerbose,
2025
1896
  /* captureGeneratorOutput: */ !!validationRun, resolvedCollection);
2026
1897
  migrationEmittedNextSteps.push(...nextSteps);
2027
1898
  const canRunValidation = !!validationRun && changes.length > 0;
@@ -2098,7 +1969,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
2098
1969
  // `nx repair` reuses executeMigrations; only record for migrate runs.
2099
1970
  if ((0, migrate_analytics_1.hasMigrateRunStarted)()) {
2100
1971
  (0, migrate_analytics_1.reportMigrateRunError)({
2101
- code: e instanceof NpmPeerDepsInstallError
1972
+ code: e instanceof execute_migration_1.NpmPeerDepsInstallError
2102
1973
  ? 'npm_install'
2103
1974
  : inAgenticStep
2104
1975
  ? 'agentic'
@@ -2109,7 +1980,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
2109
1980
  error: e,
2110
1981
  });
2111
1982
  }
2112
- if (!(e instanceof NpmPeerDepsInstallError)) {
1983
+ if (!(e instanceof execute_migration_1.NpmPeerDepsInstallError)) {
2113
1984
  // `withGeneratorOutputCapture` attaches the generator's `console.*`
2114
1985
  // output as `capturedLogs` (best-effort; may be absent). Surface it
2115
1986
  // so the user sees what the generator printed before it crashed.
@@ -2163,30 +2034,6 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
2163
2034
  retainedAtSuccess: (0, migrate_output_1.retainedMigrations)(outcomes).map((p) => `${p.package}: ${p.name}`),
2164
2035
  };
2165
2036
  }
2166
- class ChangedDepInstaller {
2167
- constructor(root, shouldSkipInstall = false) {
2168
- this.root = root;
2169
- this.shouldSkipInstall = shouldSkipInstall;
2170
- this._skippedInstall = false;
2171
- this.initialDeps = getStringifiedPackageJsonDeps(root);
2172
- }
2173
- get skippedInstall() {
2174
- return this._skippedInstall;
2175
- }
2176
- async installDepsIfChanged() {
2177
- const currentDeps = getStringifiedPackageJsonDeps(this.root);
2178
- if (this.initialDeps !== currentDeps) {
2179
- if (this.shouldSkipInstall) {
2180
- this._skippedInstall = true;
2181
- }
2182
- else {
2183
- await runInstall(this.root, 'post-migration');
2184
- }
2185
- }
2186
- this.initialDeps = currentDeps;
2187
- }
2188
- }
2189
- exports.ChangedDepInstaller = ChangedDepInstaller;
2190
2037
  function logSkippedPostMigrationInstall(root) {
2191
2038
  const packageManager = (0, package_manager_1.detectPackageManager)(root);
2192
2039
  const installCommand = (0, package_manager_1.getPackageManagerCommand)(packageManager, root).install;
@@ -2195,58 +2042,9 @@ function logSkippedPostMigrationInstall(root) {
2195
2042
  bodyLines: [`Run "${installCommand}" to install the updated dependencies.`],
2196
2043
  });
2197
2044
  }
2198
- async function runNxOrAngularMigration(root, migration, isVerbose, captureGeneratorOutput = false, resolvedCollection) {
2199
- const { collection, collectionPath } = resolvedCollection ?? readMigrationCollection(migration.package, root);
2200
- let changes = [];
2201
- let nextSteps = [];
2202
- let agentContext = [];
2203
- let logs = '';
2204
- // Angular's `ngResult.changes` is synthesized from the schematic's
2205
- // DryRunEvent stream so Nx and Angular paths can share commit/validation
2206
- // gating via `changes.length > 0`.
2207
- let madeChanges = false;
2208
- logger_1.logger.info(pc.dim('→ Running generator…'));
2209
- if (!isAngularMigration(collection, migration.name)) {
2210
- ({ nextSteps, changes, agentContext, logs } = await runNxMigration(root, collectionPath, collection, migration.name, migration.version, captureGeneratorOutput));
2211
- madeChanges = changes.length > 0;
2212
- logger_1.logger.info(`Ran ${migration.name} from ${migration.package}`);
2213
- if (migration.description) {
2214
- logger_1.logger.info(` ${migration.description}`);
2215
- }
2216
- logger_1.logger.info('');
2217
- if (!madeChanges) {
2218
- logger_1.logger.info(`No changes were made\n`);
2219
- return { changes, nextSteps, agentContext, logs, madeChanges };
2220
- }
2221
- logger_1.logger.info('Changes:');
2222
- (0, tree_1.printChanges)(changes, ' ');
2223
- logger_1.logger.info('');
2224
- }
2225
- else {
2226
- const ngCliAdapter = await getNgCompatLayer();
2227
- const migrationProjectGraph = await (0, project_graph_1.createProjectGraphAsync)();
2228
- const ngResult = await ngCliAdapter.runMigration(root, migration.package, migration.name, (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(migrationProjectGraph).projects, isVerbose, migrationProjectGraph);
2229
- changes = ngResult.changes;
2230
- madeChanges = ngResult.madeChanges;
2231
- logs = ngResult.loggingQueue.join('\n');
2232
- logger_1.logger.info(`Ran ${migration.name} from ${migration.package}`);
2233
- if (migration.description) {
2234
- logger_1.logger.info(` ${migration.description}`);
2235
- }
2236
- logger_1.logger.info('');
2237
- if (!madeChanges) {
2238
- logger_1.logger.info(`No changes were made\n`);
2239
- return { changes, nextSteps, agentContext, logs, madeChanges };
2240
- }
2241
- logger_1.logger.info('Changes:');
2242
- ngResult.loggingQueue.forEach((log) => logger_1.logger.info(' ' + log));
2243
- logger_1.logger.info('');
2244
- }
2245
- return { changes, nextSteps, agentContext, logs, madeChanges };
2246
- }
2247
2045
  async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, commitPrefix, shouldSkipInstall = false) {
2248
2046
  if (!shouldSkipInstall && !process.env.NX_MIGRATE_SKIP_INSTALL) {
2249
- await runInstall();
2047
+ await (0, execute_migration_1.runInstall)();
2250
2048
  }
2251
2049
  if (!__dirname.startsWith(workspace_root_1.workspaceRoot)) {
2252
2050
  // we are running from a temp installation with nx latest, switch to running
@@ -2419,59 +2217,6 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
2419
2217
  appliedCount,
2420
2218
  });
2421
2219
  }
2422
- function getStringifiedPackageJsonDeps(root) {
2423
- try {
2424
- const { dependencies, devDependencies } = (0, fileutils_1.readJsonFile)((0, path_1.join)(root, 'package.json'));
2425
- return JSON.stringify([dependencies, devDependencies]);
2426
- }
2427
- catch {
2428
- // We don't really care if the .nx/installation property changes,
2429
- // whenever nxw is invoked it will handle the dep updates.
2430
- return '';
2431
- }
2432
- }
2433
- async function runNxMigration(root, collectionPath, collection, name, migrationVersion, captureGeneratorOutput) {
2434
- const { path: implPath, fnSymbol } = getImplementationPath(collection, collectionPath, name, migrationVersion);
2435
- const fn = require(implPath)[fnSymbol];
2436
- const host = new tree_1.FsTree(root, process.env.NX_VERBOSE_LOGGING === 'true', `migration ${collection.name}:${name}`);
2437
- let result;
2438
- let logs = '';
2439
- if (captureGeneratorOutput) {
2440
- const { withGeneratorOutputCapture } = require('./agentic/capture-generator-output');
2441
- ({ result, logs } = await withGeneratorOutputCapture(() => fn(host, {})));
2442
- }
2443
- else {
2444
- result = await fn(host, {});
2445
- }
2446
- const { nextSteps, agentContext } = parseMigrationReturn(result);
2447
- host.lock();
2448
- const changes = host.listChanges();
2449
- (0, tree_1.flushChanges)(root, changes);
2450
- return { changes, nextSteps, agentContext, logs };
2451
- }
2452
- function parseMigrationReturn(value) {
2453
- if (Array.isArray(value)) {
2454
- return { nextSteps: filterStrings(value), agentContext: [] };
2455
- }
2456
- if (value && typeof value === 'object') {
2457
- const obj = value;
2458
- return {
2459
- nextSteps: filterStrings(obj.nextSteps),
2460
- agentContext: filterStrings(obj.agentContext),
2461
- };
2462
- }
2463
- // Catches `void`, mistakenly-returned generator callbacks, malformed values.
2464
- return { nextSteps: [], agentContext: [] };
2465
- }
2466
- // Bucket-level tolerance: a single non-string entry shouldn't discard the
2467
- // whole `nextSteps` / `agentContext` array. Migration authors occasionally
2468
- // push `null` / `undefined` / a number into the array; we drop the bad entries
2469
- // and keep the rest so end-of-run guidance isn't silently lost.
2470
- function filterStrings(value) {
2471
- if (!Array.isArray(value))
2472
- return [];
2473
- return value.filter((v) => typeof v === 'string');
2474
- }
2475
2220
  async function migrate(root, args, rawArgs) {
2476
2221
  await client_1.daemonClient.stop();
2477
2222
  return (0, handle_errors_1.handleErrors)(process.env.NX_VERBOSE_LOGGING === 'true', async () => {
@@ -2505,7 +2250,7 @@ async function migrate(root, args, rawArgs) {
2505
2250
  // The remediation guidance is already logged by `runInstall`; swallow
2506
2251
  // the error here so `handleErrors` doesn't print a noisy stack after
2507
2252
  // the friendly output.
2508
- if (e instanceof NpmPeerDepsInstallError) {
2253
+ if (e instanceof execute_migration_1.NpmPeerDepsInstallError) {
2509
2254
  (0, migrate_analytics_1.reportMigrateRunError)({ code: 'npm_install', error: e });
2510
2255
  return 1;
2511
2256
  }
@@ -2532,6 +2277,10 @@ async function runMigration() {
2532
2277
  process.env.npm_config_registry.match(/^https:\/\/registry\.(npmjs\.org|yarnpkg\.com)/)) {
2533
2278
  delete process.env.npm_config_registry;
2534
2279
  }
2280
+ // Intentionally not runNxSync: `p` is an nx CLI freshly installed into a
2281
+ // temp dir by nxCliPath() (latest, or NX_MIGRATE_CLI_VERSION), so
2282
+ // migrations run with an up-to-date migrate implementation instead of
2283
+ // the workspace's current nx.
2535
2284
  return runOrReturnExitCode(() => (0, child_process_1.execSync)(`${p} _migrate ${process.argv.slice(3).join(' ')}`, {
2536
2285
  stdio: ['inherit', 'inherit', 'inherit'],
2537
2286
  windowsHide: true,
@@ -2540,39 +2289,6 @@ async function runMigration() {
2540
2289
  return runLocalMigrate();
2541
2290
  });
2542
2291
  }
2543
- function readMigrationCollection(packageName, root) {
2544
- const collectionPath = readPackageMigrationConfig(packageName, root).migrations;
2545
- const collection = (0, fileutils_1.readJsonFile)(collectionPath);
2546
- collection.name ??= packageName;
2547
- return {
2548
- collection,
2549
- collectionPath,
2550
- };
2551
- }
2552
- function getImplementationPath(collection, collectionPath, name, migrationVersion) {
2553
- const g = collection.generators?.[name] || collection.schematics?.[name];
2554
- if (!g) {
2555
- throw new MigrationImplementationMissingError(`Unable to determine implementation path for "${collectionPath}:${name}"`, collectionPath, migrationVersion);
2556
- }
2557
- const implRelativePathAndMaybeSymbol = g.implementation || g.factory;
2558
- const [implRelativePath, fnSymbol = 'default'] = implRelativePathAndMaybeSymbol.split('#');
2559
- let implPath;
2560
- try {
2561
- implPath = require.resolve(implRelativePath, {
2562
- paths: [(0, path_1.dirname)(collectionPath)],
2563
- });
2564
- }
2565
- catch (e) {
2566
- try {
2567
- // workaround for a bug in node 12
2568
- implPath = require.resolve(`${(0, path_1.dirname)(collectionPath)}/${implRelativePath}`);
2569
- }
2570
- catch {
2571
- throw new MigrationImplementationMissingError(`Could not resolve implementation for migration "${name}" from "${collectionPath}"`, collectionPath, migrationVersion ?? g.version);
2572
- }
2573
- }
2574
- return { path: implPath, fnSymbol };
2575
- }
2576
2292
  /**
2577
2293
  * Resolves a migration's collection once and derives everything the run loop
2578
2294
  * needs from that single read: the implementation context (`collection` +
@@ -2591,11 +2307,11 @@ function getImplementationPath(collection, collectionPath, name, migrationVersio
2591
2307
  function resolveMigrationForRun(root, migration, resolveDocumentation) {
2592
2308
  let resolvedCollection;
2593
2309
  if (!(0, migration_shape_1.isPromptOnlyMigration)(migration)) {
2594
- resolvedCollection = readMigrationCollection(migration.package, root);
2310
+ resolvedCollection = (0, execute_migration_1.readMigrationCollection)(migration.package, root);
2595
2311
  }
2596
2312
  else if (resolveDocumentation && migration.documentation) {
2597
2313
  try {
2598
- resolvedCollection = readMigrationCollection(migration.package, root);
2314
+ resolvedCollection = (0, execute_migration_1.readMigrationCollection)(migration.package, root);
2599
2315
  }
2600
2316
  catch {
2601
2317
  // Non-fatal: documentation is supplementary; the warning below fires.
@@ -2630,52 +2346,6 @@ function resolveDocumentationFileToWorkspacePath(root, migrationsDir, documentat
2630
2346
  const relativePath = (0, path_1.relative)(root, documentationFile);
2631
2347
  return relativePath.startsWith('..') ? documentationFile : relativePath;
2632
2348
  }
2633
- class MigrationImplementationMissingError extends Error {
2634
- constructor(baseMessage, collectionPath, migrationVersion) {
2635
- super(buildMigrationMissingMessage(baseMessage, collectionPath, migrationVersion));
2636
- this.name = 'MigrationImplementationMissingError';
2637
- }
2638
- }
2639
- function buildMigrationMissingMessage(baseMessage, collectionPath, migrationVersion) {
2640
- if (!migrationVersion) {
2641
- return baseMessage;
2642
- }
2643
- try {
2644
- const packageJsonPath = (0, path_1.join)((0, path_1.dirname)(collectionPath), 'package.json');
2645
- if (!(0, fs_1.existsSync)(packageJsonPath)) {
2646
- return baseMessage;
2647
- }
2648
- const packageJson = (0, fileutils_1.readJsonFile)(packageJsonPath);
2649
- const installedVersion = packageJson.version;
2650
- if (installedVersion &&
2651
- (0, semver_1.lt)((0, version_utils_1.normalizeVersion)(installedVersion), (0, version_utils_1.normalizeVersion)(migrationVersion))) {
2652
- const packageManager = (0, package_manager_1.detectPackageManager)();
2653
- const pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager);
2654
- const overrideFieldName = getOverrideFieldName(packageManager);
2655
- return (`${baseMessage}\n\n` +
2656
- `The installed version of "${packageJson.name}" is ${installedVersion}, ` +
2657
- `but this migration requires version ${migrationVersion}. ` +
2658
- `This likely means the package version is being held back by an ${overrideFieldName} ` +
2659
- `in your package.json. ` +
2660
- `Remove the ${overrideFieldName} and run "${pmc.install}" to install the correct version.`);
2661
- }
2662
- }
2663
- catch {
2664
- // Fall through to return the base message if we can't read package info
2665
- }
2666
- return baseMessage;
2667
- }
2668
- function getOverrideFieldName(packageManager) {
2669
- switch (packageManager) {
2670
- case 'pnpm':
2671
- return '"pnpm.overrides"';
2672
- case 'yarn':
2673
- return '"resolutions"';
2674
- case 'npm':
2675
- case 'bun':
2676
- return '"overrides"';
2677
- }
2678
- }
2679
2349
  async function nxCliPath(nxWorkspaceRoot) {
2680
2350
  const version = process.env.NX_MIGRATE_CLI_VERSION || 'latest';
2681
2351
  const isVerbose = process.env.NX_VERBOSE_LOGGING === 'true';
@@ -2745,16 +2415,3 @@ function addToNodePath(dir) {
2745
2415
  // Update the env variable.
2746
2416
  process.env.NODE_PATH = paths.join(delimiter);
2747
2417
  }
2748
- function isAngularMigration(collection, name) {
2749
- return !collection.generators?.[name] && collection.schematics?.[name];
2750
- }
2751
- const getNgCompatLayer = (() => {
2752
- let _ngCliAdapter;
2753
- return async function getNgCompatLayer() {
2754
- if (!_ngCliAdapter) {
2755
- _ngCliAdapter = await (0, handle_import_1.handleImport)('../../adapter/ngcli-adapter.js', __dirname);
2756
- require('../../adapter/compat');
2757
- }
2758
- return _ngCliAdapter;
2759
- };
2760
- })();
@@ -26,7 +26,6 @@ const workspace_root_1 = require("../../../utils/workspace-root");
26
26
  const git_utils_1 = require("../../../utils/git-utils");
27
27
  const pc = tslib_1.__importStar(require("picocolors"));
28
28
  const ora = require('ora');
29
- const open = require('open');
30
29
  function onlyDefaultRunnerIsUsed(nxJson) {
31
30
  const defaultRunner = nxJson.tasksRunnerOptions?.default?.runner;
32
31
  if (!defaultRunner) {
@@ -161,6 +160,7 @@ async function runConnectToNxCloud(options, command) {
161
160
  try {
162
161
  const cloudConnectSpinner = ora(`Opening Nx Cloud ${connectCloudUrl} in your browser to connect your workspace.`).start();
163
162
  await sleep(2000);
163
+ const { default: open } = await new Function('return import("open")')();
164
164
  await open(connectCloudUrl);
165
165
  cloudConnectSpinner.succeed();
166
166
  }
@@ -39,6 +39,8 @@ async function viewLogs() {
39
39
  return 1;
40
40
  }
41
41
  const pmc = (0, package_manager_1.getPackageManagerCommand)();
42
+ // Intentionally not runNxSync: this invokes the separate `nx-cloud` binary,
43
+ // not the nx CLI that runNxSync resolves.
42
44
  (0, child_process_1.execSync)(`${pmc.exec} nx-cloud upload-and-show-run-details`, {
43
45
  stdio: [0, 1, 2],
44
46
  windowsHide: true,
@@ -443,8 +443,10 @@ function extractReferencesFromCommit(commit) {
443
443
  references.push({ type: 'issue', value: m[1] });
444
444
  }
445
445
  }
446
- // Extract issue references from commit body
447
- for (const m of commit.body.matchAll(IssueRE)) {
446
+ // Extract issue references from commit body, only when linked via a closing
447
+ // keyword so that other repos' issue numbers mentioned in prose are not
448
+ // picked up (e.g. "web-infra-dev/rspack#2292")
449
+ for (const m of commit.body.matchAll(IssueClosingKeywordRE)) {
448
450
  if (!references.some((i) => i.value === m[1])) {
449
451
  references.push({ type: 'issue', value: m[1] });
450
452
  }
@@ -473,6 +475,8 @@ const PullRequestRE = /\([ a-z]*(#\d+)\s*\)/gm;
473
475
  // GitLab style merge request references
474
476
  const GitLabMergeRequestRE = /See merge request (?:[a-z0-9/-]+)?(![\d]+)/gim;
475
477
  const IssueRE = /(#\d+)/gm;
478
+ // GitHub style issue closing keywords, e.g. "Fixes #1234"
479
+ const IssueClosingKeywordRE = /\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?):?\s+(#\d+)/gim;
476
480
  const ChangedFileRegex = /(A|M|D|R\d*|C\d*)\t([^\t\n]*)\t?(.*)?/gm;
477
481
  const RevertHashRE = /This reverts commit (?<hash>[\da-f]{40})./gm;
478
482
  function parseVersionPlanCommit(commit) {
@@ -86,8 +86,8 @@ export declare class ReleaseGraph {
86
86
  source: string;
87
87
  target: string;
88
88
  type: string;
89
- dependencyCollection: string;
90
- rawVersionSpec: string;
89
+ dependencyCollection: string | null;
90
+ rawVersionSpec: string | null;
91
91
  }[]>;
92
92
  readonly releaseGroupToFilteredProjects: Map<ReleaseGroupWithName, Set<string>>;
93
93
  private originalFilteredProjects;
@@ -235,7 +235,7 @@ class GithubRemoteReleaseClient extends remote_release_client_1.RemoteReleaseCli
235
235
  if (!shouldContinueInGitHub) {
236
236
  return;
237
237
  }
238
- const open = require('open');
238
+ const { default: open } = await new Function('return import("open")')();
239
239
  await open(result.url)
240
240
  .then(() => {
241
241
  console.info(`\nFollow up in the browser to manually create the release:\n\n` +
@@ -157,7 +157,7 @@ class GitLabRemoteReleaseClient extends remote_release_client_1.RemoteReleaseCli
157
157
  if (!shouldContinueInGitLab) {
158
158
  return;
159
159
  }
160
- const open = require('open');
160
+ const { default: open } = await new Function('return import("open")')();
161
161
  await open(result.url)
162
162
  .then(() => {
163
163
  console.info(`\nFollow up in the browser to manually create the release:\n\n` +