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.
- package/package.json +12 -12
- package/src/devkit-exports.d.ts +3 -1
- package/src/devkit-exports.js +5 -1
- package/src/devkit-internals.d.ts +1 -0
- package/src/devkit-internals.js +3 -1
- package/src/plugins/js/lock-file/pnpm-parser.js +1 -1
- package/src/plugins/js/project-graph/build-dependencies/build-dependencies.js +16 -3
- package/src/plugins/js/project-graph/build-dependencies/explicit-package-json-dependencies.d.ts +2 -1
- package/src/plugins/js/project-graph/build-dependencies/explicit-package-json-dependencies.js +40 -27
- package/src/plugins/js/project-graph/build-dependencies/explicit-project-dependencies.d.ts +2 -1
- package/src/plugins/js/project-graph/build-dependencies/explicit-project-dependencies.js +14 -19
- package/src/plugins/js/project-graph/build-dependencies/target-project-locator.d.ts +32 -5
- package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +146 -47
- package/src/plugins/js/utils/resolve-relative-to-dir.d.ts +5 -0
- package/src/plugins/js/utils/resolve-relative-to-dir.js +18 -0
- package/src/project-graph/error-types.d.ts +37 -19
- package/src/project-graph/error-types.js +31 -19
- package/src/project-graph/plugins/index.d.ts +1 -0
- package/src/project-graph/plugins/index.js +3 -1
- package/src/project-graph/plugins/internal-api.d.ts +2 -2
- package/src/project-graph/plugins/internal-api.js +33 -3
- package/src/project-graph/plugins/public-api.d.ts +34 -3
- package/src/project-graph/plugins/utils.d.ts +4 -3
- package/src/project-graph/plugins/utils.js +13 -26
- package/src/project-graph/utils/project-configuration-utils.js +89 -74
- package/src/tasks-runner/utils.js +18 -4
- 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.
|
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
|
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
|
44
|
+
const errors = [];
|
45
|
+
await Promise.all(configFiles.map(async (file) => {
|
48
46
|
try {
|
49
|
-
const value = await
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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(
|
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(
|
58
|
+
throw new error_types_1.AggregateCreateNodesError(errors, results);
|
72
59
|
}
|
73
60
|
return results;
|
74
61
|
}
|
75
|
-
exports.
|
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 {
|
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
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
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
|
-
|
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
|
-
|
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(
|
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];
|
package/src/utils/print-help.js
CHANGED
@@ -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/
|
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)}`;
|