nx 22.7.2 → 22.7.4

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.
@@ -1 +1 @@
1
- "use strict";(self.webpackChunk_nx_graph_client=self.webpackChunk_nx_graph_client||[]).push([[869],{1614:()=>{}},e=>{var n;n=1614,e(e.s=n)}]);
1
+ "use strict";(self.webpackChunk_nx_graph_client=self.webpackChunk_nx_graph_client||[]).push([[869],{4074(){}},e=>{var n;n=4074,e(e.s=n)}]);
Binary file
@@ -13,4 +13,11 @@ export declare function readTsConfigOptions(tsConfigPath: string): ts.CompilerOp
13
13
  export declare function resolveModuleByImport(importExpr: string, filePath: string, tsConfigPath: string): string;
14
14
  export declare function getRootTsConfigFileName(): string | null;
15
15
  export declare function getRootTsConfigPath(): string | null;
16
+ export declare function getRootTsConfigCustomConditions(root?: string): string[];
17
+ /**
18
+ * Conditions list for `resolve.exports`: workspace `customConditions` plus
19
+ * `development` as backward-compat for workspaces not yet migrated by
20
+ * `migrate-development-custom-condition` (21.5).
21
+ */
22
+ export declare function getRootTsConfigResolveExportsConditions(root?: string): string[];
16
23
  export declare function findNodes(node: Node, kind: SyntaxKind | SyntaxKind[], max?: number): Node[];
@@ -6,6 +6,8 @@ exports.readTsConfigOptions = readTsConfigOptions;
6
6
  exports.resolveModuleByImport = resolveModuleByImport;
7
7
  exports.getRootTsConfigFileName = getRootTsConfigFileName;
8
8
  exports.getRootTsConfigPath = getRootTsConfigPath;
9
+ exports.getRootTsConfigCustomConditions = getRootTsConfigCustomConditions;
10
+ exports.getRootTsConfigResolveExportsConditions = getRootTsConfigResolveExportsConditions;
9
11
  exports.findNodes = findNodes;
10
12
  const workspace_root_1 = require("../../../utils/workspace-root");
11
13
  const fs_1 = require("fs");
@@ -74,6 +76,43 @@ function getRootTsConfigPath() {
74
76
  const tsConfigFileName = getRootTsConfigFileName();
75
77
  return tsConfigFileName ? (0, path_1.join)(workspace_root_1.workspaceRoot, tsConfigFileName) : null;
76
78
  }
