nx 19.6.0-canary.20240806-a3869a8 → 19.6.0-canary.20240809-d3747e0

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.
Files changed (45) hide show
  1. package/package.json +12 -12
  2. package/release/changelog-renderer/index.js +16 -1
  3. package/release/index.d.ts +1 -1
  4. package/release/index.js +2 -1
  5. package/schemas/nx-schema.json +3 -0
  6. package/src/adapter/compat.d.ts +1 -1
  7. package/src/adapter/compat.js +1 -0
  8. package/src/command-line/connect/connect-to-nx-cloud.js +7 -3
  9. package/src/command-line/release/changelog.d.ts +2 -7
  10. package/src/command-line/release/changelog.js +415 -363
  11. package/src/command-line/release/command-object.d.ts +1 -0
  12. package/src/command-line/release/command-object.js +14 -0
  13. package/src/command-line/release/config/deep-merge-json.d.ts +1 -0
  14. package/src/command-line/release/config/deep-merge-json.js +28 -0
  15. package/src/command-line/release/config/version-plans.d.ts +5 -0
  16. package/src/command-line/release/config/version-plans.js +9 -5
  17. package/src/command-line/release/index.d.ts +16 -4
  18. package/src/command-line/release/index.js +23 -9
  19. package/src/command-line/release/plan.d.ts +2 -1
  20. package/src/command-line/release/plan.js +93 -100
  21. package/src/command-line/release/publish.d.ts +2 -6
  22. package/src/command-line/release/publish.js +67 -54
  23. package/src/command-line/release/release.d.ts +2 -1
  24. package/src/command-line/release/release.js +181 -165
  25. package/src/command-line/release/utils/generate-version-plan-content.js +2 -3
  26. package/src/command-line/release/utils/print-config.d.ts +7 -0
  27. package/src/command-line/release/utils/print-config.js +36 -0
  28. package/src/command-line/release/version.d.ts +7 -6
  29. package/src/command-line/release/version.js +179 -165
  30. package/src/config/nx-json.d.ts +6 -1
  31. package/src/core/graph/styles.css +1 -1
  32. package/src/devkit-internals.d.ts +2 -2
  33. package/src/devkit-internals.js +2 -2
  34. package/src/native/nx.wasm32-wasi.wasm +0 -0
  35. package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.d.ts +2 -1
  36. package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +49 -10
  37. package/src/nx-cloud/nx-cloud-tasks-runner-shell.d.ts +1 -0
  38. package/src/nx-cloud/utilities/axios.js +9 -2
  39. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +7 -2
  40. package/src/plugins/package-json/create-nodes.js +9 -1
  41. package/src/project-graph/plugins/isolation/plugin-pool.js +32 -10
  42. package/src/tasks-runner/run-command.js +6 -1
  43. package/src/tasks-runner/utils.js +14 -10
  44. package/src/utils/nx-cloud-utils.js +3 -1
  45. package/src/utils/package-manager.js +12 -3
@@ -42,7 +42,7 @@ function getNxInitDate() {
42
42
  return null;
43
43
  }
44
44
  }
