nx 18.2.0-canary.20240316-b69047e → 18.2.0-canary.20240320-64b2396

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.
@@ -47,11 +47,10 @@ async function default_1(options, context) {
47
47
  !options.parallel) {
48
48
  throw new Error('ERROR: Bad executor config for run-commands - "prefix", "color" and "bgColor" can only be set when "parallel=true".');
49
49
  }
50
- const terminal = (0, pseudo_terminal_1.getPseudoTerminal)();
51
50
  try {
52
51
  const result = options.parallel
53
- ? await runInParallel(terminal, normalized, context)
54
- : await runSerially(terminal, normalized, context);
52
+ ? await runInParallel(normalized, context)
53
+ : await runSerially(normalized, context);
55
54
  return result;
56
55
  }
57
56
  catch (e) {
@@ -62,8 +61,8 @@ async function default_1(options, context) {
62
61
  }
63
62
  }
64
63
  exports.default = default_1;
65
- async function runInParallel(pseudoTerminal, options, context) {
66
- const procs = options.commands.map((c) => createProcess(pseudoTerminal, c, options.readyWhen, options.color, calculateCwd(options.cwd, context), options.env ?? {}, true, options.usePty, options.streamOutput).then((result) => ({
64
+ async function runInParallel(options, context) {
65
+ const procs = options.commands.map((c) => createProcess(null, c, options.readyWhen, options.color, calculateCwd(options.cwd, context), options.env ?? {}, true, options.usePty, options.streamOutput).then((result) => ({
67
66
  result,
68
67
  command: c.command,
69
68
  })));
@@ -135,7 +134,10 @@ function normalizeOptions(options) {
135
134
  });
136
135
  return options;
137
136
  }
138
- async function runSerially(pseudoTerminal, options, context) {
137
+ async function runSerially(options, context) {
138
+ const pseudoTerminal = pseudo_terminal_1.PseudoTerminal.isSupported()
139
+ ? (0, pseudo_terminal_1.getPseudoTerminal)()
140
+ : null;
139
141
  let terminalOutput = '';
140
142
  for (const c of options.commands) {
141
143
  const result = await createProcess(pseudoTerminal, c, undefined, options.color, calculateCwd(options.cwd, context), options.env ?? {}, false, options.usePty, options.streamOutput);
@@ -155,8 +157,8 @@ async function createProcess(pseudoTerminal, commandConfig, readyWhen, color, cw
155
157
  env = processEnv(color, cwd, env);
156
158
  // The rust runCommand is always a tty, so it will not look nice in parallel and if we need prefixes
157
159
  // currently does not work properly in windows
158
- if (process.env.NX_NATIVE_COMMAND_RUNNER !== 'false' &&
159
- process.stdout.isTTY &&
160
+ if (pseudoTerminal &&
161
+ process.env.NX_NATIVE_COMMAND_RUNNER !== 'false' &&
160
162
  !commandConfig.prefix &&
161
163
  !isParallel &&
162
164
  usePty) {
@@ -265,7 +267,11 @@ function processEnv(color, cwd, env) {
265
267
  ...localEnv,
266
268
  ...env,
267
269
  };
268
- res.PATH = localEnv.PATH; // need to override PATH to make sure we are using the local node_modules
270
+ // need to override PATH to make sure we are using the local node_modules
271
+ if (localEnv.PATH)
272
+ res.PATH = localEnv.PATH; // UNIX-like
273
+ if (localEnv.Path)
274
+ res.Path = localEnv.Path; // Windows
269
275
  if (color) {
270
276
  res.FORCE_COLOR = `${color}`;
271
277
  }
@@ -17,7 +17,7 @@ async function default_1(options, context) {
17
17
  .filter((p) => !p.startsWith(path.join(context.root, 'node_modules')))
18
18
  .join(path.delimiter) ?? '';
19
19
  env.PATH = filteredPath;
20
- if (process.stdout.isTTY) {
20
+ if (pseudo_terminal_1.PseudoTerminal.isSupported()) {
21
21
  await ptyProcess(command, cwd, env);
22
22
  }
23
23
  else {
@@ -1 +1 @@
1
- export declare const typescriptVersion = "~5.3.2";
1
+ export declare const typescriptVersion = "~5.4.2";
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.typescriptVersion = void 0;
4
- exports.typescriptVersion = '~5.3.2';
4
+ exports.typescriptVersion = '~5.4.2';
@@ -32,17 +32,27 @@ skipCommandNormalization) {
32
32
  // a project.json in which case it was already updated above.
33
33
  const updatedProjectConfiguration = {
34
34
  ...matchingProject,
35
- ...project,
36
35
  };
37
- if (sourceMap) {
38
- for (const property in project) {
39
- sourceMap[`${property}`] = sourceInformation;
36
+ for (const k in project) {
37
+ if (![
38
+ 'tags',
39
+ 'implicitDependencies',
40
+ 'generators',
41
+ 'targets',
42
+ 'metadata',
43
+ 'namedInputs',
44
+ ].includes(k)) {
45
+ updatedProjectConfiguration[k] = project[k];
46
+ if (sourceMap) {
47
+ sourceMap[`${k}`] = sourceInformation;
48
+ }
40
49
  }
41
50
  }
42
51
  // The next blocks handle properties that should be themselves merged (e.g. targets, tags, and implicit dependencies)
43
52
  if (project.tags) {
44
53
  updatedProjectConfiguration.tags = Array.from(new Set((matchingProject.tags ?? []).concat(project.tags)));
45
54
  if (sourceMap) {
55
+ sourceMap['tags'] ??= sourceInformation;
46
56
  project.tags.forEach((tag) => {
47
57
  sourceMap[`tags.${tag}`] = sourceInformation;
48
58
  });
@@ -51,6 +61,7 @@ skipCommandNormalization) {
51
61
  if (project.implicitDependencies) {
52
62
  updatedProjectConfiguration.implicitDependencies = (matchingProject.implicitDependencies ?? []).concat(project.implicitDependencies);
53
63
  if (sourceMap) {
64
+ sourceMap['implicitDependencies'] ??= sourceInformation;
54
65
  project.implicitDependencies.forEach((implicitDependency) => {
55
66
  sourceMap[`implicitDependencies.${implicitDependency}`] =
56
67
  sourceInformation;
@@ -61,6 +72,7 @@ skipCommandNormalization) {
61
72
  // Start with generators config in new project.
62
73
  updatedProjectConfiguration.generators = { ...project.generators };
63
74
  if (sourceMap) {
75
+ sourceMap['generators'] ??= sourceInformation;
64
76
  for (const generator in project.generators) {
65
77
  sourceMap[`generators.${generator}`] = sourceInformation;
66
78
  for (const property in project.generators[generator]) {
@@ -85,6 +97,7 @@ skipCommandNormalization) {
85
97
  ...project.namedInputs,
86
98
  };
87
99
  if (sourceMap) {
100
+ sourceMap['namedInputs'] ??= sourceInformation;
88
101
  for (const namedInput in project.namedInputs) {
89
102
  sourceMap[`namedInputs.${namedInput}`] = sourceInformation;
90
103
  }
@@ -94,6 +107,9 @@ skipCommandNormalization) {
94
107
  // We merge the targets with special handling, so clear this back to the
95
108
  // targets as defined originally before merging.
96
109
  updatedProjectConfiguration.targets = matchingProject?.targets ?? {};
110
+ if (sourceMap) {
111
+ sourceMap['targets'] ??= sourceInformation;
112
+ }
97
113
  // For each target defined in the new config
98
114
  for (const targetName in project.targets) {
99
115
  // Always set source map info for the target, but don't overwrite info already there
@@ -117,6 +133,75 @@ skipCommandNormalization) {
117
133
  updatedProjectConfiguration.targets[targetName] = mergedTarget;
118
134
  }
119
135
  }
136
+ if (project.metadata) {
137
+ if (sourceMap) {
138
+ sourceMap['targets'] ??= sourceInformation;
139
+ }
140
+ for (const [metadataKey, value] of Object.entries({
141
+ ...project.metadata,
142
+ })) {
143
+ const existingValue = matchingProject.metadata?.[metadataKey];
144
+ if (Array.isArray(value) && Array.isArray(existingValue)) {
145
+ for (const item of [...value]) {
146
+ const newLength = updatedProjectConfiguration.metadata[metadataKey].push(item);
147
+ if (sourceMap) {
148
+ sourceMap[`metadata.${metadataKey}.${newLength - 1}`] =
149
+ sourceInformation;
150
+ }
151
+ }
152
+ }
153
+ else if (Array.isArray(value) && existingValue === undefined) {
154
+ updatedProjectConfiguration.metadata ??= {};
155
+ updatedProjectConfiguration.metadata[metadataKey] ??= value;
156
+ if (sourceMap) {
157
+ sourceMap[`metadata.${metadataKey}`] = sourceInformation;
158
+ }
159
+ for (let i = 0; i < value.length; i++) {
160
+ if (sourceMap) {
161
+ sourceMap[`metadata.${metadataKey}.${i}`] = sourceInformation;
162
+ }
163
+ }
164
+ }
165
+ else if (typeof value === 'object' &&
166
+ typeof existingValue === 'object') {
167
+ for (const key in value) {
168
+ const existingValue = matchingProject.metadata?.[metadataKey]?.[key];
169
+ if (Array.isArray(value[key]) && Array.isArray(existingValue)) {
170
+ for (const item of value[key]) {
171
+ const i = updatedProjectConfiguration.metadata[metadataKey][key].push(item);
172
+ if (sourceMap) {
173
+ sourceMap[`metadata.${metadataKey}.${key}.${i - 1}`] =
174
+ sourceInformation;
175
+ }
176
+ }
177
+ }
178
+ else {
179
+ updatedProjectConfiguration.metadata[metadataKey] = value;
180
+ if (sourceMap) {
181
+ sourceMap[`metadata.${metadataKey}`] = sourceInformation;
182
+ }
183
+ }
184
+ }
185
+ }
186
+ else {
187
+ updatedProjectConfiguration.metadata[metadataKey] = value;
188
+ if (sourceMap) {
189
+ sourceMap[`metadata.${metadataKey}`] = sourceInformation;
190
+ if (typeof value === 'object') {
191
+ for (const k in value) {
192
+ sourceMap[`metadata.${metadataKey}.${k}`] = sourceInformation;
193
+ if (Array.isArray(value[k])) {
194
+ for (let i = 0; i < value[k].length; i++) {
195
+ sourceMap[`metadata.${metadataKey}.${k}.${i}`] =
196
+ sourceInformation;
197
+ }
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
120
205
  projectRootMap.set(updatedProjectConfiguration.root, updatedProjectConfiguration);
121
206
  }
122
207
  exports.mergeProjectConfigurationIntoRootMap = mergeProjectConfigurationIntoRootMap;
@@ -22,12 +22,13 @@ export declare class ForkedProcessTaskRunner {
22
22
  code: number;
23
23
  terminalOutput: string;
24
24
  }>;
25
- forkProcess(task: Task, { temporaryOutputPath, streamOutput, pipeOutput, taskGraph, env, }: {
25
+ forkProcess(task: Task, { temporaryOutputPath, streamOutput, taskGraph, env, disablePseudoTerminal, }: {
26
26
  temporaryOutputPath: string;
27
27
  streamOutput: boolean;
28
28
  pipeOutput: boolean;
29
29
  taskGraph: TaskGraph;
30
30
  env: NodeJS.ProcessEnv;
31
+ disablePseudoTerminal: boolean;
31
32
  }): Promise<{
32
33
  code: number;
33
34
  terminalOutput: string;
@@ -21,10 +21,14 @@ class ForkedProcessTaskRunner {
21
21
  this.cliPath = (0, utils_1.getCliPath)();
22
22
  this.verbose = process.env.NX_VERBOSE_LOGGING === 'true';
23
23
  this.processes = new Set();
24
- this.pseudoTerminal = (0, pseudo_terminal_1.getPseudoTerminal)();
24
+ this.pseudoTerminal = pseudo_terminal_1.PseudoTerminal.isSupported()
25
+ ? (0, pseudo_terminal_1.getPseudoTerminal)()
26
+ : null;
25
27
  }
26
28
  async init() {
27
- await this.pseudoTerminal.init();
29
+ if (this.pseudoTerminal) {
30
+ await this.pseudoTerminal.init();
31
+ }
28
32
  this.setupProcessEventListeners();
29
33
  }
30
34
  // TODO: vsavkin delegate terminal output printing
@@ -104,11 +108,14 @@ class ForkedProcessTaskRunner {
104
108
  env,
105
109
  });
106
110
  }
107
- async forkProcess(task, { temporaryOutputPath, streamOutput, pipeOutput, taskGraph, env, }) {
111
+ async forkProcess(task, { temporaryOutputPath, streamOutput, taskGraph, env, disablePseudoTerminal, }) {
108
112
  const shouldPrefix = streamOutput && process.env.NX_PREFIX_OUTPUT === 'true';
109
113
  // streamOutput would be false if we are running multiple targets
110
114
  // there's no point in running the commands in a pty if we are not streaming the output
111
- if (!streamOutput || shouldPrefix || !process.stdout.isTTY) {
115
+ if (!this.pseudoTerminal ||
116
+ disablePseudoTerminal ||
117
+ !streamOutput ||
118
+ shouldPrefix) {
112
119
  return this.forkProcessWithPrefixAndNotTTY(task, {
113
120
  temporaryOutputPath,
114
121
  streamOutput,
@@ -303,13 +310,17 @@ class ForkedProcessTaskRunner {
303
310
  (0, fs_1.writeFileSync)(outputPath, content);
304
311
  }
305
312
  setupProcessEventListeners() {
306
- this.pseudoTerminal.onMessageFromChildren((message) => {
307
- process.send(message);
308
- });
313
+ if (this.pseudoTerminal) {
314
+ this.pseudoTerminal.onMessageFromChildren((message) => {
315
+ process.send(message);
316
+ });
317
+ }
309
318
  // When the nx process gets a message, it will be sent into the task's process
310
319
  process.on('message', (message) => {
311
320
  // this.publisher.publish(message.toString());
312
- this.pseudoTerminal.sendMessageToChildren(message);
321
+ if (this.pseudoTerminal) {
322
+ this.pseudoTerminal.sendMessageToChildren(message);
323
+ }
313
324
  this.processes.forEach((p) => {
314
325
  if ('connected' in p && p.connected) {
315
326
  p.send(message);
@@ -2,12 +2,13 @@
2
2
  import { ChildProcess, RustPseudoTerminal } from '../native';
3
3
  import { PseudoIPCServer } from './pseudo-ipc';
4
4
  import { Serializable } from 'child_process';
5
- export declare function getPseudoTerminal(): PseudoTerminal;
5
+ export declare function getPseudoTerminal(skipSupportCheck?: boolean): PseudoTerminal;
6
6
  export declare class PseudoTerminal {
7
7
  private rustPseudoTerminal;
8
8
  private pseudoIPCPath;
9
9
  private pseudoIPC;
10
10
  private initialized;
11
+ static isSupported(): boolean;
11
12
  constructor(rustPseudoTerminal: RustPseudoTerminal);
12
13
  init(): Promise<void>;
13
14
  runCommand(command: string, { cwd, jsEnv, quiet, }?: {
@@ -4,13 +4,20 @@ exports.PseudoTtyProcessWithSend = exports.PseudoTtyProcess = exports.PseudoTerm
4
4
  const native_1 = require("../native");
5
5
  const pseudo_ipc_1 = require("./pseudo-ipc");
6
6
  const socket_utils_1 = require("../daemon/socket-utils");
7
+ const os = require("os");
7
8
  let pseudoTerminal;
8
- function getPseudoTerminal() {
9
+ function getPseudoTerminal(skipSupportCheck = false) {
10
+ if (!skipSupportCheck && !PseudoTerminal.isSupported()) {
11
+ throw new Error('Pseudo terminal is not supported on this platform.');
12
+ }
9
13
  pseudoTerminal ??= new PseudoTerminal(new native_1.RustPseudoTerminal());
10
14
  return pseudoTerminal;
11
15
  }
12
16
  exports.getPseudoTerminal = getPseudoTerminal;
13
17
  class PseudoTerminal {
18
+ static isSupported() {
19
+ return process.stdout.isTTY && supportedPtyPlatform();
20
+ }
14
21
  constructor(rustPseudoTerminal) {
15
22
  this.rustPseudoTerminal = rustPseudoTerminal;
16
23
  this.pseudoIPCPath = (0, socket_utils_1.FORKED_PROCESS_OS_SOCKET_PATH)(process.pid.toString());
@@ -131,3 +138,22 @@ function messageToCode(message) {
131
138
  return 1;
132
139
  }
133
140
  }
141
+ function supportedPtyPlatform() {
142
+ if (process.platform !== 'win32') {
143
+ return true;
144
+ }
145
+ let windowsVersion = os.release().split('.');
146
+ let windowsBuild = windowsVersion[2];
147
+ if (!windowsBuild) {
148
+ return false;
149
+ }
150
+ // Mininum supported Windows version:
151
+ // https://en.wikipedia.org/wiki/Windows_10,_version_1809
152
+ // https://learn.microsoft.com/en-us/windows/console/createpseudoconsole#requirements
153
+ if (+windowsBuild < 17763) {
154
+ return false;
155
+ }
156
+ else {
157
+ return true;
158
+ }
159
+ }
@@ -11,7 +11,6 @@ const utils_1 = require("./utils");
11
11
  const tasks_schedule_1 = require("./tasks-schedule");
12
12
  const hash_task_1 = require("../hasher/hash-task");
13
13
  const task_env_1 = require("./task-env");
14
- const os = require("os");
15
14
  const workspace_root_1 = require("../utils/workspace-root");
16
15
  const output_1 = require("../utils/output");
17
16
  const params_1 = require("../utils/params");
@@ -253,8 +252,9 @@ class TaskOrchestrator {
253
252
  }
254
253
  async runTaskInForkedProcess(task, env, pipeOutput, temporaryOutputPath, streamOutput) {
255
254
  try {
256
- let usePtyFork = process.env.NX_NATIVE_COMMAND_RUNNER !== 'false' &&
257
- supportedPtyPlatform();
255
+ const usePtyFork = process.env.NX_NATIVE_COMMAND_RUNNER !== 'false';
256
+ // Disable the pseudo terminal if this is a run-many
257
+ const disablePseudoTerminal = !this.initiatingProject;
258
258
  // execution
259
259
  const { code, terminalOutput } = usePtyFork
260
260
  ? await this.forkedProcessTaskRunner.forkProcess(task, {
@@ -263,6 +263,7 @@ class TaskOrchestrator {
263
263
  pipeOutput,
264
264
  taskGraph: this.taskGraph,
265
265
  env,
266
+ disablePseudoTerminal,
266
267
  })
267
268
  : await this.forkedProcessTaskRunner.forkProcessLegacy(task, {
268
269
  temporaryOutputPath,
@@ -412,22 +413,3 @@ class TaskOrchestrator {
412
413
  }
413
414
  }
414
415
  exports.TaskOrchestrator = TaskOrchestrator;
415
- function supportedPtyPlatform() {
416
- if (process.platform !== 'win32') {
417
- return true;
418
- }
419
- let windowsVersion = os.release().split('.');
420
- let windowsBuild = windowsVersion[2];
421
- if (!windowsBuild) {
422
- return false;
423
- }
424
- // Mininum supported Windows version:
425
- // https://en.wikipedia.org/wiki/Windows_10,_version_1809
426
- // https://learn.microsoft.com/en-us/windows/console/createpseudoconsole#requirements
427
- if (+windowsBuild < 17763) {
428
- return false;
429
- }
430
- else {
431
- return true;
432
- }
433
- }