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.
- package/dist/bin/nx.js +2 -1
- package/dist/src/ai/configure-ai-agents-disclaimer.d.ts +5 -0
- package/dist/src/ai/configure-ai-agents-disclaimer.js +31 -0
- package/dist/src/analytics/analytics.d.ts +6 -0
- package/dist/src/analytics/analytics.js +16 -8
- package/dist/src/analytics/index.d.ts +1 -1
- package/dist/src/analytics/index.js +2 -1
- package/dist/src/command-line/add/add.js +8 -1
- package/dist/src/command-line/graph/graph.d.ts +1 -0
- package/dist/src/command-line/graph/graph.js +15 -6
- package/dist/src/command-line/import/import.js +1 -1
- package/dist/src/command-line/init/ai-agent-prompts.d.ts +1 -1
- package/dist/src/command-line/init/ai-agent-prompts.js +7 -6
- package/dist/src/command-line/init/command-object.js +10 -2
- package/dist/src/command-line/init/configure-plugins.js +3 -2
- package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +4 -2
- package/dist/src/command-line/init/implementation/add-nx-to-nest.js +4 -3
- package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +4 -3
- package/dist/src/command-line/init/implementation/add-nx-to-turborepo.js +4 -3
- package/dist/src/command-line/init/implementation/angular/index.js +4 -2
- package/dist/src/command-line/init/implementation/angular/integrated-workspace.js +2 -5
- package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +3 -0
- package/dist/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +4 -1
- package/dist/src/command-line/init/implementation/utils.d.ts +3 -3
- package/dist/src/command-line/init/implementation/utils.js +22 -3
- package/dist/src/command-line/migrate/execute-migration.d.ts +72 -0
- package/dist/src/command-line/migrate/execute-migration.js +389 -0
- package/dist/src/command-line/migrate/migrate-ui-api.js +17 -12
- package/dist/src/command-line/migrate/migrate.d.ts +1 -45
- package/dist/src/command-line/migrate/migrate.js +33 -376
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +1 -1
- package/dist/src/command-line/nx-cloud/connect/view-logs.js +2 -0
- package/dist/src/command-line/release/utils/git.js +6 -2
- package/dist/src/command-line/release/utils/release-graph.d.ts +2 -2
- package/dist/src/command-line/release/utils/remote-release-clients/github.js +1 -1
- package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +1 -1
- package/dist/src/command-line/release/utils/shared.d.ts +2 -2
- package/dist/src/command-line/show/show-target/info.js +11 -2
- package/dist/src/command-line/show/show-target/inputs.js +50 -153
- package/dist/src/command-line/show/show-target/outputs.js +48 -173
- package/dist/src/command-line/show/show-target/utils.d.ts +28 -0
- package/dist/src/command-line/show/show-target/utils.js +83 -3
- package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
- package/dist/src/commands-runner/create-command-graph.js +5 -0
- package/dist/src/config/nx-json.d.ts +5 -3
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/daemon/client/client.d.ts +0 -2
- package/dist/src/daemon/client/client.js +17 -19
- package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +1 -1
- package/dist/src/daemon/server/server.js +7 -4
- package/dist/src/devkit-internals.d.ts +3 -0
- package/dist/src/devkit-internals.js +10 -1
- package/dist/src/generators/utils/nx-json.js +13 -3
- package/dist/src/hasher/check-task-files.d.ts +86 -0
- package/dist/src/hasher/check-task-files.js +378 -0
- package/dist/src/native/index.d.ts +21 -2
- 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/plugins/js/lock-file/npm-parser.js +71 -27
- package/dist/src/plugins/js/lock-file/pnpm-parser.js +50 -17
- package/dist/src/plugins/js/lock-file/project-graph-pruning.js +1 -1
- package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +3 -0
- package/dist/src/plugins/js/lock-file/yarn-parser.js +32 -5
- package/dist/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +12 -4
- package/dist/src/plugins/js/utils/register.d.ts +18 -0
- package/dist/src/plugins/js/utils/register.js +81 -0
- package/dist/src/plugins/js/utils/typescript.d.ts +9 -0
- package/dist/src/plugins/js/utils/typescript.js +15 -0
- package/dist/src/project-graph/build-project-graph.js +7 -1
- package/dist/src/project-graph/error-types.js +41 -1
- package/dist/src/project-graph/file-utils.js +6 -1
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +4 -0
- package/dist/src/project-graph/plugins/loaded-nx-plugin.js +1 -0
- package/dist/src/project-graph/plugins/transpiler.js +4 -0
- package/dist/src/project-graph/project-graph.js +3 -0
- package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.d.ts +10 -12
- package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.js +93 -63
- package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.d.ts +5 -8
- package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.js +11 -14
- package/dist/src/project-graph/utils/project-configuration/source-maps.d.ts +12 -5
- package/dist/src/project-graph/utils/project-configuration/source-maps.js +21 -7
- package/dist/src/project-graph/utils/project-configuration/target-defaults.d.ts +1 -1
- package/dist/src/project-graph/utils/project-configuration/target-defaults.js +26 -27
- package/dist/src/project-graph/utils/project-configuration/target-merging.js +50 -8
- package/dist/src/project-graph/utils/project-configuration/target-normalization.js +16 -3
- package/dist/src/project-graph/utils/project-configuration/utils.d.ts +15 -0
- package/dist/src/project-graph/utils/project-configuration/utils.js +42 -6
- package/dist/src/project-graph/utils/project-configuration-utils.d.ts +15 -12
- package/dist/src/project-graph/utils/project-configuration-utils.js +79 -101
- package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +11 -4
- package/dist/src/tasks-runner/life-cycles/performance-analysis.js +15 -6
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +5 -4
- package/dist/src/tasks-runner/life-cycles/performance-report.d.ts +18 -8
- package/dist/src/tasks-runner/life-cycles/performance-report.js +66 -29
- package/dist/src/tasks-runner/run-command.js +4 -2
- package/dist/src/tasks-runner/task-env.d.ts +9 -0
- package/dist/src/tasks-runner/task-env.js +26 -2
- package/dist/src/tasks-runner/task-orchestrator.d.ts +4 -1
- package/dist/src/tasks-runner/task-orchestrator.js +23 -10
- package/dist/src/utils/acknowledge-build-scripts.d.ts +13 -0
- package/dist/src/utils/acknowledge-build-scripts.js +102 -0
- package/dist/src/utils/analytics-prompt.d.ts +0 -6
- package/dist/src/utils/analytics-prompt.js +0 -51
- package/dist/src/utils/catalog/manager-utils.d.ts +1 -2
- package/dist/src/utils/catalog/manager-utils.js +22 -5
- package/dist/src/utils/catalog/pnpm-manager.d.ts +1 -0
- package/dist/src/utils/catalog/pnpm-manager.js +3 -15
- package/dist/src/utils/catalog/yarn-manager.d.ts +1 -0
- package/dist/src/utils/catalog/yarn-manager.js +3 -15
- package/dist/src/utils/command-line-utils.js +30 -20
- package/dist/src/utils/git-revision.d.ts +12 -0
- package/dist/src/utils/git-revision.js +25 -0
- package/dist/src/utils/git-utils.d.ts +16 -3
- package/dist/src/utils/git-utils.js +146 -52
- package/dist/src/utils/min-release-age/behavior/pnpm.js +9 -7
- package/dist/src/utils/package-json.js +11 -7
- package/dist/src/utils/package-manager.d.ts +3 -1
- package/dist/src/utils/package-manager.js +28 -4
- package/dist/src/utils/provenance.js +12 -2
- package/dist/src/utils/workspace-id.d.ts +20 -0
- package/dist/src/utils/workspace-id.js +54 -0
- package/migrations.json +7 -1
- package/package.json +22 -17
- package/dist/src/migrations/update-17-3-0/nx-release-path.d.ts +0 -3
- package/dist/src/migrations/update-17-3-0/nx-release-path.js +0 -47
|
@@ -20,4 +20,13 @@ export declare function getRootTsConfigCustomConditions(root?: string): string[]
|
|
|
20
20
|
* `migrate-development-custom-condition` (21.5).
|
|
21
21
|
*/
|
|
22
22
|
export declare function getRootTsConfigResolveExportsConditions(root?: string): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Node `--conditions <name>` CLI args for spawning a plugin worker or the daemon
|
|
25
|
+
* with the plugin-resolution conditions active at startup. Mirrors the set Nx
|
|
26
|
+
* uses to resolve the plugin entry (`getRootTsConfigResolveExportsConditions`)
|
|
27
|
+
* so the entry and the plugin's transitive workspace imports resolve the same
|
|
28
|
+
* way; Node's own resolver otherwise ignores TypeScript `customConditions` and a
|
|
29
|
+
* source-loaded plugin's imports land on their unbuilt `dist`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getPluginResolveConditionNodeArgs(root?: string): string[];
|
|
23
32
|
export declare function findNodes(node: Node, kind: SyntaxKind | SyntaxKind[], max?: number): Node[];
|
|
@@ -8,6 +8,7 @@ exports.getRootTsConfigFileName = getRootTsConfigFileName;
|
|
|
8
8
|
exports.getRootTsConfigPath = getRootTsConfigPath;
|
|
9
9
|
exports.getRootTsConfigCustomConditions = getRootTsConfigCustomConditions;
|
|
10
10
|
exports.getRootTsConfigResolveExportsConditions = getRootTsConfigResolveExportsConditions;
|
|
11
|
+
exports.getPluginResolveConditionNodeArgs = getPluginResolveConditionNodeArgs;
|
|
11
12
|
exports.findNodes = findNodes;
|
|
12
13
|
const workspace_root_1 = require("../../../utils/workspace-root");
|
|
13
14
|
const fs_1 = require("fs");
|
|
@@ -113,6 +114,20 @@ function getRootTsConfigResolveExportsConditions(root = workspace_root_1.workspa
|
|
|
113
114
|
? conditions
|
|
114
115
|
: [...conditions, 'development'];
|
|
115
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Node `--conditions <name>` CLI args for spawning a plugin worker or the daemon
|
|
119
|
+
* with the plugin-resolution conditions active at startup. Mirrors the set Nx
|
|
120
|
+
* uses to resolve the plugin entry (`getRootTsConfigResolveExportsConditions`)
|
|
121
|
+
* so the entry and the plugin's transitive workspace imports resolve the same
|
|
122
|
+
* way; Node's own resolver otherwise ignores TypeScript `customConditions` and a
|
|
123
|
+
* source-loaded plugin's imports land on their unbuilt `dist`.
|
|
124
|
+
*/
|
|
125
|
+
function getPluginResolveConditionNodeArgs(root = workspace_root_1.workspaceRoot) {
|
|
126
|
+
return getRootTsConfigResolveExportsConditions(root).flatMap((c) => [
|
|
127
|
+
'--conditions',
|
|
128
|
+
c,
|
|
129
|
+
]);
|
|
130
|
+
}
|
|
116
131
|
function findNodes(node, kind, max = Infinity) {
|
|
117
132
|
if (!node || max == 0) {
|
|
118
133
|
return [];
|
|
@@ -7,6 +7,7 @@ exports.applyProjectMetadata = applyProjectMetadata;
|
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const perf_hooks_1 = require("perf_hooks");
|
|
10
|
+
const analytics_1 = require("../analytics");
|
|
10
11
|
const configuration_1 = require("../config/configuration");
|
|
11
12
|
const file_hasher_1 = require("../hasher/file-hasher");
|
|
12
13
|
const typescript_1 = require("../plugins/js/utils/typescript");
|
|
@@ -222,7 +223,12 @@ async function updateProjectGraphWithPlugins(context, initProjectGraph, plugins,
|
|
|
222
223
|
perf_hooks_1.performance.measure(`${plugin.name}:createDependencies`, {
|
|
223
224
|
start: `${plugin.name}:createDependencies - start`,
|
|
224
225
|
end: `${plugin.name}:createDependencies - end`,
|
|
225
|
-
detail: {
|
|
226
|
+
detail: {
|
|
227
|
+
track: true,
|
|
228
|
+
...(analytics_1.customDimensions && {
|
|
229
|
+
[analytics_1.customDimensions.sampleRate]: analytics_1.PERF_SPAN_SAMPLE_RATE,
|
|
230
|
+
}),
|
|
231
|
+
},
|
|
226
232
|
});
|
|
227
233
|
}));
|
|
228
234
|
perf_hooks_1.performance.mark('createDependencies:end');
|
|
@@ -242,9 +242,48 @@ class AggregateCreateNodesError extends Error {
|
|
|
242
242
|
errorTuple.length === 2)) {
|
|
243
243
|
throw new Error('AggregateCreateNodesError must be constructed with an array of tuples where the first element is a filename or undefined and the second element is the underlying error.');
|
|
244
244
|
}
|
|
245
|
+
// Plugins pass through whatever value they caught, which is not
|
|
246
|
+
// guaranteed to be an Error. Coerce so formatting can rely on
|
|
247
|
+
// message and stack being present.
|
|
248
|
+
for (const errorTuple of errors) {
|
|
249
|
+
errorTuple[1] = coerceToError(errorTuple[1]);
|
|
250
|
+
}
|
|
245
251
|
}
|
|
246
252
|
}
|
|
247
253
|
exports.AggregateCreateNodesError = AggregateCreateNodesError;
|
|
254
|
+
function coerceToError(value) {
|
|
255
|
+
if (value instanceof Error) {
|
|
256
|
+
return value;
|
|
257
|
+
}
|
|
258
|
+
let message;
|
|
259
|
+
let stack;
|
|
260
|
+
if (typeof value === 'object' && value !== null) {
|
|
261
|
+
const candidate = value;
|
|
262
|
+
if (typeof candidate.message === 'string') {
|
|
263
|
+
message = candidate.message;
|
|
264
|
+
if (typeof candidate.stack === 'string') {
|
|
265
|
+
stack = candidate.stack;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
try {
|
|
270
|
+
message = JSON.stringify(value);
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// Circular structures cannot be stringified.
|
|
274
|
+
message = String(value);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
message = String(value);
|
|
280
|
+
}
|
|
281
|
+
const error = new Error(message);
|
|
282
|
+
// A synthesized stack would point at this coercion site rather than
|
|
283
|
+
// the original failure, so prefer the original stack or just the message.
|
|
284
|
+
error.stack = stack ?? message;
|
|
285
|
+
return error;
|
|
286
|
+
}
|
|
248
287
|
function formatAggregateCreateNodesError(error, pluginName) {
|
|
249
288
|
const errorCount = error.errors.length > 1 ? `${error.errors.length} errors` : 'An error';
|
|
250
289
|
const pluginLocation = error.pluginIndex
|
|
@@ -270,7 +309,8 @@ function formatAggregateCreateNodesError(error, pluginName) {
|
|
|
270
309
|
}
|
|
271
310
|
for (const e of errors) {
|
|
272
311
|
const messageLines = e.message.split('\n');
|
|
273
|
-
|
|
312
|
+
// Errors deserialized from a plugin worker may arrive without a stack.
|
|
313
|
+
const stackLines = (e.stack ?? e.message).split('\n');
|
|
274
314
|
if (file) {
|
|
275
315
|
errorBodyLines.push(...messageLines.map((line) => ` ${line}`));
|
|
276
316
|
errorStackLines.push(...stackLines.map((line) => ` ${line}`));
|
|
@@ -12,6 +12,7 @@ const fs_1 = require("fs");
|
|
|
12
12
|
const os_1 = require("os");
|
|
13
13
|
const path_1 = require("path");
|
|
14
14
|
const fileutils_1 = require("../utils/fileutils");
|
|
15
|
+
const git_revision_1 = require("../utils/git-revision");
|
|
15
16
|
const ignore_1 = require("../utils/ignore");
|
|
16
17
|
const json_diff_1 = require("../utils/json-diff");
|
|
17
18
|
const workspace_root_1 = require("../utils/workspace-root");
|
|
@@ -116,11 +117,14 @@ function readLockFileAtRevision(file, lockFileName, revision, readFileAtRevision
|
|
|
116
117
|
}
|
|
117
118
|
exports.TEN_MEGABYTES = 1024 * 10000;
|
|
118
119
|
function defaultReadFileAtRevision(file, revision) {
|
|
120
|
+
if (revision) {
|
|
121
|
+
(0, git_revision_1.assertValidGitRevision)(revision);
|
|
122
|
+
}
|
|
119
123
|
try {
|
|
120
124
|
const filePathInGitRepository = getFilePathInGitRepository(file);
|
|
121
125
|
return !revision
|
|
122
126
|
? (0, fs_1.readFileSync)(file, 'utf-8')
|
|
123
|
-
: (0, child_process_1.
|
|
127
|
+
: (0, child_process_1.execFileSync)('git', ['show', `${revision}:${filePathInGitRepository}`], {
|
|
124
128
|
maxBuffer: exports.TEN_MEGABYTES,
|
|
125
129
|
stdio: ['pipe', 'pipe', 'ignore'],
|
|
126
130
|
windowsHide: true,
|
|
@@ -140,6 +144,7 @@ function defaultReadBunLockFileAtRevision(file, revision) {
|
|
|
140
144
|
windowsHide: true,
|
|
141
145
|
}).trim();
|
|
142
146
|
}
|
|
147
|
+
(0, git_revision_1.assertValidGitRevision)(revision);
|
|
143
148
|
const filePathInGitRepository = getFilePathInGitRepository(file);
|
|
144
149
|
const tempDirectory = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'nx-bun-lock-'));
|
|
145
150
|
const tempLockfilePath = (0, path_1.join)(tempDirectory, 'bun.lockb');
|
|
@@ -7,6 +7,7 @@ const path = require("path");
|
|
|
7
7
|
const logger_1 = require("../../../daemon/logger");
|
|
8
8
|
const socket_utils_1 = require("../../../daemon/socket-utils");
|
|
9
9
|
const consume_messages_from_socket_1 = require("../../../utils/consume-messages-from-socket");
|
|
10
|
+
const typescript_1 = require("../../../plugins/js/utils/typescript");
|
|
10
11
|
const installation_directory_1 = require("../../../utils/installation-directory");
|
|
11
12
|
const logger_2 = require("../../../utils/logger");
|
|
12
13
|
const progress_topics_1 = require("../../../utils/progress-topics");
|
|
@@ -353,6 +354,9 @@ async function startPluginWorker(name) {
|
|
|
353
354
|
};
|
|
354
355
|
const ipcPath = (0, socket_utils_1.getPluginOsSocketPath)([process.pid, global.nxPluginWorkerCount++, performance.now()].join('-'));
|
|
355
356
|
const worker = (0, child_process_1.spawn)(process.execPath, [
|
|
357
|
+
// Spawn the worker with the same resolve conditions Nx uses for plugin
|
|
358
|
+
// entries so the plugin's transitive workspace imports resolve to source.
|
|
359
|
+
...(0, typescript_1.getPluginResolveConditionNodeArgs)(),
|
|
356
360
|
...(isWorkerTypescript ? ['--require', 'ts-node/register'] : []),
|
|
357
361
|
workerPath,
|
|
358
362
|
ipcPath,
|
|
@@ -25,6 +25,10 @@ function registerPluginTSTranspiler() {
|
|
|
25
25
|
if (exports.unregisterPluginTSTranspiler !== null) {
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
|
+
// Align Node's runtime resolution with the source-first plugin entry so the
|
|
29
|
+
// plugin's transitive workspace imports don't fall through to unbuilt `dist`.
|
|
30
|
+
// A no-op inside a plugin worker/daemon already spawned with `--conditions`.
|
|
31
|
+
(0, register_1.ensureResolveConditionsInjected)((0, typescript_1.getRootTsConfigResolveExportsConditions)(workspace_root_1.workspaceRoot));
|
|
28
32
|
if ((0, register_1.isNativeStripPreferred)()) {
|
|
29
33
|
// Native strip handles `.ts` syntax but doesn't rewrite NodeNext-style
|
|
30
34
|
// `.js` relative specifiers to their `.ts` sources. Patch the CJS resolver
|
|
@@ -244,6 +244,7 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
|
|
|
244
244
|
track: true,
|
|
245
245
|
...(analytics_1.customDimensions && {
|
|
246
246
|
[analytics_1.customDimensions.projectCount]: Object.keys(currentProjectGraph.nodes).length,
|
|
247
|
+
[analytics_1.customDimensions.sampleRate]: analytics_1.PERF_SPAN_SAMPLE_RATE,
|
|
247
248
|
}),
|
|
248
249
|
},
|
|
249
250
|
});
|
|
@@ -310,6 +311,7 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
|
|
|
310
311
|
...(analytics_1.customDimensions && {
|
|
311
312
|
[analytics_1.customDimensions.projectCount]: Object.keys(res.projectGraph.nodes)
|
|
312
313
|
.length,
|
|
314
|
+
[analytics_1.customDimensions.sampleRate]: analytics_1.PERF_SPAN_SAMPLE_RATE,
|
|
313
315
|
}),
|
|
314
316
|
},
|
|
315
317
|
});
|
|
@@ -333,6 +335,7 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
|
|
|
333
335
|
track: true,
|
|
334
336
|
...(analytics_1.customDimensions && {
|
|
335
337
|
[analytics_1.customDimensions.projectCount]: Object.keys(projectGraphAndSourceMaps.projectGraph.nodes).length,
|
|
338
|
+
[analytics_1.customDimensions.sampleRate]: analytics_1.PERF_SPAN_SAMPLE_RATE,
|
|
336
339
|
}),
|
|
337
340
|
},
|
|
338
341
|
});
|
|
@@ -4,16 +4,13 @@ import { ProjectConfiguration } from '../../../config/workspace-json-project-jso
|
|
|
4
4
|
* reference. `RootRef` carries the referenced project's root (resolved
|
|
5
5
|
* via nameMap lookup); `UsageRef` carries the raw written name (for
|
|
6
6
|
* forward refs, promoted to `RootRef` in place when the name is
|
|
7
|
-
* identified). `
|
|
8
|
-
* name back; `targetPart` preserves the `:target` suffix from
|
|
7
|
+
* identified). `targetPart` preserves the `:target` suffix from
|
|
9
8
|
* `dependsOn` strings.
|
|
10
9
|
*/
|
|
11
10
|
export declare abstract class NameRef {
|
|
12
11
|
value: string;
|
|
13
|
-
parent: unknown;
|
|
14
|
-
key: string | undefined;
|
|
15
12
|
targetPart: string | undefined;
|
|
16
|
-
constructor(value: string,
|
|
13
|
+
constructor(value: string, targetPart: string | undefined);
|
|
17
14
|
}
|
|
18
15
|
export declare class RootRef extends NameRef {
|
|
19
16
|
}
|
|
@@ -27,16 +24,17 @@ export declare function isUsageRef(value: unknown): value is UsageRef;
|
|
|
27
24
|
* then resolves them after all merging is done.
|
|
28
25
|
*
|
|
29
26
|
* Tracking by array position breaks once `'...'` spreads shuffle indices,
|
|
30
|
-
* so each ref becomes a sentinel object.
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
27
|
+
* so each ref becomes a sentinel object. Merges copy sentinels by
|
|
28
|
+
* reference — one sentinel can end up in many arrays (e.g. a pattern
|
|
29
|
+
* target's dependsOn applied to every matching target) — so the final
|
|
30
|
+
* pass sweeps the merged rootMap and resolves every sentinel where it
|
|
31
|
+
* actually sits. Sentinels in arrays dropped by a full-replace are never
|
|
32
|
+
* visited and vanish with their array.
|
|
35
33
|
*/
|
|
36
34
|
export declare class ProjectNameInNodePropsManager {
|
|
37
35
|
private getNameMap;
|
|
38
|
-
private allRefs;
|
|
39
36
|
private pendingByName;
|
|
37
|
+
private nameHistory;
|
|
40
38
|
constructor(getNameMap?: () => Record<string, ProjectConfiguration>);
|
|
41
39
|
registerNameRefs(pluginResultProjects?: Record<string, Omit<ProjectConfiguration, 'root'> & Partial<ProjectConfiguration>>): void;
|
|
42
40
|
private processInputs;
|
|
@@ -45,6 +43,6 @@ export declare class ProjectNameInNodePropsManager {
|
|
|
45
43
|
private createRef;
|
|
46
44
|
identifyProjectWithRoot(root: string, name: string): void;
|
|
47
45
|
applySubstitutions(rootMap: Record<string, ProjectConfiguration>): void;
|
|
46
|
+
private substituteInArray;
|
|
48
47
|
private resolveFinalName;
|
|
49
|
-
private writeReplacement;
|
|
50
48
|
}
|
|
@@ -11,15 +11,12 @@ const split_target_1 = require("../../../utils/split-target");
|
|
|
11
11
|
* reference. `RootRef` carries the referenced project's root (resolved
|
|
12
12
|
* via nameMap lookup); `UsageRef` carries the raw written name (for
|
|
13
13
|
* forward refs, promoted to `RootRef` in place when the name is
|
|
14
|
-
* identified). `
|
|
15
|
-
* name back; `targetPart` preserves the `:target` suffix from
|
|
14
|
+
* identified). `targetPart` preserves the `:target` suffix from
|
|
16
15
|
* `dependsOn` strings.
|
|
17
16
|
*/
|
|
18
17
|
class NameRef {
|
|
19
|
-
constructor(value,
|
|
18
|
+
constructor(value, targetPart) {
|
|
20
19
|
this.value = value;
|
|
21
|
-
this.parent = parent;
|
|
22
|
-
this.key = key;
|
|
23
20
|
this.targetPart = targetPart;
|
|
24
21
|
}
|
|
25
22
|
}
|
|
@@ -44,16 +41,19 @@ function isUsageRef(value) {
|
|
|
44
41
|
* then resolves them after all merging is done.
|
|
45
42
|
*
|
|
46
43
|
* Tracking by array position breaks once `'...'` spreads shuffle indices,
|
|
47
|
-
* so each ref becomes a sentinel object.
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
44
|
+
* so each ref becomes a sentinel object. Merges copy sentinels by
|
|
45
|
+
* reference — one sentinel can end up in many arrays (e.g. a pattern
|
|
46
|
+
* target's dependsOn applied to every matching target) — so the final
|
|
47
|
+
* pass sweeps the merged rootMap and resolves every sentinel where it
|
|
48
|
+
* actually sits. Sentinels in arrays dropped by a full-replace are never
|
|
49
|
+
* visited and vanish with their array.
|
|
52
50
|
*/
|
|
53
51
|
class ProjectNameInNodePropsManager {
|
|
54
52
|
constructor(getNameMap) {
|
|
55
|
-
this.allRefs = new Set();
|
|
56
53
|
this.pendingByName = new Map();
|
|
54
|
+
// name → root for every name a project has ever been identified by, so refs
|
|
55
|
+
// to a since-renamed name still bind to the right root (see createRef).
|
|
56
|
+
this.nameHistory = new Map();
|
|
57
57
|
this.getNameMap = getNameMap ?? (() => ({}));
|
|
58
58
|
}
|
|
59
59
|
// Replaces each project-name ref in `inputs`/`dependsOn` with a sentinel.
|
|
@@ -82,26 +82,20 @@ class ProjectNameInNodePropsManager {
|
|
|
82
82
|
processInputs(inputs) {
|
|
83
83
|
for (let i = 0; i < inputs.length; i++) {
|
|
84
84
|
const entry = inputs[i];
|
|
85
|
-
|
|
86
|
-
// original array, so rebind parent to this one.
|
|
87
|
-
if (isNameRef(entry)) {
|
|
88
|
-
entry.parent = inputs;
|
|
85
|
+
if (isNameRef(entry))
|
|
89
86
|
continue;
|
|
90
|
-
}
|
|
91
87
|
if (!entry || typeof entry !== 'object')
|
|
92
88
|
continue;
|
|
93
89
|
if (!('projects' in entry))
|
|
94
90
|
continue;
|
|
95
91
|
const element = entry;
|
|
96
92
|
const projects = element.projects;
|
|
97
|
-
if (isNameRef(projects))
|
|
98
|
-
// Object-parent sentinel — element identity is stable across spread.
|
|
93
|
+
if (isNameRef(projects))
|
|
99
94
|
continue;
|
|
100
|
-
}
|
|
101
95
|
if (typeof projects === 'string') {
|
|
102
96
|
if (projects === 'self' || projects === 'dependencies')
|
|
103
97
|
continue;
|
|
104
|
-
element.projects = this.createRef(projects
|
|
98
|
+
element.projects = this.createRef(projects);
|
|
105
99
|
}
|
|
106
100
|
else if (Array.isArray(projects)) {
|
|
107
101
|
this.processProjectsArray(projects);
|
|
@@ -111,12 +105,8 @@ class ProjectNameInNodePropsManager {
|
|
|
111
105
|
processDependsOn(dependsOn, ownerTargets, ownerName) {
|
|
112
106
|
for (let i = 0; i < dependsOn.length; i++) {
|
|
113
107
|
const dep = dependsOn[i];
|
|
114
|
-
|
|
115
|
-
// merge copied it out of its original.
|
|
116
|
-
if (isNameRef(dep)) {
|
|
117
|
-
dep.parent = dependsOn;
|
|
108
|
+
if (isNameRef(dep))
|
|
118
109
|
continue;
|
|
119
|
-
}
|
|
120
110
|
if (typeof dep === 'string') {
|
|
121
111
|
// `^target` and same-project targets aren't cross-project refs.
|
|
122
112
|
if (dep.startsWith('^') || (ownerTargets && dep in ownerTargets)) {
|
|
@@ -126,7 +116,7 @@ class ProjectNameInNodePropsManager {
|
|
|
126
116
|
if (rest.length === 0)
|
|
127
117
|
continue;
|
|
128
118
|
const targetPart = rest.join(':');
|
|
129
|
-
dependsOn[i] = this.createRef(maybeProject,
|
|
119
|
+
dependsOn[i] = this.createRef(maybeProject, targetPart);
|
|
130
120
|
continue;
|
|
131
121
|
}
|
|
132
122
|
if (!dep || typeof dep !== 'object' || !('projects' in dep))
|
|
@@ -142,7 +132,7 @@ class ProjectNameInNodePropsManager {
|
|
|
142
132
|
projects === 'dependencies') {
|
|
143
133
|
continue;
|
|
144
134
|
}
|
|
145
|
-
element.projects = this.createRef(projects
|
|
135
|
+
element.projects = this.createRef(projects);
|
|
146
136
|
}
|
|
147
137
|
else if (Array.isArray(projects)) {
|
|
148
138
|
this.processProjectsArray(projects);
|
|
@@ -152,24 +142,26 @@ class ProjectNameInNodePropsManager {
|
|
|
152
142
|
processProjectsArray(projects) {
|
|
153
143
|
for (let j = 0; j < projects.length; j++) {
|
|
154
144
|
const name = projects[j];
|
|
155
|
-
if (isNameRef(name))
|
|
156
|
-
name.parent = projects;
|
|
145
|
+
if (isNameRef(name))
|
|
157
146
|
continue;
|
|
158
|
-
}
|
|
159
147
|
if (typeof name !== 'string')
|
|
160
148
|
continue;
|
|
161
149
|
if ((0, globs_1.isGlobPattern)(name))
|
|
162
150
|
continue;
|
|
163
|
-
projects[j] = this.createRef(name
|
|
151
|
+
projects[j] = this.createRef(name);
|
|
164
152
|
}
|
|
165
153
|
}
|
|
166
|
-
// Builds a sentinel and registers it.
|
|
167
|
-
|
|
168
|
-
|
|
154
|
+
// Builds a sentinel and registers it. When `referencedName` isn't in the
|
|
155
|
+
// current name map, fall back to the rename history: a batch may reference a
|
|
156
|
+
// project by a name that a project earlier in the same batch already renamed
|
|
157
|
+
// (refs register after the whole batch merges), and the old name still
|
|
158
|
+
// identifies the same root.
|
|
159
|
+
createRef(referencedName, targetPart) {
|
|
160
|
+
const referencedRoot = this.getNameMap()[referencedName]?.root ??
|
|
161
|
+
this.nameHistory.get(referencedName);
|
|
169
162
|
const ref = referencedRoot !== undefined
|
|
170
|
-
? new RootRef(referencedRoot,
|
|
171
|
-
: new UsageRef(referencedName,
|
|
172
|
-
this.allRefs.add(ref);
|
|
163
|
+
? new RootRef(referencedRoot, targetPart)
|
|
164
|
+
: new UsageRef(referencedName, targetPart);
|
|
173
165
|
if (ref instanceof UsageRef) {
|
|
174
166
|
let set = this.pendingByName.get(referencedName);
|
|
175
167
|
if (!set) {
|
|
@@ -184,6 +176,11 @@ class ProjectNameInNodePropsManager {
|
|
|
184
176
|
// RootRef by prototype swap. Sentinel identity across spread copies means
|
|
185
177
|
// one promotion updates every array the sentinel reached.
|
|
186
178
|
identifyProjectWithRoot(root, name) {
|
|
179
|
+
// Every name a root has ever gone by, including pre-rename names. A later
|
|
180
|
+
// ref to a stale name resolves to the root it identified at the time.
|
|
181
|
+
// (If two roots use the same name over a graph construction, the later
|
|
182
|
+
// one wins — matching how the live name map would have resolved it.)
|
|
183
|
+
this.nameHistory.set(name, root);
|
|
187
184
|
const pending = this.pendingByName.get(name);
|
|
188
185
|
if (!pending)
|
|
189
186
|
return;
|
|
@@ -195,24 +192,72 @@ class ProjectNameInNodePropsManager {
|
|
|
195
192
|
ref.value = root;
|
|
196
193
|
}
|
|
197
194
|
}
|
|
198
|
-
//
|
|
199
|
-
//
|
|
195
|
+
// Resolves every sentinel in the merged rootMap in place. Sweeping the
|
|
196
|
+
// final config (rather than writing through back-references held by the
|
|
197
|
+
// sentinels) covers sentinels that merges copied into arrays other than
|
|
198
|
+
// the one they were created in, e.g. a pattern target's dependsOn applied
|
|
199
|
+
// to every matching target. Called once after all plugin results have
|
|
200
|
+
// been merged.
|
|
200
201
|
applySubstitutions(rootMap) {
|
|
201
202
|
const nameByRoot = {};
|
|
202
203
|
for (const root in rootMap) {
|
|
203
204
|
nameByRoot[root] = rootMap[root]?.name;
|
|
204
205
|
}
|
|
205
|
-
for (const
|
|
206
|
-
const
|
|
207
|
-
if (
|
|
208
|
-
continue;
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
206
|
+
for (const root in rootMap) {
|
|
207
|
+
const targets = rootMap[root]?.targets;
|
|
208
|
+
if (!targets)
|
|
209
|
+
continue;
|
|
210
|
+
for (const targetName in targets) {
|
|
211
|
+
const targetConfig = targets[targetName];
|
|
212
|
+
if (!targetConfig || typeof targetConfig !== 'object')
|
|
213
|
+
continue;
|
|
214
|
+
if (Array.isArray(targetConfig.inputs)) {
|
|
215
|
+
this.substituteInArray(targetConfig.inputs, nameByRoot);
|
|
216
|
+
}
|
|
217
|
+
if (Array.isArray(targetConfig.dependsOn)) {
|
|
218
|
+
this.substituteInArray(targetConfig.dependsOn, nameByRoot);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
213
221
|
}
|
|
214
|
-
this.allRefs.clear();
|
|
215
222
|
this.pendingByName.clear();
|
|
223
|
+
this.nameHistory.clear();
|
|
224
|
+
}
|
|
225
|
+
substituteInArray(entries, nameByRoot) {
|
|
226
|
+
for (let i = 0; i < entries.length; i++) {
|
|
227
|
+
const entry = entries[i];
|
|
228
|
+
if (isNameRef(entry)) {
|
|
229
|
+
const finalName = this.resolveFinalName(entry, nameByRoot);
|
|
230
|
+
if (finalName !== undefined) {
|
|
231
|
+
entries[i] =
|
|
232
|
+
entry.targetPart !== undefined
|
|
233
|
+
? `${finalName}:${entry.targetPart}`
|
|
234
|
+
: finalName;
|
|
235
|
+
}
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
if (!entry || typeof entry !== 'object' || !('projects' in entry)) {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
const element = entry;
|
|
242
|
+
if (isNameRef(element.projects)) {
|
|
243
|
+
const finalName = this.resolveFinalName(element.projects, nameByRoot);
|
|
244
|
+
if (finalName !== undefined) {
|
|
245
|
+
element.projects = finalName;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else if (Array.isArray(element.projects)) {
|
|
249
|
+
const projects = element.projects;
|
|
250
|
+
for (let j = 0; j < projects.length; j++) {
|
|
251
|
+
const name = projects[j];
|
|
252
|
+
if (!isNameRef(name))
|
|
253
|
+
continue;
|
|
254
|
+
const finalName = this.resolveFinalName(name, nameByRoot);
|
|
255
|
+
if (finalName !== undefined) {
|
|
256
|
+
projects[j] = finalName;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
216
261
|
}
|
|
217
262
|
resolveFinalName(ref, nameByRoot) {
|
|
218
263
|
if (ref instanceof RootRef) {
|
|
@@ -221,20 +266,5 @@ class ProjectNameInNodePropsManager {
|
|
|
221
266
|
// Unpromoted forward ref — best effort, fall back to the written name.
|
|
222
267
|
return this.getNameMap()[ref.value]?.name ?? ref.value;
|
|
223
268
|
}
|
|
224
|
-
writeReplacement(ref, replacement) {
|
|
225
|
-
const parent = ref.parent;
|
|
226
|
-
if (Array.isArray(parent)) {
|
|
227
|
-
// One sentinel may appear at multiple indices (e.g. `[..., ...]`
|
|
228
|
-
// pushed the same reference twice via spread), so replace all.
|
|
229
|
-
for (let i = 0; i < parent.length; i++) {
|
|
230
|
-
if (parent[i] === ref)
|
|
231
|
-
parent[i] = replacement;
|
|
232
|
-
}
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
if (parent && typeof parent === 'object' && ref.key !== undefined) {
|
|
236
|
-
parent[ref.key] = replacement;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
269
|
}
|
|
240
270
|
exports.ProjectNameInNodePropsManager = ProjectNameInNodePropsManager;
|
|
@@ -28,15 +28,12 @@ export declare class ProjectNodesManager {
|
|
|
28
28
|
mergeProjectNode(project: ProjectConfiguration, configurationSourceMaps?: ConfigurationSourceMaps, sourceInformation?: SourceInformation): void;
|
|
29
29
|
/**
|
|
30
30
|
* Inserts project-name sentinels into `inputs` and `dependsOn` on the
|
|
31
|
-
* merged objects
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* Pass a different `mergedRootMap` for the default-plugin intermediate
|
|
36
|
-
* pass, then call again with `this.rootMap` after it's applied so
|
|
37
|
-
* sentinel parents rebind onto the final arrays.
|
|
31
|
+
* merged objects in this manager's rootMap. Walking the merged entries —
|
|
32
|
+
* not the plugin results — matters because a spread-produced array is a
|
|
33
|
+
* fresh instance, and because sentinels written into plugin-result arrays
|
|
34
|
+
* would corrupt them for any later merge that re-reads the results.
|
|
38
35
|
*/
|
|
39
|
-
registerNameRefs(pluginResultProjects?: Record<string, Omit<ProjectConfiguration, 'root'> & Partial<ProjectConfiguration
|
|
36
|
+
registerNameRefs(pluginResultProjects?: Record<string, Omit<ProjectConfiguration, 'root'> & Partial<ProjectConfiguration>>): void;
|
|
40
37
|
/**
|
|
41
38
|
* Applies all pending name substitutions. Call once after all plugin
|
|
42
39
|
* results have been merged.
|
|
@@ -129,10 +129,10 @@ deferSpreadsWithoutBase = true) {
|
|
|
129
129
|
// if augmenting an existing target.
|
|
130
130
|
const target = project.targets?.[targetName];
|
|
131
131
|
if (sourceMap) {
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
132
|
+
// Claims the node key for a newly-created target (or reclaims it from
|
|
133
|
+
// a weak target-defaults stamp). Whether an *existing* target changes
|
|
134
|
+
// owners is decided inside `mergeTargetConfigurations`, which knows
|
|
135
|
+
// whether this merge changed the target's identity.
|
|
136
136
|
(0, source_maps_1.recordTargetIdentitySourceMapInfo)(sourceMap, (0, source_maps_1.targetSourceMapKey)(targetName), sourceInformation);
|
|
137
137
|
}
|
|
138
138
|
const normalizedTarget = skipTargetNormalization
|
|
@@ -257,21 +257,18 @@ class ProjectNodesManager {
|
|
|
257
257
|
}
|
|
258
258
|
/**
|
|
259
259
|
* Inserts project-name sentinels into `inputs` and `dependsOn` on the
|
|
260
|
-
* merged objects
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
* Pass a different `mergedRootMap` for the default-plugin intermediate
|
|
265
|
-
* pass, then call again with `this.rootMap` after it's applied so
|
|
266
|
-
* sentinel parents rebind onto the final arrays.
|
|
260
|
+
* merged objects in this manager's rootMap. Walking the merged entries —
|
|
261
|
+
* not the plugin results — matters because a spread-produced array is a
|
|
262
|
+
* fresh instance, and because sentinels written into plugin-result arrays
|
|
263
|
+
* would corrupt them for any later merge that re-reads the results.
|
|
267
264
|
*/
|
|
268
|
-
registerNameRefs(pluginResultProjects
|
|
265
|
+
registerNameRefs(pluginResultProjects) {
|
|
269
266
|
if (!pluginResultProjects)
|
|
270
267
|
return;
|
|
271
268
|
const scoped = {};
|
|
272
269
|
for (const root in pluginResultProjects) {
|
|
273
|
-
if (
|
|
274
|
-
scoped[root] =
|
|
270
|
+
if (this.rootMap[root]) {
|
|
271
|
+
scoped[root] = this.rootMap[root];
|
|
275
272
|
}
|
|
276
273
|
}
|
|
277
274
|
this.nameSubstitutionManager.registerNameRefs(scoped);
|
|
@@ -9,12 +9,19 @@ export type SourceInformation = [file: string | null, plugin: string];
|
|
|
9
9
|
*/
|
|
10
10
|
export declare const TARGET_DEFAULTS_PLUGIN_NAME = "nx/target-defaults";
|
|
11
11
|
/**
|
|
12
|
-
* Write the source for
|
|
13
|
-
* its
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* Write the source for the target node key (`targets.<name>`). Ownership of a
|
|
13
|
+
* target follows its identity, not the last writer:
|
|
14
|
+
*
|
|
15
|
+
* - An unowned key goes to whoever writes it first (the creator).
|
|
16
|
+
* - A target-defaults stamp is weak — it never authors a target's existence,
|
|
17
|
+
* so any real plugin reclaims the key from it, and it can never take the
|
|
18
|
+
* key from a real plugin.
|
|
19
|
+
* - Between real plugins, the key only changes hands when the merge changed
|
|
20
|
+
* the target's identity (executor/command) — a plugin that merely layers
|
|
21
|
+
* fields (dependsOn, options, …) onto an existing target does not become
|
|
22
|
+
* its owner.
|
|
16
23
|
*/
|
|
17
|
-
export declare function recordTargetIdentitySourceMapInfo(sourceMap: Record<string, SourceInformation>, key: string, sourceInfo: SourceInformation): void;
|
|
24
|
+
export declare function recordTargetIdentitySourceMapInfo(sourceMap: Record<string, SourceInformation>, key: string, sourceInfo: SourceInformation, identityChanged?: boolean): void;
|
|
18
25
|
/** Source map per project root. */
|
|
19
26
|
export type ConfigurationSourceMaps = Record<string, Record<string, SourceInformation>>;
|
|
20
27
|
export declare function forEachSourceMapKeyForArray(prefixKey: string, array: unknown[], callback: (key: string, index: number) => void, startIndex?: number): void;
|