nx 19.2.0-canary.20240528-7f11a1d → 19.2.0-canary.20240531-2cb7ecb

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 (27) hide show
  1. package/package.json +12 -12
  2. package/src/devkit-exports.d.ts +3 -1
  3. package/src/devkit-exports.js +5 -1
  4. package/src/devkit-internals.d.ts +1 -0
  5. package/src/devkit-internals.js +3 -1
  6. package/src/plugins/js/lock-file/pnpm-parser.js +1 -1
  7. package/src/plugins/js/project-graph/build-dependencies/build-dependencies.js +16 -3
  8. package/src/plugins/js/project-graph/build-dependencies/explicit-package-json-dependencies.d.ts +2 -1
  9. package/src/plugins/js/project-graph/build-dependencies/explicit-package-json-dependencies.js +40 -27
  10. package/src/plugins/js/project-graph/build-dependencies/explicit-project-dependencies.d.ts +2 -1
  11. package/src/plugins/js/project-graph/build-dependencies/explicit-project-dependencies.js +14 -19
  12. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.d.ts +32 -5
  13. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +146 -47
  14. package/src/plugins/js/utils/resolve-relative-to-dir.d.ts +5 -0
  15. package/src/plugins/js/utils/resolve-relative-to-dir.js +18 -0
  16. package/src/project-graph/error-types.d.ts +37 -19
  17. package/src/project-graph/error-types.js +31 -19
  18. package/src/project-graph/plugins/index.d.ts +1 -0
  19. package/src/project-graph/plugins/index.js +3 -1
  20. package/src/project-graph/plugins/internal-api.d.ts +2 -2
  21. package/src/project-graph/plugins/internal-api.js +33 -3
  22. package/src/project-graph/plugins/public-api.d.ts +34 -3
  23. package/src/project-graph/plugins/utils.d.ts +4 -3
  24. package/src/project-graph/plugins/utils.js +13 -26
  25. package/src/project-graph/utils/project-configuration-utils.js +89 -74
  26. package/src/tasks-runner/utils.js +18 -4
  27. package/src/utils/print-help.js +1 -1
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runCreateNodesInParallel = exports.normalizeNxPlugin = exports.isNxPluginV1 = exports.isNxPluginV2 = void 0;
3
+ exports.createNodesFromFiles = exports.normalizeNxPlugin = exports.isNxPluginV1 = exports.isNxPluginV2 = void 0;
4
4
  const node_path_1 = require("node:path");
5
5
  const to_project_name_1 = require("../../config/to-project-name");
6
6
  const globs_1 = require("../../utils/globs");
7
7
  const error_types_1 = require("../error-types");
8
- const perf_hooks_1 = require("perf_hooks");
9
8
  function isNxPluginV2(plugin) {
10
9
  return 'createNodes' in plugin || 'createDependencies' in plugin;
11
10
  }
@@ -40,36 +39,24 @@ function normalizeNxPlugin(plugin) {
40
39
  return plugin;
41
40
  }
42
41
  exports.normalizeNxPlugin = normalizeNxPlugin;
