nx 23.0.0 → 23.0.2
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/README.md +1 -2
- package/dist/bin/init-local.js +1 -1
- package/dist/release/changelog-renderer/index.d.ts +1 -0
- package/dist/release/changelog-renderer/index.js +27 -12
- package/dist/src/command-line/init/implementation/dot-nx/add-nx-scripts.d.ts +1 -0
- package/dist/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +6 -1
- package/dist/src/command-line/init/init-v2.js +1 -1
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +3 -2
- package/dist/src/command-line/migrate/migrate.d.ts +2 -0
- package/dist/src/command-line/migrate/migrate.js +34 -7
- package/dist/src/command-line/migrate/resolve-package-version.js +3 -25
- package/dist/src/command-line/migrate/update-filters.js +2 -1
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.d.ts +1 -1
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +37 -20
- package/dist/src/command-line/release/version/resolve-current-version.js +4 -1
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/daemon/server/project-graph-incremental-recomputation.js +30 -11
- 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/bun-parser.js +61 -38
- package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +1 -3
- package/dist/src/plugins/js/package-json/create-package-json.js +22 -1
- package/dist/src/plugins/js/project-graph/affected/tsconfig-json-changes.js +1 -1
- package/dist/src/plugins/js/project-graph/build-dependencies/target-project-locator.d.ts +7 -0
- package/dist/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +26 -1
- package/dist/src/plugins/js/utils/register.d.ts +31 -10
- package/dist/src/plugins/js/utils/register.js +87 -18
- package/dist/src/plugins/package-json/create-nodes.js +5 -3
- package/dist/src/project-graph/operators.d.ts +0 -1
- package/dist/src/project-graph/operators.js +0 -44
- package/dist/src/project-graph/project-graph-builder.js +26 -10
- package/dist/src/project-graph/utils/project-configuration/target-defaults.js +23 -6
- package/dist/src/project-graph/utils/project-configuration-utils.js +28 -28
- package/dist/src/tasks-runner/batch/run-batch.js +3 -0
- package/dist/src/tasks-runner/cache.js +6 -0
- package/dist/src/tasks-runner/pseudo-terminal.d.ts +1 -0
- package/dist/src/tasks-runner/pseudo-terminal.js +18 -4
- package/dist/src/tasks-runner/run-command.js +24 -8
- package/dist/src/tasks-runner/utils.d.ts +1 -0
- package/dist/src/tasks-runner/utils.js +4 -0
- package/dist/src/utils/ab-testing.d.ts +9 -0
- package/dist/src/utils/ab-testing.js +18 -4
- package/dist/src/utils/catalog/index.d.ts +7 -0
- package/dist/src/utils/catalog/index.js +31 -0
- package/dist/src/utils/catalog/manager-utils.d.ts +9 -0
- package/dist/src/utils/catalog/manager-utils.js +215 -0
- package/dist/src/utils/catalog/pnpm-manager.js +4 -102
- package/dist/src/utils/catalog/yarn-manager.js +4 -102
- package/dist/src/utils/is-sandbox.js +2 -0
- package/dist/src/utils/min-release-age/behavior/pnpm.d.ts +6 -5
- package/dist/src/utils/min-release-age/behavior/pnpm.js +87 -339
- package/dist/src/utils/package-json.d.ts +1 -0
- package/dist/src/utils/package-manager.d.ts +6 -3
- package/dist/src/utils/package-manager.js +21 -7
- package/dist/src/utils/spinner.d.ts +13 -1
- package/dist/src/utils/spinner.js +20 -4
- package/dist/src/utils/terminal-link.d.ts +16 -0
- package/dist/src/utils/terminal-link.js +87 -0
- package/package.json +19 -15
|
@@ -208,7 +208,6 @@ class ProjectGraphBuilder {
|
|
|
208
208
|
if (!this.graph.dependencies[source]) {
|
|
209
209
|
this.graph.dependencies[source] = [];
|
|
210
210
|
}
|
|
211
|
-
const isDuplicate = !!this.graph.dependencies[source].find((d) => d.target === target && d.type === type);
|
|
212
211
|
if (sourceFile) {
|
|
213
212
|
let fileData = getProjectFileData(source, sourceFile, this.projectFileMap);
|
|
214
213
|
const isProjectFileData = !!fileData;
|
|
@@ -225,14 +224,17 @@ class ProjectGraphBuilder {
|
|
|
225
224
|
fileData.deps.push(dep);
|
|
226
225
|
}
|
|
227
226
|
}
|
|
228
|
-
else
|
|
227
|
+
else {
|
|
229
228
|
// only add to dependencies section if the source file is not specified
|
|
230
229
|
// and not already added
|
|
231
|
-
this.graph.dependencies[source].
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
230
|
+
const isDuplicate = !!this.graph.dependencies[source].find((d) => d.target === target && d.type === type);
|
|
231
|
+
if (!isDuplicate) {
|
|
232
|
+
this.graph.dependencies[source].push({
|
|
233
|
+
source: source,
|
|
234
|
+
target: target,
|
|
235
|
+
type,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
236
238
|
}
|
|
237
239
|
}
|
|
238
240
|
removeDependenciesWithNode(name) {
|
|
@@ -355,11 +357,25 @@ function validateStaticDependency(d, { projects }) {
|
|
|
355
357
|
throw new Error(`Source project file is required`);
|
|
356
358
|
}
|
|
357
359
|
}
|
|
360
|
+
// Per-project file-name -> FileData index, keyed by the fileMap object so the
|
|
361
|
+
// linear scan (once per source project's file list) is paid once instead of on
|
|
362
|
+
// every addDependency/validateDependency call. Cached against the source's file
|
|
363
|
+
// array reference: a fresh array (new build, or reuse with a swapped list)
|
|
364
|
+
// rebuilds the index.
|
|
365
|
+
const projectFileDataIndex = new WeakMap();
|
|
358
366
|
function getProjectFileData(source, sourceFile, fileMap) {
|
|
359
|
-
let
|
|
360
|
-
if (
|
|
361
|
-
|
|
367
|
+
let byProject = projectFileDataIndex.get(fileMap);
|
|
368
|
+
if (!byProject) {
|
|
369
|
+
byProject = new Map();
|
|
370
|
+
projectFileDataIndex.set(fileMap, byProject);
|
|
371
|
+
}
|
|
372
|
+
const files = fileMap[source] || [];
|
|
373
|
+
let entry = byProject.get(source);
|
|
374
|
+
if (!entry || entry.files !== files) {
|
|
375
|
+
entry = { files, byFile: new Map(files.map((f) => [f.file, f])) };
|
|
376
|
+
byProject.set(source, entry);
|
|
362
377
|
}
|
|
378
|
+
return entry.byFile.get(sourceFile);
|
|
363
379
|
}
|
|
364
380
|
function getNonProjectFileData(sourceFile, files) {
|
|
365
381
|
const fileData = files.find((f) => f.file === sourceFile);
|
|
@@ -91,15 +91,32 @@ function buildSyntheticTargetForRoot(targetName, root, specifiedTarget, defaultT
|
|
|
91
91
|
// matching the default plugin's executor are useful.
|
|
92
92
|
const targetDefaults = readAndPrepareTargetDefaults(targetName, resolvedDefault.executor, root, targetDefaultsConfig);
|
|
93
93
|
if (targetDefaults && (0, target_merging_1.isCompatibleTarget)(resolvedDefault, targetDefaults)) {
|
|
94
|
-
// Stamp
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
command: resolvedDefault.command,
|
|
99
|
-
};
|
|
94
|
+
// Stamp the default's identity so the default layer merges cleanly on top.
|
|
95
|
+
const synthetic = { ...targetDefaults };
|
|
96
|
+
stampTargetIdentity(synthetic, resolvedDefault);
|
|
97
|
+
return synthetic;
|
|
100
98
|
}
|
|
101
99
|
return undefined;
|
|
102
100
|
}
|
|
101
|
+
// Copies `source`'s identity (executor, command, and — for run-commands — its
|
|
102
|
+
// options.command/commands) onto `target` so the two compare compatible and
|
|
103
|
+
// the synthetic isn't dropped when the default replaces the specified target
|
|
104
|
+
// downstream (#36067). run-commands compatibility keys off
|
|
105
|
+
// options.command/commands, not the top-level command, so both are carried.
|
|
106
|
+
function stampTargetIdentity(target, source) {
|
|
107
|
+
target.executor = source.executor;
|
|
108
|
+
target.command = source.command;
|
|
109
|
+
if (source.executor !== 'nx:run-commands')
|
|
110
|
+
return;
|
|
111
|
+
const { command, commands } = source.options ?? {};
|
|
112
|
+
if (command === undefined && commands === undefined)
|
|
113
|
+
return;
|
|
114
|
+
target.options = {
|
|
115
|
+
...target.options,
|
|
116
|
+
...(command !== undefined ? { command } : {}),
|
|
117
|
+
...(commands !== undefined ? { commands } : {}),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
103
120
|
function readAndPrepareTargetDefaults(targetName, executor, root, targetDefaultsConfig) {
|
|
104
121
|
const rawTargetDefaults = readTargetDefaultsForTarget(targetName, targetDefaultsConfig, executor);
|
|
105
122
|
if (!rawTargetDefaults)
|
|
@@ -267,31 +267,9 @@ function mergeCreateNodesResults(specifiedResults, defaultResults, nxJsonConfigu
|
|
|
267
267
|
return { projectRootMap, externalNodes, rootMap, configurationSourceMaps };
|
|
268
268
|
}
|
|
269
269
|
/**
|
|
270
|
-
*
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
return patterns.some((pattern) => (0, minimatch_1.minimatch)(file, pattern, { dot: true }));
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Full matcher for patterns with negations - processes all patterns sequentially.
|
|
277
|
-
* Patterns starting with '!' are negation patterns that remove files from the match set.
|
|
278
|
-
* Patterns are processed in order, with later patterns overriding earlier ones.
|
|
279
|
-
*/
|
|
280
|
-
function matchesNegationPatterns(file, patterns) {
|
|
281
|
-
// If first pattern is negation, start by matching everything
|
|
282
|
-
let isMatch = patterns[0].startsWith('!');
|
|
283
|
-
for (const pattern of patterns) {
|
|
284
|
-
const isNegation = pattern.startsWith('!');
|
|
285
|
-
const actualPattern = isNegation ? pattern.substring(1) : pattern;
|
|
286
|
-
if ((0, minimatch_1.minimatch)(file, actualPattern, { dot: true })) {
|
|
287
|
-
// Last matching pattern wins
|
|
288
|
-
isMatch = !isNegation;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return isMatch;
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Creates a matcher function for the given patterns.
|
|
270
|
+
* Creates a matcher function for the given patterns. Globs are compiled once
|
|
271
|
+
* here so matching a file list only runs the pre-parsed regex per file, instead
|
|
272
|
+
* of recompiling every pattern on each call.
|
|
295
273
|
* @param patterns Array of glob patterns (can include negation patterns starting with '!')
|
|
296
274
|
* @param emptyValue Value to return when patterns array is empty
|
|
297
275
|
* @returns A function that checks if a file matches the patterns
|
|
@@ -301,9 +279,31 @@ function createMatcher(patterns, emptyValue) {
|
|
|
301
279
|
return () => emptyValue;
|
|
302
280
|
}
|
|
303
281
|
const hasNegationPattern = patterns.some((p) => p.startsWith('!'));
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
282
|
+
if (hasNegationPattern) {
|
|
283
|
+
// Patterns are processed in order, with later matches overriding earlier
|
|
284
|
+
// ones; a leading negation starts from "matches everything".
|
|
285
|
+
const compiled = patterns.map((pattern) => {
|
|
286
|
+
const isNegation = pattern.startsWith('!');
|
|
287
|
+
return {
|
|
288
|
+
isNegation,
|
|
289
|
+
matcher: new minimatch_1.Minimatch(isNegation ? pattern.substring(1) : pattern, {
|
|
290
|
+
dot: true,
|
|
291
|
+
}),
|
|
292
|
+
};
|
|
293
|
+
});
|
|
294
|
+
const initialMatch = patterns[0].startsWith('!');
|
|
295
|
+
return (file) => {
|
|
296
|
+
let isMatch = initialMatch;
|
|
297
|
+
for (const { isNegation, matcher } of compiled) {
|
|
298
|
+
if (matcher.match(file)) {
|
|
299
|
+
isMatch = !isNegation;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return isMatch;
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
const compiled = patterns.map((p) => new minimatch_1.Minimatch(p, { dot: true }));
|
|
306
|
+
return (file) => compiled.some((m) => m.match(file));
|
|
307
307
|
}
|
|
308
308
|
function findMatchingConfigFiles(projectFiles, include, exclude) {
|
|
309
309
|
// projectFiles already comes from multiGlobWithWorkspaceContext for the
|
|
@@ -7,6 +7,9 @@ const project_graph_1 = require("../../project-graph/project-graph");
|
|
|
7
7
|
const configuration_1 = require("../../config/configuration");
|
|
8
8
|
const async_iterator_1 = require("../../utils/async-iterator");
|
|
9
9
|
const executor_utils_1 = require("../../command-line/run/executor-utils");
|
|
10
|
+
// Batch workers are inside an Nx run just like task workers (see
|
|
11
|
+
// bin/run-executor.ts) — mark it so nested tooling can detect Nx.
|
|
12
|
+
process.env.NX_CLI_SET = 'true';
|
|
10
13
|
function getBatchExecutor(executorName, projects) {
|
|
11
14
|
const [nodeModule, exportName] = (0, executor_utils_1.parseExecutor)(executorName);
|
|
12
15
|
return (0, executor_utils_1.getExecutorInformation)(nodeModule, exportName, workspace_root_1.workspaceRoot, projects);
|
|
@@ -251,6 +251,12 @@ class DbCache {
|
|
|
251
251
|
logger_1.logger.warn('The HTTP remote cache is not yet supported in the wasm build of Nx.');
|
|
252
252
|
return null;
|
|
253
253
|
}
|
|
254
|
+
// The cache request runs in Rust (reqwest), which honors
|
|
255
|
+
// NODE_TLS_REJECT_UNAUTHORIZED but bypasses Node's TLS stack, so Node's own
|
|
256
|
+
// insecure-TLS warning never fires for it. Re-emit Node's warning here.
|
|
257
|
+
if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0') {
|
|
258
|
+
process.emitWarning("Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.");
|
|
259
|
+
}
|
|
254
260
|
return new native_1.HttpRemoteCache();
|
|
255
261
|
}
|
|
256
262
|
return null;
|
|
@@ -13,6 +13,7 @@ export declare class PseudoTerminal {
|
|
|
13
13
|
constructor(rustPseudoTerminal: RustPseudoTerminal);
|
|
14
14
|
init(): Promise<void>;
|
|
15
15
|
shutdown(code: number): void;
|
|
16
|
+
private releaseChild;
|
|
16
17
|
runCommand(command: string, { cwd, execArgv, jsEnv, quiet, tty, }?: {
|
|
17
18
|
cwd?: string;
|
|
18
19
|
execArgv?: string[];
|
|
@@ -8,17 +8,18 @@ const socket_utils_1 = require("../daemon/socket-utils");
|
|
|
8
8
|
const native_1 = require("../native");
|
|
9
9
|
const pseudo_ipc_1 = require("./pseudo-ipc");
|
|
10
10
|
const exit_codes_1 = require("../utils/exit-codes");
|
|
11
|
-
//
|
|
12
|
-
|
|
11
|
+
// Kill any children still alive when Nx exits. Terminals remove themselves once
|
|
12
|
+
// their children exit (see releaseChild), so finished runs skip a per-terminal scan.
|
|
13
|
+
const activePseudoTerminals = new Set();
|
|
13
14
|
process.on('exit', (code) => {
|
|
14
|
-
|
|
15
|
+
activePseudoTerminals.forEach((t) => t.shutdown(code));
|
|
15
16
|
});
|
|
16
17
|
function createPseudoTerminal(skipSupportCheck = false) {
|
|
17
18
|
if (!skipSupportCheck && !PseudoTerminal.isSupported()) {
|
|
18
19
|
throw new Error('Pseudo terminal is not supported on this platform.');
|
|
19
20
|
}
|
|
20
21
|
const pseudoTerminal = new PseudoTerminal(new native_1.RustPseudoTerminal());
|
|
21
|
-
|
|
22
|
+
activePseudoTerminals.add(pseudoTerminal);
|
|
22
23
|
return pseudoTerminal;
|
|
23
24
|
}
|
|
24
25
|
let id = 0;
|
|
@@ -56,9 +57,21 @@ class PseudoTerminal {
|
|
|
56
57
|
this.pseudoIPC.close();
|
|
57
58
|
}
|
|
58
59
|
}
|
|
60
|
+
// Once all children have exited, drop the process-exit handler and close IPC.
|
|
61
|
+
releaseChild(cp) {
|
|
62
|
+
this.childProcesses.delete(cp);
|
|
63
|
+
if (this.childProcesses.size === 0) {
|
|
64
|
+
activePseudoTerminals.delete(this);
|
|
65
|
+
if (this.initialized) {
|
|
66
|
+
this.pseudoIPC.close();
|
|
67
|
+
this.initialized = false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
59
71
|
runCommand(command, { cwd, execArgv, jsEnv, quiet, tty, } = {}) {
|
|
60
72
|
const cp = new PseudoTtyProcess(this.rustPseudoTerminal, this.rustPseudoTerminal.runCommand(command, cwd, jsEnv, execArgv, quiet, tty));
|
|
61
73
|
this.childProcesses.add(cp);
|
|
74
|
+
cp.onExit(() => this.releaseChild(cp));
|
|
62
75
|
return cp;
|
|
63
76
|
}
|
|
64
77
|
async fork(id, script, { cwd, execArgv, jsEnv, quiet, commandLabel, }) {
|
|
@@ -67,6 +80,7 @@ class PseudoTerminal {
|
|
|
67
80
|
}
|
|
68
81
|
const cp = new PseudoTtyProcessWithSend(this.rustPseudoTerminal, this.rustPseudoTerminal.fork(id, script, this.pseudoIPCPath, cwd, jsEnv, execArgv, quiet, commandLabel), id, this.pseudoIPC);
|
|
69
82
|
this.childProcesses.add(cp);
|
|
83
|
+
cp.onExit(() => this.releaseChild(cp));
|
|
70
84
|
await this.pseudoIPC.waitForChildReady(id);
|
|
71
85
|
return cp;
|
|
72
86
|
}
|
|
@@ -50,6 +50,27 @@ const originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
|
50
50
|
const originalStderrWrite = process.stderr.write.bind(process.stderr);
|
|
51
51
|
const originalConsoleLog = console.log.bind(console);
|
|
52
52
|
const originalConsoleError = console.error.bind(console);
|
|
53
|
+
// Only used in the non-TTY error path. In non-TTY the function `process.exit(1)`s
|
|
54
|
+
// before the `applyChanges` branch can auto-sync, so the auto-sync bullet keeps
|
|
55
|
+
// the "interactive environments" qualifier to avoid suggesting a config change
|
|
56
|
+
// that won't help in CI/agent contexts.
|
|
57
|
+
const SYNC_FIX_MESSAGE_LINES = [
|
|
58
|
+
'To sync the workspace:',
|
|
59
|
+
'- Run `nx sync` (no flags) to sync now.',
|
|
60
|
+
'- Run `nx sync:check` to preview the changes without modifying any files.',
|
|
61
|
+
'- Set `sync.applyChanges` to `true` in your `nx.json` to sync automatically when running tasks in interactive environments.',
|
|
62
|
+
'',
|
|
63
|
+
'For more information, refer to the docs: https://nx.dev/concepts/sync-generators',
|
|
64
|
+
];
|
|
65
|
+
const APPLY_CHANGES_FALSE_FIX_MESSAGE_LINES = [
|
|
66
|
+
'Your workspace is set to not sync automatically (`sync.applyChanges` is `false` in your `nx.json`).',
|
|
67
|
+
'Run `nx sync` (no flags) to sync now, or set `sync.applyChanges` to `true` to sync automatically before each task run.',
|
|
68
|
+
];
|
|
69
|
+
const SYNC_SKIPPED_FIX_MESSAGE_LINES = [
|
|
70
|
+
'This could lead to unexpected results or errors when running tasks.',
|
|
71
|
+
'',
|
|
72
|
+
'Run `nx sync` (no flags) later to sync the workspace.',
|
|
73
|
+
];
|
|
53
74
|
async function getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, projectNames, tasks, taskGraph, nxArgs, nxJson, overrides) {
|
|
54
75
|
const overridesWithoutHidden = { ...overrides };
|
|
55
76
|
delete overridesWithoutHidden['__overrides_unparsed__'];
|
|
@@ -414,7 +435,6 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
|
|
|
414
435
|
const failedSyncGeneratorsFixMessageLines = (0, sync_generators_1.getFailedSyncGeneratorsFixMessageLines)(results, nxArgs.verbose);
|
|
415
436
|
const outOfSyncTitle = 'The workspace is out of sync';
|
|
416
437
|
const resultBodyLines = (0, sync_generators_1.getSyncGeneratorSuccessResultsMessageLines)(results);
|
|
417
|
-
const fixMessage = 'Make sure to run `nx sync` to apply the identified changes or set `sync.applyChanges` to `true` in your `nx.json` to apply them automatically when running tasks in interactive environments.';
|
|
418
438
|
if (!process.stdout.isTTY) {
|
|
419
439
|
// If the user is running a non-TTY environment we
|
|
420
440
|
// throw an error to stop the execution of the tasks.
|
|
@@ -429,7 +449,7 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
|
|
|
429
449
|
else {
|
|
430
450
|
output_1.output.error({
|
|
431
451
|
title: outOfSyncTitle,
|
|
432
|
-
bodyLines: [...resultBodyLines, '',
|
|
452
|
+
bodyLines: [...resultBodyLines, '', ...SYNC_FIX_MESSAGE_LINES],
|
|
433
453
|
});
|
|
434
454
|
if (anySyncGeneratorsFailed) {
|
|
435
455
|
output_1.output.error({
|
|
@@ -463,8 +483,7 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
|
|
|
463
483
|
bodyLines: [
|
|
464
484
|
...resultBodyLines,
|
|
465
485
|
'',
|
|
466
|
-
|
|
467
|
-
fixMessage,
|
|
486
|
+
...APPLY_CHANGES_FALSE_FIX_MESSAGE_LINES,
|
|
468
487
|
],
|
|
469
488
|
});
|
|
470
489
|
if (anySyncGeneratorsFailed) {
|
|
@@ -549,10 +568,7 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
|
|
|
549
568
|
else {
|
|
550
569
|
output_1.output.warn({
|
|
551
570
|
title: 'Syncing the workspace was skipped',
|
|
552
|
-
bodyLines:
|
|
553
|
-
'This could lead to unexpected results or errors when running tasks.',
|
|
554
|
-
fixMessage,
|
|
555
|
-
],
|
|
571
|
+
bodyLines: SYNC_SKIPPED_FIX_MESSAGE_LINES,
|
|
556
572
|
});
|
|
557
573
|
}
|
|
558
574
|
}
|
|
@@ -56,5 +56,6 @@ export declare function getUnparsedOverrideArgs(task: Task): string[];
|
|
|
56
56
|
export declare function getPrintableCommandArgsForTask(task: Task): string[];
|
|
57
57
|
export declare function getSerializedArgsForTask(task: Task, isVerbose: boolean): string[];
|
|
58
58
|
export declare function shouldStreamOutput(task: Task, initiatingProject: string | null): boolean;
|
|
59
|
+
export declare function isCacheableTask(task: Task): boolean;
|
|
59
60
|
export declare function unparse(options: Object): string[];
|
|
60
61
|
export declare function createTaskId(project: string, target: string, configuration: string | undefined): string;
|
|
@@ -24,6 +24,7 @@ exports.getUnparsedOverrideArgs = getUnparsedOverrideArgs;
|
|
|
24
24
|
exports.getPrintableCommandArgsForTask = getPrintableCommandArgsForTask;
|
|
25
25
|
exports.getSerializedArgsForTask = getSerializedArgsForTask;
|
|
26
26
|
exports.shouldStreamOutput = shouldStreamOutput;
|
|
27
|
+
exports.isCacheableTask = isCacheableTask;
|
|
27
28
|
exports.unparse = unparse;
|
|
28
29
|
exports.createTaskId = createTaskId;
|
|
29
30
|
const minimatch_1 = require("minimatch");
|
|
@@ -420,6 +421,9 @@ function shouldStreamOutput(task, initiatingProject) {
|
|
|
420
421
|
return true;
|
|
421
422
|
return false;
|
|
422
423
|
}
|
|
424
|
+
function isCacheableTask(task) {
|
|
425
|
+
return task.cache;
|
|
426
|
+
}
|
|
423
427
|
function longRunningTask(task) {
|
|
424
428
|
const t = task.target.target;
|
|
425
429
|
return (task.continuous ||
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
export declare const NX_CLOUD_URL = "https://nx.dev/nx-cloud";
|
|
2
|
+
/**
|
|
3
|
+
* Clickable Nx Cloud marketing link for cloud prompt footers. The visible text
|
|
4
|
+
* stays the clean `NX_CLOUD_URL` while clicks carry UTM attribution; terminals
|
|
5
|
+
* without OSC 8 support just render the bare URL (CLOUD-4642). The content tag
|
|
6
|
+
* is per-command because `nx init` and `nx migrate` share a footer but report
|
|
7
|
+
* different commands.
|
|
8
|
+
*/
|
|
9
|
+
export declare function nxCloudHyperlink(utmContent: string): string;
|
|
1
10
|
/**
|
|
2
11
|
* Meta payload types for recordStat telemetry (matches CNW format).
|
|
3
12
|
*/
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.messages = exports.PromptMessages = void 0;
|
|
3
|
+
exports.messages = exports.PromptMessages = exports.NX_CLOUD_URL = void 0;
|
|
4
|
+
exports.nxCloudHyperlink = nxCloudHyperlink;
|
|
4
5
|
exports.recordStat = recordStat;
|
|
5
6
|
const tslib_1 = require("tslib");
|
|
6
7
|
const node_child_process_1 = require("node:child_process");
|
|
7
8
|
const is_ci_1 = require("./is-ci");
|
|
8
9
|
const package_manager_1 = require("./package-manager");
|
|
9
10
|
const get_cloud_options_1 = require("../nx-cloud/utilities/get-cloud-options");
|
|
11
|
+
const terminal_link_1 = require("./terminal-link");
|
|
10
12
|
const pc = tslib_1.__importStar(require("picocolors"));
|
|
13
|
+
exports.NX_CLOUD_URL = 'https://nx.dev/nx-cloud';
|
|
14
|
+
/**
|
|
15
|
+
* Clickable Nx Cloud marketing link for cloud prompt footers. The visible text
|
|
16
|
+
* stays the clean `NX_CLOUD_URL` while clicks carry UTM attribution; terminals
|
|
17
|
+
* without OSC 8 support just render the bare URL (CLOUD-4642). The content tag
|
|
18
|
+
* is per-command because `nx init` and `nx migrate` share a footer but report
|
|
19
|
+
* different commands.
|
|
20
|
+
*/
|
|
21
|
+
function nxCloudHyperlink(utmContent) {
|
|
22
|
+
const tracked = `${exports.NX_CLOUD_URL}?utm_source=nx-cli&utm_medium=cli&utm_campaign=nx-cloud-connect&utm_content=${utmContent}`;
|
|
23
|
+
return (0, terminal_link_1.terminalLink)(exports.NX_CLOUD_URL, tracked);
|
|
24
|
+
}
|
|
11
25
|
const messageOptions = {
|
|
12
26
|
setupNxCloud: [
|
|
13
27
|
{
|
|
@@ -19,7 +33,7 @@ const messageOptions = {
|
|
|
19
33
|
{ value: 'skip', name: 'Skip for now' },
|
|
20
34
|
{ value: 'never', name: pc.dim("No, don't ask again") },
|
|
21
35
|
],
|
|
22
|
-
footer: '\nFree for small teams. Remote caching and task distribution. 2-minute setup:
|
|
36
|
+
footer: '\nFree for small teams. Remote caching and task distribution. 2-minute setup:',
|
|
23
37
|
},
|
|
24
38
|
{
|
|
25
39
|
code: 'cloud-self-healing-remote-cache',
|
|
@@ -30,7 +44,7 @@ const messageOptions = {
|
|
|
30
44
|
{ value: 'skip', name: 'Skip for now' },
|
|
31
45
|
{ value: 'never', name: pc.dim("No, don't ask again") },
|
|
32
46
|
],
|
|
33
|
-
footer: '\nLearn about it at
|
|
47
|
+
footer: '\nLearn about it at',
|
|
34
48
|
hint: `\n(it's free and can be disabled any time)`,
|
|
35
49
|
},
|
|
36
50
|
],
|
|
@@ -47,7 +61,7 @@ const messageOptions = {
|
|
|
47
61
|
},
|
|
48
62
|
{ value: 'skip', name: 'No' },
|
|
49
63
|
],
|
|
50
|
-
footer: '\nRead more about Nx Cloud at
|
|
64
|
+
footer: '\nRead more about Nx Cloud at',
|
|
51
65
|
hint: `\n(it's free and can be disabled any time)`,
|
|
52
66
|
},
|
|
53
67
|
],
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Tree } from '../../generators/tree';
|
|
2
|
+
import type { PackageJson } from '../package-json';
|
|
2
3
|
import type { CatalogManager } from './manager';
|
|
3
4
|
import { getCatalogManager } from './manager-factory';
|
|
4
5
|
export { type CatalogManager, getCatalogManager };
|
|
@@ -8,6 +9,12 @@ export { type CatalogManager, getCatalogManager };
|
|
|
8
9
|
* applies). Throws when the reference cannot be resolved.
|
|
9
10
|
*/
|
|
10
11
|
export declare function resolveCatalogReferenceIfNeeded(packageName: string, version: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Resolves a package.json's `catalog:` dependency / devDependency specifiers to
|
|
14
|
+
* their declared version range. Non-catalog or unresolvable specifiers are
|
|
15
|
+
* returned unchanged.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveCatalogSpecifiers(packageJson: PackageJson | null): PackageJson | null;
|
|
11
18
|
/**
|
|
12
19
|
* Detects which packages in a package.json use catalog references
|
|
13
20
|
* Returns Map of package name -> catalog name (undefined for default catalog)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getCatalogManager = void 0;
|
|
4
4
|
exports.resolveCatalogReferenceIfNeeded = resolveCatalogReferenceIfNeeded;
|
|
5
|
+
exports.resolveCatalogSpecifiers = resolveCatalogSpecifiers;
|
|
5
6
|
exports.getCatalogDependenciesFromPackageJson = getCatalogDependenciesFromPackageJson;
|
|
6
7
|
const json_1 = require("../../generators/utils/json");
|
|
7
8
|
const workspace_root_1 = require("../workspace-root");
|
|
@@ -23,6 +24,36 @@ function resolveCatalogReferenceIfNeeded(packageName, version) {
|
|
|
23
24
|
}
|
|
24
25
|
return resolvedVersion;
|
|
25
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolves a package.json's `catalog:` dependency / devDependency specifiers to
|
|
29
|
+
* their declared version range. Non-catalog or unresolvable specifiers are
|
|
30
|
+
* returned unchanged.
|
|
31
|
+
*/
|
|
32
|
+
function resolveCatalogSpecifiers(packageJson) {
|
|
33
|
+
if (!packageJson) {
|
|
34
|
+
return packageJson;
|
|
35
|
+
}
|
|
36
|
+
const resolveSection = (section) => {
|
|
37
|
+
const resolved = {};
|
|
38
|
+
for (const [name, specifier] of Object.entries(section)) {
|
|
39
|
+
try {
|
|
40
|
+
resolved[name] = resolveCatalogReferenceIfNeeded(name, specifier);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
resolved[name] = specifier;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return resolved;
|
|
47
|
+
};
|
|
48
|
+
const result = { ...packageJson };
|
|
49
|
+
if (packageJson.dependencies) {
|
|
50
|
+
result.dependencies = resolveSection(packageJson.dependencies);
|
|
51
|
+
}
|
|
52
|
+
if (packageJson.devDependencies) {
|
|
53
|
+
result.devDependencies = resolveSection(packageJson.devDependencies);
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
26
57
|
/**
|
|
27
58
|
* Detects which packages in a package.json use catalog references
|
|
28
59
|
* Returns Map of package name -> catalog name (undefined for default catalog)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Tree } from '../../generators/tree';
|
|
2
|
+
import type { CatalogDefinitions } from './types';
|
|
3
|
+
export declare function readCatalogConfigFromFs(filename: string, fullPath: string): CatalogDefinitions | null;
|
|
4
|
+
export declare function readCatalogConfigFromTree(filename: string, tree: Tree): CatalogDefinitions | null;
|
|
5
|
+
export declare function updateCatalogVersionsInFile(filename: string, treeOrRoot: Tree | string, updates: Array<{
|
|
6
|
+
packageName: string;
|
|
7
|
+
version: string;
|
|
8
|
+
catalogName?: string;
|
|
9
|
+
}>): void;
|