79
+ const customConditionsCache = new Map();
80
+ function getRootTsConfigCustomConditions(root = workspace_root_1.workspaceRoot) {
81
+ if (customConditionsCache.has(root)) {
82
+ return customConditionsCache.get(root);
83
+ }
84
+ // Resolve via the TypeScript API rather than a raw JSON read so that
85
+ // `customConditions` inherited through `extends` chains are honored —
86
+ // matches what TypeScript itself sees when resolving package exports.
87
+ let conditions = [];
88
+ for (const name of ['tsconfig.base.json', 'tsconfig.json']) {
89
+ const tsConfigPath = (0, path_1.join)(root, name);
90
+ if (!(0, fs_1.existsSync)(tsConfigPath)) {
91
+ continue;
92
+ }
93
+ try {
94
+ const options = readTsConfigOptions(tsConfigPath);
95
+ if (Array.isArray(options.customConditions)) {
96
+ conditions = options.customConditions.filter((c) => typeof c === 'string');
97
+ }
98
+ }
99
+ catch { }
100
+ break;
101
+ }
102
+ customConditionsCache.set(root, conditions);
103
+ return conditions;
104
+ }
105
+ /**
106
+ * Conditions list for `resolve.exports`: workspace `customConditions` plus
107
+ * `development` as backward-compat for workspaces not yet migrated by
108
+ * `migrate-development-custom-condition` (21.5).
109
+ */
110
+ function getRootTsConfigResolveExportsConditions(root = workspace_root_1.workspaceRoot) {
111
+ const conditions = getRootTsConfigCustomConditions(root);
112
+ return conditions.includes('development')
113
+ ? conditions
114
+ : [...conditions, 'development'];
115
+ }
77
116
  function findNodes(node, kind, max = Infinity) {
78
117
  if (!node || max == 0) {
79
118
  return [];
@@ -1,15 +1,18 @@
1
1
  import type { ProjectConfiguration } from '../../config/workspace-json-project-json';
2
+ type LocalPluginMatch = {
3
+ path: string;
4
+ projectConfig: ProjectConfiguration;
5
+ resolvedFile?: string;
6
+ };
2
7
  export declare function resolveNxPlugin(moduleName: string, root: string, paths: string[]): Promise<{
3
8
  pluginPath: string;
4
9
  name: any;
5
10
  shouldRegisterTSTranspiler: boolean;
6
11
  }>;
7
- export declare function resolveLocalNxPlugin(importPath: string, projects: Record<string, ProjectConfiguration>, root?: string): {
8
- path: string;
9
- projectConfig: ProjectConfiguration;
10
- } | null;
12
+ export declare function resolveLocalNxPlugin(importPath: string, projects: Record<string, ProjectConfiguration>, root?: string): LocalPluginMatch | null;
11
13
  export declare function getPluginPathAndName(moduleName: string, paths: string[], projects: Record<string, ProjectConfiguration>, root: string): {
12
14
  pluginPath: string;
13
15
  name: any;
14
16
  shouldRegisterTSTranspiler: boolean;
15
17
  };
18
+ export {};
@@ -6,28 +6,59 @@ exports.getPluginPathAndName = getPluginPathAndName;
6
6
  const tslib_1 = require("tslib");
7
7
  const path = tslib_1.__importStar(require("node:path"));
8
8
  const node_fs_1 = require("node:fs");
9
+ const resolve_exports_1 = require("resolve.exports");
9
10
  const packages_1 = require("../../plugins/js/utils/packages");
11
+ const typescript_1 = require("../../plugins/js/utils/typescript");
10
12
  const fileutils_1 = require("../../utils/fileutils");
11
13
  const logger_1 = require("../../utils/logger");
12
14
  const path_1 = require("../../utils/path");
13
15
  const workspace_root_1 = require("../../utils/workspace-root");
14
16
  const find_project_for_path_1 = require("../utils/find-project-for-path");
15
17
  const retrieve_workspace_files_1 = require("../utils/retrieve-workspace-files");
18
+ const TS_SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.cts', '.mts']);
16
19
  let projectsWithoutInference;
17
20
  let projectsWithoutInferencePromise = null;
18
21
  async function resolveNxPlugin(moduleName, root, paths) {
19
- try {
20
- require.resolve(moduleName, { paths });
21
- }
22
- catch {
23
- // If a plugin cannot be resolved, we will need projects to resolve it
24
- projectsWithoutInferencePromise ??=
25
- (0, retrieve_workspace_files_1.retrieveProjectConfigurationsWithoutPluginInference)(root);
26
- projectsWithoutInference ??= await projectsWithoutInferencePromise;
22
+ // Default plugins (see `getDefaultPlugins` in `get-plugins.ts`) are passed
23
+ // as absolute file paths to compiled bundles inside `nx` itself; they are
24
+ // never workspace-local. Skip the project load entirely for them to avoid
25
+ // recursing through `retrieveProjectConfigurationsWithoutPluginInference`,
26
+ // which itself triggers default-plugin loading.
27
+ if (!path.isAbsolute(moduleName)) {
28
+ let resolvedFromNode;
29
+ try {
30
+ resolvedFromNode = require.resolve(moduleName, { paths });
31
+ }
32
+ catch { }
33
+ // Load projects if Node couldn't resolve (so the local fallback can run)
34
+ // OR if Node resolved to a workspace-internal path (a symlinked workspace
35
+ // package whose source-first lookup should win over the symlinked dist).
36
+ if (!resolvedFromNode ||
37
+ isWorkspaceLocalResolution(resolvedFromNode, root)) {
38
+ projectsWithoutInferencePromise ??=
39
+ (0, retrieve_workspace_files_1.retrieveProjectConfigurationsWithoutPluginInference)(root);
40
+ projectsWithoutInference ??= await projectsWithoutInferencePromise;
41
+ }
27
42
  }
28
43
  const { pluginPath, name, shouldRegisterTSTranspiler } = getPluginPathAndName(moduleName, paths, projectsWithoutInference, root);
29
44
  return { pluginPath, name, shouldRegisterTSTranspiler };
30
45
  }
46
+ /**
47
+ * Distinguishes a symlinked workspace package (where `require.resolve`
48
+ * follows the package-manager symlink into the workspace source tree) from
49
+ * a truly-installed dependency under `node_modules/`. The former needs the
50
+ * source-first lookup to bypass the dist that Node would otherwise return.
51
+ */
52
+ function isWorkspaceLocalResolution(resolvedPath, root) {
53
+ const normalizedRoot = path.normalize(root);
54
+ const normalizedPath = path.normalize(resolvedPath);
55
+ return (normalizedPath.startsWith(normalizedRoot + path.sep) &&
56
+ !normalizedPath.includes(path.sep + 'node_modules' + path.sep));
57
+ }
58
+ function isPackageResolutionError(e) {
59
+ const code = e.code;
60
+ return (code === 'MODULE_NOT_FOUND' || code === 'ERR_PACKAGE_PATH_NOT_EXPORTED');
61
+ }
31
62
  function readPluginMainFromProjectConfiguration(plugin) {
32
63
  const { main } = Object.values(plugin.targets).find((x) => [
33
64
  '@nx/js:tsc',
@@ -46,31 +77,44 @@ function resolveLocalNxPlugin(importPath, projects, root = workspace_root_1.work
46
77
  }
47
78
  function getPluginPathAndName(moduleName, paths, projects, root) {
48
79
  let pluginPath;
49
- let shouldRegisterTSTranspiler = false;
50
- try {
51
- pluginPath = require.resolve(moduleName, {
52
- paths,
53
- });
54
- const extension = path.extname(pluginPath);
55
- shouldRegisterTSTranspiler = extension === '.ts';
80
+ // Resolve local workspace plugins from source first so the workspace's
81
+ // `customConditions`/`development` exports condition wins over the built
82
+ // `dist` artifact that Node's resolver would otherwise pick up via the
83
+ // `default` condition (Node ignores TypeScript custom conditions). Skipped
84
+ // when `projects` weren't loaded — the caller already determined that the
85
+ // import isn't a workspace package.
86
+ const localPlugin = projects
87
+ ? resolveLocalNxPlugin(moduleName, projects, root)
88
+ : null;
89
+ if (localPlugin) {
90
+ pluginPath = tryResolveLocalPluginFromSource(moduleName, localPlugin, root);
91
+ if (!pluginPath && getSubpathOfLocalPackage(moduleName, localPlugin)) {
92
+ throwUnresolvableLocalPluginError(moduleName, localPlugin, root);
93
+ }
56
94
  }
57
- catch (e) {
58
- if (e.code === 'MODULE_NOT_FOUND') {
59
- const plugin = resolveLocalNxPlugin(moduleName, projects, root);
60
- if (plugin) {
61
- shouldRegisterTSTranspiler = true;
62
- const main = readPluginMainFromProjectConfiguration(plugin.projectConfig);
63
- pluginPath = main ? path.join(root, main) : plugin.path;
95
+ if (!pluginPath) {
96
+ try {
97
+ pluginPath = require.resolve(moduleName, { paths });
98
+ }
99
+ catch (e) {
100
+ if (localPlugin && isPackageResolutionError(e)) {
101
+ throwUnresolvableLocalPluginError(moduleName, localPlugin, root);
64
102
  }
65
- else {
66
- logger_1.logger.error(`Plugin listed in \`nx.json\` not found: ${moduleName}`);
103
+ if (e.code !== 'MODULE_NOT_FOUND') {
67
104
  throw e;
68
105
  }
69
- }
70
- else {
106
+ if (localPlugin) {
107
+ throwUnresolvableLocalPluginError(moduleName, localPlugin, root);
108
+ }
109
+ logger_1.logger.error(`Plugin listed in \`nx.json\` not found: ${moduleName}`);
71
110
  throw e;
72
111
  }
73
112
  }
113
+ const ext = path.extname(pluginPath);
114
+ // Directory paths fall through to Node's `package.json` `main` resolution
115
+ // which may land on a TS file; only opt out of TS transpiler registration
116
+ // when the resolved path is unambiguously JS.
117
+ const shouldRegisterTSTranspiler = ext === '' || TS_SOURCE_EXTENSIONS.has(ext);
74
118
  const packageJsonPath = path.join(pluginPath, 'package.json');
75
119
  const { name } = !['.ts', '.js'].some((x) => path.extname(moduleName) === x) && // Not trying to point to a ts or js file
76
120
  (0, node_fs_1.existsSync)(packageJsonPath) // plugin has a package.json
@@ -78,12 +122,84 @@ function getPluginPathAndName(moduleName, paths, projects, root) {
78
122
  : { name: moduleName };
79
123
  return { pluginPath, name, shouldRegisterTSTranspiler };
80
124
  }
125
+ function getSubpathOfLocalPackage(moduleName, plugin) {
126
+ const packageName = plugin.projectConfig.metadata?.js?.packageName;
127
+ if (!packageName || !moduleName.startsWith(packageName + '/')) {
128
+ return null;
129
+ }
130
+ return '.' + moduleName.slice(packageName.length);
131
+ }
132
+ function tryResolveLocalPluginFromSource(moduleName, plugin, root) {
133
+ if (plugin.resolvedFile) {
134
+ return plugin.resolvedFile;
135
+ }
136
+ const subpath = getSubpathOfLocalPackage(moduleName, plugin);
137
+ if (subpath) {
138
+ return resolveSubpathFromExports(plugin.projectConfig, plugin.path, subpath, root);
139
+ }
140
+ const main = readPluginMainFromProjectConfiguration(plugin.projectConfig);
141
+ return main ? path.join(root, main) : null;
142
+ }
143
+ function throwUnresolvableLocalPluginError(moduleName, plugin, root) {
144
+ const subpath = getSubpathOfLocalPackage(moduleName, plugin);
145
+ const packageName = plugin.projectConfig.metadata?.js?.packageName;
146
+ if (subpath) {
147
+ throw new Error(`Unable to resolve local plugin "${moduleName}". The import targets ` +
148
+ `the subpath "${subpath}" of the local package "${packageName}", but ` +
149
+ `the package's "exports" map has no resolvable entry for "${subpath}", ` +
150
+ `or none of the matched paths exist on disk. Check the "exports" field ` +
151
+ `in "${path.relative(root, path.join(plugin.path, 'package.json'))}" ` +
152
+ `and ensure the source file referenced by "${subpath}" exists.`);
153
+ }
154
+ throw new Error(`Unable to resolve local plugin "${moduleName}". The local package ` +
155
+ `"${packageName ?? moduleName}" does not declare a build target with ` +
156
+ `a "main" source path, and Node could not resolve it either.`);
157
+ }
158
+ function resolveSubpathFromExports(projectConfig, projectPath, subpath, root) {
159
+ const packageExports = projectConfig.metadata?.js?.packageExports;
160
+ if (!packageExports) {
161
+ return null;
162
+ }
163
+ const pkg = {
164
+ name: projectConfig.metadata.js.packageName,
165
+ exports: packageExports,
166
+ };
167
+ try {
168
+ const matches = (0, resolve_exports_1.resolve)(pkg, subpath, {
169
+ conditions: (0, typescript_1.getRootTsConfigResolveExportsConditions)(root),
170
+ });
171
+ if (!matches || !matches.length) {
172
+ return null;
173
+ }
174
+ for (const match of matches) {
175
+ const candidate = path.join(projectPath, match);
176
+ if ((0, node_fs_1.existsSync)(candidate)) {
177
+ return candidate;
178
+ }
179
+ }
180
+ }
181
+ catch (e) {
182
+ logger_1.logger.verbose(`Failed to resolve subpath "${subpath}" of local plugin via package.json exports`, e);
183
+ }
184
+ return null;
185
+ }
81
186
  function lookupLocalPlugin(importPath, projects, root = workspace_root_1.workspaceRoot) {
82
- const projectConfig = findNxProjectForImportPath(importPath, projects, root);
83
- if (!projectConfig) {
187
+ const match = findNxProjectForImportPath(importPath, projects, root);
188
+ if (!match) {
84
189
  return null;
85
190
  }
86
- return { path: path.join(root, projectConfig.root), projectConfig };
191
+ let resolvedFile;
192
+ if (match.tsPathFile) {
193
+ const candidate = path.join(root, match.tsPathFile);
194
+ if (path.extname(candidate) && (0, node_fs_1.existsSync)(candidate)) {
195
+ resolvedFile = candidate;
196
+ }
197
+ }
198
+ return {
199
+ path: path.join(root, match.projectConfig.root),
200
+ projectConfig: match.projectConfig,
201
+ resolvedFile,
202
+ };
87
203
  }
88
204
  let packageEntryPointsToProjectMap;
89
205
  let wildcardEntryPointsToProjectMap;
@@ -101,7 +217,10 @@ function findNxProjectForImportPath(importPath, projects, root = workspace_root_
101
217
  for (const tsConfigPath of possibleTsPaths) {
102
218
  const nxProject = (0, find_project_for_path_1.findProjectForPath)(tsConfigPath, projectRootMappings);
103
219
  if (nxProject) {
104
- return projectNameMap.get(nxProject);
220
+ return {
221
+ projectConfig: projectNameMap.get(nxProject),
222
+ tsPathFile: tsConfigPath,
223
+ };
105
224
  }
106
225
  }
107
226
  }
@@ -112,14 +231,14 @@ function findNxProjectForImportPath(importPath, projects, root = workspace_root_
112
231
  } = (0, packages_1.getWorkspacePackagesMetadata)(projects));
113
232
  }
114
233
  if (packageEntryPointsToProjectMap[importPath]) {
115
- return packageEntryPointsToProjectMap[importPath];
234
+ return { projectConfig: packageEntryPointsToProjectMap[importPath] };
116
235
  }
117
236
  const project = (0, packages_1.matchImportToWildcardEntryPointsToProjectMap)(wildcardEntryPointsToProjectMap, importPath);
118
237
  if (project) {
119
- return project;
238
+ return { projectConfig: project };
120
239
  }
121
240
  logger_1.logger.verbose('Unable to find local plugin', possibleTsPaths, projectRootMappings);
122
- throw new Error('Unable to resolve local plugin with import path ' + importPath);
241
+ return null;
123
242
  }
124
243
  let tsconfigPaths;
125
244
  function readTsConfigPaths(root = workspace_root_1.workspaceRoot) {
@@ -3,22 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createNodesFromFiles = createNodesFromFiles;
4
4
  const error_types_1 = require("../error-types");
5
5
  async function createNodesFromFiles(createNodes, configFiles, options, context) {
6
- const results = [];
7
- const errors = [];
8
- await Promise.all(configFiles.map(async (file, idx) => {
6
+ const settled = await Promise.all(configFiles.map(async (file, idx) => {
9
7
  try {
10
8
  const value = await createNodes(file, options, {
11
9
  ...context,
12
10
  configFiles,
13
11
  }, idx);
14
- if (value) {
15
- results.push([file, value]);
16
- }
12
+ return value ? { kind: 'value', file, value } : { kind: 'empty' };
17
13
  }
18
14
  catch (e) {
19
- errors.push([file, e]);
15
+ return { kind: 'error', file, error: e };
20
16
  }
21
17
  }));
18
+ const results = [];
19
+ const errors = [];
20
+ for (const entry of settled) {
21
+ if (entry.kind === 'value') {
22
+ results.push([entry.file, entry.value]);
23
+ }
24
+ else if (entry.kind === 'error') {
25
+ errors.push([entry.file, entry.error]);
26
+ }
27
+ }
22
28
  if (errors.length > 0) {
23
29
  throw new error_types_1.AggregateCreateNodesError(errors, results);
24
30
  }
@@ -223,9 +223,9 @@ class TasksSchedule {
223
223
  }
224
224
  }
225
225
  canBatchTaskBeScheduled(task, batchTaskGraph) {
226
- // task self needs to have parallelism true
226
+ // task self needs to support parallelism (undefined defaults to parallel)
227
227
  // all deps have either completed or belong to the same batch
228
- return (task.parallelism === true &&
228
+ return (task.parallelism !== false &&
229
229
  this.taskGraph.dependencies[task.id].every((id) => this.completedTasks.has(id) || !!batchTaskGraph?.tasks[id]));
230
230
  }
231
231
  canBeScheduled(taskId) {
@@ -248,7 +248,7 @@ class TasksSchedule {
248
248
  }
249
249
  else {
250
250
  // if all running tasks support parallelism, can only schedule task with parallelism
251
- return this.taskGraph.tasks[taskId].parallelism === true;
251
+ return this.taskGraph.tasks[taskId].parallelism !== false;
252
252
  }
253
253
  }
254
254
  getEstimatedTaskTimings() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "22.7.2",
3
+ "version": "22.7.4",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
@@ -64,7 +64,7 @@
64
64
  "balanced-match": "4.0.3",
65
65
  "base64-js": "1.5.1",
66
66
  "bl": "4.1.0",
67
- "brace-expansion": "5.0.5",
67
+ "brace-expansion": "5.0.6",
68
68
  "buffer": "5.7.1",
69
69
  "call-bind-apply-helpers": "1.0.2",
70
70
  "chalk": "4.1.2",
@@ -154,7 +154,7 @@
154
154
  "wrap-ansi": "7.0.0",
155
155
  "wrappy": "1.0.2",
156
156
  "y18n": "5.0.8",
157
- "yaml": "2.8.0",
157
+ "yaml": "2.9.0",
158
158
  "yargs": "17.7.2",
159
159
  "yargs-parser": "21.1.1"
160
160
  },
@@ -171,16 +171,16 @@
171
171
  }
172
172
  },
173
173
  "optionalDependencies": {
174
- "@nx/nx-darwin-arm64": "22.7.2",
175
- "@nx/nx-darwin-x64": "22.7.2",
176
- "@nx/nx-freebsd-x64": "22.7.2",
177
- "@nx/nx-linux-arm-gnueabihf": "22.7.2",
178
- "@nx/nx-linux-arm64-gnu": "22.7.2",
179
- "@nx/nx-linux-arm64-musl": "22.7.2",
180
- "@nx/nx-linux-x64-gnu": "22.7.2",
181
- "@nx/nx-linux-x64-musl": "22.7.2",
182
- "@nx/nx-win32-arm64-msvc": "22.7.2",
183
- "@nx/nx-win32-x64-msvc": "22.7.2"
174
+ "@nx/nx-darwin-arm64": "22.7.4",
175
+ "@nx/nx-darwin-x64": "22.7.4",
176
+ "@nx/nx-freebsd-x64": "22.7.4",
177
+ "@nx/nx-linux-arm-gnueabihf": "22.7.4",
178
+ "@nx/nx-linux-arm64-gnu": "22.7.4",
179
+ "@nx/nx-linux-arm64-musl": "22.7.4",
180
+ "@nx/nx-linux-x64-gnu": "22.7.4",
181
+ "@nx/nx-linux-x64-musl": "22.7.4",
182
+ "@nx/nx-win32-arm64-msvc": "22.7.4",
183
+ "@nx/nx-win32-x64-msvc": "22.7.4"
184
184
  },
185
185
  "nx-migrations": {
186
186
  "migrations": "./migrations.json",