43
- async function runCreateNodesInParallel(configFiles, plugin, options, context) {
44
- perf_hooks_1.performance.mark(`${plugin.name}:createNodes - start`);
45
- const errors = [];
42
+ async function createNodesFromFiles(createNodes, configFiles, options, context) {
46
43
  const results = [];
47
- const promises = configFiles.map(async (file) => {
44
+ const errors = [];
45
+ await Promise.all(configFiles.map(async (file) => {
48
46
  try {
49
- const value = await plugin.createNodes[1](file, options, context);
50
- if (value) {
51
- results.push({
52
- ...value,
53
- file,
54
- pluginName: plugin.name,
55
- });
56
- }
47
+ const value = await createNodes(file, options, {
48
+ ...context,
49
+ configFiles,
50
+ });
51
+ results.push([file, value]);
57
52
  }
58
53
  catch (e) {
59
- errors.push(new error_types_1.CreateNodesError({
60
- error: e,
61
- pluginName: plugin.name,
62
- file,
63
- }));
54
+ errors.push([file, e]);
64
55
  }
65
- });
66
- await Promise.all(promises).then(() => {
67
- perf_hooks_1.performance.mark(`${plugin.name}:createNodes - end`);
68
- perf_hooks_1.performance.measure(`${plugin.name}:createNodes`, `${plugin.name}:createNodes - start`, `${plugin.name}:createNodes - end`);
69
- });
56
+ }));
70
57
  if (errors.length > 0) {
71
- throw new error_types_1.AggregateCreateNodesError(plugin.name, errors, results);
58
+ throw new error_types_1.AggregateCreateNodesError(errors, results);
72
59
  }
73
60
  return results;
74
61
  }
75
- exports.runCreateNodesInParallel = runCreateNodesInParallel;
62
+ exports.createNodesFromFiles = createNodesFromFiles;
@@ -227,92 +227,35 @@ plugins) {
227
227
  const results = [];
228
228
  const errors = [];
229
229
  // We iterate over plugins first - this ensures that plugins specified first take precedence.
230
- for (const { name: pluginName, createNodes: createNodesTuple, include, exclude, } of plugins) {
230
+ for (const { createNodes: createNodesTuple, include, exclude, name: pluginName, } of plugins) {
231
231
  const [pattern, createNodes] = createNodesTuple ?? [];
232
232
  if (!pattern) {
233
233
  continue;
234
234
  }
235
- const matchingConfigFiles = [];
236
- for (const file of projectFiles) {
237
- if ((0, minimatch_1.minimatch)(file, pattern, { dot: true })) {
238
- if (include) {
239
- const included = include.some((includedPattern) => (0, minimatch_1.minimatch)(file, includedPattern, { dot: true }));
240
- if (!included) {
241
- continue;
242
- }
243
- }
244
- if (exclude) {
245
- const excluded = exclude.some((excludedPattern) => (0, minimatch_1.minimatch)(file, excludedPattern, { dot: true }));
246
- if (excluded) {
247
- continue;
248
- }
249
- }
250
- matchingConfigFiles.push(file);
251
- }
252
- }
235
+ const matchingConfigFiles = findMatchingConfigFiles(projectFiles, pattern, include, exclude);
253
236
  let r = createNodes(matchingConfigFiles, {
254
237
  nxJsonConfiguration: nxJson,
255
238
  workspaceRoot: root,
256
- configFiles: matchingConfigFiles,
257
239
  }).catch((e) => {
258
- if ((0, error_types_1.isAggregateCreateNodesError)(e)) {
259
- errors.push(...e.errors);
260
- return e.partialResults;
261
- }
262
- else {
263
- throw e;
264
- }
240
+ const errorBodyLines = [
241
+ `An error occurred while processing files for the ${pluginName} plugin.`,
242
+ ];
243
+ const error = (0, error_types_1.isAggregateCreateNodesError)(e)
244
+ ? // This is an expected error if something goes wrong while processing files.
245
+ e
246
+ : // This represents a single plugin erroring out with a hard error.
247
+ new error_types_1.AggregateCreateNodesError([[null, e]], []);
248
+ errorBodyLines.push(...error.errors.map(([file, e]) => ` - ${file}: ${e.message}`));
249
+ error.message = errorBodyLines.join('\n');
250
+ // This represents a single plugin erroring out with a hard error.
251
+ errors.push(error);
252
+ // The plugin didn't return partial results, so we return an empty array.
253
+ return error.partialResults.map((r) => [pluginName, r[0], r[1]]);
265
254
  });
266
255
  results.push(r);
267
256
  }
268
257
  return Promise.all(results).then((results) => {
269
- perf_hooks_1.performance.mark('createNodes:merge - start');
270
- const projectRootMap = {};
271
- const externalNodes = {};
272
- const configurationSourceMaps = {};
273
- for (const result of results.flat()) {
274
- const { projects: projectNodes, externalNodes: pluginExternalNodes, file, pluginName, } = result;
275
- const sourceInfo = [file, pluginName];
276
- if (result[symbols_1.OVERRIDE_SOURCE_FILE]) {
277
- sourceInfo[0] = result[symbols_1.OVERRIDE_SOURCE_FILE];
278
- }
279
- for (const node in projectNodes) {
280
- // Handles `{projects: {'libs/foo': undefined}}`.
281
- if (!projectNodes[node]) {
282
- continue;
283
- }
284
- const project = {
285
- root: node,
286
- ...projectNodes[node],
287
- };
288
- try {
289
- mergeProjectConfigurationIntoRootMap(projectRootMap, project, configurationSourceMaps, sourceInfo);
290
- }
291
- catch (error) {
292
- errors.push(new error_types_1.MergeNodesError({
293
- file,
294
- pluginName,
295
- error,
296
- }));
297
- }
298
- }
299
- Object.assign(externalNodes, pluginExternalNodes);
300
- }
301
- try {
302
- validateAndNormalizeProjectRootMap(projectRootMap);
303
- }
304
- catch (e) {
305
- if ((0, error_types_1.isProjectsWithNoNameError)(e) ||
306
- (0, error_types_1.isMultipleProjectsWithSameNameError)(e)) {
307
- errors.push(e);
308
- }
309
- else {
310
- throw e;
311
- }
312
- }
313
- const rootMap = createRootMap(projectRootMap);
314
- perf_hooks_1.performance.mark('createNodes:merge - end');
315
- perf_hooks_1.performance.measure('createNodes:merge', 'createNodes:merge - start', 'createNodes:merge - end');
258
+ const { projectRootMap, externalNodes, rootMap, configurationSourceMaps } = mergeCreateNodesResults(results, errors);
316
259
  perf_hooks_1.performance.mark('build-project-configs:end');
317
260
  perf_hooks_1.performance.measure('build-project-configs', 'build-project-configs:start', 'build-project-configs:end');
318
261
  if (errors.length === 0) {
@@ -336,6 +279,78 @@ plugins) {
336
279
  });
337
280
  }
338
281
  exports.createProjectConfigurations = createProjectConfigurations;
282
+ function mergeCreateNodesResults(results, errors) {
283
+ perf_hooks_1.performance.mark('createNodes:merge - start');
284
+ const projectRootMap = {};
285
+ const externalNodes = {};
286
+ const configurationSourceMaps = {};
287
+ for (const result of results.flat()) {
288
+ const [file, pluginName, nodes] = result;
289
+ const { projects: projectNodes, externalNodes: pluginExternalNodes } = nodes;
290
+ const sourceInfo = [file, pluginName];
291
+ if (result[symbols_1.OVERRIDE_SOURCE_FILE]) {
292
+ sourceInfo[0] = result[symbols_1.OVERRIDE_SOURCE_FILE];
293
+ }
294
+ for (const node in projectNodes) {
295
+ // Handles `{projects: {'libs/foo': undefined}}`.
296
+ if (!projectNodes[node]) {
297
+ continue;
298
+ }
299
+ const project = {
300
+ root: node,
301
+ ...projectNodes[node],
302
+ };
303
+ try {
304
+ mergeProjectConfigurationIntoRootMap(projectRootMap, project, configurationSourceMaps, sourceInfo);
305
+ }
306
+ catch (error) {
307
+ errors.push(new error_types_1.MergeNodesError({
308
+ file,
309
+ pluginName,
310
+ error,
311
+ }));
312
+ }
313
+ }
314
+ Object.assign(externalNodes, pluginExternalNodes);
315
+ }
316
+ try {
317
+ validateAndNormalizeProjectRootMap(projectRootMap);
318
+ }
319
+ catch (e) {
320
+ if ((0, error_types_1.isProjectsWithNoNameError)(e) ||
321
+ (0, error_types_1.isMultipleProjectsWithSameNameError)(e)) {
322
+ errors.push(e);
323
+ }
324
+ else {
325
+ throw e;
326
+ }
327
+ }
328
+ const rootMap = createRootMap(projectRootMap);
329
+ perf_hooks_1.performance.mark('createNodes:merge - end');
330
+ perf_hooks_1.performance.measure('createNodes:merge', 'createNodes:merge - start', 'createNodes:merge - end');
331
+ return { projectRootMap, externalNodes, rootMap, configurationSourceMaps };
332
+ }
333
+ function findMatchingConfigFiles(projectFiles, pattern, include, exclude) {
334
+ const matchingConfigFiles = [];
335
+ for (const file of projectFiles) {
336
+ if ((0, minimatch_1.minimatch)(file, pattern, { dot: true })) {
337
+ if (include) {
338
+ const included = include.some((includedPattern) => (0, minimatch_1.minimatch)(file, includedPattern, { dot: true }));
339
+ if (!included) {
340
+ continue;
341
+ }
342
+ }
343
+ if (exclude) {
344
+ const excluded = exclude.some((excludedPattern) => (0, minimatch_1.minimatch)(file, excludedPattern, { dot: true }));
345
+ if (excluded) {
346
+ continue;
347
+ }
348
+ }
349
+ matchingConfigFiles.push(file);
350
+ }
351
+ }
352
+ return matchingConfigFiles;
353
+ }
339
354
  function readProjectConfigurationsFromRootMap(projectRootMap) {
340
355
  const projects = {};
341
356
  // If there are projects that have the same name, that is an error.
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.unparse = exports.isCacheableTask = exports.shouldStreamOutput = exports.getSerializedArgsForTask = exports.getPrintableCommandArgsForTask = exports.getCliPath = exports.calculateReverseDeps = exports.removeIdsFromGraph = exports.removeTasksFromTaskGraph = exports.getCustomHasher = exports.getExecutorForTask = exports.getExecutorNameForTask = exports.getTargetConfigurationForTask = exports.interpolate = exports.getOutputsForTargetAndConfiguration = exports.transformLegacyOutputs = exports.validateOutputs = exports.getOutputs = exports.expandDependencyConfigSyntaxSugar = exports.getDependencyConfigs = void 0;
4
4
  const output_1 = require("../utils/output");
5
5
  const path_1 = require("path");
6
+ const posix_1 = require("path/posix");
6
7
  const workspace_root_1 = require("../utils/workspace-root");
7
8
  const path_2 = require("../utils/path");
8
9
  const fileutils_1 = require("../utils/fileutils");
@@ -166,18 +167,32 @@ function getOutputsForTargetAndConfiguration(taskTargetOrTask, overridesOrNode,
166
167
  }
167
168
  }
168
169
  exports.getOutputsForTargetAndConfiguration = getOutputsForTargetAndConfiguration;
170
+ /**
171
+ * Matches portions of a string which need to be interpolated.
172
+ * Matches anything within curly braces, excluding the braces.
173
+ */
174
+ const replacementRegex = /{([\s\S]+?)}/g;
169
175
  function interpolate(template, data) {
176
+ // Path is absolute or doesn't need interpolation
177
+ if (template.startsWith('/') || !replacementRegex.test(template)) {
178
+ return template;
179
+ }
170
180
  if (template.includes('{workspaceRoot}', 1)) {
171
181
  throw new Error(`Output '${template}' is invalid. {workspaceRoot} can only be used at the beginning of the expression.`);
172
182
  }
173
183
  if (data.projectRoot == '.' && template.includes('{projectRoot}', 1)) {
174
184
  throw new Error(`Output '${template}' is invalid. When {projectRoot} is '.', it can only be used at the beginning of the expression.`);
175
185
  }
176
- let res = template.replace('{workspaceRoot}/', '');
186
+ const parts = template.split('/').map((s) => _interpolate(s, data));
187
+ return (0, posix_1.join)(...parts).replace('{workspaceRoot}/', '');
188
+ }
189
+ exports.interpolate = interpolate;
190
+ function _interpolate(template, data) {
191
+ let res = template;
177
192
  if (data.projectRoot == '.') {
178
- res = res.replace('{projectRoot}/', '');
193
+ res = res.replace('{projectRoot}', '');
179
194
  }
180
- return res.replace(/{([\s\S]+?)}/g, (match) => {
195
+ return res.replace(replacementRegex, (match) => {
181
196
  let value = data;
182
197
  let path = match.slice(1, -1).trim().split('.');
183
198
  for (let idx = 0; idx < path.length; idx++) {
@@ -189,7 +204,6 @@ function interpolate(template, data) {
189
204
  return value;
190
205
  });
191
206
  }
192
- exports.interpolate = interpolate;
193
207
  function getTargetConfigurationForTask(task, projectGraph) {
194
208
  const project = projectGraph.nodes[task.target.project].data;
195
209
  return project.targets[task.target.target];
@@ -226,7 +226,7 @@ function generateLinkOutput({ pluginName, name, type, }) {
226
226
  !pluginName.startsWith(nrwlPackagePrefix)) {
227
227
  return '';
228
228
  }
229
- const link = `https://nx.dev/packages/${pluginName.substring(pluginName.startsWith(nxPackagePrefix)
229
+ const link = `https://nx.dev/nx-api/${pluginName.substring(pluginName.startsWith(nxPackagePrefix)
230
230
  ? nxPackagePrefix.length
231
231
  : nrwlPackagePrefix.length)}/${type}/${name}`;
232
232
  return `\n\n${chalk.dim('Find more information and examples at:')} ${chalk.bold(link)}`;