45
- async function createNxCloudWorkspace(workspaceName, installationSource, nxInitDate) {
45
+ async function createNxCloudWorkspaceV1(workspaceName, installationSource, nxInitDate) {
46
46
  const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
47
47
  const response = await require('axios').post(`${apiUrl}/nx-cloud/create-org-and-workspace`, {
48
48
  workspaceName,
@@ -54,6 +54,18 @@ async function createNxCloudWorkspace(workspaceName, installationSource, nxInitD
54
54
  }
55
55
  return response.data;
56
56
  }
57
+ async function createNxCloudWorkspaceV2(workspaceName, installationSource, nxInitDate) {
58
+ const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
59
+ const response = await require('axios').post(`${apiUrl}/nx-cloud/v2/create-org-and-workspace`, {
60
+ workspaceName,
61
+ installationSource,
62
+ nxInitDate,
63
+ });
64
+ if (response.data.message) {
65
+ throw new Error(response.data.message);
66
+ }
67
+ return response.data;
68
+ }
57
69
  async function printSuccessMessage(token, installationSource, usesGithub) {
58
70
  const connectCloudUrl = await (0, url_shorten_1.createNxCloudOnboardingURL)(installationSource, token, usesGithub);
59
71
  output_1.output.note({
@@ -69,7 +81,7 @@ async function printSuccessMessage(token, installationSource, usesGithub) {
69
81
  });
70
82
  return connectCloudUrl;
71
83
  }
72
- function addNxCloudOptionsToNxJson(tree, token, directory = tree.root) {
84
+ function addNxCloudOptionsToNxJson(tree, token, directory = '') {
73
85
  const nxJsonPath = (0, path_1.join)(directory, 'nx.json');
74
86
  if (tree.exists(nxJsonPath)) {
75
87
  (0, json_1.updateJson)(tree, (0, path_1.join)(directory, 'nx.json'), (nxJson) => {
@@ -82,6 +94,19 @@ function addNxCloudOptionsToNxJson(tree, token, directory = tree.root) {
82
94
  });
83
95
  }
84
96
  }
97
+ function addNxCloudIdToNxJson(tree, nxCloudId, directory = tree.root) {
98
+ const nxJsonPath = (0, path_1.join)(directory, 'nx.json');
99
+ if (tree.exists(nxJsonPath)) {
100
+ (0, json_1.updateJson)(tree, (0, path_1.join)(directory, 'nx.json'), (nxJson) => {
101
+ const overrideUrl = process.env.NX_CLOUD_API || process.env.NRWL_API;
102
+ if (overrideUrl) {
103
+ nxJson.nxCloudUrl = overrideUrl;
104
+ }
105
+ nxJson.nxCloudId = nxCloudId;
106
+ return nxJson;
107
+ });
108
+ }
109
+ }
85
110
  async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)(tree)) {
86
111
  schema.installationSource ??= 'user';
87
112
  if (nxJson?.neverConnectToCloud) {
@@ -90,17 +115,31 @@ async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)
90
115
  }
91
116
  else {
92
117
  const usesGithub = schema.github ?? (await (0, url_shorten_1.repoUsesGithub)(schema.github));
93
- let responseFromCreateNxCloudWorkspace;
118
+ let responseFromCreateNxCloudWorkspaceV1;
119
+ let responseFromCreateNxCloudWorkspaceV2;
94
120
  // do NOT create Nx Cloud token (createNxCloudWorkspace)
95
121
  // if user is using github and is running nx-connect
96
122
  if (!(usesGithub && schema.installationSource === 'nx-connect')) {
97
- responseFromCreateNxCloudWorkspace = await createNxCloudWorkspace(getRootPackageName(tree), schema.installationSource, getNxInitDate());
98
- addNxCloudOptionsToNxJson(tree, responseFromCreateNxCloudWorkspace?.token, schema.directory);
99
- await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
100
- silent: schema.hideFormatLogs,
101
- });
102
- return responseFromCreateNxCloudWorkspace.token;
123
+ if (process.env.NX_ENABLE_LOGIN === 'true') {
124
+ responseFromCreateNxCloudWorkspaceV2 = await createNxCloudWorkspaceV2(getRootPackageName(tree), schema.installationSource, getNxInitDate());
125
+ addNxCloudIdToNxJson(tree, responseFromCreateNxCloudWorkspaceV2?.nxCloudId, schema.directory);
126
+ await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
127
+ silent: schema.hideFormatLogs,
128
+ });
129
+ return responseFromCreateNxCloudWorkspaceV2.nxCloudId;
130
+ }
131
+ else {
132
+ responseFromCreateNxCloudWorkspaceV1 = await createNxCloudWorkspaceV1(getRootPackageName(tree), schema.installationSource, getNxInitDate());
133
+ addNxCloudOptionsToNxJson(tree, responseFromCreateNxCloudWorkspaceV1?.token, schema.directory);
134
+ await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
135
+ silent: schema.hideFormatLogs,
136
+ });
137
+ return responseFromCreateNxCloudWorkspaceV1.token;
138
+ }
103
139
  }
104
140
  }
105
141
  }
