@nx/devkit 18.3.0-canary.20240413-134cbbc → 18.3.0

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/devkit",
3
- "version": "18.3.0-canary.20240413-134cbbc",
3
+ "version": "18.3.0",
4
4
  "private": false,
5
5
  "description": "The Nx Devkit is used to customize Nx for different technologies and use cases. It contains many utility functions for reading and writing files, updating configuration, working with Abstract Syntax Trees(ASTs), and more. Learn more about [extending Nx by leveraging the Nx Devkit](https://nx.dev/extending-nx/intro/getting-started) on our docs.",
6
6
  "repository": {
@@ -35,7 +35,7 @@
35
35
  "tslib": "^2.3.0",
36
36
  "semver": "^7.5.3",
37
37
  "yargs-parser": "21.1.1",
38
- "@nrwl/devkit": "18.3.0-canary.20240413-134cbbc"
38
+ "@nrwl/devkit": "18.3.0"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "nx": ">= 16 <= 19"
@@ -0,0 +1,7 @@
1
+ import { type CreateNodes, type ProjectGraph, type Tree } from 'nx/src/devkit-exports';
2
+ /**
3
+ * Iterates through various forms of plugin options to find the one which does not conflict with the current graph
4
+
5
+ */
6
+ export declare function addPlugin<PluginOptions>(tree: Tree, graph: ProjectGraph, pluginName: string, createNodesTuple: CreateNodes<PluginOptions>, options: Partial<Record<keyof PluginOptions, PluginOptions[keyof PluginOptions][]>>, shouldUpdatePackageJsonScripts: boolean): Promise<void>;
7
+ export declare function generateCombinations<T>(input: Record<string, T[]>): Record<string, T>[];
@@ -1,21 +1,83 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updatePackageScripts = void 0;
4
- const path_1 = require("path");
3
+ exports.generateCombinations = exports.addPlugin = void 0;
5
4
  const yargs = require("yargs-parser");
6
5
  const nx_1 = require("../../nx");
7
- const { glob, readJson, readNxJson, workspaceRoot, writeJson } = (0, nx_1.requireNx)();
8
- async function updatePackageScripts(tree, createNodesTuple) {
6
+ const { readJson, writeJson, readNxJson, updateNxJson, retrieveProjectConfigurations, LoadedNxPlugin, ProjectConfigurationsError, } = (0, nx_1.requireNx)();
7
+ /**
8
+ * Iterates through various forms of plugin options to find the one which does not conflict with the current graph
9
+
10
+ */
11
+ async function addPlugin(tree, graph, pluginName, createNodesTuple, options, shouldUpdatePackageJsonScripts) {
12
+ const graphNodes = Object.values(graph.nodes);
9
13
  const nxJson = readNxJson(tree);
10
- const [pattern, createNodes] = createNodesTuple;
11
- const matchingFiles = glob(tree, [pattern]);
12
- for (const file of matchingFiles) {
13
- const projectRoot = getProjectRootFromConfigFile(file);
14
- await processProject(tree, projectRoot, file, createNodes, nxJson, matchingFiles);
14
+ let pluginOptions;
15
+ let projConfigs;
16
+ const combinations = generateCombinations(options);
17
+ optionsLoop: for (const _pluginOptions of combinations) {
18
+ pluginOptions = _pluginOptions;
19
+ nxJson.plugins ??= [];
20
+ if (nxJson.plugins.some((p) => typeof p === 'string' ? p === pluginName : p.plugin === pluginName)) {
21
+ // Plugin has already been added
22
+ return;
23
+ }
24
+ global.NX_GRAPH_CREATION = true;
25
+ try {
26
+ projConfigs = await retrieveProjectConfigurations([
27
+ new LoadedNxPlugin({
28
+ name: pluginName,
29
+ createNodes: createNodesTuple,
30
+ }, {
31
+ plugin: pluginName,
32
+ options: pluginOptions,
33
+ }),
34
+ ], tree.root, nxJson);
35
+ }
36
+ catch (e) {
37
+ // Errors are okay for this because we're only running 1 plugin
38
+ if (e instanceof ProjectConfigurationsError) {
39
+ projConfigs = e.partialProjectConfigurationsResult;
40
+ }
41
+ else {
42
+ throw e;
43
+ }
44
+ }
45
+ global.NX_GRAPH_CREATION = false;
46
+ for (const projConfig of Object.values(projConfigs.projects)) {
47
+ const node = graphNodes.find((node) => node.data.root === projConfig.root);
48
+ if (!node) {
49
+ continue;
50
+ }
51
+ for (const targetName in projConfig.targets) {
52
+ if (node.data.targets[targetName]) {
53
+ // Conflicting Target Name, check the next one
54
+ pluginOptions = null;
55
+ continue optionsLoop;
56
+ }
57
+ }
58
+ }
59
+ break;
60
+ }
61
+ if (!pluginOptions) {
62
+ throw new Error('Could not add the plugin in a way which does not conflict with existing targets. Please report this error at: https://github.com/nrwl/nx/issues/new/choose');
63
+ }
64
+ nxJson.plugins.push({
65
+ plugin: pluginName,
66
+ options: pluginOptions,
67
+ });
68
+ updateNxJson(tree, nxJson);
69
+ if (shouldUpdatePackageJsonScripts) {
70
+ updatePackageScripts(tree, projConfigs);
15
71
  }
16
72
  }
17
- exports.updatePackageScripts = updatePackageScripts;
18
- async function processProject(tree, projectRoot, projectConfigurationFile, createNodesFunction, nxJsonConfiguration, configFiles) {
73
+ exports.addPlugin = addPlugin;
74
+ function updatePackageScripts(tree, projectConfigurations) {
75
+ for (const projectConfig of Object.values(projectConfigurations.projects)) {
76
+ const projectRoot = projectConfig.root;
77
+ processProject(tree, projectRoot, projectConfig);
78
+ }
79
+ }
80
+ function processProject(tree, projectRoot, projectConfiguration) {
19
81
  const packageJsonPath = `${projectRoot}/package.json`;
20
82
  if (!tree.exists(packageJsonPath)) {
21
83
  return;
@@ -24,12 +86,7 @@ async function processProject(tree, projectRoot, projectConfigurationFile, creat
24
86
  if (!packageJson.scripts || !Object.keys(packageJson.scripts).length) {
25
87
  return;
26
88
  }
27
- const result = await createNodesFunction(projectConfigurationFile, {}, {
28
- nxJsonConfiguration,
29
- workspaceRoot,
30
- configFiles,
31
- });
32
- const targetCommands = getInferredTargetCommands(result);
89
+ const targetCommands = getInferredTargetCommands(projectConfiguration);
33
90
  if (!targetCommands.length) {
34
91
  return;
35
92
  }
@@ -116,68 +173,68 @@ async function processProject(tree, projectRoot, projectConfigurationFile, creat
116
173
  }
117
174
  }
118
175
  }
119
- if (process.env.NX_RUNNING_NX_INIT === 'true') {
120
- // running `nx init` so we want to exclude everything by default
121
- packageJson.nx ??= {};
122
- packageJson.nx.includedScripts = [];
123
- }
124
- else if (replacedTargets.size) {
125
- /**
126
- * Running `nx add`. In this case we want to:
127
- * - if `includedScripts` is already set: exclude scripts that match inferred targets that were used to replace a script
128
- * - if `includedScripts` is not set: set `includedScripts` with all scripts except the ones that match an inferred target that was used to replace a script
129
- */
130
- const includedScripts = packageJson.nx?.includedScripts ?? Object.keys(packageJson.scripts);
131
- const filteredScripts = includedScripts.filter((s) => !replacedTargets.has(s));
132
- if (filteredScripts.length !== includedScripts.length) {
133
- packageJson.nx ??= {};
134
- packageJson.nx.includedScripts = filteredScripts;
135
- }
136
- }
137
176
  writeJson(tree, packageJsonPath, packageJson);
138
177
  }
139
- function getInferredTargetCommands(result) {
178
+ function getInferredTargetCommands(project) {
140
179
  const targetCommands = [];
141
- for (const project of Object.values(result.projects ?? {})) {
142
- for (const [targetName, target] of Object.entries(project.targets ?? {})) {
143
- if (target.command) {
144
- targetCommands.push({ command: target.command, target: targetName });
180
+ for (const [targetName, target] of Object.entries(project.targets ?? {})) {
181
+ if (target.command) {
182
+ targetCommands.push({ command: target.command, target: targetName });
183
+ }
184
+ else if (target.executor === 'nx:run-commands' &&
185
+ target.options?.command) {
186
+ targetCommands.push({
187
+ command: target.options.command,
188
+ target: targetName,
189
+ });
190
+ }
191
+ if (!target.configurations) {
192
+ continue;
193
+ }
194
+ for (const [configurationName, configuration] of Object.entries(target.configurations)) {
195
+ if (configuration.command) {
196
+ targetCommands.push({
197
+ command: configuration.command,
198
+ target: targetName,
199
+ configuration: configurationName,
200
+ });
145
201
  }
146
202
  else if (target.executor === 'nx:run-commands' &&
147
- target.options?.command) {
203
+ configuration.options?.command) {
148
204
  targetCommands.push({
149
- command: target.options.command,
205
+ command: configuration.options.command,
150
206
  target: targetName,
207
+ configuration: configurationName,
151
208
  });
152
209
  }
153
- if (!target.configurations) {
154
- continue;
155
- }
156
- for (const [configurationName, configuration] of Object.entries(target.configurations)) {
157
- if (configuration.command) {
158
- targetCommands.push({
159
- command: configuration.command,
160
- target: targetName,
161
- configuration: configurationName,
162
- });
163
- }
164
- else if (target.executor === 'nx:run-commands' &&
165
- configuration.options?.command) {
166
- targetCommands.push({
167
- command: configuration.options.command,
168
- target: targetName,
169
- configuration: configurationName,
170
- });
171
- }
172
- }
173
210
  }
174
211
  }
175
212
  return targetCommands;
176
213
  }
177
- function getProjectRootFromConfigFile(file) {
178
- let projectRoot = (0, path_1.dirname)(file);
179
- if ((0, path_1.basename)(projectRoot) === '.storybook') {
180
- projectRoot = (0, path_1.dirname)(projectRoot);
214
+ function generateCombinations(input) {
215
+ // This is reversed so that combinations have the first defined property updated first
216
+ const keys = Object.keys(input).reverse();
217
+ return _generateCombinations(Object.values(input).reverse()).map((combination) => {
218
+ const result = {};
219
+ combination.reverse().forEach((combo, i) => {
220
+ result[keys[keys.length - i - 1]] = combo;
221
+ });
222
+ return result;
223
+ });
224
+ }
225
+ exports.generateCombinations = generateCombinations;
226
+ /**
227
+ * Generate all possible combinations of a 2-dimensional array.
228
+ *
229
+ * Useful for generating all possible combinations of options for a plugin
230
+ */
231
+ function _generateCombinations(input) {
232
+ if (input.length === 0) {
233
+ return [[]];
234
+ }
235
+ else {
236
+ const [first, ...rest] = input;
237
+ const partialCombinations = _generateCombinations(rest);
238
+ return first.flatMap((value) => partialCombinations.map((combination) => [value, ...combination]));
181
239
  }
182
- return projectRoot;
183
240
  }
@@ -1,2 +0,0 @@
1
- import type { CreateNodes, Tree } from 'nx/src/devkit-exports';
2
- export declare function updatePackageScripts(tree: Tree, createNodesTuple: CreateNodes): Promise<void>;