nx 23.0.0-beta.11 → 23.0.0-beta.13
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/src/command-line/examples.js +1 -1
- package/dist/src/command-line/init/implementation/angular/standalone-workspace.js +14 -18
- package/dist/src/command-line/init/implementation/utils.d.ts +7 -1
- package/dist/src/command-line/init/implementation/utils.js +44 -14
- package/dist/src/command-line/migrate/command-object.js +1 -1
- package/dist/src/command-line/migrate/migrate.d.ts +23 -5
- package/dist/src/command-line/migrate/migrate.js +76 -28
- package/dist/src/command-line/migrate/multi-major.d.ts +23 -2
- package/dist/src/command-line/migrate/multi-major.js +47 -28
- package/dist/src/command-line/migrate/prompt-files.d.ts +12 -0
- package/dist/src/command-line/migrate/prompt-files.js +107 -0
- package/dist/src/command-line/migrate/version-utils.d.ts +1 -0
- package/dist/src/command-line/migrate/version-utils.js +9 -3
- package/dist/src/command-line/release/config/config.d.ts +3 -6
- package/dist/src/command-line/release/config/config.js +77 -45
- package/dist/src/command-line/release/utils/release-graph.js +2 -3
- package/dist/src/command-line/release/utils/repository-git-tags.js +1 -1
- package/dist/src/command-line/release/version/resolve-current-version.js +1 -1
- package/dist/src/command-line/show/show-target/info.js +4 -5
- package/dist/src/command-line/watch/command-object.js +24 -4
- package/dist/src/command-line/watch/watch.d.ts +7 -0
- package/dist/src/command-line/watch/watch.js +1 -1
- package/dist/src/config/misc-interfaces.d.ts +3 -1
- package/dist/src/config/nx-json.d.ts +43 -56
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/daemon/client/client.d.ts +1 -1
- package/dist/src/daemon/server/file-watching/file-watcher-sockets.d.ts +1 -1
- package/dist/src/daemon/server/file-watching/file-watcher-sockets.js +1 -1
- package/dist/src/devkit-exports.d.ts +1 -1
- package/dist/src/devkit-internals.d.ts +1 -0
- package/dist/src/devkit-internals.js +4 -1
- package/dist/src/executors/run-commands/running-tasks.d.ts +7 -0
- package/dist/src/executors/run-commands/running-tasks.js +178 -105
- package/dist/src/executors/run-script/run-script.impl.js +3 -10
- package/dist/src/hasher/task-hasher.js +6 -4
- package/dist/src/migrations/update-16-2-0/remove-run-commands-output-path.js +6 -2
- package/dist/src/migrations/update-17-0-0/use-minimal-config-for-tasks-runner-options.js +20 -4
- package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.d.ts +9 -0
- package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.js +18 -0
- package/dist/src/migrations/update-23-0-0/convert-target-defaults-to-array.d.ts +25 -0
- package/dist/src/migrations/update-23-0-0/convert-target-defaults-to-array.js +117 -0
- package/dist/src/native/index.d.ts +18 -1
- package/dist/src/native/native-bindings.js +2 -0
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/project-graph/plugins/utils.js +13 -7
- package/dist/src/project-graph/utils/project-configuration/target-defaults.d.ts +95 -4
- package/dist/src/project-graph/utils/project-configuration/target-defaults.js +515 -68
- package/dist/src/project-graph/utils/project-configuration-utils.d.ts +13 -5
- package/dist/src/project-graph/utils/project-configuration-utils.js +14 -6
- package/dist/src/tasks-runner/forked-process-task-runner.d.ts +1 -1
- package/dist/src/tasks-runner/forked-process-task-runner.js +11 -6
- package/dist/src/tasks-runner/legacy-depends-on-warning.d.ts +18 -0
- package/dist/src/tasks-runner/legacy-depends-on-warning.js +109 -0
- package/dist/src/tasks-runner/pseudo-terminal.d.ts +1 -1
- package/dist/src/tasks-runner/pseudo-terminal.js +22 -10
- package/dist/src/tasks-runner/run-command.js +0 -10
- package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +1 -1
- package/dist/src/tasks-runner/running-tasks/batch-process.js +3 -5
- package/dist/src/tasks-runner/running-tasks/node-child-process.d.ts +2 -2
- package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -7
- package/dist/src/tasks-runner/task-orchestrator.d.ts +1 -0
- package/dist/src/tasks-runner/task-orchestrator.js +33 -24
- package/dist/src/tasks-runner/utils.d.ts +6 -4
- package/dist/src/tasks-runner/utils.js +26 -7
- package/dist/src/utils/installed-nx-version.js +5 -2
- package/dist/src/utils/package-json.js +10 -1
- package/migrations.json +11 -0
- package/package.json +11 -12
- package/schemas/nx-schema.json +114 -80
|
@@ -378,7 +378,7 @@ exports.examples = {
|
|
|
378
378
|
description: 'Watch the "app" project and echo the project name and the files that changed',
|
|
379
379
|
},
|
|
380
380
|
{
|
|
381
|
-
command: 'watch --projects=app1,app2 --
|
|
381
|
+
command: 'watch --projects=app1,app2 --includeDependencies -- echo \\$NX_PROJECT_NAME',
|
|
382
382
|
description: 'Watch "app1" and "app2" and echo the project name whenever a specified project or its dependencies change',
|
|
383
383
|
},
|
|
384
384
|
{
|
|
@@ -54,29 +54,26 @@ function createNxJson(repoRoot, angularJson, cacheableOperations, { eslintProjec
|
|
|
54
54
|
: []),
|
|
55
55
|
].filter(Boolean),
|
|
56
56
|
};
|
|
57
|
-
nxJson.targetDefaults
|
|
57
|
+
const defaults = Array.isArray(nxJson.targetDefaults)
|
|
58
|
+
? [...nxJson.targetDefaults]
|
|
59
|
+
: [];
|
|
58
60
|
if (workspaceTargets.includes('build')) {
|
|
59
|
-
|
|
60
|
-
...nxJson.targetDefaults.build,
|
|
61
|
+
(0, utils_1.upsertTargetDefaultEntry)(defaults, 'build', {
|
|
61
62
|
dependsOn: ['^build'],
|
|
62
63
|
inputs: ['production', '^production'],
|
|
63
|
-
};
|
|
64
|
+
});
|
|
64
65
|
}
|
|
65
66
|
if (workspaceTargets.includes('server')) {
|
|
66
|
-
|
|
67
|
-
...nxJson.targetDefaults.server,
|
|
67
|
+
(0, utils_1.upsertTargetDefaultEntry)(defaults, 'server', {
|
|
68
68
|
inputs: ['production', '^production'],
|
|
69
|
-
};
|
|
69
|
+
});
|
|
70
70
|
}
|
|
71
71
|
if (workspaceTargets.includes('test')) {
|
|
72
72
|
const inputs = ['default', '^production'];
|
|
73
73
|
if ((0, fileutils_1.fileExists)((0, node_path_1.join)(repoRoot, 'karma.conf.js'))) {
|
|
74
74
|
inputs.push('{workspaceRoot}/karma.conf.js');
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
...nxJson.targetDefaults.test,
|
|
78
|
-
inputs,
|
|
79
|
-
};
|
|
76
|
+
(0, utils_1.upsertTargetDefaultEntry)(defaults, 'test', { inputs });
|
|
80
77
|
}
|
|
81
78
|
if (workspaceTargets.includes('lint')) {
|
|
82
79
|
const inputs = ['default'];
|
|
@@ -86,16 +83,15 @@ function createNxJson(repoRoot, angularJson, cacheableOperations, { eslintProjec
|
|
|
86
83
|
if ((0, fileutils_1.fileExists)((0, node_path_1.join)(repoRoot, 'eslint.config.cjs'))) {
|
|
87
84
|
inputs.push('{workspaceRoot}/eslint.config.cjs');
|
|
88
85
|
}
|
|
89
|
-
|
|
90
|
-
...nxJson.targetDefaults.lint,
|
|
91
|
-
inputs,
|
|
92
|
-
};
|
|
86
|
+
(0, utils_1.upsertTargetDefaultEntry)(defaults, 'lint', { inputs });
|
|
93
87
|
}
|
|
94
88
|
if (workspaceTargets.includes('e2e')) {
|
|
95
|
-
|
|
96
|
-
...nxJson.targetDefaults.e2e,
|
|
89
|
+
(0, utils_1.upsertTargetDefaultEntry)(defaults, 'e2e', {
|
|
97
90
|
inputs: ['default', '^production'],
|
|
98
|
-
};
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (defaults.length > 0) {
|
|
94
|
+
nxJson.targetDefaults = defaults;
|
|
99
95
|
}
|
|
100
96
|
(0, fileutils_1.writeJsonFile)((0, node_path_1.join)(repoRoot, 'nx.json'), nxJson);
|
|
101
97
|
}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { NxJsonConfiguration } from '../../../config/nx-json';
|
|
1
|
+
import { NxJsonConfiguration, TargetDefaultEntry } from '../../../config/nx-json';
|
|
2
2
|
import { PackageJson } from '../../../utils/package-json';
|
|
3
3
|
import { PackageManagerCommands } from '../../../utils/package-manager';
|
|
4
4
|
export declare function createNxJsonFile(repoRoot: string, topologicalTargets: string[], cacheableOperations: string[], scriptOutputs: {
|
|
5
5
|
[name: string]: string;
|
|
6
6
|
}): void;
|
|
7
|
+
/**
|
|
8
|
+
* Locate-by-target upsert against an in-memory `targetDefaults` array.
|
|
9
|
+
* Used by `nx init` code paths that operate on raw JSON before a Tree
|
|
10
|
+
* exists — generators should use `upsertTargetDefault` from devkit instead.
|
|
11
|
+
*/
|
|
12
|
+
export declare function upsertTargetDefaultEntry(entries: TargetDefaultEntry[], target: string, patch: Partial<TargetDefaultEntry>): void;
|
|
7
13
|
export declare function createNxJsonFromTurboJson(turboJson: Record<string, any>): NxJsonConfiguration;
|
|
8
14
|
export declare function addDepsToPackageJson(repoRoot: string, additionalPackages?: string[]): void;
|
|
9
15
|
export declare function updateGitIgnore(root: string): void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createNxJsonFile = createNxJsonFile;
|
|
4
|
+
exports.upsertTargetDefaultEntry = upsertTargetDefaultEntry;
|
|
4
5
|
exports.createNxJsonFromTurboJson = createNxJsonFromTurboJson;
|
|
5
6
|
exports.addDepsToPackageJson = addDepsToPackageJson;
|
|
6
7
|
exports.updateGitIgnore = updateGitIgnore;
|
|
@@ -34,27 +35,37 @@ function createNxJsonFile(repoRoot, topologicalTargets, cacheableOperations, scr
|
|
|
34
35
|
}
|
|
35
36
|
catch { }
|
|
36
37
|
nxJson.$schema = './node_modules/nx/schemas/nx-schema.json';
|
|
37
|
-
nxJson.targetDefaults
|
|
38
|
+
const entries = Array.isArray(nxJson.targetDefaults)
|
|
39
|
+
? [...nxJson.targetDefaults]
|
|
40
|
+
: [];
|
|
38
41
|
if (topologicalTargets.length > 0) {
|
|
39
42
|
for (const scriptName of topologicalTargets) {
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
upsertTargetDefaultEntry(entries, scriptName, {
|
|
44
|
+
dependsOn: [`^${scriptName}`],
|
|
45
|
+
});
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
for (const [scriptName, output] of Object.entries(scriptOutputs)) {
|
|
45
49
|
if (!output) {
|
|
46
50
|
continue;
|
|
47
51
|
}
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
upsertTargetDefaultEntry(entries, scriptName, {
|
|
53
|
+
outputs: [`{projectRoot}/${output}`],
|
|
54
|
+
});
|
|
50
55
|
}
|
|
51
56
|
for (const target of cacheableOperations) {
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
const existing = findUnfilteredTargetEntry(entries, target);
|
|
58
|
+
if (existing)
|
|
59
|
+
existing.cache ??= true;
|
|
60
|
+
else
|
|
61
|
+
entries.push({ target, cache: true });
|
|
54
62
|
}
|
|
55
|
-
if (
|
|
63
|
+
if (entries.length === 0) {
|
|
56
64
|
delete nxJson.targetDefaults;
|
|
57
65
|
}
|
|
66
|
+
else {
|
|
67
|
+
nxJson.targetDefaults = entries;
|
|
68
|
+
}
|
|
58
69
|
const defaultBase = (0, deduce_default_base_1.deduceDefaultBase)();
|
|
59
70
|
// Do not add defaultBase if it is inferred to be the Nx default value of main
|
|
60
71
|
if (defaultBase !== 'main') {
|
|
@@ -62,6 +73,21 @@ function createNxJsonFile(repoRoot, topologicalTargets, cacheableOperations, scr
|
|
|
62
73
|
}
|
|
63
74
|
(0, fileutils_1.writeJsonFile)(nxJsonPath, nxJson);
|
|
64
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Locate-by-target upsert against an in-memory `targetDefaults` array.
|
|
78
|
+
* Used by `nx init` code paths that operate on raw JSON before a Tree
|
|
79
|
+
* exists — generators should use `upsertTargetDefault` from devkit instead.
|
|
80
|
+
*/
|
|
81
|
+
function upsertTargetDefaultEntry(entries, target, patch) {
|
|
82
|
+
const existing = findUnfilteredTargetEntry(entries, target);
|
|
83
|
+
if (existing)
|
|
84
|
+
Object.assign(existing, patch, { target });
|
|
85
|
+
else
|
|
86
|
+
entries.push({ ...patch, target });
|
|
87
|
+
}
|
|
88
|
+
function findUnfilteredTargetEntry(entries, target) {
|
|
89
|
+
return entries.find((e) => e.target === target && e.projects === undefined && e.plugin === undefined);
|
|
90
|
+
}
|
|
65
91
|
function createNxJsonFromTurboJson(turboJson) {
|
|
66
92
|
const nxJson = {
|
|
67
93
|
$schema: './node_modules/nx/schemas/nx-schema.json',
|
|
@@ -88,20 +114,20 @@ function createNxJsonFromTurboJson(turboJson) {
|
|
|
88
114
|
}
|
|
89
115
|
// Handle task configurations
|
|
90
116
|
if (turboJson.tasks) {
|
|
91
|
-
|
|
117
|
+
const entries = [];
|
|
92
118
|
for (const [taskName, taskConfig] of Object.entries(turboJson.tasks)) {
|
|
93
119
|
// Skip project-specific tasks (containing #)
|
|
94
120
|
if (taskName.includes('#'))
|
|
95
121
|
continue;
|
|
96
122
|
const config = taskConfig;
|
|
97
|
-
|
|
123
|
+
const entry = { target: taskName };
|
|
98
124
|
// Handle dependsOn
|
|
99
125
|
if (config.dependsOn?.length > 0) {
|
|
100
|
-
|
|
126
|
+
entry.dependsOn = config.dependsOn;
|
|
101
127
|
}
|
|
102
128
|
// Handle inputs
|
|
103
129
|
if (config.inputs?.length > 0) {
|
|
104
|
-
|
|
130
|
+
entry.inputs = config.inputs
|
|
105
131
|
.map((input) => {
|
|
106
132
|
if (input === '$TURBO_DEFAULT$') {
|
|
107
133
|
return '{projectRoot}/**/*';
|
|
@@ -124,7 +150,7 @@ function createNxJsonFromTurboJson(turboJson) {
|
|
|
124
150
|
}
|
|
125
151
|
// Handle outputs
|
|
126
152
|
if (config.outputs?.length > 0) {
|
|
127
|
-
|
|
153
|
+
entry.outputs = config.outputs.map((output) => {
|
|
128
154
|
// Don't add projectRoot if it's already there
|
|
129
155
|
if (output.startsWith('{projectRoot}/'))
|
|
130
156
|
return output;
|
|
@@ -136,7 +162,11 @@ function createNxJsonFromTurboJson(turboJson) {
|
|
|
136
162
|
});
|
|
137
163
|
}
|
|
138
164
|
// Handle cache setting - true by default in Turbo
|
|
139
|
-
|
|
165
|
+
entry.cache = config.cache !== false;
|
|
166
|
+
entries.push(entry);
|
|
167
|
+
}
|
|
168
|
+
if (entries.length > 0) {
|
|
169
|
+
nxJson.targetDefaults = entries;
|
|
140
170
|
}
|
|
141
171
|
}
|
|
142
172
|
/**
|
|
@@ -68,7 +68,7 @@ function withMigrationOptions(yargs) {
|
|
|
68
68
|
default: false,
|
|
69
69
|
})
|
|
70
70
|
.option('mode', {
|
|
71
|
-
describe: "Restrict which packages to migrate. Only applies when migrating Nx itself. 'first-party' processes only Nx and its plugins (the target package plus its nx.packageGroup); 'third-party' processes only the third-party dependencies referenced by Nx packageJsonUpdates entries, catching up on any updates that may have been skipped previously; 'all' processes everything.
|
|
71
|
+
describe: "Restrict which packages to migrate. Only applies when migrating Nx itself. 'first-party' processes only Nx and its plugins (the target package plus its nx.packageGroup); 'third-party' processes only the third-party dependencies referenced by Nx packageJsonUpdates entries, catching up on any updates that may have been skipped previously; 'all' processes everything. When targeting Nx in an interactive terminal, prompts for the value if not provided; otherwise defaults to 'all'.",
|
|
72
72
|
type: 'string',
|
|
73
73
|
choices: ['first-party', 'third-party', 'all'],
|
|
74
74
|
})
|
|
@@ -2,11 +2,14 @@ import { MigrationsJson, PackageJsonUpdateForPackage as PackageUpdate } from '..
|
|
|
2
2
|
import { NxJsonConfiguration } from '../../config/nx-json';
|
|
3
3
|
import { FileChange } from '../../generators/tree';
|
|
4
4
|
import { ArrayPackageGroup, PackageJson } from '../../utils/package-json';
|
|
5
|
+
import { type MultiMajorMode } from './multi-major';
|
|
5
6
|
import { filterDowngradedUpdates } from './update-filters';
|
|
6
7
|
import { normalizeVersion } from './version-utils';
|
|
7
8
|
export { normalizeVersion };
|
|
8
9
|
export interface ResolvedMigrationConfiguration extends MigrationsJson {
|
|
9
10
|
packageGroup?: ArrayPackageGroup;
|
|
11
|
+
/** Prompt file contents keyed by the `prompt` value as it appears on the migration entry. */
|
|
12
|
+
resolvedPromptFiles?: Record<string, string>;
|
|
10
13
|
}
|
|
11
14
|
type CommandFailure = {
|
|
12
15
|
message?: string;
|
|
@@ -14,6 +17,7 @@ type CommandFailure = {
|
|
|
14
17
|
stdout?: string | Buffer;
|
|
15
18
|
};
|
|
16
19
|
export declare function formatCommandFailure(command: string, error: CommandFailure): string;
|
|
20
|
+
export type MigrateMode = 'first-party' | 'third-party' | 'all';
|
|
17
21
|
export interface MigratorOptions {
|
|
18
22
|
packageJson?: PackageJson;
|
|
19
23
|
nxInstallation?: NxJsonConfiguration['installation'];
|
|
@@ -33,7 +37,7 @@ export interface MigratorOptions {
|
|
|
33
37
|
* - 'third-party' keeps only packages NOT in `firstPartyPackages`
|
|
34
38
|
* - 'all' / undefined keeps all packages (no filtering)
|
|
35
39
|
*/
|
|
36
|
-
mode?:
|
|
40
|
+
mode?: MigrateMode;
|
|
37
41
|
/** First-party package names used by `mode` for filtering. */
|
|
38
42
|
firstPartyPackages?: ReadonlySet<string>;
|
|
39
43
|
}
|
|
@@ -55,6 +59,8 @@ export declare class Migrator {
|
|
|
55
59
|
constructor(opts: MigratorOptions);
|
|
56
60
|
private fetchMigrationConfig;
|
|
57
61
|
migrate(targetPackage: string, targetVersion: string): Promise<{
|
|
62
|
+
minVersionWithSkippedUpdates: string;
|
|
63
|
+
promptContents?: Record<string, string>;
|
|
58
64
|
packageUpdates: Record<string, PackageUpdate>;
|
|
59
65
|
migrations: {
|
|
60
66
|
package: string;
|
|
@@ -63,9 +69,9 @@ export declare class Migrator {
|
|
|
63
69
|
description?: string;
|
|
64
70
|
implementation?: string;
|
|
65
71
|
factory?: string;
|
|
72
|
+
prompt?: string;
|
|
66
73
|
requires?: Record<string, string>;
|
|
67
74
|
}[];
|
|
68
|
-
minVersionWithSkippedUpdates: string;
|
|
69
75
|
}>;
|
|
70
76
|
private createMigrateJson;
|
|
71
77
|
private buildPackageJsonUpdates;
|
|
@@ -106,10 +112,10 @@ export declare class Migrator {
|
|
|
106
112
|
* walking the cascade.
|
|
107
113
|
*/
|
|
108
114
|
export declare function resolveCanonicalNxPackage(targetVersion: string): 'nx' | '@nrwl/workspace';
|
|
109
|
-
export declare function resolveMode(mode:
|
|
115
|
+
export declare function resolveMode(mode: MigrateMode | undefined, targetPackage: string, targetVersion: string, context?: {
|
|
110
116
|
hasFrom: boolean;
|
|
111
117
|
hasExcludeAppliedMigrations: boolean;
|
|
112
|
-
}): Promise<
|
|
118
|
+
}): Promise<MigrateMode>;
|
|
113
119
|
type GenerateMigrations = {
|
|
114
120
|
type: 'generateMigrations';
|
|
115
121
|
targetPackage: string;
|
|
@@ -122,7 +128,19 @@ type GenerateMigrations = {
|
|
|
122
128
|
};
|
|
123
129
|
interactive?: boolean;
|
|
124
130
|
excludeAppliedMigrations?: boolean;
|
|
125
|
-
mode:
|
|
131
|
+
mode: MigrateMode;
|
|
132
|
+
/**
|
|
133
|
+
* Set when multi-major redirected `targetVersion` to an incremental step
|
|
134
|
+
* (gradual mode or the interactive prompt picking a smaller jump). Holds
|
|
135
|
+
* the concrete resolved target so Next Steps can suggest re-running toward
|
|
136
|
+
* it.
|
|
137
|
+
*/
|
|
138
|
+
originalTargetVersion?: string;
|
|
139
|
+
/**
|
|
140
|
+
* The `--multi-major-mode` value to propagate to a continuation command,
|
|
141
|
+
* or undefined to omit it. See `MultiMajorResult.gradual` for when it's set.
|
|
142
|
+
*/
|
|
143
|
+
multiMajorMode?: MultiMajorMode;
|
|
126
144
|
};
|
|
127
145
|
type RunMigrations = {
|
|
128
146
|
type: 'runMigrations';
|
|
@@ -48,6 +48,7 @@ const format_changed_files_with_prettier_if_available_1 = require("../../generat
|
|
|
48
48
|
const provenance_1 = require("../../utils/provenance");
|
|
49
49
|
const catalog_1 = require("../../utils/catalog");
|
|
50
50
|
const multi_major_1 = require("./multi-major");
|
|
51
|
+
const prompt_files_1 = require("./prompt-files");
|
|
51
52
|
const update_filters_1 = require("./update-filters");
|
|
52
53
|
Object.defineProperty(exports, "filterDowngradedUpdates", { enumerable: true, get: function () { return update_filters_1.filterDowngradedUpdates; } });
|
|
53
54
|
const version_utils_1 = require("./version-utils");
|
|
@@ -122,14 +123,16 @@ class Migrator {
|
|
|
122
123
|
addToPackageJson: false,
|
|
123
124
|
});
|
|
124
125
|
this.applyModeFilter();
|
|
125
|
-
const migrations = await this.createMigrateJson();
|
|
126
|
+
const { migrations, promptContents } = await this.createMigrateJson();
|
|
126
127
|
return {
|
|
127
128
|
packageUpdates: this.packageUpdates,
|
|
128
129
|
migrations,
|
|
130
|
+
...(Object.keys(promptContents).length > 0 ? { promptContents } : {}),
|
|
129
131
|
minVersionWithSkippedUpdates: this.minVersionWithSkippedUpdates,
|
|
130
132
|
};
|
|
131
133
|
}
|
|
132
134
|
async createMigrateJson() {
|
|
135
|
+
const promptContents = {};
|
|
133
136
|
const migrations = await Promise.all(Object.keys(this.packageUpdates).map(async (packageName) => {
|
|
134
137
|
if (this.packageUpdates[packageName].ignoreMigrations) {
|
|
135
138
|
return [];
|
|
@@ -138,10 +141,15 @@ class Migrator {
|
|
|
138
141
|
if (currentVersion === null)
|
|
139
142
|
return [];
|
|
140
143
|
const { version } = this.packageUpdates[packageName];
|
|
141
|
-
const { generators } = await this.fetchMigrationConfig(packageName, version);
|
|
142
|
-
if (!
|
|
144
|
+
const { generators: migrationEntries, resolvedPromptFiles } = await this.fetchMigrationConfig(packageName, version);
|
|
145
|
+
if (!migrationEntries)
|
|
143
146
|
return [];
|
|
144
|
-
|
|
147
|
+
if (resolvedPromptFiles) {
|
|
148
|
+
for (const [promptPath, content] of Object.entries(resolvedPromptFiles)) {
|
|
149
|
+
promptContents[(0, prompt_files_1.promptContentKey)(packageName, promptPath)] = content;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return Object.entries(migrationEntries)
|
|
145
153
|
.filter(([, migration]) => migration.version &&
|
|
146
154
|
this.gt(migration.version, currentVersion) &&
|
|
147
155
|
this.lte(migration.version, version) &&
|
|
@@ -152,7 +160,7 @@ class Migrator {
|
|
|
152
160
|
name: migrationName,
|
|
153
161
|
}));
|
|
154
162
|
}));
|
|
155
|
-
return migrations.flat();
|
|
163
|
+
return { migrations: migrations.flat(), promptContents };
|
|
156
164
|
}
|
|
157
165
|
async buildPackageJsonUpdates(targetPackage, target) {
|
|
158
166
|
const packagesToCheck = await this.populatePackageJsonUpdatesAndGetPackagesToCheck(targetPackage, target);
|
|
@@ -250,7 +258,7 @@ class Migrator {
|
|
|
250
258
|
if (ignorePackageGroup) {
|
|
251
259
|
return [];
|
|
252
260
|
}
|
|
253
|
-
const packageGroup = packageName === '@nrwl/workspace' && (0,
|
|
261
|
+
const packageGroup = packageName === '@nrwl/workspace' && (0, version_utils_1.isLegacyEra)(targetVersion)
|
|
254
262
|
? LEGACY_NRWL_PACKAGE_GROUP
|
|
255
263
|
: (migrationConfig.packageGroup ?? []);
|
|
256
264
|
let packageGroupOrder = [];
|
|
@@ -503,9 +511,7 @@ function resolveFirstPartyPackages(targetPackage, packageGroup) {
|
|
|
503
511
|
* walking the cascade.
|
|
504
512
|
*/
|
|
505
513
|
function resolveCanonicalNxPackage(targetVersion) {
|
|
506
|
-
return (0,
|
|
507
|
-
? '@nrwl/workspace'
|
|
508
|
-
: 'nx';
|
|
514
|
+
return (0, version_utils_1.isLegacyEra)(targetVersion) ? '@nrwl/workspace' : 'nx';
|
|
509
515
|
}
|
|
510
516
|
async function resolveMode(mode, targetPackage, targetVersion, context = {
|
|
511
517
|
hasFrom: false,
|
|
@@ -588,9 +594,9 @@ async function parseTargetPackageAndVersion(args) {
|
|
|
588
594
|
// on the registry
|
|
589
595
|
const targetVersion = await (0, version_utils_1.normalizeVersionWithTagCheck)('nx', args);
|
|
590
596
|
const isDistTag = version_utils_1.DIST_TAGS.includes(args);
|
|
591
|
-
const targetPackage =
|
|
592
|
-
? '
|
|
593
|
-
:
|
|
597
|
+
const targetPackage = isDistTag
|
|
598
|
+
? 'nx'
|
|
599
|
+
: resolveCanonicalNxPackage(targetVersion);
|
|
594
600
|
return { targetPackage, targetVersion };
|
|
595
601
|
}
|
|
596
602
|
return { targetPackage: args, targetVersion: 'latest' };
|
|
@@ -602,6 +608,9 @@ async function parseMigrationsOptions(options) {
|
|
|
602
608
|
if (options.mode && options.runMigrations) {
|
|
603
609
|
throw new Error(`Error: '--mode' cannot be combined with '--run-migrations'.`);
|
|
604
610
|
}
|
|
611
|
+
if (options.multiMajorMode && options.runMigrations) {
|
|
612
|
+
throw new Error(`Error: '--multi-major-mode' cannot be combined with '--run-migrations'.`);
|
|
613
|
+
}
|
|
605
614
|
if (options.runMigrations) {
|
|
606
615
|
return {
|
|
607
616
|
type: 'runMigrations',
|
|
@@ -625,12 +634,13 @@ async function parseMigrationsOptions(options) {
|
|
|
625
634
|
// Spec §10: prompt or warn when crossing more than one major boundary.
|
|
626
635
|
// Each major's metadata may have pruned migrations from much-older versions,
|
|
627
636
|
// so jumping multiple majors at once can silently skip migrations.
|
|
628
|
-
|
|
637
|
+
const multiMajorResult = await (0, multi_major_1.maybePromptOrWarnMultiMajorMigration)({
|
|
629
638
|
mode,
|
|
630
639
|
options,
|
|
631
640
|
targetPackage,
|
|
632
641
|
targetVersion,
|
|
633
642
|
});
|
|
643
|
+
targetVersion = multiMajorResult.chosen;
|
|
634
644
|
if (mode === 'third-party') {
|
|
635
645
|
assertThirdPartyTargetBounds({
|
|
636
646
|
targetPackage,
|
|
@@ -648,6 +658,8 @@ async function parseMigrationsOptions(options) {
|
|
|
648
658
|
interactive: options.interactive,
|
|
649
659
|
excludeAppliedMigrations: options.excludeAppliedMigrations,
|
|
650
660
|
mode,
|
|
661
|
+
originalTargetVersion: multiMajorResult.originalTarget,
|
|
662
|
+
multiMajorMode: multiMajorResult.gradual ? 'gradual' : undefined,
|
|
651
663
|
};
|
|
652
664
|
}
|
|
653
665
|
function assertThirdPartyModeFlagCompatibility(options) {
|
|
@@ -708,7 +720,7 @@ async function resolveTargetAndMode(args) {
|
|
|
708
720
|
targetVersion = 'latest';
|
|
709
721
|
}
|
|
710
722
|
if (options.mode && !(0, version_utils_1.isNxEquivalentTarget)(targetPackage, targetVersion)) {
|
|
711
|
-
const isLegacy = (0,
|
|
723
|
+
const isLegacy = (0, version_utils_1.isLegacyEra)(targetVersion);
|
|
712
724
|
const validTargets = isLegacy
|
|
713
725
|
? `'@nrwl/workspace'`
|
|
714
726
|
: `'nx' or '@nx/workspace'`;
|
|
@@ -767,10 +779,10 @@ function assertThirdPartyTargetBounds(args) {
|
|
|
767
779
|
function resolveInstalledCanonical() {
|
|
768
780
|
const installedNx = (0, installed_nx_version_1.getInstalledNxVersion)();
|
|
769
781
|
if (installedNx) {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
782
|
+
return {
|
|
783
|
+
canonical: resolveCanonicalNxPackage(installedNx),
|
|
784
|
+
version: installedNx,
|
|
785
|
+
};
|
|
774
786
|
}
|
|
775
787
|
const installedLegacy = (0, installed_nx_version_1.getInstalledLegacyNrwlWorkspaceVersion)();
|
|
776
788
|
if (installedLegacy) {
|
|
@@ -923,11 +935,22 @@ async function downloadPackageMigrationsFromRegistry(packageName, packageVersion
|
|
|
923
935
|
let result;
|
|
924
936
|
try {
|
|
925
937
|
const { tarballPath } = await (0, package_manager_1.packageRegistryPack)(dir, packageName, packageVersion);
|
|
926
|
-
const
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
938
|
+
const fullTarballPath = (0, path_1.join)(dir, tarballPath);
|
|
939
|
+
let migrations;
|
|
940
|
+
try {
|
|
941
|
+
migrations = await (0, fileutils_1.extractFileFromTarball)(fullTarballPath, (0, path_2.joinPathFragments)('package', migrationsFilePath), (0, path_1.join)(dir, migrationsFilePath)).then((path) => (0, fileutils_1.readJsonFile)(path));
|
|
942
|
+
}
|
|
943
|
+
catch {
|
|
944
|
+
throw new Error(`Failed to find migrations file "${migrationsFilePath}" in package "${packageName}@${packageVersion}".`);
|
|
945
|
+
}
|
|
946
|
+
(0, prompt_files_1.validateMigrationEntries)(packageName, packageVersion, migrations);
|
|
947
|
+
const resolvedPromptFiles = await (0, prompt_files_1.extractPromptFilesFromTarball)(packageName, packageVersion, migrations, migrationsFilePath, fullTarballPath, dir);
|
|
948
|
+
result = {
|
|
949
|
+
...migrations,
|
|
950
|
+
packageGroup,
|
|
951
|
+
version: packageVersion,
|
|
952
|
+
...(resolvedPromptFiles ? { resolvedPromptFiles } : {}),
|
|
953
|
+
};
|
|
931
954
|
}
|
|
932
955
|
finally {
|
|
933
956
|
await cleanup();
|
|
@@ -981,10 +1004,18 @@ async function getPackageMigrationsUsingInstallImpl(packageName, packageVersion)
|
|
|
981
1004
|
});
|
|
982
1005
|
const { migrations: migrationsFilePath, packageGroup, packageJson, } = readPackageMigrationConfig(packageName, dir);
|
|
983
1006
|
let migrations = undefined;
|
|
1007
|
+
let resolvedPromptFiles;
|
|
984
1008
|
if (migrationsFilePath) {
|
|
985
1009
|
migrations = (0, fileutils_1.readJsonFile)(migrationsFilePath);
|
|
986
|
-
|
|
987
|
-
|
|
1010
|
+
(0, prompt_files_1.validateMigrationEntries)(packageName, packageVersion, migrations);
|
|
1011
|
+
resolvedPromptFiles = await (0, prompt_files_1.readPromptFilesFromInstall)(packageName, packageVersion, migrations, migrationsFilePath);
|
|
1012
|
+
}
|
|
1013
|
+
result = {
|
|
1014
|
+
...migrations,
|
|
1015
|
+
packageGroup,
|
|
1016
|
+
version: packageJson.version,
|
|
1017
|
+
...(resolvedPromptFiles ? { resolvedPromptFiles } : {}),
|
|
1018
|
+
};
|
|
988
1019
|
}
|
|
989
1020
|
catch (e) {
|
|
990
1021
|
const pmc = (0, package_manager_1.getPackageManagerCommand)((0, package_manager_1.detectPackageManager)(dir), dir);
|
|
@@ -1191,8 +1222,7 @@ async function generateMigrationsJsonAndUpdatePackageJson(root, opts) {
|
|
|
1191
1222
|
// `LEGACY_NRWL_PACKAGE_GROUP` for that case, and the post-build
|
|
1192
1223
|
// third-party filter must mirror that set or first-party `@nrwl/*`
|
|
1193
1224
|
// plugins slip past it.
|
|
1194
|
-
const packageGroup = sourcePackage === '@nrwl/workspace' &&
|
|
1195
|
-
(0, semver_1.lt)(opts.targetVersion, '14.0.0-beta.0')
|
|
1225
|
+
const packageGroup = sourcePackage === '@nrwl/workspace' && (0, version_utils_1.isLegacyEra)(opts.targetVersion)
|
|
1196
1226
|
? LEGACY_NRWL_PACKAGE_GROUP
|
|
1197
1227
|
: rootMetadata.packageGroup;
|
|
1198
1228
|
firstPartyPackages = resolveFirstPartyPackages(sourcePackage, packageGroup);
|
|
@@ -1210,7 +1240,7 @@ async function generateMigrationsJsonAndUpdatePackageJson(root, opts) {
|
|
|
1210
1240
|
mode,
|
|
1211
1241
|
firstPartyPackages,
|
|
1212
1242
|
});
|
|
1213
|
-
const { migrations, packageUpdates, minVersionWithSkippedUpdates } = await migrator.migrate(walkedTargetPackage, opts.targetVersion);
|
|
1243
|
+
const { migrations, packageUpdates, promptContents, minVersionWithSkippedUpdates, } = await migrator.migrate(walkedTargetPackage, opts.targetVersion);
|
|
1214
1244
|
// The cascade collects packageJsonUpdates entries against the cascade
|
|
1215
1245
|
// root's installed version, but inner per-package pins are only gated
|
|
1216
1246
|
// against the in-flight cascade tally — not against each inner package's
|
|
@@ -1221,6 +1251,7 @@ async function generateMigrationsJsonAndUpdatePackageJson(root, opts) {
|
|
|
1221
1251
|
const writableUpdates = (0, update_filters_1.filterDowngradedUpdates)(packageUpdates, originalPackageJson, installedPackageVersions);
|
|
1222
1252
|
const wrotePackageJson = await updatePackageJson(root, writableUpdates);
|
|
1223
1253
|
const wroteNxJsonInstallation = await updateInstallationDetails(root, writableUpdates);
|
|
1254
|
+
const promptMigrationFiles = (0, prompt_files_1.writePromptMigrationFiles)(root, migrations, promptContents ?? {}, packageUpdates[walkedTargetPackage].version);
|
|
1224
1255
|
if (migrations.length > 0) {
|
|
1225
1256
|
await createMigrationsFile(root, [
|
|
1226
1257
|
...addSplitConfigurationMigrationIfAvailable(from, writableUpdates),
|
|
@@ -1258,6 +1289,11 @@ async function generateMigrationsJsonAndUpdatePackageJson(root, opts) {
|
|
|
1258
1289
|
migrations.length > 0
|
|
1259
1290
|
? `- migrations.json has been generated.`
|
|
1260
1291
|
: `- There are no migrations to run, so migrations.json has not been created.`,
|
|
1292
|
+
...(promptMigrationFiles.length > 0
|
|
1293
|
+
? [
|
|
1294
|
+
`- ${promptMigrationFiles.length} AI migration prompt(s) have been written to ${prompt_files_1.AI_MIGRATIONS_DIR}/.`,
|
|
1295
|
+
]
|
|
1296
|
+
: []),
|
|
1261
1297
|
],
|
|
1262
1298
|
});
|
|
1263
1299
|
try {
|
|
@@ -1291,9 +1327,21 @@ async function generateMigrationsJsonAndUpdatePackageJson(root, opts) {
|
|
|
1291
1327
|
]
|
|
1292
1328
|
: [
|
|
1293
1329
|
`- Make sure package.json changes make sense and then run '${pmc.install}',`,
|
|
1330
|
+
...(promptMigrationFiles.length > 0
|
|
1331
|
+
? [
|
|
1332
|
+
`- Review and tweak the AI migration prompts in ${prompt_files_1.AI_MIGRATIONS_DIR}/ as needed.`,
|
|
1333
|
+
]
|
|
1334
|
+
: []),
|
|
1294
1335
|
...(migrations.length > 0
|
|
1295
1336
|
? [`- Run '${pmc.exec} nx migrate --run-migrations'`]
|
|
1296
1337
|
: []),
|
|
1338
|
+
...(opts.originalTargetVersion
|
|
1339
|
+
? [
|
|
1340
|
+
`- After applying these migrations, run '${pmc.exec} nx migrate ${opts.targetPackage}@${opts.originalTargetVersion} --mode=${opts.mode}${opts.multiMajorMode === 'gradual'
|
|
1341
|
+
? ` ${multi_major_1.MULTI_MAJOR_MODE_FLAG}=gradual`
|
|
1342
|
+
: ''}' to continue toward your original target.`,
|
|
1343
|
+
]
|
|
1344
|
+
: []),
|
|
1297
1345
|
...(opts.interactive && minVersionWithSkippedUpdates
|
|
1298
1346
|
? [
|
|
1299
1347
|
`- You opted out of some migrations for now. Write the following command down somewhere to apply these migrations later:`,
|
|
@@ -1,9 +1,30 @@
|
|
|
1
|
+
import type { MigrateMode } from './migrate';
|
|
2
|
+
export declare const MULTI_MAJOR_MODE_FLAG = "--multi-major-mode";
|
|
1
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
|
+
};
|
|
2
23
|
export declare function maybePromptOrWarnMultiMajorMigration(args: {
|
|
3
|
-
mode:
|
|
24
|
+
mode: MigrateMode;
|
|
4
25
|
options: {
|
|
5
26
|
multiMajorMode?: MultiMajorMode;
|
|
6
27
|
};
|
|
7
28
|
targetPackage: string;
|
|
8
29
|
targetVersion: string;
|
|
9
|
-
}): Promise<
|
|
30
|
+
}): Promise<MultiMajorResult>;
|