106
- exports.default = connectToNxCloud;
142
+ async function connectToNxCloudGenerator(tree, options) {
143
+ await connectToNxCloud(tree, options);
144
+ }
145
+ exports.default = connectToNxCloudGenerator;
@@ -11,5 +11,6 @@ export interface CloudTaskRunnerOptions extends DefaultTasksRunnerOptions {
11
11
  url?: string;
12
12
  useLightClient?: boolean;
13
13
  clientVersion?: string;
14
+ nxCloudId?: string;
14
15
  }
15
16
  export declare const nxCloudTasksRunnerShell: TasksRunner<CloudTaskRunnerOptions>;
@@ -8,8 +8,15 @@ function createApiAxiosInstance(options) {
8
8
  let axiosConfigBuilder = (axiosConfig) => axiosConfig;
9
9
  const baseUrl = process.env.NX_CLOUD_API || options.url || 'https://cloud.nx.app';
10
10
  const accessToken = environment_1.ACCESS_TOKEN ? environment_1.ACCESS_TOKEN : options.accessToken;
11
- if (!accessToken) {
12
- throw new Error(`Unable to authenticate. Either define accessToken in nx.json or set the NX_CLOUD_ACCESS_TOKEN env variable.`);
11
+ const nxCloudId = options.nxCloudId;
12
+ // TODO(lourw): Update message with NxCloudId once it is supported
13
+ if (!accessToken && !nxCloudId) {
14
+ if (process.env.NX_ENABLE_LOGIN === 'true' && !nxCloudId) {
15
+ throw new Error(`Unable to authenticate. Please connect your workspace to Nx Cloud to define a valid Nx Cloud Id. If you are in a CI context, please set the NX_CLOUD_ACCESS_TOKEN environment variable or define an access token in your nx.json.`);
16
+ }
17
+ else {
18
+ throw new Error(`Unable to authenticate. Either define accessToken in nx.json or set the NX_CLOUD_ACCESS_TOKEN env variable. If you do not want to use Nx Cloud for this command, either set NX_NO_CLOUD=true, or pass the --no-cloud flag.`);
19
+ }
13
20
  }
14
21
  if (options.customProxyConfigPath) {
15
22
  const { nxCloudProxyConfig } = require((0, path_1.join)(process.cwd(), options.customProxyConfigPath));
@@ -141,9 +141,14 @@ class TargetProjectLocator {
141
141
  }
142
142
  const version = (0, semver_1.clean)(externalPackageJson.version);
143
143
  const npmProjectKey = `npm:${externalPackageJson.name}@${version}`;
144
- const matchingExternalNode = this.npmProjects[npmProjectKey];
144
+ let matchingExternalNode = this.npmProjects[npmProjectKey];
145
145
  if (!matchingExternalNode) {
146
- return null;
146
+ // check if it's a package alias, where the resolved package key is used as the version
147
+ const aliasNpmProjectKey = `npm:${packageName}@${npmProjectKey}`;
148
+ matchingExternalNode = this.npmProjects[aliasNpmProjectKey];
149
+ if (!matchingExternalNode) {
150
+ return null;
151
+ }
147
152
  }
148
153
  this.npmResolutionCache.set(npmImportForProject, matchingExternalNode.name);
149
154
  return matchingExternalNode.name;
@@ -90,7 +90,15 @@ function buildProjectConfigurationFromPackageJson(packageJson, workspaceRoot, pa
90
90
  const siblingProjectJson = tryReadJson((0, node_path_1.join)(workspaceRoot, projectRoot, 'project.json'));
91
91
  if (siblingProjectJson) {
92
92
  for (const target of Object.keys(siblingProjectJson?.targets ?? {})) {
93
- delete packageJson.scripts?.[target];
93
+ const { executor, command, options } = siblingProjectJson.targets[target];
94
+ if (
95
+ // will use run-commands, different target
96
+ command ||
97
+ // Either uses a different executor or runs a different script
98
+ (executor &&
99
+ (executor !== 'nx:run-script' || options?.script !== target))) {
100
+ delete packageJson.scripts?.[target];
101
+ }
94
102
  }
95
103
  }
96
104
  if (!packageJson.name && projectRoot === '.') {
@@ -13,7 +13,11 @@ const exit_codes_1 = require("../../../utils/exit-codes");
13
13
  const messaging_1 = require("./messaging");
14
14
  const cleanupFunctions = new Set();
15
15
  const pluginNames = new Map();
16
- const MAX_MESSAGE_WAIT = 1000 * 60 * 5; // 5 minutes
16
+ const PLUGIN_TIMEOUT_HINT_TEXT = 'As a last resort, you can set NX_PLUGIN_NO_TIMEOUTS=true to bypass this timeout.';
17
+ const MINUTES = 10;
18
+ const MAX_MESSAGE_WAIT = process.env.NX_PLUGIN_NO_TIMEOUTS === 'true'
19
+ ? undefined
20
+ : 1000 * 60 * MINUTES; // 10 minutes
17
21
  const nxPluginWorkerCache = (global['nxPluginWorkerCache'] ??= new Map());
18
22
  async function loadRemoteNxPlugin(plugin, root) {
19
23
  const cacheKey = JSON.stringify({ plugin, root });
@@ -36,11 +40,14 @@ async function loadRemoteNxPlugin(plugin, root) {
36
40
  payload: { plugin, root },
37
41
  });
38
42
  // logger.verbose(`[plugin-worker] started worker: ${worker.pid}`);
39
- const loadTimeout = setTimeout(() => {
40
- rej(new Error('Plugin worker timed out when loading plugin:' + plugin));
41
- }, MAX_MESSAGE_WAIT);
43
+ const loadTimeout = MAX_MESSAGE_WAIT
44
+ ? setTimeout(() => {
45
+ rej(new Error(`Loading "${plugin}" timed out after ${MINUTES} minutes. ${PLUGIN_TIMEOUT_HINT_TEXT}`));
46
+ }, MAX_MESSAGE_WAIT)
47
+ : undefined;
42
48
  socket.on('data', (0, consume_messages_from_socket_1.consumeMessagesFromSocket)(createWorkerHandler(worker, pendingPromises, (val) => {
43
- clearTimeout(loadTimeout);
49
+ if (loadTimeout)
50
+ clearTimeout(loadTimeout);
44
51
  res(val);
45
52
  }, rej, socket)));
46
53
  worker.on('exit', exitHandler);
@@ -90,6 +97,9 @@ function createWorkerHandler(worker, pending, onload, onloadError, socket) {
90
97
  type: 'createNodes',
91
98
  payload: { configFiles, context: ctx, tx },
92
99
  });
100
+ }, {
101
+ plugin: pluginName,
102
+ operation: 'createNodes',
93
103
  });
94
104
  },
95
105
  ]
