nx 21.2.0-canary.20250529-c8a6ffb → 21.2.0-canary.20250603-88c5196

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "21.2.0-canary.20250529-c8a6ffb",
3
+ "version": "21.2.0-canary.20250603-88c5196",
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.2.0-canary.20250529-c8a6ffb",
87
- "@nx/nx-darwin-x64": "21.2.0-canary.20250529-c8a6ffb",
88
- "@nx/nx-freebsd-x64": "21.2.0-canary.20250529-c8a6ffb",
89
- "@nx/nx-linux-arm-gnueabihf": "21.2.0-canary.20250529-c8a6ffb",
90
- "@nx/nx-linux-arm64-gnu": "21.2.0-canary.20250529-c8a6ffb",
91
- "@nx/nx-linux-arm64-musl": "21.2.0-canary.20250529-c8a6ffb",
92
- "@nx/nx-linux-x64-gnu": "21.2.0-canary.20250529-c8a6ffb",
93
- "@nx/nx-linux-x64-musl": "21.2.0-canary.20250529-c8a6ffb",
94
- "@nx/nx-win32-arm64-msvc": "21.2.0-canary.20250529-c8a6ffb",
95
- "@nx/nx-win32-x64-msvc": "21.2.0-canary.20250529-c8a6ffb"
86
+ "@nx/nx-darwin-arm64": "21.2.0-canary.20250603-88c5196",
87
+ "@nx/nx-darwin-x64": "21.2.0-canary.20250603-88c5196",
88
+ "@nx/nx-freebsd-x64": "21.2.0-canary.20250603-88c5196",
89
+ "@nx/nx-linux-arm-gnueabihf": "21.2.0-canary.20250603-88c5196",
90
+ "@nx/nx-linux-arm64-gnu": "21.2.0-canary.20250603-88c5196",
91
+ "@nx/nx-linux-arm64-musl": "21.2.0-canary.20250603-88c5196",
92
+ "@nx/nx-linux-x64-gnu": "21.2.0-canary.20250603-88c5196",
93
+ "@nx/nx-linux-x64-musl": "21.2.0-canary.20250603-88c5196",
94
+ "@nx/nx-win32-arm64-msvc": "21.2.0-canary.20250603-88c5196",
95
+ "@nx/nx-win32-x64-msvc": "21.2.0-canary.20250603-88c5196"
96
96
  },
