nx 23.0.0-beta.21 → 23.0.0-beta.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugins/package-json.js +1 -1
- package/dist/src/adapter/angular-json.d.ts +2 -2
- package/dist/src/adapter/angular-json.js +0 -1
- package/dist/src/adapter/compat.d.ts +1 -1
- package/dist/src/adapter/compat.js +1 -0
- package/dist/src/ai/set-up-ai-agents/set-up-ai-agents.js +2 -1
- package/dist/src/command-line/configure-ai-agents/configure-ai-agents.js +1 -1
- package/dist/src/command-line/examples.js +4 -4
- package/dist/src/command-line/graph/graph.js +1 -1
- package/dist/src/command-line/init/init-v2.js +1 -1
- package/dist/src/command-line/migrate/agentic/prompts/generic-validation.d.ts +5 -0
- package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +1 -0
- package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.d.ts +5 -0
- package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.js +1 -0
- package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.d.ts +5 -0
- package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.js +1 -0
- package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.d.ts +1 -0
- package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.js +15 -0
- package/dist/src/command-line/migrate/agentic/run-step.d.ts +7 -0
- package/dist/src/command-line/migrate/agentic/run-step.js +3 -1
- package/dist/src/command-line/migrate/agentic/select.js +120 -32
- package/dist/src/command-line/migrate/command-object.d.ts +42 -0
- package/dist/src/command-line/migrate/command-object.js +38 -8
- package/dist/src/command-line/migrate/migrate-config.d.ts +27 -0
- package/dist/src/command-line/migrate/migrate-config.js +103 -0
- package/dist/src/command-line/migrate/migrate.d.ts +39 -2
- package/dist/src/command-line/migrate/migrate.js +203 -41
- package/dist/src/command-line/migrate/multi-major.js +5 -2
- package/dist/src/command-line/release/changelog/version-plan-filtering.d.ts +3 -1
- package/dist/src/command-line/release/changelog/version-plan-filtering.js +7 -3
- package/dist/src/command-line/release/changelog.d.ts +7 -0
- package/dist/src/command-line/release/changelog.js +22 -9
- package/dist/src/command-line/release/release.js +65 -55
- package/dist/src/command-line/release/utils/git.d.ts +6 -0
- package/dist/src/command-line/release/utils/git.js +33 -0
- package/dist/src/command-line/release/version/derive-specifier-from-conventional-commits.js +3 -2
- package/dist/src/command-line/release/version.d.ts +3 -0
- package/dist/src/command-line/release/version.js +13 -3
- package/dist/src/config/misc-interfaces.d.ts +8 -0
- package/dist/src/config/nx-json.d.ts +49 -0
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/daemon/server/latest-nx.js +3 -1
- package/dist/src/devkit-exports.d.ts +11 -11
- package/dist/src/devkit-exports.js +7 -4
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/plugins/js/index.d.ts +2 -2
- package/dist/src/plugins/js/index.js +4 -4
- package/dist/src/plugins/js/lock-file/lock-file.d.ts +7 -2
- package/dist/src/plugins/js/lock-file/lock-file.js +35 -25
- package/dist/src/plugins/js/project-graph/affected/lock-file-changes.d.ts +2 -4
- package/dist/src/plugins/js/project-graph/affected/lock-file-changes.js +121 -43
- package/dist/src/plugins/js/utils/register.d.ts +52 -0
- package/dist/src/plugins/js/utils/register.js +195 -0
- package/dist/src/plugins/package-json/create-nodes.d.ts +2 -2
- package/dist/src/plugins/package-json/create-nodes.js +2 -2
- package/dist/src/plugins/project-json/build-nodes/project-json.d.ts +2 -2
- package/dist/src/plugins/project-json/build-nodes/project-json.js +1 -1
- package/dist/src/project-graph/error-types.d.ts +6 -6
- package/dist/src/project-graph/error-types.js +1 -1
- package/dist/src/project-graph/file-utils.d.ts +7 -0
- package/dist/src/project-graph/file-utils.js +78 -10
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.d.ts +2 -2
- package/dist/src/project-graph/plugins/isolation/messaging.d.ts +2 -2
- package/dist/src/project-graph/plugins/loaded-nx-plugin.d.ts +3 -3
- package/dist/src/project-graph/plugins/loaded-nx-plugin.js +6 -4
- package/dist/src/project-graph/plugins/public-api.d.ts +31 -12
- package/dist/src/project-graph/plugins/transpiler.js +11 -0
- package/dist/src/project-graph/plugins/utils.d.ts +3 -3
- package/dist/src/project-graph/utils/project-configuration-utils.d.ts +1 -1
- package/dist/src/project-graph/utils/project-configuration-utils.js +6 -17
- package/dist/src/tasks-runner/init-tasks-runner.d.ts +2 -2
- package/dist/src/tasks-runner/init-tasks-runner.js +6 -6
- package/dist/src/tasks-runner/task-orchestrator.d.ts +2 -2
- package/dist/src/tasks-runner/task-orchestrator.js +6 -6
- package/dist/src/utils/package-json.d.ts +3 -3
- package/dist/src/utils/package-json.js +9 -11
- package/dist/src/utils/package-manager.d.ts +13 -0
- package/dist/src/utils/package-manager.js +27 -0
- package/migrations.json +18 -9
- package/package.json +11 -11
- package/schemas/nx-schema.json +41 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyNxJsonMigrateDefaults = applyNxJsonMigrateDefaults;
|
|
4
|
+
exports.assertCommitPrefixHasCommits = assertCommitPrefixHasCommits;
|
|
5
|
+
const cli_args_1 = require("./agentic/cli-args");
|
|
6
|
+
const command_object_1 = require("./command-object");
|
|
7
|
+
const MULTI_MAJOR_MODE_ENV = 'NX_MULTI_MAJOR_MODE';
|
|
8
|
+
/**
|
|
9
|
+
* Overlays `nx.json` `migrate` defaults onto the raw `nx migrate` CLI args so a
|
|
10
|
+
* CLI flag always wins, then `nx.json`, then the built-in default. Returns a new
|
|
11
|
+
* args object; the input is not mutated.
|
|
12
|
+
*
|
|
13
|
+
* Phase-aware: generate-only options (`mode`, `multiMajorMode`) are applied only
|
|
14
|
+
* when not running migrations; run-only options (`createCommits`,
|
|
15
|
+
* `commitPrefix`, `agentic`, `validate`) only when running migrations. This
|
|
16
|
+
* mirrors where each option is consumed and avoids tripping the "cannot be
|
|
17
|
+
* combined with --run-migrations" guards in `parseMigrationsOptions`.
|
|
18
|
+
*
|
|
19
|
+
* `mode` is carried as `modeFromConfig` rather than `mode` so it is never
|
|
20
|
+
* mistaken for an explicit `--mode`: `resolveMode` applies it only when the
|
|
21
|
+
* target is Nx itself, leaving `nx migrate <non-nx-pkg>` unaffected.
|
|
22
|
+
*/
|
|
23
|
+
function applyNxJsonMigrateDefaults(args, migrateConfig, env = process.env) {
|
|
24
|
+
if (!migrateConfig) {
|
|
25
|
+
return args;
|
|
26
|
+
}
|
|
27
|
+
const merged = { ...args };
|
|
28
|
+
// `--run-migrations` with no value is normalized to '' by yargs, so a defined
|
|
29
|
+
// (even empty-string) value means we're in the run-migrations phase.
|
|
30
|
+
const isRunMigrations = merged.runMigrations !== undefined;
|
|
31
|
+
if (isRunMigrations) {
|
|
32
|
+
if (merged.createCommits === undefined &&
|
|
33
|
+
migrateConfig.createCommits !== undefined) {
|
|
34
|
+
assertType(migrateConfig.createCommits, 'boolean', 'createCommits');
|
|
35
|
+
merged.createCommits = migrateConfig.createCommits;
|
|
36
|
+
}
|
|
37
|
+
// `commitPrefix` carries a yargs default, so the default value is
|
|
38
|
+
// indistinguishable from "not provided" - treat it as not provided so
|
|
39
|
+
// nx.json can override it.
|
|
40
|
+
if ((merged.commitPrefix === undefined ||
|
|
41
|
+
merged.commitPrefix === command_object_1.DEFAULT_MIGRATION_COMMIT_PREFIX) &&
|
|
42
|
+
migrateConfig.commitPrefix !== undefined) {
|
|
43
|
+
assertType(migrateConfig.commitPrefix, 'string', 'commitPrefix');
|
|
44
|
+
merged.commitPrefix = migrateConfig.commitPrefix;
|
|
45
|
+
}
|
|
46
|
+
if (merged.agentic === undefined && migrateConfig.agentic !== undefined) {
|
|
47
|
+
assertValidAgentic(migrateConfig.agentic);
|
|
48
|
+
merged.agentic = (0, cli_args_1.coerceAgenticArg)(migrateConfig.agentic);
|
|
49
|
+
}
|
|
50
|
+
if (merged.validate === undefined && migrateConfig.validate !== undefined) {
|
|
51
|
+
assertType(migrateConfig.validate, 'boolean', 'validate');
|
|
52
|
+
merged.validate = migrateConfig.validate;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (merged.mode === undefined && migrateConfig.mode !== undefined) {
|
|
57
|
+
assertOneOf(migrateConfig.mode, command_object_1.MIGRATE_MODES, 'mode');
|
|
58
|
+
merged.modeFromConfig = migrateConfig.mode;
|
|
59
|
+
}
|
|
60
|
+
// The NX_MULTI_MAJOR_MODE env var is an established per-invocation override,
|
|
61
|
+
// so it takes precedence over nx.json (CLI flag > env > nx.json > default).
|
|
62
|
+
if (merged.multiMajorMode === undefined &&
|
|
63
|
+
!env[MULTI_MAJOR_MODE_ENV] &&
|
|
64
|
+
migrateConfig.multiMajorMode !== undefined) {
|
|
65
|
+
assertOneOf(migrateConfig.multiMajorMode, command_object_1.MULTI_MAJOR_MODES, 'multiMajorMode');
|
|
66
|
+
merged.multiMajorMode = migrateConfig.multiMajorMode;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return merged;
|
|
70
|
+
}
|
|
71
|
+
function assertOneOf(value, allowed, field) {
|
|
72
|
+
if (!allowed.includes(value)) {
|
|
73
|
+
throw new Error(`Error: Invalid nx.json migrate.${field} "${value}". Allowed: ${allowed.join(', ')}.`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function assertType(value, type, field) {
|
|
77
|
+
if (typeof value !== type) {
|
|
78
|
+
throw new Error(`Error: Invalid nx.json migrate.${field} ${JSON.stringify(value)}. Expected a ${type}.`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function assertValidAgentic(agentic) {
|
|
82
|
+
if (typeof agentic === 'boolean') {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (typeof agentic !== 'string' ||
|
|
86
|
+
!cli_args_1.AGENT_IDS.includes(agentic)) {
|
|
87
|
+
throw new Error(`Error: Invalid nx.json migrate.agentic "${agentic}". Allowed: ${cli_args_1.AGENT_IDS.join(', ')}, true, false.`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The single authority for the "a custom commit prefix needs commits enabled"
|
|
92
|
+
* invariant. Run it against the final merged args (after
|
|
93
|
+
* `applyNxJsonMigrateDefaults`): the yargs `.check()` only sees the CLI args,
|
|
94
|
+
* but nx.json may enable commits via `createCommits` or `agentic`. The CLI
|
|
95
|
+
* `.check()` only fast-fails the unrescuable explicit `--no-create-commits`
|
|
96
|
+
* case; everything else is decided here.
|
|
97
|
+
*/
|
|
98
|
+
function assertCommitPrefixHasCommits(merged) {
|
|
99
|
+
const { createCommits, commitPrefix, agentic } = merged;
|
|
100
|
+
if ((0, command_object_1.customCommitPrefixHasNoEffect)({ createCommits, commitPrefix, agentic })) {
|
|
101
|
+
throw new Error('Error: A custom migrate commit prefix requires commits to be enabled. Set `migrate.createCommits` to `true` in nx.json or pass `--create-commits`.');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -74,6 +74,7 @@ export declare class Migrator {
|
|
|
74
74
|
factory?: string;
|
|
75
75
|
prompt?: string;
|
|
76
76
|
requires?: Record<string, string>;
|
|
77
|
+
documentation?: string;
|
|
77
78
|
}[];
|
|
78
79
|
}>;
|
|
79
80
|
private createMigrateJson;
|
|
@@ -118,7 +119,9 @@ export declare function resolveCanonicalNxPackage(targetVersion: string): 'nx' |
|
|
|
118
119
|
export declare function resolveMode(mode: MigrateMode | undefined, targetPackage: string, targetVersion: string, context?: {
|
|
119
120
|
hasFrom: boolean;
|
|
120
121
|
hasExcludeAppliedMigrations: boolean;
|
|
121
|
-
|
|
122
|
+
installedMajor?: number | null;
|
|
123
|
+
isV23Plus?: boolean;
|
|
124
|
+
}, configuredMode?: MigrateMode): Promise<MigrateMode>;
|
|
122
125
|
type GenerateMigrations = {
|
|
123
126
|
type: 'generateMigrations';
|
|
124
127
|
targetPackage: string;
|
|
@@ -172,6 +175,7 @@ type ExecutableMigration = {
|
|
|
172
175
|
implementation?: string;
|
|
173
176
|
factory?: string;
|
|
174
177
|
prompt?: string;
|
|
178
|
+
documentation?: string;
|
|
175
179
|
};
|
|
176
180
|
export { isPromptOnlyMigration, isHybridMigration };
|
|
177
181
|
export declare function resolveAgenticRunId(migrations: ExecutableMigration[]): string;
|
|
@@ -235,7 +239,10 @@ export declare function runNxOrAngularMigration(root: string, migration: {
|
|
|
235
239
|
name: string;
|
|
236
240
|
description?: string;
|
|
237
241
|
version: string;
|
|
238
|
-
}, isVerbose: boolean, captureGeneratorOutput?: boolean
|
|
242
|
+
}, isVerbose: boolean, captureGeneratorOutput?: boolean, resolvedCollection?: {
|
|
243
|
+
collection: MigrationsJson;
|
|
244
|
+
collectionPath: string;
|
|
245
|
+
}): Promise<{
|
|
239
246
|
changes: FileChange[];
|
|
240
247
|
nextSteps: string[];
|
|
241
248
|
agentContext: string[];
|
|
@@ -258,4 +265,34 @@ export declare function getImplementationPath(collection: MigrationsJson, collec
|
|
|
258
265
|
path: string;
|
|
259
266
|
fnSymbol: string;
|
|
260
267
|
};
|
|
268
|
+
/**
|
|
269
|
+
* Resolves a migration's collection once and derives everything the run loop
|
|
270
|
+
* needs from that single read: the implementation context (`collection` +
|
|
271
|
+
* `collectionPath`, handed to `runNxOrAngularMigration`) and, for agentic runs,
|
|
272
|
+
* the workspace-relative documentation path handed to the agent.
|
|
273
|
+
*
|
|
274
|
+
* Read fresh per migration (not cached across the loop) so a prior migration's
|
|
275
|
+
* reinstall is reflected, exactly as before. Error handling matches each field's
|
|
276
|
+
* role:
|
|
277
|
+
* - Migrations that run an implementation REQUIRE the collection; an unreadable
|
|
278
|
+
* collection throws and aborts that migration (caught by the run loop).
|
|
279
|
+
* - Prompt-only migrations don't run an implementation, so the collection is
|
|
280
|
+
* read only to resolve documentation - a failure there is non-fatal: the
|
|
281
|
+
* prompt still runs and the supplementary doc is skipped with a warning.
|
|
282
|
+
*/
|
|
283
|
+
export declare function resolveMigrationForRun(root: string, migration: {
|
|
284
|
+
package: string;
|
|
285
|
+
name: string;
|
|
286
|
+
documentation?: string;
|
|
287
|
+
implementation?: string;
|
|
288
|
+
factory?: string;
|
|
289
|
+
prompt?: string;
|
|
290
|
+
}, resolveDocumentation: boolean): {
|
|
291
|
+
resolvedCollection?: {
|
|
292
|
+
collection: MigrationsJson;
|
|
293
|
+
collectionPath: string;
|
|
294
|
+
};
|
|
295
|
+
documentationPath?: string;
|
|
296
|
+
};
|
|
297
|
+
export declare function resolveDocumentationFileToWorkspacePath(root: string, migrationsDir: string, documentation: string): string | undefined;
|
|
261
298
|
export declare function nxCliPath(nxWorkspaceRoot?: string): Promise<string>;
|
|
@@ -17,6 +17,8 @@ exports.migrate = migrate;
|
|
|
17
17
|
exports.runMigration = runMigration;
|
|
18
18
|
exports.readMigrationCollection = readMigrationCollection;
|
|
19
19
|
exports.getImplementationPath = getImplementationPath;
|
|
20
|
+
exports.resolveMigrationForRun = resolveMigrationForRun;
|
|
21
|
+
exports.resolveDocumentationFileToWorkspacePath = resolveDocumentationFileToWorkspacePath;
|
|
20
22
|
exports.nxCliPath = nxCliPath;
|
|
21
23
|
const tslib_1 = require("tslib");
|
|
22
24
|
const pc = tslib_1.__importStar(require("picocolors"));
|
|
@@ -56,6 +58,7 @@ const catalog_1 = require("../../utils/catalog");
|
|
|
56
58
|
const multi_major_1 = require("./multi-major");
|
|
57
59
|
const prompt_files_1 = require("./prompt-files");
|
|
58
60
|
const command_object_1 = require("./command-object");
|
|
61
|
+
const migrate_config_1 = require("./migrate-config");
|
|
59
62
|
const handoff_gitignore_1 = require("./agentic/handoff-gitignore");
|
|
60
63
|
const migrate_commits_1 = require("./migrate-commits");
|
|
61
64
|
const migrate_output_1 = require("./migrate-output");
|
|
@@ -529,28 +532,76 @@ function resolveCanonicalNxPackage(targetVersion) {
|
|
|
529
532
|
async function resolveMode(mode, targetPackage, targetVersion, context = {
|
|
530
533
|
hasFrom: false,
|
|
531
534
|
hasExcludeAppliedMigrations: false,
|
|
532
|
-
}) {
|
|
535
|
+
}, configuredMode) {
|
|
536
|
+
// The first-party/third-party split relies on migration metadata that only
|
|
537
|
+
// exists in Nx v23+. `first-party` needs a v22+ install migrating into a v23+
|
|
538
|
+
// target; `third-party` catches up deps a prior first-party migration
|
|
539
|
+
// deferred, so it needs the workspace already on v23+.
|
|
540
|
+
const installedMajor = context.installedMajor ?? null;
|
|
541
|
+
const firstPartyAvailable = installedMajor !== null &&
|
|
542
|
+
installedMajor >= 22 &&
|
|
543
|
+
context.isV23Plus === true;
|
|
544
|
+
const thirdPartyAvailable = installedMajor !== null && installedMajor >= 23;
|
|
533
545
|
if (mode) {
|
|
546
|
+
if ((0, version_utils_1.isNxEquivalentTarget)(targetPackage, targetVersion)) {
|
|
547
|
+
if (mode === 'first-party' && !firstPartyAvailable) {
|
|
548
|
+
if (context.isV23Plus !== true) {
|
|
549
|
+
throw new Error(`Error: '--mode=first-party' requires migrating to Nx v23 or later.`);
|
|
550
|
+
}
|
|
551
|
+
throw new Error(`Error: '--mode=first-party' requires the workspace to be on Nx v22 or later. Migrate to the latest Nx v22 first, then to v23 or later.`);
|
|
552
|
+
}
|
|
553
|
+
// When the installed version is unknown, defer to the downstream
|
|
554
|
+
// "requires nx to be installed" check rather than the v23 gate.
|
|
555
|
+
if (mode === 'third-party' &&
|
|
556
|
+
installedMajor !== null &&
|
|
557
|
+
!thirdPartyAvailable) {
|
|
558
|
+
throw new Error(`Error: '--mode=third-party' requires the workspace to be on Nx v23 or later.`);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
534
561
|
return mode;
|
|
535
562
|
}
|
|
536
563
|
if (!(0, version_utils_1.isNxEquivalentTarget)(targetPackage, targetVersion)) {
|
|
537
564
|
return 'all';
|
|
538
565
|
}
|
|
539
|
-
|
|
566
|
+
// nx.json `migrate.mode` pre-selects the prompt answer (Nx targets only; non-Nx
|
|
567
|
+
// returned 'all' above). Honor it only when the v23+ gate makes that mode
|
|
568
|
+
// available; otherwise warn and fall back to the always-valid 'all'.
|
|
569
|
+
if (configuredMode) {
|
|
570
|
+
const configuredAvailable = configuredMode === 'all' ||
|
|
571
|
+
(configuredMode === 'first-party' && firstPartyAvailable) ||
|
|
572
|
+
(configuredMode === 'third-party' && thirdPartyAvailable);
|
|
573
|
+
if (configuredAvailable) {
|
|
574
|
+
return configuredMode;
|
|
575
|
+
}
|
|
576
|
+
output_1.output.warn({
|
|
577
|
+
title: `The configured nx.json migrate.mode '${configuredMode}' is not available for this migration; falling back to 'all'.`,
|
|
578
|
+
bodyLines: [
|
|
579
|
+
`The 'first-party' and 'third-party' modes require Nx v23 or later.`,
|
|
580
|
+
],
|
|
581
|
+
});
|
|
540
582
|
return 'all';
|
|
541
583
|
}
|
|
542
|
-
const choices = [
|
|
543
|
-
|
|
584
|
+
const choices = [];
|
|
585
|
+
if (firstPartyAvailable) {
|
|
586
|
+
choices.push({
|
|
544
587
|
name: 'first-party',
|
|
545
588
|
message: 'First-party only (Nx and its official packages)',
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
if (
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
if (thirdPartyAvailable &&
|
|
592
|
+
!context.hasFrom &&
|
|
593
|
+
!context.hasExcludeAppliedMigrations) {
|
|
549
594
|
choices.push({
|
|
550
595
|
name: 'third-party',
|
|
551
596
|
message: 'Third-party only (deps managed by Nx)',
|
|
552
597
|
});
|
|
553
598
|
}
|
|
599
|
+
if (!choices.length) {
|
|
600
|
+
return 'all';
|
|
601
|
+
}
|
|
602
|
+
if (!process.stdin.isTTY || (0, is_ci_1.isCI)()) {
|
|
603
|
+
return 'all';
|
|
604
|
+
}
|
|
554
605
|
choices.push({
|
|
555
606
|
name: 'all',
|
|
556
607
|
message: 'All (first-party and third-party)',
|
|
@@ -656,6 +707,13 @@ async function parseMigrationsOptions(options) {
|
|
|
656
707
|
});
|
|
657
708
|
targetVersion = multiMajorResult.chosen;
|
|
658
709
|
if (mode === 'third-party') {
|
|
710
|
+
// `mode` can resolve to third-party via nx.json, which bypasses the early
|
|
711
|
+
// CLI-only check above; re-assert against the resolved mode.
|
|
712
|
+
assertThirdPartyModeFlagCompatibility({
|
|
713
|
+
mode,
|
|
714
|
+
from: options.from,
|
|
715
|
+
excludeAppliedMigrations: options.excludeAppliedMigrations,
|
|
716
|
+
});
|
|
659
717
|
assertThirdPartyTargetBounds({
|
|
660
718
|
targetPackage,
|
|
661
719
|
targetVersion,
|
|
@@ -686,9 +744,11 @@ function assertThirdPartyModeFlagCompatibility(options) {
|
|
|
686
744
|
throw new Error(`Error: '--mode=third-party' cannot be combined with '--exclude-applied-migrations'.`);
|
|
687
745
|
}
|
|
688
746
|
}
|
|
689
|
-
//
|
|
690
|
-
// canonical
|
|
691
|
-
// is
|
|
747
|
+
// Resolves the target package/version up front (third-party → installed
|
|
748
|
+
// canonical; otherwise resolves dist-tags so the v23 mode gate reads a concrete
|
|
749
|
+
// major), then resolves the mode and enforces the era gate when --mode is
|
|
750
|
+
// explicit. Bare invocations on a pre-v22 install throw rather than defaulting
|
|
751
|
+
// to `latest` across the major gap into the v23 era.
|
|
692
752
|
async function resolveTargetAndMode(args) {
|
|
693
753
|
const { positional, from, options } = args;
|
|
694
754
|
let targetPackage;
|
|
@@ -698,15 +758,55 @@ async function resolveTargetAndMode(args) {
|
|
|
698
758
|
targetPackage = normalizeSlashes(parsed.targetPackage);
|
|
699
759
|
targetVersion = parsed.targetVersion;
|
|
700
760
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
//
|
|
704
|
-
//
|
|
705
|
-
|
|
761
|
+
const installed = resolveInstalledCanonical();
|
|
762
|
+
const installedMajor = installed && (0, semver_1.valid)(installed.version) ? (0, semver_1.major)(installed.version) : null;
|
|
763
|
+
// `--mode=third-party` anchors the target to the installed version below, so
|
|
764
|
+
// it never needs a target or dist-tag resolved up front.
|
|
765
|
+
const isExplicitThirdParty = options.mode === 'third-party';
|
|
766
|
+
// Bare invocation: restore the requirement to specify a target when on a
|
|
767
|
+
// pre-v23 install. We can't safely default to `latest` across the major gap
|
|
768
|
+
// into the new era, and the first-party/third-party functionality isn't
|
|
769
|
+
// available there anyway.
|
|
770
|
+
if (!positional && !isExplicitThirdParty) {
|
|
771
|
+
if (installedMajor === null || installedMajor < 22) {
|
|
772
|
+
throw new Error(`Provide the package and version to migrate to. E.g., \`nx migrate nx@<version>\`.`);
|
|
773
|
+
}
|
|
774
|
+
targetPackage = 'nx';
|
|
775
|
+
targetVersion = 'latest';
|
|
776
|
+
}
|
|
777
|
+
// Explicit dist-tags arrive already resolved from
|
|
778
|
+
// `parseTargetPackageAndVersion`; only bare invocations and bare package
|
|
779
|
+
// names (`nx migrate nx`) reach here unresolved.
|
|
780
|
+
let isV23Plus = false;
|
|
781
|
+
if (!isExplicitThirdParty &&
|
|
782
|
+
(0, version_utils_1.isNxEquivalentTarget)(targetPackage, targetVersion)) {
|
|
783
|
+
if (targetVersion && (0, semver_1.valid)(targetVersion)) {
|
|
784
|
+
isV23Plus = (0, semver_1.major)(targetVersion) >= 23;
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
// Resolving the dist-tag here (rather than only in the multi-major check
|
|
788
|
+
// as before) just moves the single registry round-trip earlier — the
|
|
789
|
+
// multi-major check short-circuits on the now-concrete version.
|
|
790
|
+
const tag = targetVersion;
|
|
791
|
+
try {
|
|
792
|
+
targetVersion = await (0, version_utils_1.normalizeVersionWithTagCheck)(targetPackage, tag);
|
|
793
|
+
isV23Plus = (0, semver_1.valid)(targetVersion) ? (0, semver_1.major)(targetVersion) >= 23 : true;
|
|
794
|
+
}
|
|
795
|
+
catch {
|
|
796
|
+
// Registry unavailable: assume dist-tags resolve to >= v23 (true once
|
|
797
|
+
// v23 is released) so the gate stays sensible. The retained sentinel
|
|
798
|
+
// still degrades gracefully downstream (multi-major and the cascade).
|
|
799
|
+
targetVersion = tag;
|
|
800
|
+
isV23Plus = true;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
706
804
|
const mode = await resolveMode(options.mode, targetPackage ?? 'nx', targetVersion ?? 'latest', {
|
|
707
805
|
hasFrom: Object.keys(from).length > 0,
|
|
708
806
|
hasExcludeAppliedMigrations: options.excludeAppliedMigrations === true,
|
|
709
|
-
|
|
807
|
+
installedMajor,
|
|
808
|
+
isV23Plus,
|
|
809
|
+
}, options.modeFromConfig);
|
|
710
810
|
let installedNxVersion;
|
|
711
811
|
// For third-party, anchor `targetPackage`/`targetVersion` to the installed
|
|
712
812
|
// canonical when the positional was either omitted or a bare package name
|
|
@@ -715,7 +815,6 @@ async function resolveTargetAndMode(args) {
|
|
|
715
815
|
// the literal `'latest'` that `parseTargetPackageAndVersion` emits for bare
|
|
716
816
|
// package names.
|
|
717
817
|
if (mode === 'third-party' && (!positional || !(0, semver_1.valid)(targetVersion))) {
|
|
718
|
-
const installed = resolveInstalledCanonical();
|
|
719
818
|
if (!installed) {
|
|
720
819
|
throw new Error(`Error: '--mode=third-party' requires 'nx' (or '@nrwl/workspace' on Nx <14) to be installed in your workspace. Install dependencies first, then re-run.`);
|
|
721
820
|
}
|
|
@@ -723,15 +822,6 @@ async function resolveTargetAndMode(args) {
|
|
|
723
822
|
targetPackage = installed.canonical;
|
|
724
823
|
targetVersion = installed.version;
|
|
725
824
|
}
|
|
726
|
-
else if (!positional) {
|
|
727
|
-
// Bare invocation: default to `nx@latest` as a literal sentinel rather
|
|
728
|
-
// than resolving via the registry here. Multi-major resolves the dist-tag
|
|
729
|
-
// when needed (and bails gracefully on registry failure), and the cascade
|
|
730
|
-
// resolves it for the walk (honouring `NX_MIGRATE_SKIP_REGISTRY_FETCH`).
|
|
731
|
-
// This matches the resilience of `nx migrate nx`.
|
|
732
|
-
targetPackage = 'nx';
|
|
733
|
-
targetVersion = 'latest';
|
|
734
|
-
}
|
|
735
825
|
if (options.mode && !(0, version_utils_1.isNxEquivalentTarget)(targetPackage, targetVersion)) {
|
|
736
826
|
const isLegacy = (0, version_utils_1.isLegacyEra)(targetVersion);
|
|
737
827
|
const validTargets = isLegacy
|
|
@@ -848,14 +938,14 @@ function createInstalledPackageVersionsResolver(root) {
|
|
|
848
938
|
return getInstalledPackageVersion;
|
|
849
939
|
}
|
|
850
940
|
// testing-fetch-start
|
|
851
|
-
function createFetcher() {
|
|
941
|
+
function createFetcher(pmc) {
|
|
852
942
|
const migrationsCache = {};
|
|
853
943
|
const resolvedVersionCache = {};
|
|
854
944
|
function fetchMigrations(packageName, packageVersion, setCache) {
|
|
855
945
|
if (process.env.NX_MIGRATE_SKIP_REGISTRY_FETCH === 'true') {
|
|
856
946
|
// Skip registry fetch and use installation method directly
|
|
857
947
|
logger_1.logger.info(`Fetching ${packageName}@${packageVersion}`);
|
|
858
|
-
return getPackageMigrationsUsingInstall(packageName, packageVersion);
|
|
948
|
+
return getPackageMigrationsUsingInstall(packageName, packageVersion, pmc);
|
|
859
949
|
}
|
|
860
950
|
const cacheKey = packageName + '-' + packageVersion;
|
|
861
951
|
return Promise.resolve(resolvedVersionCache[cacheKey])
|
|
@@ -877,7 +967,7 @@ function createFetcher() {
|
|
|
877
967
|
.catch((e) => {
|
|
878
968
|
logger_1.logger.verbose(`Failed to get migrations from registry for ${packageName}@${packageVersion}: ${e.message}. Falling back to install.`);
|
|
879
969
|
logger_1.logger.info(`Fetching ${packageName}@${packageVersion}`);
|
|
880
|
-
return getPackageMigrationsUsingInstall(packageName, packageVersion);
|
|
970
|
+
return getPackageMigrationsUsingInstall(packageName, packageVersion, pmc);
|
|
881
971
|
});
|
|
882
972
|
}
|
|
883
973
|
return function nxMigrateFetcher(packageName, packageVersion) {
|
|
@@ -996,18 +1086,17 @@ function createConcurrencyLimiter(concurrency) {
|
|
|
996
1086
|
const installConcurrencyLimit = process.env.NX_MIGRATE_INSTALL_CONCURRENCY
|
|
997
1087
|
? createConcurrencyLimiter(Math.max(1, Math.floor(Number(process.env.NX_MIGRATE_INSTALL_CONCURRENCY)) || 1))
|
|
998
1088
|
: null;
|
|
999
|
-
async function getPackageMigrationsUsingInstall(packageName, packageVersion) {
|
|
1000
|
-
const run = () => getPackageMigrationsUsingInstallImpl(packageName, packageVersion);
|
|
1089
|
+
async function getPackageMigrationsUsingInstall(packageName, packageVersion, pmc) {
|
|
1090
|
+
const run = () => getPackageMigrationsUsingInstallImpl(packageName, packageVersion, pmc);
|
|
1001
1091
|
return installConcurrencyLimit ? installConcurrencyLimit(run) : run();
|
|
1002
1092
|
}
|
|
1003
|
-
async function getPackageMigrationsUsingInstallImpl(packageName, packageVersion) {
|
|
1093
|
+
async function getPackageMigrationsUsingInstallImpl(packageName, packageVersion, pmc) {
|
|
1004
1094
|
const { dir, cleanup } = (0, package_manager_1.createTempNpmDirectory)();
|
|
1005
1095
|
let result;
|
|
1006
1096
|
if ((0, provenance_1.getNxPackageGroup)().includes(packageName)) {
|
|
1007
1097
|
await (0, provenance_1.ensurePackageHasProvenance)(packageName, packageVersion);
|
|
1008
1098
|
}
|
|
1009
1099
|
try {
|
|
1010
|
-
const pmc = (0, package_manager_1.getPackageManagerCommand)((0, package_manager_1.detectPackageManager)(dir), dir);
|
|
1011
1100
|
await execAsync(`${pmc.add} ${packageName}@${packageVersion}`, {
|
|
1012
1101
|
cwd: dir,
|
|
1013
1102
|
env: {
|
|
@@ -1031,7 +1120,6 @@ async function getPackageMigrationsUsingInstallImpl(packageName, packageVersion)
|
|
|
1031
1120
|
};
|
|
1032
1121
|
}
|
|
1033
1122
|
catch (e) {
|
|
1034
|
-
const pmc = (0, package_manager_1.getPackageManagerCommand)((0, package_manager_1.detectPackageManager)(dir), dir);
|
|
1035
1123
|
throw new Error([
|
|
1036
1124
|
`Failed to fetch migrations for ${packageName}@${packageVersion}`,
|
|
1037
1125
|
formatCommandFailure(`${pmc.add} ${packageName}@${packageVersion}`, e),
|
|
@@ -1218,7 +1306,7 @@ async function generateMigrationsJsonAndUpdatePackageJson(root, opts) {
|
|
|
1218
1306
|
}
|
|
1219
1307
|
logger_1.logger.info(`Fetching meta data about packages.`);
|
|
1220
1308
|
logger_1.logger.info(`It may take a few minutes.`);
|
|
1221
|
-
const fetch = createFetcher();
|
|
1309
|
+
const fetch = createFetcher(pmc);
|
|
1222
1310
|
let firstPartyPackages;
|
|
1223
1311
|
if (mode === 'first-party' || mode === 'third-party') {
|
|
1224
1312
|
// `@nx/workspace` is version-synced with `nx` and declares an
|
|
@@ -1572,9 +1660,16 @@ function resolveCreateCommits(args) {
|
|
|
1572
1660
|
}
|
|
1573
1661
|
return { effective: true, agenticHasDiffContext: true };
|
|
1574
1662
|
}
|
|
1663
|
+
// Commits aren't enabled here. A custom prefix only reaches this path via
|
|
1664
|
+
// nx.json (e.g. `migrate.commitPrefix` + `migrate.agentic` when the agentic
|
|
1665
|
+
// flow resolves to disabled); surface that it has no effect rather than
|
|
1666
|
+
// dropping it silently.
|
|
1575
1667
|
return {
|
|
1576
1668
|
effective: createCommits === true,
|
|
1577
1669
|
agenticHasDiffContext: false,
|
|
1670
|
+
warning: commitPrefixIsCustom && createCommits !== true
|
|
1671
|
+
? 'A custom migrate commit prefix is configured, but commits are not enabled for this run, so it has no effect. Set `migrate.createCommits` to `true` (or pass `--create-commits`) to create a commit per migration.'
|
|
1672
|
+
: undefined,
|
|
1578
1673
|
};
|
|
1579
1674
|
}
|
|
1580
1675
|
/**
|
|
@@ -1716,6 +1811,11 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1716
1811
|
// already-dirty shared file like `package.json`) doesn't collapse.
|
|
1717
1812
|
const baselineWorkingTreeSnapshot = (0, git_utils_1.getUncommittedChangesSnapshot)(root);
|
|
1718
1813
|
try {
|
|
1814
|
+
// Read this migration's collection once and derive everything from it:
|
|
1815
|
+
// the implementation context (passed to runNxOrAngularMigration) and the
|
|
1816
|
+
// documentation path (passed to the agent). Read fresh per iteration so a
|
|
1817
|
+
// prior migration's reinstall is reflected.
|
|
1818
|
+
const { resolvedCollection, documentationPath } = resolveMigrationForRun(root, m, !!agenticRun);
|
|
1719
1819
|
let outcome;
|
|
1720
1820
|
let commit = { kind: 'none' };
|
|
1721
1821
|
if ((0, migration_shape_1.isPromptOnlyMigration)(m)) {
|
|
@@ -1726,6 +1826,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1726
1826
|
agentic: agenticRun.agentic,
|
|
1727
1827
|
runDir: agenticRun.runDir,
|
|
1728
1828
|
installDepsIfChanged,
|
|
1829
|
+
documentationPath,
|
|
1729
1830
|
});
|
|
1730
1831
|
commit = await attemptMigrationCommit(m);
|
|
1731
1832
|
(0, migrate_output_1.logAgenticSuccessOutcome)(stepResult.ambiguous ? 'Marked complete by user' : 'Applied', commit.kind === 'landed' ? commit.sha : null, stepResult.summary);
|
|
@@ -1740,7 +1841,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1740
1841
|
}
|
|
1741
1842
|
else if ((0, migration_shape_1.isHybridMigration)(m)) {
|
|
1742
1843
|
const { changes, nextSteps, agentContext, logs, madeChanges } = await runNxOrAngularMigration(root, m, isVerbose,
|
|
1743
|
-
/* captureGeneratorOutput: */ !!agenticRun);
|
|
1844
|
+
/* captureGeneratorOutput: */ !!agenticRun, resolvedCollection);
|
|
1744
1845
|
migrationEmittedNextSteps.push(...nextSteps);
|
|
1745
1846
|
if (agenticRun) {
|
|
1746
1847
|
// Install any deps the deterministic phase added/bumped before the
|
|
@@ -1753,6 +1854,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1753
1854
|
agentic: agenticRun.agentic,
|
|
1754
1855
|
runDir: agenticRun.runDir,
|
|
1755
1856
|
installDepsIfChanged,
|
|
1857
|
+
documentationPath,
|
|
1756
1858
|
implContext: {
|
|
1757
1859
|
logs,
|
|
1758
1860
|
changes,
|
|
@@ -1801,7 +1903,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1801
1903
|
// changes uncommitted in the working tree for the user to review.
|
|
1802
1904
|
const validationRun = agenticRun && shouldRunValidation ? agenticRun : undefined;
|
|
1803
1905
|
const { changes, nextSteps, agentContext, logs, madeChanges } = await runNxOrAngularMigration(root, m, isVerbose,
|
|
1804
|
-
/* captureGeneratorOutput: */ !!validationRun);
|
|
1906
|
+
/* captureGeneratorOutput: */ !!validationRun, resolvedCollection);
|
|
1805
1907
|
migrationEmittedNextSteps.push(...nextSteps);
|
|
1806
1908
|
const canRunValidation = !!validationRun && changes.length > 0;
|
|
1807
1909
|
if (canRunValidation) {
|
|
@@ -1814,6 +1916,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1814
1916
|
agentic: validationRun.agentic,
|
|
1815
1917
|
runDir: validationRun.runDir,
|
|
1816
1918
|
installDepsIfChanged,
|
|
1919
|
+
documentationPath,
|
|
1817
1920
|
implContext: {
|
|
1818
1921
|
logs,
|
|
1819
1922
|
changes,
|
|
@@ -1957,8 +2060,8 @@ function logSkippedPostMigrationInstall(root) {
|
|
|
1957
2060
|
bodyLines: [`Run "${installCommand}" to install the updated dependencies.`],
|
|
1958
2061
|
});
|
|
1959
2062
|
}
|
|
1960
|
-
async function runNxOrAngularMigration(root, migration, isVerbose, captureGeneratorOutput = false) {
|
|
1961
|
-
const { collection, collectionPath } = readMigrationCollection(migration.package, root);
|
|
2063
|
+
async function runNxOrAngularMigration(root, migration, isVerbose, captureGeneratorOutput = false, resolvedCollection) {
|
|
2064
|
+
const { collection, collectionPath } = resolvedCollection ?? readMigrationCollection(migration.package, root);
|
|
1962
2065
|
let changes = [];
|
|
1963
2066
|
let nextSteps = [];
|
|
1964
2067
|
let agentContext = [];
|
|
@@ -2219,13 +2322,15 @@ function filterStrings(value) {
|
|
|
2219
2322
|
async function migrate(root, args, rawArgs) {
|
|
2220
2323
|
await client_1.daemonClient.stop();
|
|
2221
2324
|
return (0, handle_errors_1.handleErrors)(process.env.NX_VERBOSE_LOGGING === 'true', async () => {
|
|
2222
|
-
const
|
|
2325
|
+
const mergedArgs = (0, migrate_config_1.applyNxJsonMigrateDefaults)(args, (0, configuration_1.readNxJson)().migrate);
|
|
2326
|
+
(0, migrate_config_1.assertCommitPrefixHasCommits)(mergedArgs);
|
|
2327
|
+
const opts = await parseMigrationsOptions(mergedArgs);
|
|
2223
2328
|
if (opts.type === 'generateMigrations') {
|
|
2224
2329
|
await generateMigrationsJsonAndUpdatePackageJson(root, opts);
|
|
2225
2330
|
}
|
|
2226
2331
|
else {
|
|
2227
2332
|
try {
|
|
2228
|
-
return await runMigrations(root, opts, rawArgs,
|
|
2333
|
+
return await runMigrations(root, opts, rawArgs, mergedArgs['verbose'], mergedArgs['createCommits'], mergedArgs['commitPrefix'] ?? command_object_1.DEFAULT_MIGRATION_COMMIT_PREFIX, mergedArgs['skipInstall']);
|
|
2229
2334
|
}
|
|
2230
2335
|
catch (e) {
|
|
2231
2336
|
// The remediation guidance is already logged by `runInstall`; swallow
|
|
@@ -2297,6 +2402,63 @@ function getImplementationPath(collection, collectionPath, name, migrationVersio
|
|
|
2297
2402
|
}
|
|
2298
2403
|
return { path: implPath, fnSymbol };
|
|
2299
2404
|
}
|
|
2405
|
+
/**
|
|
2406
|
+
* Resolves a migration's collection once and derives everything the run loop
|
|
2407
|
+
* needs from that single read: the implementation context (`collection` +
|
|
2408
|
+
* `collectionPath`, handed to `runNxOrAngularMigration`) and, for agentic runs,
|
|
2409
|
+
* the workspace-relative documentation path handed to the agent.
|
|
2410
|
+
*
|
|
2411
|
+
* Read fresh per migration (not cached across the loop) so a prior migration's
|
|
2412
|
+
* reinstall is reflected, exactly as before. Error handling matches each field's
|
|
2413
|
+
* role:
|
|
2414
|
+
* - Migrations that run an implementation REQUIRE the collection; an unreadable
|
|
2415
|
+
* collection throws and aborts that migration (caught by the run loop).
|
|
2416
|
+
* - Prompt-only migrations don't run an implementation, so the collection is
|
|
2417
|
+
* read only to resolve documentation - a failure there is non-fatal: the
|
|
2418
|
+
* prompt still runs and the supplementary doc is skipped with a warning.
|
|
2419
|
+
*/
|
|
2420
|
+
function resolveMigrationForRun(root, migration, resolveDocumentation) {
|
|
2421
|
+
let resolvedCollection;
|
|
2422
|
+
if (!(0, migration_shape_1.isPromptOnlyMigration)(migration)) {
|
|
2423
|
+
resolvedCollection = readMigrationCollection(migration.package, root);
|
|
2424
|
+
}
|
|
2425
|
+
else if (resolveDocumentation && migration.documentation) {
|
|
2426
|
+
try {
|
|
2427
|
+
resolvedCollection = readMigrationCollection(migration.package, root);
|
|
2428
|
+
}
|
|
2429
|
+
catch {
|
|
2430
|
+
// Non-fatal: documentation is supplementary; the warning below fires.
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
let documentationPath;
|
|
2434
|
+
if (resolveDocumentation && migration.documentation) {
|
|
2435
|
+
documentationPath = resolvedCollection
|
|
2436
|
+
? resolveDocumentationFileToWorkspacePath(root, (0, path_1.dirname)(resolvedCollection.collectionPath), migration.documentation)
|
|
2437
|
+
: undefined;
|
|
2438
|
+
if (!documentationPath) {
|
|
2439
|
+
logger_1.logger.warn(`Could not resolve the "documentation" file "${migration.documentation}" declared for migration "${migration.package}: ${migration.name}". It will be skipped as additional context for the AI agent.`);
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
return { resolvedCollection, documentationPath };
|
|
2443
|
+
}
|
|
2444
|
+
// Resolves a `documentation` path (relative to the package's migrations dir) to
|
|
2445
|
+
// a workspace-relative path - or the absolute path when it resolves outside the
|
|
2446
|
+
// workspace (unusual hoisted/symlinked layouts). The agent runs with cwd =
|
|
2447
|
+
// workspace root, so the workspace-relative form is preferred. Returns
|
|
2448
|
+
// undefined when the file can't be resolved.
|
|
2449
|
+
function resolveDocumentationFileToWorkspacePath(root, migrationsDir, documentation) {
|
|
2450
|
+
let documentationFile;
|
|
2451
|
+
try {
|
|
2452
|
+
documentationFile = require.resolve(documentation, {
|
|
2453
|
+
paths: [migrationsDir],
|
|
2454
|
+
});
|
|
2455
|
+
}
|
|
2456
|
+
catch {
|
|
2457
|
+
return undefined;
|
|
2458
|
+
}
|
|
2459
|
+
const relativePath = (0, path_1.relative)(root, documentationFile);
|
|
2460
|
+
return relativePath.startsWith('..') ? documentationFile : relativePath;
|
|
2461
|
+
}
|
|
2300
2462
|
class MigrationImplementationMissingError extends Error {
|
|
2301
2463
|
constructor(baseMessage, collectionPath, migrationVersion) {
|
|
2302
2464
|
super(buildMigrationMissingMessage(baseMessage, collectionPath, migrationVersion));
|
|
@@ -149,8 +149,11 @@ async function maybePromptOrWarnMultiMajorMigration(args) {
|
|
|
149
149
|
resolveLatestStableInMajor(targetPackage, installedMajor + 1),
|
|
150
150
|
]);
|
|
151
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
|
-
|
|
152
|
+
// delta — a same-minor patch bump isn't a meaningful incremental step. Skip
|
|
153
|
+
// major 22 (last pre-v23) entirely: a 22.x step is the only sub-v23 option
|
|
154
|
+
// and conflicts with the mode gate already decided against the v23+ target.
|
|
155
|
+
const showCurrent = installedMajor !== 22 &&
|
|
156
|
+
latestInCurrent &&
|
|
154
157
|
(0, semver_1.gt)(latestInCurrent, installed) &&
|
|
155
158
|
(0, semver_1.minor)(latestInCurrent) > (0, semver_1.minor)(installed)
|
|
156
159
|
? latestInCurrent
|
|
@@ -16,7 +16,7 @@ export declare function filterVersionPlansByCommitRange(versionPlans: RawVersion
|
|
|
16
16
|
* Resolves the "from SHA" for changelog purposes.
|
|
17
17
|
* This determines the starting point for changelog generation and optional version plan filtering.
|
|
18
18
|
*/
|
|
19
|
-
export declare function resolveChangelogFromSHA({ fromRef, tagPattern, tagPatternValues, checkAllBranchesWhen, preid, requireSemver, strictPreid, useAutomaticFromRef, resolveRepositoryTags, }: {
|
|
19
|
+
export declare function resolveChangelogFromSHA({ fromRef, tagPattern, tagPatternValues, checkAllBranchesWhen, preid, requireSemver, strictPreid, useAutomaticFromRef, resolveRepositoryTags, projectRoot, }: {
|
|
20
20
|
fromRef?: string;
|
|
21
21
|
tagPattern: string;
|
|
22
22
|
tagPatternValues: Record<string, string>;
|
|
@@ -26,6 +26,8 @@ export declare function resolveChangelogFromSHA({ fromRef, tagPattern, tagPatter
|
|
|
26
26
|
strictPreid: boolean;
|
|
27
27
|
useAutomaticFromRef: boolean;
|
|
28
28
|
resolveRepositoryTags: RepoGitTags['resolveTags'];
|
|
29
|
+
/** When provided, scopes the fallback to the project's first commit instead of the repo's first commit */
|
|
30
|
+
projectRoot?: string;
|
|
29
31
|
}): Promise<string | null>;
|
|
30
32
|
/**
|
|
31
33
|
* Helper function for workspace-level "from SHA" resolution.
|