@@ -102,6 +112,9 @@ function createWorkerHandler(worker, pending, onload, onloadError, socket) {
102
112
  type: 'createDependencies',
103
113
  payload: { context: ctx, tx },
104
114
  });
115
+ }, {
116
+ plugin: pluginName,
117
+ operation: 'createDependencies',
105
118
  });
106
119
  }
107
120
  : undefined,
@@ -113,6 +126,9 @@ function createWorkerHandler(worker, pending, onload, onloadError, socket) {
113
126
  type: 'processProjectGraph',
114
127
  payload: { graph, ctx, tx },
115
128
  });
129
+ }, {
130
+ operation: 'processProjectGraph',
131
+ plugin: pluginName,
116
132
  });
117
133
  }
118
134
  : undefined,
@@ -124,6 +140,9 @@ function createWorkerHandler(worker, pending, onload, onloadError, socket) {
124
140
  type: 'createMetadata',
125
141
  payload: { graph, context: ctx, tx },
126
142
  });
143
+ }, {
144
+ plugin: pluginName,
145
+ operation: 'createMetadata',
127
146
  });
128
147
  }
129
148
  : undefined,
@@ -192,18 +211,21 @@ process.on('SIGINT', () => {
192
211
  process.exit((0, exit_codes_1.signalToCode)('SIGINT'));
193
212
  });
194
213
  process.on('SIGTERM', exitHandler);
