nx 19.2.0-beta.2 → 19.2.0-beta.3

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "19.2.0-beta.2",
3
+ "version": "19.2.0-beta.3",
4
4
  "private": false,
5
5
  "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
6
6
  "repository": {
@@ -69,7 +69,7 @@
69
69
  "yargs-parser": "21.1.1",
70
70
  "node-machine-id": "1.1.12",
71
71
  "ora": "5.3.0",
72
- "@nrwl/tao": "19.2.0-beta.2"
72
+ "@nrwl/tao": "19.2.0-beta.3"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@swc-node/register": "^1.8.0",
@@ -84,16 +84,16 @@
84
84
  }
85
85
  },
86
86
  "optionalDependencies": {
87
- "@nx/nx-darwin-x64": "19.2.0-beta.2",
88
- "@nx/nx-darwin-arm64": "19.2.0-beta.2",
89
- "@nx/nx-linux-x64-gnu": "19.2.0-beta.2",
90
- "@nx/nx-linux-x64-musl": "19.2.0-beta.2",
91
- "@nx/nx-win32-x64-msvc": "19.2.0-beta.2",
92
- "@nx/nx-linux-arm64-gnu": "19.2.0-beta.2",
93
- "@nx/nx-linux-arm64-musl": "19.2.0-beta.2",
94
- "@nx/nx-linux-arm-gnueabihf": "19.2.0-beta.2",
95
- "@nx/nx-win32-arm64-msvc": "19.2.0-beta.2",
96
- "@nx/nx-freebsd-x64": "19.2.0-beta.2"
87
+ "@nx/nx-darwin-x64": "19.2.0-beta.3",
88
+ "@nx/nx-darwin-arm64": "19.2.0-beta.3",
89
+ "@nx/nx-linux-x64-gnu": "19.2.0-beta.3",
90
+ "@nx/nx-linux-x64-musl": "19.2.0-beta.3",
91
+ "@nx/nx-win32-x64-msvc": "19.2.0-beta.3",
92
+ "@nx/nx-linux-arm64-gnu": "19.2.0-beta.3",
93
+ "@nx/nx-linux-arm64-musl": "19.2.0-beta.3",
94
+ "@nx/nx-linux-arm-gnueabihf": "19.2.0-beta.3",
95
+ "@nx/nx-win32-arm64-msvc": "19.2.0-beta.3",
96
+ "@nx/nx-freebsd-x64": "19.2.0-beta.3"
97
97
  },