97
97
  "nx-migrations": {
98
98
  "migrations": "./migrations.json",
@@ -6,7 +6,7 @@ const documentation_1 = require("../yargs-utils/documentation");
6
6
  const shared_options_1 = require("../yargs-utils/shared-options");
7
7
  exports.yargsAffectedCommand = {
8
8
  command: 'affected',
9
- describe: 'Run target for affected projects. See https://nx.dev/ci/features/affected for more details.',
9
+ describe: 'Run target for affected projects. Affected projects are projects that have been changed and projects that depend on the changed projects. See https://nx.dev/ci/features/affected for more details.',
10
10
  builder: (yargs) => (0, documentation_1.linkToNxDevAndExamples)((0, shared_options_1.withAffectedOptions)((0, shared_options_1.withTuiOptions)((0, shared_options_1.withRunOptions)((0, shared_options_1.withOutputStyleOption)((0, shared_options_1.withTargetAndConfigurationOption)((0, shared_options_1.withBatch)(yargs))))))
11
11
  .option('all', {
12
12
  type: 'boolean',
@@ -36,6 +36,7 @@ export interface ExpandedTaskInputsReponse {
36
36
  }
37
37
  export declare function generateGraph(args: {
38
38
  file?: string;
39
+ print?: boolean;
39
40
  host?: string;
40
41
  port?: number;
41
42
  groupByFolder?: boolean;
@@ -9,6 +9,7 @@ const minimatch_1 = require("minimatch");
9
9
  const node_url_1 = require("node:url");
10
10
  const open = require("open");
11
11
  const path_1 = require("path");
12
+ const net = require("net");
12
13
  const perf_hooks_1 = require("perf_hooks");
13
14
  const configuration_1 = require("../../config/configuration");
14
15
  const fileutils_1 = require("../../utils/fileutils");
@@ -207,7 +208,7 @@ async function generateGraph(args, affectedProjects) {
207
208
  }
208
209
  }
209
210
  if (args.affected) {
210
- affectedProjects = (await (0, affected_1.getAffectedGraphNodes)((0, command_line_utils_1.splitArgsIntoNxArgsAndOverrides)(args, 'affected', { printWarnings: args.file !== 'stdout' }, (0, configuration_1.readNxJson)()).nxArgs, rawGraph)).map((n) => n.name);
211
+ affectedProjects = (await (0, affected_1.getAffectedGraphNodes)((0, command_line_utils_1.splitArgsIntoNxArgsAndOverrides)(args, 'affected', { printWarnings: !args.print && args.file !== 'stdout' }, (0, configuration_1.readNxJson)()).nxArgs, rawGraph)).map((n) => n.name);
211
212
  }
212
213
  if (args.exclude) {
213
214
  const invalidExcludes = [];
@@ -226,13 +227,12 @@ async function generateGraph(args, affectedProjects) {
226
227
  }
227
228
  let html = (0, node_fs_1.readFileSync)((0, path_1.join)(__dirname, '../../core/graph/index.html'), 'utf-8');
228
229
  prunedGraph = filterGraph(prunedGraph, args.focus || null, args.exclude || []);
230
+ if (args.print || args.file === 'stdout') {
231
+ console.log(JSON.stringify(await createJsonOutput(prunedGraph, rawGraph, args.projects, args.targets), null, 2));
232
+ await output_1.output.drain();
233
+ process.exit(0);
234
+ }
229
235
  if (args.file) {
230
- // stdout is a magical constant that doesn't actually write a file
231
- if (args.file === 'stdout') {
232
- console.log(JSON.stringify(await createJsonOutput(prunedGraph, rawGraph, args.projects, args.targets), null, 2));
233
- await output_1.output.drain();
234
- process.exit(0);
235
- }
236
236
  const workspaceFolder = workspace_root_1.workspaceRoot;
237
237
  const ext = (0, path_1.extname)(args.file);
238
238
  const fullFilePath = (0, path_1.isAbsolute)(args.file)
@@ -287,7 +287,20 @@ async function generateGraph(args, affectedProjects) {
287
287
  }
288
288
  else {
289
289
  const environmentJs = buildEnvironmentJs(args.exclude || [], args.watch, !!args.file && args.file.endsWith('html') ? 'build' : 'serve');
290
- const { app, url } = await startServer(html, environmentJs, args.host || '127.0.0.1', args.port || 4211, args.watch, affectedProjects, args.focus, args.groupByFolder, args.exclude);
290
+ let app;
291
+ let url;
292
+ try {
293
+ const result = await startServer(html, environmentJs, args.host || '127.0.0.1', args.port || 4211, args.watch, affectedProjects, args.focus, args.groupByFolder, args.exclude);
294
+ app = result.app;
295
+ url = result.url;
296
+ }
297
+ catch (err) {
298
+ output_1.output.error({
299
+ title: 'Failed to start graph server',
300
+ bodyLines: [err.message],
301
+ });
302
+ process.exit(1);
303
+ }
291
304
  url.pathname = args.view;
292
305
  if (args.focus) {
293
306
  url.pathname += '/' + encodeURIComponent(args.focus);
@@ -318,6 +331,28 @@ async function generateGraph(args, affectedProjects) {
318
331
  });
319
332
  }
320
333
  }
334
+ function findAvailablePort(startPort, host = '127.0.0.1') {
335
+ return new Promise((resolve, reject) => {
336
+ const server = net.createServer();
337
+ server.listen(startPort, host, () => {
338
+ const port = server.address().port;
339
+ server.close(() => {
340
+ resolve(port);
341
+ });
342
+ });
343
+ server.on('error', (err) => {
344
+ if (err.code === 'EADDRINUSE') {
345
+ // Port is in use, try the next one
346
+ findAvailablePort(startPort + 1, host)
347
+ .then(resolve)
348
+ .catch(reject);
349
+ }
350
+ else {
351
+ reject(err);
352
+ }
353
+ });
354
+ });
355
+ }
321
356
  async function startServer(html, environmentJs, host, port = 4211, watchForChanges = true, affected = [], focus = null, groupByFolder = false, exclude = []) {
322
357
  let unregisterFileWatcher;
323
358
  if (watchForChanges && !client_1.daemonClient.enabled()) {
@@ -418,9 +453,19 @@ async function startServer(html, environmentJs, host, port = 4211, watchForChang
418
453
  };
419
454
  process.on('SIGINT', () => handleTermination(128 + 2));
420
455
  process.on('SIGTERM', () => handleTermination(128 + 15));
421
- return new Promise((res) => {
422
- app.listen(port, host, () => {
423
- res({ app, url: new node_url_1.URL(`http://${host}:${port}`) });
456
+ // Find an available port starting from the requested port
457
+ const availablePort = await findAvailablePort(port, host);
458
+ return new Promise((res, rej) => {
459
+ app.on('error', (err) => {
460
+ rej(err);
461
+ });
462
+ app.listen(availablePort, host, () => {
463
+ if (availablePort !== port) {
464
+ output_1.output.note({
465
+ title: `Port ${port} was already in use, using port ${availablePort} instead`,
466
+ });
467
+ }
468
+ res({ app, url: new node_url_1.URL(`http://${host}:${availablePort}`) });
424
469
  });
425
470
  });
426
471
  }
@@ -17,9 +17,10 @@ const nxAngularLegacyVersionMap = {
17
17
  14: '~17.0.0',
18
18
  15: '~19.0.0',
19
19
  16: '~20.1.0',
20
+ 17: '~21.1.0',
20
21
  };
21
22
  // min major angular version supported in latest Nx
22
- const minMajorAngularVersionSupported = 17;
23
+ const minMajorAngularVersionSupported = Math.max(...Object.keys(nxAngularLegacyVersionMap).map(Number)) + 1;
23
24
  // version when the Nx CLI changed from @nrwl/tao & @nrwl/cli to nx
24
25
  const versionWithConsolidatedPackages = '13.9.0';
25
26
  // version when packages were rescoped from @nrwl/* to @nx/*
@@ -1,4 +1,5 @@
1
1
  import { ExecutorContext } from '../../config/misc-interfaces';
2
+ import { NoopChildProcess } from '../../tasks-runner/running-tasks/noop-child-process';
2
3
  import { ParallelRunningTasks, SeriallyRunningTasks } from './running-tasks';
3
4
  export declare const LARGE_BUFFER: number;
4
5
  export type Json = {
@@ -54,5 +55,5 @@ export default function (options: RunCommandsOptions, context: ExecutorContext):
54
55
  success: boolean;
55
56
  terminalOutput: string;
56
57
  }>;
57
- export declare function runCommands(options: RunCommandsOptions, context: ExecutorContext): Promise<import("../../tasks-runner/pseudo-terminal").PseudoTtyProcess | ParallelRunningTasks | SeriallyRunningTasks>;
58
+ export declare function runCommands(options: RunCommandsOptions, context: ExecutorContext): Promise<import("../../tasks-runner/pseudo-terminal").PseudoTtyProcess | NoopChildProcess | ParallelRunningTasks | SeriallyRunningTasks>;
58
59
  export declare function interpolateArgsIntoCommand(command: string, opts: Pick<NormalizedRunCommandsOptions, 'args' | 'parsedArgs' | '__unparsed__' | 'unknownOptions' | 'unparsedCommandArgs'>, forwardAllArgs: boolean): string;
@@ -7,6 +7,7 @@ exports.interpolateArgsIntoCommand = interpolateArgsIntoCommand;
7
7
  const yargsParser = require("yargs-parser");
8
8
  const is_tui_enabled_1 = require("../../tasks-runner/is-tui-enabled");
9
9
  const pseudo_terminal_1 = require("../../tasks-runner/pseudo-terminal");
10
+ const noop_child_process_1 = require("../../tasks-runner/running-tasks/noop-child-process");
10
11
  const running_tasks_1 = require("./running-tasks");
11
12
  exports.LARGE_BUFFER = 1024 * 1000000;
12
13
  const propKeys = [
@@ -45,6 +46,10 @@ async function runCommands(options, context) {
45
46
  !options.parallel) {
46
47
  throw new Error('ERROR: Bad executor config for run-commands - "prefix", "prefixColor", "color" and "bgColor" can only be set when "parallel=true".');
47
48
  }
49
+ // Handle empty commands array - return immediately with success
50
+ if (normalized.commands.length === 0) {
51
+ return new noop_child_process_1.NoopChildProcess({ code: 0, terminalOutput: '' });
52
+ }
48
53
  const isSingleCommand = normalized.commands.length === 1;
49
54
  const usePseudoTerminal = (isSingleCommand || !options.parallel) && pseudo_terminal_1.PseudoTerminal.isSupported();
50
55
  const isSingleCommandAndCanUsePseudoTerminal = isSingleCommand &&
Binary file
@@ -51,10 +51,13 @@ const getProjectPathsAffectedByDependencyUpdates = (changedLockFile) => {
51
51
  return Array.from(changedProjectPaths);
52
52
  };
53
53
  const getProjectsNamesFromPaths = (projectGraphNodes, projectPaths) => {
54
+ if (!projectPaths.length) {
55
+ return [];
56
+ }
54
57
  const lookup = new RootPathLookup(projectGraphNodes);
55
- return projectPaths.map((path) => {
56
- return lookup.findNodeNameByRoot(path);
57
- });
58
+ return projectPaths
59
+ .map((path) => lookup.findNodeNameByRoot(path))
60
+ .filter(Boolean);
58
61
  };
59
62
  class RootPathLookup {
60
63
  constructor(nodes) {
@@ -11,5 +11,6 @@ export declare class NoopChildProcess implements RunningTask {
11
11
  terminalOutput: string;
12
12
  }>;
13
13
  kill(): void;
14
- onExit(cb: (code: number) => void): void;
14
+ onExit(cb: (code: number, terminalOutput: string) => void): void;
15
+ onOutput(cb: (terminalOutput: string) => void): void;
15
16
  }
@@ -13,7 +13,10 @@ class NoopChildProcess {
13
13
  return;
14
14
  }
15
15
  onExit(cb) {
16
- cb(this.results.code);
16
+ cb(this.results.code, this.results.terminalOutput);
17
+ }
18
+ onOutput(cb) {
19
+ cb(this.results.terminalOutput);
17
20
  }
18
21
  }
19
22
  exports.NoopChildProcess = NoopChildProcess;