195
- function registerPendingPromise(tx, pending, callback) {
214
+ function registerPendingPromise(tx, pending, callback, context) {
196
215
  let resolver, rejector, timeout;
197
216
  const promise = new Promise((res, rej) => {
198
217
  rejector = rej;
199
218
  resolver = res;
200
- timeout = setTimeout(() => {
201
- rej(new Error(`Plugin worker timed out when processing message ${tx}`));
202
- }, MAX_MESSAGE_WAIT);
219
+ timeout = MAX_MESSAGE_WAIT
220
+ ? setTimeout(() => {
221
+ rej(new Error(`${context.plugin} timed out after ${MINUTES} minutes during ${context.operation}. ${PLUGIN_TIMEOUT_HINT_TEXT}`));
222
+ }, MAX_MESSAGE_WAIT)
223
+ : undefined;
203
224
  callback();
204
225
  }).finally(() => {
205
226
  pending.delete(tx);
206
- clearTimeout(timeout);
227
+ if (timeout)
228
+ clearTimeout(timeout);
207
229
  });
208
230
  pending.set(tx, {
209
231
  promise,
@@ -318,7 +318,9 @@ function getTasksRunnerPath(runner, nxJson) {
318
318
  // No runner prop in tasks runner options, check if access token is set.
319
319
  nxJson.tasksRunnerOptions?.[runner]?.options?.accessToken ||
320
320
  // Cloud access token specified in env var.
321
- process.env.NX_CLOUD_ACCESS_TOKEN;
321
+ process.env.NX_CLOUD_ACCESS_TOKEN ||
322
+ // Nx Cloud Id specified in nxJson
323
+ nxJson.nxCloudId;
322
324
  return isCloudRunner ? 'nx-cloud' : require.resolve('./default-tasks-runner');
323
325
  }
324
326
  function getRunnerOptions(runner, nxJson, nxArgs, isCloudDefault) {
@@ -339,6 +341,9 @@ function getRunnerOptions(runner, nxJson, nxArgs, isCloudDefault) {
339
341
  if (nxJson.nxCloudAccessToken && isCloudDefault) {
340
342
  result.accessToken ??= nxJson.nxCloudAccessToken;
341
343
  }
344
+ if (nxJson.nxCloudId && isCloudDefault) {
345
+ result.nxCloudId ??= nxJson.nxCloudId;
346
+ }
342
347
  if (nxJson.nxCloudUrl && isCloudDefault) {
343
348
  result.url ??= nxJson.nxCloudUrl;
344
349
  }
@@ -77,27 +77,31 @@ function expandDependencyConfigSyntaxSugar(dependencyConfigString, graph) {
77
77
  }
78
78
  // Weakmap let's the cache get cleared by garbage collector if allTargetNames is no longer used
79
79
  const patternResultCache = new WeakMap();
80
- function expandWildcardTargetConfiguration(dependencyConfig, allTargetNames) {
81
- if (!(0, globs_1.isGlobPattern)(dependencyConfig.target)) {
82
- return [dependencyConfig];
83
- }
80
+ function findMatchingTargets(pattern, allTargetNames) {
84
81
  let cache = patternResultCache.get(allTargetNames);
85
82
  if (!cache) {
86
83
  cache = new Map();
87
84
  patternResultCache.set(allTargetNames, cache);
88
85
  }
89
- const cachedResult = cache.get(dependencyConfig.target);
86
+ const cachedResult = cache.get(pattern);
90
87
  if (cachedResult) {
91
88
  return cachedResult;
92
89
  }
93
- const matcher = minimatch_1.minimatch.filter(dependencyConfig.target);
90
+ const matcher = minimatch_1.minimatch.filter(pattern);
94
91
  const matchingTargets = allTargetNames.filter((t) => matcher(t));
95
- const result = matchingTargets.map((t) => ({
96
- ...dependencyConfig,
92
+ cache.set(pattern, matchingTargets);
93
+ return matchingTargets;
94
+ }
95
+ function expandWildcardTargetConfiguration(dependencyConfig, allTargetNames) {
96
+ if (!(0, globs_1.isGlobPattern)(dependencyConfig.target)) {
97
+ return [dependencyConfig];
98
+ }
99
+ const matchingTargets = findMatchingTargets(dependencyConfig.target, allTargetNames);
100
+ return matchingTargets.map((t) => ({
97
101
  target: t,
102
+ projects: dependencyConfig.projects,
103
+ dependencies: dependencyConfig.dependencies,
98
104
  }));
99
- cache.set(dependencyConfig.target, result);
100
- return result;
101
105
  }
102
106
  function readProjectAndTargetFromTargetString(targetString, projects) {
103
107
  // Support for both `project:target` and `target:with:colons` syntax
@@ -6,12 +6,14 @@ exports.getNxCloudToken = getNxCloudToken;
6
6
  function isNxCloudUsed(nxJson) {
7
7
  return (!!process.env.NX_CLOUD_ACCESS_TOKEN ||
8
8
  !!nxJson.nxCloudAccessToken ||
9
+ !!nxJson.nxCloudId ||
9
10
  !!Object.values(nxJson.tasksRunnerOptions ?? {}).find((r) => r.runner == '@nrwl/nx-cloud' || r.runner == 'nx-cloud'));
10
11
  }
11
12
  function getNxCloudUrl(nxJson) {
12
13
  const cloudRunner = Object.values(nxJson.tasksRunnerOptions ?? {}).find((r) => r.runner == '@nrwl/nx-cloud' || r.runner == 'nx-cloud');
13
14
  if (!cloudRunner &&
14
- !(nxJson.nxCloudAccessToken || process.env.NX_CLOUD_ACCESS_TOKEN))
15
+ !(nxJson.nxCloudAccessToken || process.env.NX_CLOUD_ACCESS_TOKEN) &&
16
+ !nxJson.nxCloudId)
15
17
  throw new Error('nx-cloud runner not found in nx.json');
16
18
  return cloudRunner?.options?.url ?? nxJson.nxCloudUrl ?? 'https://nx.app';
17
19
  }
@@ -176,6 +176,7 @@ function getPackageManagerVersion(packageManager = detectPackageManager(), cwd =
176
176
  version = (0, child_process_1.execSync)(`${packageManager} --version`, {
177
177
  cwd,
178
178
  encoding: 'utf-8',
179
+ windowsHide: true,
179
180
  }).trim();
180
181
  }
181
182
  catch {
@@ -349,7 +350,10 @@ async function resolvePackageVersionUsingInstallation(packageName, version) {
349
350
  const { dir, cleanup } = createTempNpmDirectory();
350
351
  try {
351
352
  const pmc = getPackageManagerCommand();
352
- await execAsync(`${pmc.add} ${packageName}@${version}`, { cwd: dir });
353
+ await execAsync(`${pmc.add} ${packageName}@${version}`, {
354
+ cwd: dir,
355
+ windowsHide: true,
356
+ });
353
357
  const { packageJson } = (0, package_json_1.readModulePackageJson)(packageName, [dir]);
354
358
  return packageJson.version;
355
359
  }
@@ -372,7 +376,9 @@ async function packageRegistryView(pkg, version, args) {
372
376
  */
373
377
  pm = 'npm';
374
378
  }
375
- const { stdout } = await execAsync(`${pm} view ${pkg}@${version} ${args}`);
379
+ const { stdout } = await execAsync(`${pm} view ${pkg}@${version} ${args}`, {
380
+ windowsHide: true,
381
+ });
376
382
  return stdout.toString().trim();
377
383
  }
378
384
  async function packageRegistryPack(cwd, pkg, version) {
@@ -389,7 +395,10 @@ async function packageRegistryPack(cwd, pkg, version) {
389
395
  */
390
396
  pm = 'npm';
391
397
  }
392
- const { stdout } = await execAsync(`${pm} pack ${pkg}@${version}`, { cwd });
398
+ const { stdout } = await execAsync(`${pm} pack ${pkg}@${version}`, {
399
+ cwd,
400
+ windowsHide: true,
401
+ });
393
402
  const tarballPath = stdout.trim();
394
403
  return { tarballPath };
395
404
  }