98
98
  "nx-migrations": {
99
99
  "migrations": "./migrations.json",
@@ -15,7 +15,9 @@ export type { WorkspaceJsonConfiguration, ProjectsConfigurations, TargetDependen
15
15
  */
16
16
  export type { Generator, GeneratorCallback, Executor, ExecutorContext, TaskGraphExecutor, GeneratorsJson, ExecutorsJson, MigrationsJson, CustomHasher, HasherContext, } from './config/misc-interfaces';
17
17
  export { workspaceLayout } from './config/configuration';
18
- export type { NxPlugin, NxPluginV2, CreateNodes, CreateNodesFunction, CreateNodesResult, CreateNodesContext, CreateDependencies, CreateDependenciesContext, CreateMetadata, CreateMetadataContext, ProjectsMetadata, } from './project-graph/plugins';
18
+ export type { NxPlugin, NxPluginV2, CreateNodes, CreateNodesFunction, CreateNodesResult, CreateNodesContext, CreateNodesContextV2, CreateNodesFunctionV2, CreateNodesResultV2, CreateNodesV2, CreateDependencies, CreateDependenciesContext, CreateMetadata, CreateMetadataContext, ProjectsMetadata, } from './project-graph/plugins';
19
+ export { AggregateCreateNodesError } from './project-graph/error-types';
20
+ export { createNodesFromFiles } from './project-graph/plugins';
19
21
  export type { NxPluginV1, ProjectTargetConfigurator, } from './utils/nx-plugin.deprecated';
20
22
  /**
21
23
  * @category Workspace
@@ -4,9 +4,13 @@
4
4
  * Try hard to not add to this API to reduce the surface area we need to maintain.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.createProjectFileMapUsingProjectGraph = exports.cacheDir = exports.hashArray = exports.defaultTasksRunner = exports.getOutputsForTargetAndConfiguration = exports.readProjectsConfigurationFromProjectGraph = exports.readCachedProjectGraph = exports.createProjectGraphAsync = exports.reverse = exports.appRootPath = exports.workspaceRoot = exports.normalizePath = exports.joinPathFragments = exports.stripIndents = exports.writeJsonFile = exports.readJsonFile = exports.stripJsonComments = exports.serializeJson = exports.parseJson = exports.updateJson = exports.writeJson = exports.readJson = exports.validateDependency = exports.ProjectGraphBuilder = exports.DependencyType = exports.updateNxJson = exports.readNxJson = exports.glob = exports.getProjects = exports.updateProjectConfiguration = exports.removeProjectConfiguration = exports.readProjectConfiguration = exports.addProjectConfiguration = exports.runExecutor = exports.isWorkspacesEnabled = exports.getPackageManagerVersion = exports.detectPackageManager = exports.getPackageManagerCommand = exports.output = exports.logger = exports.workspaceLayout = void 0;
7
+ exports.createProjectFileMapUsingProjectGraph = exports.cacheDir = exports.hashArray = exports.defaultTasksRunner = exports.getOutputsForTargetAndConfiguration = exports.readProjectsConfigurationFromProjectGraph = exports.readCachedProjectGraph = exports.createProjectGraphAsync = exports.reverse = exports.appRootPath = exports.workspaceRoot = exports.normalizePath = exports.joinPathFragments = exports.stripIndents = exports.writeJsonFile = exports.readJsonFile = exports.stripJsonComments = exports.serializeJson = exports.parseJson = exports.updateJson = exports.writeJson = exports.readJson = exports.validateDependency = exports.ProjectGraphBuilder = exports.DependencyType = exports.updateNxJson = exports.readNxJson = exports.glob = exports.getProjects = exports.updateProjectConfiguration = exports.removeProjectConfiguration = exports.readProjectConfiguration = exports.addProjectConfiguration = exports.runExecutor = exports.isWorkspacesEnabled = exports.getPackageManagerVersion = exports.detectPackageManager = exports.getPackageManagerCommand = exports.output = exports.logger = exports.createNodesFromFiles = exports.AggregateCreateNodesError = exports.workspaceLayout = void 0;
8
8
  var configuration_1 = require("./config/configuration");
9
9
  Object.defineProperty(exports, "workspaceLayout", { enumerable: true, get: function () { return configuration_1.workspaceLayout; } });
10
+ var error_types_1 = require("./project-graph/error-types");
11
+ Object.defineProperty(exports, "AggregateCreateNodesError", { enumerable: true, get: function () { return error_types_1.AggregateCreateNodesError; } });
12
+ var plugins_1 = require("./project-graph/plugins");
13
+ Object.defineProperty(exports, "createNodesFromFiles", { enumerable: true, get: function () { return plugins_1.createNodesFromFiles; } });
10
14
  /**
11
15
  * @category Logger
12
16
  */
@@ -4,11 +4,11 @@ import { ProjectGraphExternalNode, ProjectGraphProjectNode } from '../../../../c
4
4
  * containing the file importing it e.g. `lodash__packages/my-lib`, the value is the
5
5
  * resolved external node name from the project graph.
6
6
  */
7
- type NpmResolutionCache = Map<string, string>;
7
+ type NpmResolutionCache = Map<string, string | null>;
8
8
  export declare function isBuiltinModuleImport(importExpr: string): boolean;
9
9
  export declare class TargetProjectLocator {
10
10
  private readonly nodes;
11
- readonly externalNodes: Record<string, ProjectGraphExternalNode>;
11
+ private readonly externalNodes;
12
12
  private readonly npmResolutionCache;
13
13
  private projectRootMappings;
14
14
  private npmProjects;
@@ -31,7 +31,7 @@ export declare class TargetProjectLocator {
31
31
  * @param importExpr
32
32
  * @param projectRoot
33
33
  */
34
- findNpmProjectFromImport(importExpr: string, fromFilePath: string): string | undefined;
34
+ findNpmProjectFromImport(importExpr: string, fromFilePath: string): string | null;
35
35
  /**
36
36
  * Return file paths matching the import relative to the repo root
37
37
  * @param normalizedImportExpr
@@ -44,5 +44,16 @@ export declare class TargetProjectLocator {
44
44
  private getAbsolutePath;
45
45
  private getRootTsConfig;
46
46
  private findMatchingProjectFiles;
47
+ /**
48
+ * In many cases the package.json will be directly resolvable, so we try that first.
49
+ * If, however, package exports are used and the package.json is not defined, we will
50
+ * need to resolve the main entry point of the package and traverse upwards to find the
51
+ * package.json.
52
+ *
53
+ * In some cases, such as when multiple module formats are published, the resolved package.json
54
+ * might only contain the "type" field - no "name" or "version", so in such cases we keep traversing
55
+ * until we find a package.json that contains the "name" and "version" fields.
56
+ */
57
+ private readPackageJson;
47
58
  }
48
59
  export {};
@@ -6,7 +6,7 @@ const node_path_1 = require("node:path");
6
6
  const find_project_for_path_1 = require("../../../../project-graph/utils/find-project-for-path");
7
7
  const fileutils_1 = require("../../../../utils/fileutils");
8
8
  const workspace_root_1 = require("../../../../utils/workspace-root");
9
- const find_external_package_json_path_1 = require("../../utils/find-external-package-json-path");
9
+ const resolve_relative_to_dir_1 = require("../../utils/resolve-relative-to-dir");
10
10
  const typescript_1 = require("../../utils/typescript");
11
11
  /**
12
12
  * Use a shared cache to avoid repeated npm package resolution work within the TargetProjectLocator.
@@ -30,17 +30,22 @@ class TargetProjectLocator {
30
30
  this.tsConfig = this.getRootTsConfig();
31
31
  this.paths = this.tsConfig.config?.compilerOptions?.paths;
32
32
  this.typescriptResolutionCache = new Map();
33
- this.npmProjects = externalNodes;
34
33
  /**
35
34
  * Only the npm external nodes should be included.
36
35
  *
37
- * Unlike the raw externalNodes, ensure that the version is always set in the key
38
- * for optimal lookup.
36
+ * Unlike the raw externalNodes, ensure that there is always copy of the node where the version
37
+ * is set in the key for optimal lookup.
39
38
  */
40
- this.npmProjects = Object.values(externalNodes).reduce((acc, node) => {
39
+ this.npmProjects = Object.values(this.externalNodes).reduce((acc, node) => {
41
40
  if (node.type === 'npm') {
42
- const key = `npm:${node.data.packageName}@${node.data.version}`;
43
- acc[key] = node;
41
+ const keyWithVersion = `npm:${node.data.packageName}@${node.data.version}`;
42
+ if (!acc[node.name]) {
43
+ acc[node.name] = node;
44
+ }
45
+ // The node.name may have already contained the version
46
+ if (!acc[keyWithVersion]) {
47
+ acc[keyWithVersion] = node;
48
+ }
44
49
  }
45
50
  return acc;
46
51
  }, {});
@@ -123,17 +128,20 @@ class TargetProjectLocator {
123
128
  }
124
129
  try {
125
130
  // package.json refers to an external package, we do not match against the version found in there, we instead try and resolve the relevant package how node would
126
- const externalPackageJsonPath = (0, find_external_package_json_path_1.findExternalPackageJsonPath)(packageName, fullDirPath);
131
+ const externalPackageJson = this.readPackageJson(packageName, fullDirPath);
127
132
  // The external package.json path might be not be resolvable, e.g. if a reference has been added to a project package.json, but the install command has not been run yet.
128
- if (!externalPackageJsonPath) {
129
- return undefined;
133
+ if (!externalPackageJson) {
134
+ // Try and fall back to resolving an external node from the graph by name
135
+ const externalNode = this.npmProjects[`npm:${packageName}`];
136
+ const externalNodeName = externalNode?.name || null;
137
+ this.npmResolutionCache.set(npmImportForProject, externalNodeName);
138
+ return externalNodeName;
130
139
  }
131
- const externalPackageJson = (0, fileutils_1.readJsonFile)(externalPackageJsonPath);
132
140
  const npmProjectKey = `npm:${externalPackageJson.name}@${externalPackageJson.version}`;
133
- if (!this.npmProjects[npmProjectKey]) {
134
- return undefined;
135
- }
136
141
  const matchingExternalNode = this.npmProjects[npmProjectKey];
142
+ if (!matchingExternalNode) {
143
+ return null;
144
+ }
137
145
  this.npmResolutionCache.set(npmImportForProject, matchingExternalNode.name);
138
146
  return matchingExternalNode.name;
139
147
  }
@@ -141,7 +149,7 @@ class TargetProjectLocator {
141
149
  if (process.env.NX_VERBOSE_LOGGING === 'true') {
142
150
  console.error(e);
143
151
  }
144
- return undefined;
152
+ return null;
145
153
  }
146
154
  }
147
155
  /**
@@ -221,6 +229,46 @@ class TargetProjectLocator {
221
229
  const project = (0, find_project_for_path_1.findProjectForPath)(file, this.projectRootMappings);
222
230
  return this.nodes[project];
223
231
  }
232
+ /**
233
+ * In many cases the package.json will be directly resolvable, so we try that first.
234
+ * If, however, package exports are used and the package.json is not defined, we will
235
+ * need to resolve the main entry point of the package and traverse upwards to find the
236
+ * package.json.
237
+ *
238
+ * In some cases, such as when multiple module formats are published, the resolved package.json
239
+ * might only contain the "type" field - no "name" or "version", so in such cases we keep traversing
240
+ * until we find a package.json that contains the "name" and "version" fields.
241
+ */
242
+ readPackageJson(packageName, relativeToDir) {
243
+ // The package.json is directly resolvable
244
+ const packageJsonPath = (0, resolve_relative_to_dir_1.resolveRelativeToDir)((0, node_path_1.join)(packageName, 'package.json'), relativeToDir);
245
+ if (packageJsonPath) {
246
+ return (0, fileutils_1.readJsonFile)(packageJsonPath);
247
+ }
248
+ try {
249
+ // Resolve the main entry point of the package
250
+ const mainPath = (0, resolve_relative_to_dir_1.resolveRelativeToDir)(packageName, relativeToDir);
251
+ let dir = (0, node_path_1.dirname)(mainPath);
252
+ while (dir !== (0, node_path_1.parse)(dir).root) {
253
+ const packageJsonPath = (0, node_path_1.join)(dir, 'package.json');
254
+ try {
255
+ const parsedPackageJson = (0, fileutils_1.readJsonFile)(packageJsonPath);
256
+ // Ensure the package.json contains the "name" and "version" fields
257
+ if (parsedPackageJson.name && parsedPackageJson.version) {
258
+ return parsedPackageJson;
259
+ }
260
+ }
261
+ catch {
262
+ // Package.json doesn't exist, keep traversing
263
+ }
264
+ dir = (0, node_path_1.dirname)(dir);
265
+ }
266
+ return null;
267
+ }
268
+ catch {
269
+ return null;
270
+ }
271
+ }
224
272
  }
225
273
  exports.TargetProjectLocator = TargetProjectLocator;
226
274
  function parsePackageNameFromImportExpression(importExpression) {
@@ -0,0 +1,5 @@
1
+ /**
2
+ * NOTE: This function is in its own file because it is not possible to mock
3
+ * require.resolve directly in jest https://github.com/jestjs/jest/issues/9543
4
+ */
5
+ export declare function resolveRelativeToDir(path: string, relativeToDir: any): string;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveRelativeToDir = void 0;
4
+ /**
5
+ * NOTE: This function is in its own file because it is not possible to mock
6
+ * require.resolve directly in jest https://github.com/jestjs/jest/issues/9543
7
+ */
8
+ function resolveRelativeToDir(path, relativeToDir) {
9
+ try {
10
+ return require.resolve(path, {
11
+ paths: [relativeToDir],
12
+ });
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ exports.resolveRelativeToDir = resolveRelativeToDir;
@@ -1,10 +1,10 @@
1
- import { CreateNodesResultWithContext } from './plugins/internal-api';
2
1
  import { ConfigurationResult, ConfigurationSourceMaps } from './utils/project-configuration-utils';
3
2
  import { ProjectConfiguration } from '../config/workspace-json-project-json';
4
3
  import { ProjectGraph } from '../config/project-graph';
4
+ import { CreateNodesFunctionV2 } from './plugins';
5
5
  export declare class ProjectGraphError extends Error {
6
6
  #private;
7
- constructor(errors: Array<CreateNodesError | MergeNodesError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError | ProcessDependenciesError | ProcessProjectGraphError | CreateMetadataError | WorkspaceValidityError>, partialProjectGraph: ProjectGraph, partialSourceMaps: ConfigurationSourceMaps);
7
+ constructor(errors: Array<AggregateCreateNodesError | MergeNodesError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError | ProcessDependenciesError | ProcessProjectGraphError | CreateMetadataError | WorkspaceValidityError>, partialProjectGraph: ProjectGraph, partialSourceMaps: ConfigurationSourceMaps);
8
8
  /**
9
9
  * The daemon cannot throw errors which contain methods as they are not serializable.
10
10
  *
@@ -18,7 +18,7 @@ export declare class ProjectGraphError extends Error {
18
18
  */
19
19
  getPartialProjectGraph(): ProjectGraph;
20
20
  getPartialSourcemaps(): ConfigurationSourceMaps;
21
- getErrors(): (CreateNodesError | MergeNodesError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError | CreateMetadataError | ProcessDependenciesError | ProcessProjectGraphError | WorkspaceValidityError)[];
21
+ getErrors(): (AggregateCreateNodesError | MergeNodesError | CreateMetadataError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError | ProcessDependenciesError | ProcessProjectGraphError | WorkspaceValidityError)[];
22
22
  }
23
23
  export declare class MultipleProjectsWithSameNameError extends Error {
24
24
  conflicts: Map<string, string[]>;
@@ -44,25 +44,44 @@ export declare class ProjectWithNoNameError extends Error {
44
44
  }
45
45
  export declare function isProjectWithNoNameError(e: unknown): e is ProjectWithNoNameError;
46
46
  export declare class ProjectConfigurationsError extends Error {
47
- readonly errors: Array<MergeNodesError | CreateNodesError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError>;
47
+ readonly errors: Array<MergeNodesError | AggregateCreateNodesError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError>;
48
48
  readonly partialProjectConfigurationsResult: ConfigurationResult;
49
- constructor(errors: Array<MergeNodesError | CreateNodesError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError>, partialProjectConfigurationsResult: ConfigurationResult);
49
+ constructor(errors: Array<MergeNodesError | AggregateCreateNodesError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError>, partialProjectConfigurationsResult: ConfigurationResult);
50
50
  }
51
51
  export declare function isProjectConfigurationsError(e: unknown): e is ProjectConfigurationsError;
52
- export declare class CreateNodesError extends Error {
53
- file: string;
54
- pluginName: string;
55
- constructor({ file, pluginName, error, }: {
56
- file: string;
57
- pluginName: string;
58
- error: Error;
59
- });
60
- }
52
+ /**
53
+ * This error should be thrown when a `createNodesV2` function hits a recoverable error.
54
+ * It allows Nx to recieve partial results and continue processing for better UX.
55
+ */
61
56
  export declare class AggregateCreateNodesError extends Error {
62
- readonly pluginName: string;
63
- readonly errors: Array<CreateNodesError>;
64
- readonly partialResults: Array<CreateNodesResultWithContext>;
65
- constructor(pluginName: string, errors: Array<CreateNodesError>, partialResults: Array<CreateNodesResultWithContext>);
57
+ readonly errors: Array<[file: string | null, error: Error]>;
58
+ readonly partialResults: Awaited<ReturnType<CreateNodesFunctionV2>>;
59
+ /**
60
+ * Throwing this error from a `createNodesV2` function will allow Nx to continue processing and recieve partial results from your plugin.
61
+ * @example
62
+ * export async function createNodesV2(
63
+ * files: string[],
64
+ * ) {
65
+ * const partialResults = [];
66
+ * const errors = [];
67
+ * await Promise.all(files.map(async (file) => {
68
+ * try {
69
+ * const result = await createNodes(file);
70
+ * partialResults.push(result);
71
+ * } catch (e) {
72
+ * errors.push([file, e]);
73
+ * }
74
+ * }));
75
+ * if (errors.length > 0) {
76
+ * throw new AggregateCreateNodesError(errors, partialResults);
77
+ * }
78
+ * return partialResults;
79
+ * }
80
+ *
81
+ * @param errors An array of tuples that represent errors encountered when processing a given file. An example entry might look like ['path/to/project.json', [Error: 'Invalid JSON. Unexpected token 'a' in JSON at position 0]]
82
+ * @param partialResults The partial results of the `createNodesV2` function. This should be the results for each file that didn't encounter an issue.
83
+ */
84
+ constructor(errors: Array<[file: string | null, error: Error]>, partialResults: Awaited<ReturnType<CreateNodesFunctionV2>>);
66
85
  }
67
86
  export declare class MergeNodesError extends Error {
68
87
  file: string;
@@ -102,7 +121,6 @@ export declare class AggregateProjectGraphError extends Error {
102
121
  }
103
122
  export declare function isAggregateProjectGraphError(e: unknown): e is AggregateProjectGraphError;
104
123
  export declare function isCreateMetadataError(e: unknown): e is CreateMetadataError;
105
- export declare function isCreateNodesError(e: unknown): e is CreateNodesError;
106
124
  export declare function isAggregateCreateNodesError(e: unknown): e is AggregateCreateNodesError;
107
125
  export declare function isMergeNodesError(e: unknown): e is MergeNodesError;
108
126
  export declare class DaemonProjectGraphError extends Error {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _ProjectGraphError_errors, _ProjectGraphError_partialProjectGraph, _ProjectGraphError_partialSourceMaps;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.LoadPluginError = exports.DaemonProjectGraphError = exports.isMergeNodesError = exports.isAggregateCreateNodesError = exports.isCreateNodesError = exports.isCreateMetadataError = exports.isAggregateProjectGraphError = exports.AggregateProjectGraphError = exports.ProcessProjectGraphError = exports.isWorkspaceValidityError = exports.WorkspaceValidityError = exports.ProcessDependenciesError = exports.CreateMetadataError = exports.MergeNodesError = exports.AggregateCreateNodesError = exports.CreateNodesError = exports.isProjectConfigurationsError = exports.ProjectConfigurationsError = exports.isProjectWithNoNameError = exports.ProjectWithNoNameError = exports.isProjectsWithNoNameError = exports.ProjectsWithNoNameError = exports.isMultipleProjectsWithSameNameError = exports.isProjectWithExistingNameError = exports.ProjectWithExistingNameError = exports.MultipleProjectsWithSameNameError = exports.ProjectGraphError = void 0;
4
+ exports.LoadPluginError = exports.DaemonProjectGraphError = exports.isMergeNodesError = exports.isAggregateCreateNodesError = exports.isCreateMetadataError = exports.isAggregateProjectGraphError = exports.AggregateProjectGraphError = exports.ProcessProjectGraphError = exports.isWorkspaceValidityError = exports.WorkspaceValidityError = exports.ProcessDependenciesError = exports.CreateMetadataError = exports.MergeNodesError = exports.AggregateCreateNodesError = exports.isProjectConfigurationsError = exports.ProjectConfigurationsError = exports.isProjectWithNoNameError = exports.ProjectWithNoNameError = exports.isProjectsWithNoNameError = exports.ProjectsWithNoNameError = exports.isMultipleProjectsWithSameNameError = exports.isProjectWithExistingNameError = exports.ProjectWithExistingNameError = exports.MultipleProjectsWithSameNameError = exports.ProjectGraphError = void 0;
5
5
  const tslib_1 = require("tslib");
6
6
  class ProjectGraphError extends Error {
7
7
  constructor(errors, partialProjectGraph, partialSourceMaps) {
@@ -126,21 +126,38 @@ function isProjectConfigurationsError(e) {
126
126
  e?.name === ProjectConfigurationsError.name));
127
127
  }
128
128
  exports.isProjectConfigurationsError = isProjectConfigurationsError;
129
- class CreateNodesError extends Error {
130
- constructor({ file, pluginName, error, }) {
131
- const msg = `The "${pluginName}" plugin threw an error while creating nodes from ${file}:`;
132
- super(msg, { cause: error });
133
- this.name = this.constructor.name;
134
- this.file = file;
135
- this.pluginName = pluginName;
136
- this.stack = `${this.message}\n ${error.stack.split('\n').join('\n ')}`;
137
- }
138
- }
139
- exports.CreateNodesError = CreateNodesError;
129
+ /**
130
+ * This error should be thrown when a `createNodesV2` function hits a recoverable error.
131
+ * It allows Nx to recieve partial results and continue processing for better UX.
132
+ */
140
133
  class AggregateCreateNodesError extends Error {
141
- constructor(pluginName, errors, partialResults) {
134
+ /**
135
+ * Throwing this error from a `createNodesV2` function will allow Nx to continue processing and recieve partial results from your plugin.
136
+ * @example
137
+ * export async function createNodesV2(
138
+ * files: string[],
139
+ * ) {
140
+ * const partialResults = [];
141
+ * const errors = [];
142
+ * await Promise.all(files.map(async (file) => {
143
+ * try {
144
+ * const result = await createNodes(file);
145
+ * partialResults.push(result);
146
+ * } catch (e) {
147
+ * errors.push([file, e]);
148
+ * }
149
+ * }));
150
+ * if (errors.length > 0) {
151
+ * throw new AggregateCreateNodesError(errors, partialResults);
152
+ * }
153
+ * return partialResults;
154
+ * }
155
+ *
156
+ * @param errors An array of tuples that represent errors encountered when processing a given file. An example entry might look like ['path/to/project.json', [Error: 'Invalid JSON. Unexpected token 'a' in JSON at position 0]]
157
+ * @param partialResults The partial results of the `createNodesV2` function. This should be the results for each file that didn't encounter an issue.
158
+ */
159
+ constructor(errors, partialResults) {
142
160
  super('Failed to create nodes');
143
- this.pluginName = pluginName;
144
161
  this.errors = errors;
145
162
  this.partialResults = partialResults;
146
163
  this.name = this.constructor.name;
@@ -230,11 +247,6 @@ function isCreateMetadataError(e) {
230
247
  e?.name === CreateMetadataError.name));
231
248
  }
232
249
  exports.isCreateMetadataError = isCreateMetadataError;
233
- function isCreateNodesError(e) {
234
- return (e instanceof CreateNodesError ||
235
- (typeof e === 'object' && 'name' in e && e?.name === CreateNodesError.name));
236
- }
237
- exports.isCreateNodesError = isCreateNodesError;
238
250
  function isAggregateCreateNodesError(e) {
239
251
  return (e instanceof AggregateCreateNodesError ||
240
252
  (typeof e === 'object' &&
@@ -1,2 +1,3 @@
1
1
  export * from './public-api';
2
2
  export { readPluginPackageJson, registerPluginTSTranspiler } from './loader';
3
+ export { createNodesFromFiles } from './utils';
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerPluginTSTranspiler = exports.readPluginPackageJson = void 0;
3
+ exports.createNodesFromFiles = exports.registerPluginTSTranspiler = exports.readPluginPackageJson = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  tslib_1.__exportStar(require("./public-api"), exports);
6
6
  var loader_1 = require("./loader");
7
7
  Object.defineProperty(exports, "readPluginPackageJson", { enumerable: true, get: function () { return loader_1.readPluginPackageJson; } });
8
8
  Object.defineProperty(exports, "registerPluginTSTranspiler", { enumerable: true, get: function () { return loader_1.registerPluginTSTranspiler; } });
9
+ var utils_1 = require("./utils");
10
+ Object.defineProperty(exports, "createNodesFromFiles", { enumerable: true, get: function () { return utils_1.createNodesFromFiles; } });
@@ -1,12 +1,12 @@
1
1
  import { PluginConfiguration } from '../../config/nx-json';
2
2
  import { NxPluginV1 } from '../../utils/nx-plugin.deprecated';
3
- import { CreateDependencies, CreateDependenciesContext, CreateMetadata, CreateMetadataContext, CreateNodesContext, CreateNodesResult, NxPluginV2 } from './public-api';
3
+ import { CreateDependencies, CreateDependenciesContext, CreateMetadata, CreateMetadataContext, CreateNodesContextV2, CreateNodesResult, NxPluginV2 } from './public-api';
4
4
  import { ProjectGraph, ProjectGraphProcessor } from '../../config/project-graph';
5
5
  export declare class LoadedNxPlugin {
6
6
  readonly name: string;
7
7
  readonly createNodes?: [
8
8
  filePattern: string,
9
- fn: (matchedFiles: string[], context: CreateNodesContext) => Promise<CreateNodesResultWithContext[]>
9
+ fn: (matchedFiles: string[], context: CreateNodesContextV2) => Promise<Array<readonly [plugin: string, file: string, result: CreateNodesResult]>>
10
10
  ];
11
11
  readonly createDependencies?: (context: CreateDependenciesContext) => ReturnType<CreateDependencies>;
12
12
  readonly createMetadata?: (graph: ProjectGraph, context: CreateMetadataContext) => ReturnType<CreateMetadata>;
@@ -6,9 +6,10 @@ exports.getDefaultPlugins = exports.loadNxPlugins = exports.nxPluginCache = expo
6
6
  const path_1 = require("path");
7
7
  const workspace_root_1 = require("../../utils/workspace-root");
8
8
  const angular_json_1 = require("../../adapter/angular-json");
9
- const utils_1 = require("./utils");
10
9
  const isolation_1 = require("./isolation");
11
10
  const loader_1 = require("./loader");
11
+ const utils_1 = require("./utils");
12
+ const error_types_1 = require("../error-types");
12
13
  class LoadedNxPlugin {
13
14
  constructor(plugin, pluginDefinition) {
14
15
  this.name = plugin.name;
@@ -17,12 +18,41 @@ class LoadedNxPlugin {
17
18
  this.include = pluginDefinition.include;
18
19
  this.exclude = pluginDefinition.exclude;
19
20
  }
20
- if (plugin.createNodes) {
21
+ if (plugin.createNodes && !plugin.createNodesV2) {
21
22
  this.createNodes = [
22
23
  plugin.createNodes[0],
23
- (files, context) => (0, utils_1.runCreateNodesInParallel)(files, plugin, this.options, context),
24
+ (configFiles, context) => (0, utils_1.createNodesFromFiles)(plugin.createNodes[1], configFiles, this.options, context).then((results) => results.map((r) => [this.name, r[0], r[1]])),
25
+ ];
26
+ }
27
+ if (plugin.createNodesV2) {
28
+ this.createNodes = [
29
+ plugin.createNodesV2[0],
30
+ async (configFiles, context) => {
31
+ const result = await plugin.createNodesV2[1](configFiles, this.options, context);
32
+ return result.map((r) => [this.name, r[0], r[1]]);
33
+ },
24
34
  ];
25
35
  }
36
+ if (this.createNodes) {
37
+ const inner = this.createNodes[1];
38
+ this.createNodes[1] = async (...args) => {
39
+ performance.mark(`${plugin.name}:createNodes - start`);
40
+ try {
41
+ return await inner(...args);
42
+ }
43
+ catch (e) {
44
+ if ((0, error_types_1.isAggregateCreateNodesError)(e)) {
45
+ throw e;
46
+ }
47
+ // The underlying plugin errored out. We can't know any partial results.
48
+ throw new error_types_1.AggregateCreateNodesError([null, e], []);
49
+ }
50
+ finally {
51
+ performance.mark(`${plugin.name}:createNodes - end`);
52
+ performance.measure(`${plugin.name}:createNodes`, `${plugin.name}:createNodes - start`, `${plugin.name}:createNodes - end`);
53
+ }
54
+ };
55
+ }
26
56
  if (plugin.createDependencies) {
27
57
  this.createDependencies = (context) => plugin.createDependencies(this.options, context);
28
58
  }
@@ -6,19 +6,23 @@ import { RawProjectGraphDependency } from '../project-graph-builder';
6
6
  /**
7
7
  * Context for {@link CreateNodesFunction}
8
8
  */
9
- export interface CreateNodesContext {
10
- readonly nxJsonConfiguration: NxJsonConfiguration;
11
- readonly workspaceRoot: string;
9
+ export interface CreateNodesContext extends CreateNodesContextV2 {
12
10
  /**
13
11
  * The subset of configuration files which match the createNodes pattern
14
12
  */
15
13
  readonly configFiles: readonly string[];
16
14
  }
15
+ export interface CreateNodesContextV2 {
16
+ readonly nxJsonConfiguration: NxJsonConfiguration;
17
+ readonly workspaceRoot: string;
18
+ }
17
19
  /**
18
20
  * A function which parses a configuration file into a set of nodes.
19
21
  * Used for creating nodes for the {@link ProjectGraph}
20
22
  */
21
23
  export type CreateNodesFunction<T = unknown> = (projectConfigurationFile: string, options: T | undefined, context: CreateNodesContext) => CreateNodesResult | Promise<CreateNodesResult>;
24
+ export type CreateNodesResultV2 = Array<readonly [configFileSource: string, result: CreateNodesResult]>;
25
+ export type CreateNodesFunctionV2<T = unknown> = (projectConfigurationFiles: readonly string[], options: T | undefined, context: CreateNodesContextV2) => CreateNodesResultV2 | Promise<CreateNodesResultV2>;
22
26
  export type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
23
27
  export interface CreateNodesResult {
24
28
  /**
@@ -32,11 +36,29 @@ export interface CreateNodesResult {
32
36
  }
33
37
  /**
34
38
  * A pair of file patterns and {@link CreateNodesFunction}
39
+ *
40
+ * Nx 19.2+: Both original `CreateNodes` and `CreateNodesV2` are supported. Nx will only invoke `CreateNodesV2` if it is present.
41
+ * Nx 20.X : The `CreateNodesV2` will be the only supported API. This typing will still exist, but be identical to `CreateNodesV2`.
42
+ Nx **will not** invoke the original `plugin.createNodes` callback. This should give plugin authors a window to transition.
43
+ Plugin authors should update their plugin's `createNodes` function to align with `CreateNodesV2` / the updated `CreateNodes`.
44
+ The plugin should contain something like: `export createNodes = createNodesV2;` during this period. This will allow the plugin
45
+ to maintain compatibility with Nx 19.2 and up.
46
+ * Nx 21.X : The `CreateNodesV2` typing will be removed, as it has replaced `CreateNodes`.
47
+ *
48
+ * @deprecated Use {@link CreateNodesV2} instead. CreateNodesV2 will replace this API. Read more about the transition above.
35
49
  */
36
50
  export type CreateNodes<T = unknown> = readonly [
37
51
  projectFilePattern: string,
38
52
  createNodesFunction: CreateNodesFunction<T>
39
53
  ];
54
+ /**
55
+ * A pair of file patterns and {@link CreateNodesFunctionV2}
56
+ * In Nx 20 {@link CreateNodes} will be replaced with this type. In Nx 21, this type will be removed.
57
+ */
58
+ export type CreateNodesV2<T = unknown> = readonly [
59
+ projectFilePattern: string,
60
+ createNodesFunction: CreateNodesFunctionV2<T>
61
+ ];
40
62
  /**
41
63
  * Context for {@link CreateDependencies}
42
64
  */
@@ -82,8 +104,17 @@ export type NxPluginV2<TOptions = unknown> = {
82
104
  /**
83
105
  * Provides a file pattern and function that retrieves configuration info from
84
106
  * those files. e.g. { '**\/*.csproj': buildProjectsFromCsProjFile }
107
+ *
108
+ * @deprecated Use {@link createNodesV2} instead. In Nx 20 support for calling createNodes with a single file for the first argument will be removed.
85
109
  */
86
110
  createNodes?: CreateNodes<TOptions>;
111
+ /**
112
+ * Provides a file pattern and function that retrieves configuration info from
113
+ * those files. e.g. { '**\/*.csproj': buildProjectsFromCsProjFiles }
114
+ *
115
+ * In Nx 20 {@link createNodes} will be replaced with this property. In Nx 21, this property will be removed.
116
+ */
117
+ createNodesV2?: CreateNodesV2<TOptions>;
87
118
  /**
88
119
  * Provides a function to analyze files to create dependencies for the {@link ProjectGraph}
89
120
  */
@@ -1,7 +1,8 @@
1
1
  import type { NxPluginV1 } from '../../utils/nx-plugin.deprecated';
2
- import type { CreateNodesResultWithContext, LoadedNxPlugin, NormalizedPlugin } from './internal-api';
3
- import { type CreateNodesContext, type NxPlugin, type NxPluginV2 } from './public-api';
2
+ import type { LoadedNxPlugin, NormalizedPlugin } from './internal-api';
3
+ import { CreateNodesContextV2, CreateNodesFunction, CreateNodesResult, type NxPlugin, type NxPluginV2 } from './public-api';
4
4
  export declare function isNxPluginV2(plugin: NxPlugin): plugin is NxPluginV2;
5
5
  export declare function isNxPluginV1(plugin: NxPlugin | LoadedNxPlugin): plugin is NxPluginV1;
6
6
  export declare function normalizeNxPlugin(plugin: NxPlugin): NormalizedPlugin;
7
- export declare function runCreateNodesInParallel(configFiles: readonly string[], plugin: NormalizedPlugin, options: unknown, context: CreateNodesContext): Promise<CreateNodesResultWithContext[]>;
7
+ export type AsyncFn<T extends Function> = T extends (...args: infer A) => infer R ? (...args: A) => Promise<Awaited<R>> : never;
8
+ export declare function createNodesFromFiles<T = unknown>(createNodes: CreateNodesFunction, configFiles: readonly string[], options: T, context: CreateNodesContextV2): Promise<[file: string, value: CreateNodesResult][]>;
@@ -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.
@@ -1,10 +0,0 @@
1
- /**
2
- * In many cases the package.json will be directly resolvable, so we try that first.
3
- * If, however, package exports are used and the package.json is not defined, we will
4
- * need to resolve the main entry point of the package and traverse upwards to find the
5
- * package.json.
6
- *
7
- * NOTE: Unit testing this code is currently impractical as it is not possible to mock
8
- * require.resolve in jest https://github.com/jestjs/jest/issues/9543
9
- */
10
- export declare function findExternalPackageJsonPath(packageName: string, relativeToDir: string): string | null;
@@ -1,42 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findExternalPackageJsonPath = void 0;
4
- const node_fs_1 = require("node:fs");
5
- const node_path_1 = require("node:path");
6
- /**
7
- * In many cases the package.json will be directly resolvable, so we try that first.
8
- * If, however, package exports are used and the package.json is not defined, we will
9
- * need to resolve the main entry point of the package and traverse upwards to find the
10
- * package.json.
11
- *
12
- * NOTE: Unit testing this code is currently impractical as it is not possible to mock
13
- * require.resolve in jest https://github.com/jestjs/jest/issues/9543
14
- */
15
- function findExternalPackageJsonPath(packageName, relativeToDir) {
16
- try {
17
- return require.resolve((0, node_path_1.join)(packageName, 'package.json'), {
18
- paths: [relativeToDir],
19
- });
20
- }
21
- catch {
22
- try {
23
- // Resolve the main entry point of the package
24
- const mainPath = require.resolve(packageName, {
25
- paths: [relativeToDir],
26
- });
27
- let dir = (0, node_path_1.dirname)(mainPath);
28
- while (dir !== (0, node_path_1.parse)(dir).root) {
29
- const packageJsonPath = (0, node_path_1.join)(dir, 'package.json');
30
- if ((0, node_fs_1.existsSync)(packageJsonPath)) {
31
- return packageJsonPath;
32
- }
33
- dir = (0, node_path_1.dirname)(dir);
34
- }
35
- throw new Error(`Could not find package.json for ${packageName}`);
36
- }
37
- catch {
38
- return null;
39
- }
40
- }
41
- }
42
- exports.findExternalPackageJsonPath = findExternalPackageJsonPath;