nx 21.3.0-canary.20250626-8b6ad42 → 21.3.0-canary.20250628-7430238
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/package.json +11 -11
- package/src/adapter/ngcli-adapter.d.ts +11 -0
- package/src/adapter/ngcli-adapter.js +101 -7
- package/src/daemon/server/server.js +7 -1
- package/src/plugins/js/lock-file/lock-file.js +1 -0
- package/src/tasks-runner/forked-process-task-runner.js +4 -0
- package/src/tasks-runner/running-tasks/node-child-process.d.ts +2 -0
- package/src/tasks-runner/running-tasks/node-child-process.js +16 -2
- package/src/tasks-runner/task-orchestrator.js +7 -1
- package/src/utils/package-json.js +1 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "nx",
|
3
|
-
"version": "21.3.0-canary.
|
3
|
+
"version": "21.3.0-canary.20250628-7430238",
|
4
4
|
"private": false,
|
5
5
|
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
6
6
|
"repository": {
|
@@ -83,16 +83,16 @@
|
|
83
83
|
}
|
84
84
|
},
|
85
85
|
"optionalDependencies": {
|
86
|
-
"@nx/nx-darwin-arm64": "21.3.0-canary.
|
87
|
-
"@nx/nx-darwin-x64": "21.3.0-canary.
|
88
|
-
"@nx/nx-freebsd-x64": "21.3.0-canary.
|
89
|
-
"@nx/nx-linux-arm-gnueabihf": "21.3.0-canary.
|
90
|
-
"@nx/nx-linux-arm64-gnu": "21.3.0-canary.
|
91
|
-
"@nx/nx-linux-arm64-musl": "21.3.0-canary.
|
92
|
-
"@nx/nx-linux-x64-gnu": "21.3.0-canary.
|
93
|
-
"@nx/nx-linux-x64-musl": "21.3.0-canary.
|
94
|
-
"@nx/nx-win32-arm64-msvc": "21.3.0-canary.
|
95
|
-
"@nx/nx-win32-x64-msvc": "21.3.0-canary.
|
86
|
+
"@nx/nx-darwin-arm64": "21.3.0-canary.20250628-7430238",
|
87
|
+
"@nx/nx-darwin-x64": "21.3.0-canary.20250628-7430238",
|
88
|
+
"@nx/nx-freebsd-x64": "21.3.0-canary.20250628-7430238",
|
89
|
+
"@nx/nx-linux-arm-gnueabihf": "21.3.0-canary.20250628-7430238",
|
90
|
+
"@nx/nx-linux-arm64-gnu": "21.3.0-canary.20250628-7430238",
|
91
|
+
"@nx/nx-linux-arm64-musl": "21.3.0-canary.20250628-7430238",
|
92
|
+
"@nx/nx-linux-x64-gnu": "21.3.0-canary.20250628-7430238",
|
93
|
+
"@nx/nx-linux-x64-musl": "21.3.0-canary.20250628-7430238",
|
94
|
+
"@nx/nx-win32-arm64-msvc": "21.3.0-canary.20250628-7430238",
|
95
|
+
"@nx/nx-win32-x64-msvc": "21.3.0-canary.20250628-7430238"
|
96
96
|
},
|
97
97
|
"nx-migrations": {
|
98
98
|
"migrations": "./migrations.json",
|
@@ -87,4 +87,15 @@ export declare function wrapAngularDevkitSchematic(collectionName: string, gener
|
|
87
87
|
[k: string]: any;
|
88
88
|
}) => Promise<GeneratorCallback>;
|
89
89
|
export declare const getLogger: (isVerbose?: boolean) => logging.Logger;
|
90
|
+
/**
|
91
|
+
* Restores Nx tokens in options when possible by comparing new and previous
|
92
|
+
* options.
|
93
|
+
* The function preserves tokens in the following cases:
|
94
|
+
* 1. When the resolved previous value matches the new value exactly
|
95
|
+
* 2. When the previous value used {workspaceRoot}
|
96
|
+
* 3. When the previous value used {projectRoot} and the new value starts with
|
97
|
+
* the project root path
|
98
|
+
* Those are the only safe cases, for all other cases, the new value is used as-is.
|
99
|
+
*/
|
100
|
+
export declare function restoreNxTokensInOptions<T extends Object | Array<unknown>>(newOptions: T, previousOptions: T, project: ProjectConfiguration): T;
|
90
101
|
export {};
|
@@ -8,6 +8,7 @@ exports.generate = generate;
|
|
8
8
|
exports.runMigration = runMigration;
|
9
9
|
exports.mockSchematicsForTesting = mockSchematicsForTesting;
|
10
10
|
exports.wrapAngularDevkitSchematic = wrapAngularDevkitSchematic;
|
11
|
+
exports.restoreNxTokensInOptions = restoreNxTokensInOptions;
|
11
12
|
const core_1 = require("@angular-devkit/core");
|
12
13
|
const node_1 = require("@angular-devkit/core/node");
|
13
14
|
const chalk = require("chalk");
|
@@ -28,6 +29,7 @@ const angular_json_1 = require("./angular-json");
|
|
28
29
|
const executor_utils_1 = require("../command-line/run/executor-utils");
|
29
30
|
const plugins_1 = require("../project-graph/plugins");
|
30
31
|
const schema_utils_1 = require("../config/schema-utils");
|
32
|
+
const project_configuration_utils_1 = require("../project-graph/utils/project-configuration-utils");
|
31
33
|
async function createBuilderContext(builderInfo, context) {
|
32
34
|
require('./compat');
|
33
35
|
const fsHost = new NxScopedHostForBuilders(context.root);
|
@@ -296,10 +298,32 @@ class NxScopedHost extends core_1.virtualFs.ScopedHost {
|
|
296
298
|
const projects = configV2.projects;
|
297
299
|
const allObservables = [];
|
298
300
|
Object.keys(projects).forEach((projectName) => {
|
299
|
-
if (projectsInAngularJson.includes(projectName)) {
|
300
|
-
//
|
301
|
-
|
302
|
-
|
301
|
+
if (!projectsInAngularJson.includes(projectName)) {
|
302
|
+
// Restore tokens in options if they were present before
|
303
|
+
const previousProject = existingConfig.projects[projectName];
|
304
|
+
const newProject = projects[projectName];
|
305
|
+
if (previousProject &&
|
306
|
+
newProject.targets &&
|
307
|
+
previousProject.targets) {
|
308
|
+
for (const [targetName, target] of Object.entries(newProject.targets)) {
|
309
|
+
const previousTarget = previousProject.targets[targetName];
|
310
|
+
if (target.options &&
|
311
|
+
previousTarget &&
|
312
|
+
previousTarget.options) {
|
313
|
+
target.options = restoreNxTokensInOptions(target.options, previousTarget.options, newProject);
|
314
|
+
}
|
315
|
+
if (target.configurations &&
|
316
|
+
previousTarget &&
|
317
|
+
previousTarget.configurations) {
|
318
|
+
for (const [configName, config] of Object.entries(target.configurations)) {
|
319
|
+
if (previousTarget.configurations[configName]) {
|
320
|
+
target.configurations[configName] =
|
321
|
+
restoreNxTokensInOptions(config, previousTarget.configurations[configName], newProject);
|
322
|
+
}
|
323
|
+
}
|
324
|
+
}
|
325
|
+
}
|
326
|
+
}
|
303
327
|
(0, project_configuration_1.updateProjectConfiguration)({
|
304
328
|
root,
|
305
329
|
exists: () => true,
|
@@ -430,9 +454,23 @@ class NxScopeHostUsedForWrappedSchematics extends NxScopedHost {
|
|
430
454
|
read(path) {
|
431
455
|
if ((path === 'angular.json' || path === '/angular.json') &&
|
432
456
|
(0, angular_json_1.isAngularPluginInstalled)()) {
|
433
|
-
|
434
|
-
|
435
|
-
|
457
|
+
// Replace the Nx-specific tokens in all target options
|
458
|
+
const projects = Object.fromEntries((0, project_configuration_1.getProjects)(this.host));
|
459
|
+
for (const [projectName, project] of Object.entries(projects)) {
|
460
|
+
if (project.targets) {
|
461
|
+
for (const [targetName, target] of Object.entries(project.targets)) {
|
462
|
+
if (target.options) {
|
463
|
+
target.options = (0, project_configuration_utils_1.resolveNxTokensInOptions)(target.options, { ...project, name: projectName }, `${projectName}:${targetName}`);
|
464
|
+
}
|
465
|
+
if (target.configurations) {
|
466
|
+
for (const [configName, config] of Object.entries(target.configurations)) {
|
467
|
+
target.configurations[configName] = (0, project_configuration_utils_1.resolveNxTokensInOptions)(config, { ...project, name: projectName }, `${projectName}:${targetName}:${configName}`);
|
468
|
+
}
|
469
|
+
}
|
470
|
+
}
|
471
|
+
}
|
472
|
+
}
|
473
|
+
const projectJsonConfig = (0, angular_json_1.toOldFormat)({ projects });
|
436
474
|
return super.readExistingAngularJson().pipe((0, operators_1.map)((angularJson) => {
|
437
475
|
if (angularJson) {
|
438
476
|
return Buffer.from(JSON.stringify({
|
@@ -852,3 +890,59 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(workspace, root, proj
|
|
852
890
|
}
|
853
891
|
return new WrappedWorkspaceNodeModulesArchitectHost(workspace, root, projects);
|
854
892
|
}
|
893
|
+
/**
|
894
|
+
* Restores Nx tokens in options when possible by comparing new and previous
|
895
|
+
* options.
|
896
|
+
* The function preserves tokens in the following cases:
|
897
|
+
* 1. When the resolved previous value matches the new value exactly
|
898
|
+
* 2. When the previous value used {workspaceRoot}
|
899
|
+
* 3. When the previous value used {projectRoot} and the new value starts with
|
900
|
+
* the project root path
|
901
|
+
* Those are the only safe cases, for all other cases, the new value is used as-is.
|
902
|
+
*/
|
903
|
+
function restoreNxTokensInOptions(newOptions, previousOptions, project) {
|
904
|
+
if (!newOptions || !previousOptions) {
|
905
|
+
return newOptions;
|
906
|
+
}
|
907
|
+
const result = Array.isArray(newOptions)
|
908
|
+
? [...newOptions]
|
909
|
+
: { ...newOptions };
|
910
|
+
const resolvedPreviousOptions = (0, project_configuration_utils_1.resolveNxTokensInOptions)(previousOptions, project, '');
|
911
|
+
for (const key of Object.keys(newOptions)) {
|
912
|
+
const newValue = newOptions[key];
|
913
|
+
const previousValue = previousOptions[key];
|
914
|
+
if (typeof newValue === 'string' && typeof previousValue === 'string') {
|
915
|
+
if (resolvedPreviousOptions[key] === newValue) {
|
916
|
+
// If the resolved previous value matches the new value, use the previous
|
917
|
+
// value (potentially with tokens)
|
918
|
+
result[key] = previousValue;
|
919
|
+
}
|
920
|
+
else if (previousValue.startsWith('{workspaceRoot}/')) {
|
921
|
+
// If the previous value started with {workspaceRoot}, prefix the new
|
922
|
+
// value with {workspaceRoot}
|
923
|
+
result[key] = `{workspaceRoot}/${newValue.replace(/^\//, '')}`;
|
924
|
+
}
|
925
|
+
else if (previousValue.startsWith('{projectRoot}/') &&
|
926
|
+
newValue.startsWith(`${project.root}/`)) {
|
927
|
+
// If the previous value started with {projectRoot} and the new value
|
928
|
+
// starts with the project root, replace the project root with the
|
929
|
+
// {projectRoot} token
|
930
|
+
result[key] = newValue.replace(`${project.root}/`, '{projectRoot}/');
|
931
|
+
}
|
932
|
+
else {
|
933
|
+
// Otherwise, use the new value as-is
|
934
|
+
result[key] = newValue;
|
935
|
+
}
|
936
|
+
}
|
937
|
+
else if (typeof newValue === 'object' &&
|
938
|
+
typeof previousValue === 'object' &&
|
939
|
+
newValue &&
|
940
|
+
previousValue) {
|
941
|
+
result[key] = restoreNxTokensInOptions(newValue, previousValue, project);
|
942
|
+
}
|
943
|
+
else {
|
944
|
+
result[key] = newValue;
|
945
|
+
}
|
946
|
+
}
|
947
|
+
return result;
|
948
|
+
}
|
@@ -182,8 +182,14 @@ async function handleMessage(socket, data) {
|
|
182
182
|
}
|
183
183
|
}
|
184
184
|
async function handleResult(socket, type, hrFn) {
|
185
|
+
let hr;
|
185
186
|
const startMark = new Date();
|
186
|
-
|
187
|
+
try {
|
188
|
+
hr = await hrFn();
|
189
|
+
}
|
190
|
+
catch (error) {
|
191
|
+
hr = { description: `[${type}]`, error };
|
192
|
+
}
|
187
193
|
const doneHandlingMark = new Date();
|
188
194
|
if (hr.error) {
|
189
195
|
await (0, shutdown_utils_1.respondWithErrorAndExit)(socket, hr.description, hr.error);
|
@@ -89,6 +89,7 @@ class ForkedProcessTaskRunner {
|
|
89
89
|
if (pseudo_terminal_1.PseudoTerminal.isSupported() &&
|
90
90
|
!disablePseudoTerminal &&
|
91
91
|
(this.tuiEnabled || (streamOutput && !shouldPrefix))) {
|
92
|
+
// Use pseudo-terminal for interactive tasks that can support user input
|
92
93
|
return this.forkProcessWithPseudoTerminal(task, {
|
93
94
|
temporaryOutputPath,
|
94
95
|
streamOutput,
|
@@ -97,6 +98,9 @@ class ForkedProcessTaskRunner {
|
|
97
98
|
});
|
98
99
|
}
|
99
100
|
else {
|
101
|
+
// Use non-interactive process with piped output
|
102
|
+
// Tradeoff: These tasks cannot support interactivity but can still provide
|
103
|
+
// progressive output to the TUI if it's enabled
|
100
104
|
return this.forkProcessWithPrefixAndNotTTY(task, {
|
101
105
|
temporaryOutputPath,
|
102
106
|
streamOutput,
|
@@ -4,12 +4,14 @@ export declare class NodeChildProcessWithNonDirectOutput implements RunningTask
|
|
4
4
|
private childProcess;
|
5
5
|
private terminalOutput;
|
6
6
|
private exitCallbacks;
|
7
|
+
private outputCallbacks;
|
7
8
|
private exitCode;
|
8
9
|
constructor(childProcess: ChildProcess, { streamOutput, prefix }: {
|
9
10
|
streamOutput: boolean;
|
10
11
|
prefix: string;
|
11
12
|
});
|
12
13
|
onExit(cb: (code: number, terminalOutput: string) => void): void;
|
14
|
+
onOutput(cb: (output: string) => void): void;
|
13
15
|
getResults(): Promise<{
|
14
16
|
code: number;
|
15
17
|
terminalOutput: string;
|
@@ -10,6 +10,7 @@ class NodeChildProcessWithNonDirectOutput {
|
|
10
10
|
this.childProcess = childProcess;
|
11
11
|
this.terminalOutput = '';
|
12
12
|
this.exitCallbacks = [];
|
13
|
+
this.outputCallbacks = [];
|
13
14
|
if (streamOutput) {
|
14
15
|
if (process.env.NX_PREFIX_OUTPUT === 'true') {
|
15
16
|
const color = getColor(prefix);
|
@@ -47,15 +48,28 @@ class NodeChildProcessWithNonDirectOutput {
|
|
47
48
|
}
|
48
49
|
});
|
49
50
|
this.childProcess.stdout.on('data', (chunk) => {
|
50
|
-
|
51
|
+
const output = chunk.toString();
|
52
|
+
this.terminalOutput += output;
|
53
|
+
// Stream output to TUI via callbacks
|
54
|
+
for (const cb of this.outputCallbacks) {
|
55
|
+
cb(output);
|
56
|
+
}
|
51
57
|
});
|
52
58
|
this.childProcess.stderr.on('data', (chunk) => {
|
53
|
-
|
59
|
+
const output = chunk.toString();
|
60
|
+
this.terminalOutput += output;
|
61
|
+
// Stream output to TUI via callbacks
|
62
|
+
for (const cb of this.outputCallbacks) {
|
63
|
+
cb(output);
|
64
|
+
}
|
54
65
|
});
|
55
66
|
}
|
56
67
|
onExit(cb) {
|
57
68
|
this.exitCallbacks.push(cb);
|
58
69
|
}
|
70
|
+
onOutput(cb) {
|
71
|
+
this.outputCallbacks.push(cb);
|
72
|
+
}
|
59
73
|
async getResults() {
|
60
74
|
if (typeof this.exitCode === 'number') {
|
61
75
|
return {
|
@@ -398,12 +398,18 @@ class TaskOrchestrator {
|
|
398
398
|
this.options.lifeCycle.appendTaskOutput(task.id, output, true);
|
399
399
|
});
|
400
400
|
}
|
401
|
-
else if ('onOutput' in runningTask
|
401
|
+
else if ('onOutput' in runningTask &&
|
402
|
+
typeof runningTask.onOutput === 'function') {
|
403
|
+
// Register task that can provide progressive output but isn't interactive (e.g., NodeChildProcessWithNonDirectOutput)
|
402
404
|
this.options.lifeCycle.registerRunningTaskWithEmptyParser(task.id);
|
403
405
|
runningTask.onOutput((output) => {
|
404
406
|
this.options.lifeCycle.appendTaskOutput(task.id, output, false);
|
405
407
|
});
|
406
408
|
}
|
409
|
+
else {
|
410
|
+
// Fallback for tasks that don't support progressive output
|
411
|
+
this.options.lifeCycle.registerRunningTaskWithEmptyParser(task.id);
|
412
|
+
}
|
407
413
|
}
|
408
414
|
return runningTask;
|
409
415
|
}
|
@@ -124,7 +124,7 @@ function readTargetsFromPackageJson(packageJson, nxJson, projectRoot, workspaceR
|
|
124
124
|
function hasNxJsPlugin(projectRoot, workspaceRoot) {
|
125
125
|
try {
|
126
126
|
// nx-ignore-next-line
|
127
|
-
require.resolve('@nx/js', {
|
127
|
+
require.resolve('@nx/js/package.json', {
|
128
128
|
paths: [projectRoot, ...(0, installation_directory_1.getNxRequirePaths)(workspaceRoot), __dirname],
|
129
129
|
});
|
130
130
|
return true;
|