nx 18.2.0-canary.20240321-2a4c57d → 18.2.0-canary.20240323-54d4780

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/LICENSE +1 -1
  2. package/package.json +12 -12
  3. package/schemas/nx-schema.json +32 -6
  4. package/src/command-line/add/add.js +1 -1
  5. package/src/command-line/affected/command-object.js +49 -22
  6. package/src/command-line/generate/generate.js +3 -3
  7. package/src/command-line/init/init-v2.js +16 -11
  8. package/src/command-line/run/command-object.js +9 -2
  9. package/src/command-line/run/run-one.js +1 -1
  10. package/src/command-line/run-many/command-object.js +4 -1
  11. package/src/command-line/show/command-object.d.ts +2 -0
  12. package/src/command-line/show/command-object.js +19 -2
  13. package/src/config/nx-json.d.ts +2 -0
  14. package/src/daemon/client/client.js +19 -7
  15. package/src/daemon/daemon-project-graph-error.d.ts +8 -0
  16. package/src/daemon/daemon-project-graph-error.js +13 -0
  17. package/src/daemon/server/handle-hash-tasks.js +11 -1
  18. package/src/daemon/server/project-graph-incremental-recomputation.d.ts +1 -0
  19. package/src/daemon/server/project-graph-incremental-recomputation.js +55 -6
  20. package/src/daemon/server/shutdown-utils.js +1 -3
  21. package/src/daemon/socket-utils.js +7 -1
  22. package/src/project-graph/build-project-graph.d.ts +18 -1
  23. package/src/project-graph/build-project-graph.js +71 -24
  24. package/src/project-graph/project-graph.d.ts +23 -2
  25. package/src/project-graph/project-graph.js +117 -14
  26. package/src/project-graph/utils/project-configuration-utils.d.ts +27 -4
  27. package/src/project-graph/utils/project-configuration-utils.js +106 -43
  28. package/src/project-graph/utils/retrieve-workspace-files.d.ts +4 -12
  29. package/src/project-graph/utils/retrieve-workspace-files.js +3 -16
  30. package/src/tasks-runner/cache.js +6 -3
  31. package/src/utils/nx-plugin.d.ts +2 -0
  32. package/src/utils/nx-plugin.js +18 -2
  33. package/src/utils/output.d.ts +1 -1
  34. package/src/utils/params.d.ts +2 -2
  35. package/src/utils/params.js +14 -0
@@ -13,6 +13,8 @@ const workspace_context_1 = require("../../utils/workspace-context");
13
13
  const workspace_root_1 = require("../../utils/workspace-root");
14
14
  const file_watcher_sockets_1 = require("./file-watching/file-watcher-sockets");
15
15
  const logger_1 = require("./logger");
16
+ const project_configuration_utils_1 = require("../../project-graph/utils/project-configuration-utils");
17
+ const daemon_project_graph_error_1 = require("../daemon-project-graph-error");
16
18
  let cachedSerializedProjectGraphPromise;
17
19
  const collectedUpdatedFiles = new Set();
18
20
  const collectedDeletedFiles = new Set();
@@ -48,6 +50,7 @@ async function getCachedSerializedProjectGraphPromise() {
48
50
  serializedProjectGraph: null,
49
51
  serializedSourceMaps: null,
50
52
  projectGraph: null,
53
+ projectFileMapCache: null,
51
54
  fileMap: null,
52
55
  allWorkspaceFiles: null,
53
56
  rustReferences: null,
@@ -139,22 +142,66 @@ async function processFilesAndCreateAndSerializeProjectGraph() {
139
142
  const nxJson = (0, nx_json_1.readNxJson)(workspace_root_1.workspaceRoot);
140
143
  // Set this globally to allow plugins to know if they are being called from the project graph creation
141
144
  global.NX_GRAPH_CREATION = true;
142
- const graphNodes = await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(workspace_root_1.workspaceRoot, nxJson);
145
+ let graphNodes;
146
+ let projectConfigurationsError;
147
+ try {
148
+ graphNodes = await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(workspace_root_1.workspaceRoot, nxJson);
149
+ }
150
+ catch (e) {
151
+ if (e instanceof project_configuration_utils_1.ProjectConfigurationsError) {
152
+ graphNodes = e.partialProjectConfigurationsResult;
153
+ projectConfigurationsError = e;
154
+ }
155
+ }
143
156
  await processCollectedUpdatedAndDeletedFiles(graphNodes, updatedFileHashes, deletedFiles);
144
- const g = createAndSerializeProjectGraph(graphNodes);
157
+ const g = await createAndSerializeProjectGraph(graphNodes);
145
158
  delete global.NX_GRAPH_CREATION;
146
- return g;
159
+ const errors = [...(projectConfigurationsError?.errors ?? [])];
160
+ if (g.error) {
161
+ if (g.error instanceof build_project_graph_1.CreateDependenciesError) {
162
+ errors.concat(g.error.errors);
163
+ }
164
+ else {
165
+ return {
166
+ error: g.error,
167
+ projectGraph: null,
168
+ projectFileMapCache: null,
169
+ fileMap: null,
170
+ rustReferences: null,
171
+ allWorkspaceFiles: null,
172
+ serializedProjectGraph: null,
173
+ serializedSourceMaps: null,
174
+ };
175
+ }
176
+ }
177
+ if (errors.length > 0) {
178
+ return {
179
+ error: new daemon_project_graph_error_1.DaemonProjectGraphError(errors, g.projectGraph, graphNodes.sourceMaps),
180
+ projectGraph: null,
181
+ projectFileMapCache: null,
182
+ fileMap: null,
183
+ rustReferences: null,
184
+ allWorkspaceFiles: null,
185
+ serializedProjectGraph: null,
186
+ serializedSourceMaps: null,
187
+ };
188
+ }
189
+ else {
190
+ (0, nx_deps_cache_1.writeCache)(g.projectFileMapCache, g.projectGraph);
191
+ return g;
192
+ }
147
193
  }
148
194
  catch (err) {
149
- return Promise.resolve({
195
+ return {
150
196
  error: err,
151
197
  projectGraph: null,
198
+ projectFileMapCache: null,
152
199
  fileMap: null,
153
200
  rustReferences: null,
154
201
  allWorkspaceFiles: null,
155
202
  serializedProjectGraph: null,
156
203
  serializedSourceMaps: null,
157
- });
204
+ };
158
205
  }
159
206
  }
160
207
  function copyFileData(d) {
@@ -176,7 +223,7 @@ async function createAndSerializeProjectGraph({ projects, sourceMaps, }) {
176
223
  const fileMap = copyFileMap(exports.fileMapWithFiles.fileMap);
177
224
  const allWorkspaceFiles = copyFileData(exports.fileMapWithFiles.allWorkspaceFiles);
178
225
  const rustReferences = exports.fileMapWithFiles.rustReferences;
179
- const { projectGraph, projectFileMapCache } = await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, knownExternalNodes, fileMap, allWorkspaceFiles, rustReferences, exports.currentProjectFileMapCache || (0, nx_deps_cache_1.readFileMapCache)(), true);
226
+ const { projectGraph, projectFileMapCache } = await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, knownExternalNodes, fileMap, allWorkspaceFiles, rustReferences, exports.currentProjectFileMapCache || (0, nx_deps_cache_1.readFileMapCache)());
180
227
  exports.currentProjectFileMapCache = projectFileMapCache;
181
228
  exports.currentProjectGraph = projectGraph;
182
229
  perf_hooks_1.performance.mark('create-project-graph-end');
@@ -189,6 +236,7 @@ async function createAndSerializeProjectGraph({ projects, sourceMaps, }) {
189
236
  return {
190
237
  error: null,
191
238
  projectGraph,
239
+ projectFileMapCache,
192
240
  fileMap,
193
241
  allWorkspaceFiles,
194
242
  serializedProjectGraph,
@@ -201,6 +249,7 @@ async function createAndSerializeProjectGraph({ projects, sourceMaps, }) {
201
249
  return {
202
250
  error: e,
203
251
  projectGraph: null,
252
+ projectFileMapCache: null,
204
253
  fileMap: null,
205
254
  allWorkspaceFiles: null,
206
255
  serializedProjectGraph: null,
@@ -69,9 +69,7 @@ exports.respondToClient = respondToClient;
69
69
  async function respondWithErrorAndExit(socket, description, error) {
70
70
  // print some extra stuff in the error message
71
71
  logger_1.serverLogger.requestLog(`Responding to the client with an error.`, description, error.message);
72
- console.error(error);
73
- error.message = `${error.message}\n\nBecause of the error the Nx daemon process has exited. The next Nx command is going to restart the daemon process.\nIf the error persists, please run "nx reset".`;
72
+ console.error(error.stack);
74
73
  await respondToClient(socket, (0, socket_utils_1.serializeResult)(error, null, null), null);
75
- process.exit(1);
76
74
  }
77
75
  exports.respondWithErrorAndExit = respondWithErrorAndExit;
@@ -5,6 +5,7 @@ const fs_1 = require("fs");
5
5
  const os_1 = require("os");
6
6
  const path_1 = require("path");
7
7
  const tmp_dir_1 = require("./tmp-dir");
8
+ const daemon_project_graph_error_1 = require("./daemon-project-graph-error");
8
9
  exports.isWindows = (0, os_1.platform)() === 'win32';
9
10
  /**
10
11
  * For IPC with the daemon server we use unix sockets or windows named pipes, depending on the user's operating system.
@@ -32,7 +33,12 @@ function serializeError(error) {
32
33
  if (!error) {
33
34
  return null;
34
35
  }
35
- return JSON.stringify(error, Object.getOwnPropertyNames(error));
36
+ if (error instanceof daemon_project_graph_error_1.DaemonProjectGraphError) {
37
+ error.errors = error.errors.map((e) => JSON.parse(serializeError(e)));
38
+ }
39
+ return `{${Object.getOwnPropertyNames(error)
40
+ .map((k) => `"${k}": ${JSON.stringify(error[k])}`)
41
+ .join(',')}}`;
36
42
  }
37
43
  // Prepare a serialized project graph result for sending over IPC from the server to the client
38
44
  function serializeResult(error, serializedProjectGraph, serializedSourceMaps) {
@@ -8,7 +8,24 @@ export declare function getFileMap(): {
8
8
  allWorkspaceFiles: FileData[];
9
9
  rustReferences: NxWorkspaceFilesExternals | null;
10
10
  };
11
- export declare function buildProjectGraphUsingProjectFileMap(projects: Record<string, ProjectConfiguration>, externalNodes: Record<string, ProjectGraphExternalNode>, fileMap: FileMap, allWorkspaceFiles: FileData[], rustReferences: NxWorkspaceFilesExternals, fileMapCache: FileMapCache | null, shouldWriteCache: boolean): Promise<{
11
+ export declare function buildProjectGraphUsingProjectFileMap(projects: Record<string, ProjectConfiguration>, externalNodes: Record<string, ProjectGraphExternalNode>, fileMap: FileMap, allWorkspaceFiles: FileData[], rustReferences: NxWorkspaceFilesExternals, fileMapCache: FileMapCache | null): Promise<{
12
12
  projectGraph: ProjectGraph;
13
13
  projectFileMapCache: FileMapCache;
14
14
  }>;
15
+ export declare class ProcessDependenciesError extends Error {
16
+ readonly pluginName: string;
17
+ constructor(pluginName: string, { cause }: {
18
+ cause: any;
19
+ });
20
+ }
21
+ export declare class ProcessProjectGraphError extends Error {
22
+ readonly pluginName: string;
23
+ constructor(pluginName: string, { cause }: {
24
+ cause: any;
25
+ });
26
+ }
27
+ export declare class CreateDependenciesError extends Error {
28
+ readonly errors: Array<ProcessDependenciesError | ProcessProjectGraphError>;
29
+ readonly partialProjectGraph: ProjectGraph;
30
+ constructor(errors: Array<ProcessDependenciesError | ProcessProjectGraphError>, partialProjectGraph: ProjectGraph);
31
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildProjectGraphUsingProjectFileMap = exports.getFileMap = void 0;
3
+ exports.CreateDependenciesError = exports.ProcessProjectGraphError = exports.ProcessDependenciesError = exports.buildProjectGraphUsingProjectFileMap = exports.getFileMap = void 0;
4
4
  const workspace_root_1 = require("../utils/workspace-root");
5
5
  const path_1 = require("path");
6
6
  const perf_hooks_1 = require("perf_hooks");
@@ -39,7 +39,7 @@ function getFileMap() {
39
39
  }
40
40
  }
41
41
  exports.getFileMap = getFileMap;
42
- async function buildProjectGraphUsingProjectFileMap(projects, externalNodes, fileMap, allWorkspaceFiles, rustReferences, fileMapCache, shouldWriteCache) {
42
+ async function buildProjectGraphUsingProjectFileMap(projects, externalNodes, fileMap, allWorkspaceFiles, rustReferences, fileMapCache) {
43
43
  storedFileMap = fileMap;
44
44
  storedAllWorkspaceFiles = allWorkspaceFiles;
45
45
  storedRustReferences = rustReferences;
@@ -65,11 +65,8 @@ async function buildProjectGraphUsingProjectFileMap(projects, externalNodes, fil
65
65
  };
66
66
  }
67
67
  const context = createContext(projects, nxJson, externalNodes, fileMap, filesToProcess);
68
- let projectGraph = await buildProjectGraphUsingContext(nxJson, externalNodes, context, cachedFileData, projectGraphVersion);
68
+ let projectGraph = await buildProjectGraphUsingContext(externalNodes, context, cachedFileData, projectGraphVersion);
69
69
  const projectFileMapCache = (0, nx_deps_cache_1.createProjectFileMapCache)(nxJson, packageJsonDeps, fileMap, rootTsConfig);
70
- if (shouldWriteCache) {
71
- (0, nx_deps_cache_1.writeCache)(projectFileMapCache, projectGraph);
72
- }
73
70
  return {
74
71
  projectGraph,
75
72
  projectFileMapCache,
@@ -92,7 +89,7 @@ function readCombinedDeps() {
92
89
  ...installationPackageJson.devDependencies,
93
90
  };
94
91
  }
95
- async function buildProjectGraphUsingContext(nxJson, knownExternalNodes, ctx, cachedFileData, projectGraphVersion) {
92
+ async function buildProjectGraphUsingContext(knownExternalNodes, ctx, cachedFileData, projectGraphVersion) {
96
93
  perf_hooks_1.performance.mark('build project graph:start');
97
94
  const builder = new project_graph_builder_1.ProjectGraphBuilder(null, ctx.fileMap.projectFileMap);
98
95
  builder.setVersion(projectGraphVersion);
@@ -101,8 +98,21 @@ async function buildProjectGraphUsingContext(nxJson, knownExternalNodes, ctx, ca
101
98
  }
102
99
  await (0, normalize_project_nodes_1.normalizeProjectNodes)(ctx, builder);
103
100
  const initProjectGraph = builder.getUpdatedProjectGraph();
104
- const r = await updateProjectGraphWithPlugins(ctx, initProjectGraph);
105
- const updatedBuilder = new project_graph_builder_1.ProjectGraphBuilder(r, ctx.fileMap.projectFileMap);
101
+ let updatedGraph;
102
+ let error;
103
+ try {
104
+ updatedGraph = await updateProjectGraphWithPlugins(ctx, initProjectGraph);
105
+ }
106
+ catch (e) {
107
+ if (e instanceof CreateDependenciesError) {
108
+ updatedGraph = e.partialProjectGraph;
109
+ error = e;
110
+ }
111
+ else {
112
+ throw e;
113
+ }
114
+ }
115
+ const updatedBuilder = new project_graph_builder_1.ProjectGraphBuilder(updatedGraph, ctx.fileMap.projectFileMap);
106
116
  for (const proj of Object.keys(cachedFileData.projectFileMap)) {
107
117
  for (const f of ctx.fileMap.projectFileMap[proj] || []) {
108
118
  const cached = cachedFileData.projectFileMap[proj][f.file];
@@ -121,7 +131,12 @@ async function buildProjectGraphUsingContext(nxJson, knownExternalNodes, ctx, ca
121
131
  const finalGraph = updatedBuilder.getUpdatedProjectGraph();
122
132
  perf_hooks_1.performance.mark('build project graph:end');
123
133
  perf_hooks_1.performance.measure('build project graph', 'build project graph:start', 'build project graph:end');
124
- return finalGraph;
134
+ if (!error) {
135
+ return finalGraph;
136
+ }
137
+ else {
138
+ throw new CreateDependenciesError(error.errors, finalGraph);
139
+ }
125
140
  }
126
141
  function createContext(projects, nxJson, externalNodes, fileMap, filesToProcess) {
127
142
  const clonedProjects = Object.keys(projects).reduce((map, projectName) => {
@@ -142,6 +157,7 @@ function createContext(projects, nxJson, externalNodes, fileMap, filesToProcess)
142
157
  async function updateProjectGraphWithPlugins(context, initProjectGraph) {
143
158
  const plugins = await (0, nx_plugin_1.loadNxPlugins)(context.nxJsonConfiguration?.plugins, (0, installation_directory_1.getNxRequirePaths)(), context.workspaceRoot, context.projects);
144
159
  let graph = initProjectGraph;
160
+ const errors = [];
145
161
  for (const { plugin } of plugins) {
146
162
  try {
147
163
  if ((0, nx_plugin_1.isNxPluginV1)(plugin) &&
@@ -173,12 +189,9 @@ async function updateProjectGraphWithPlugins(context, initProjectGraph) {
173
189
  }
174
190
  }
175
191
  catch (e) {
176
- let message = `Failed to process the project graph with "${plugin.name}".`;
177
- if (e instanceof Error) {
178
- e.message = message + '\n' + e.message;
179
- throw e;
180
- }
181
- throw new Error(message);
192
+ errors.push(new ProcessProjectGraphError(plugin.name, {
193
+ cause: e,
194
+ }));
182
195
  }
183
196
  }
184
197
  const builder = new project_graph_builder_1.ProjectGraphBuilder(graph, context.fileMap.projectFileMap, context.fileMap.nonProjectFiles);
@@ -193,19 +206,53 @@ async function updateProjectGraphWithPlugins(context, initProjectGraph) {
193
206
  builder.addDependency(dep.source, dep.target, dep.type, 'sourceFile' in dep ? dep.sourceFile : null);
194
207
  }
195
208
  }
196
- catch (e) {
197
- let message = `Failed to process project dependencies with "${plugin.name}".`;
198
- if (e instanceof Error) {
199
- e.message = message + '\n' + e.message;
200
- throw e;
201
- }
202
- throw new Error(message);
209
+ catch (cause) {
210
+ errors.push(new ProcessDependenciesError(plugin.name, {
211
+ cause,
212
+ }));
203
213
  }
204
214
  perf_hooks_1.performance.mark(`${plugin.name}:createDependencies - end`);
205
215
  perf_hooks_1.performance.measure(`${plugin.name}:createDependencies`, `${plugin.name}:createDependencies - start`, `${plugin.name}:createDependencies - end`);
206
216
  }));
207
- return builder.getUpdatedProjectGraph();
217
+ const result = builder.getUpdatedProjectGraph();
218
+ if (errors.length === 0) {
219
+ return result;
220
+ }
221
+ else {
222
+ throw new CreateDependenciesError(errors, result);
223
+ }
224
+ }
225
+ class ProcessDependenciesError extends Error {
226
+ constructor(pluginName, { cause }) {
227
+ super(`The "${pluginName}" plugin threw an error while creating dependencies:`, {
228
+ cause,
229
+ });
230
+ this.pluginName = pluginName;
231
+ this.name = this.constructor.name;
232
+ this.stack = `${this.message}\n ${cause.stack.split('\n').join('\n ')}`;
233
+ }
234
+ }
235
+ exports.ProcessDependenciesError = ProcessDependenciesError;
236
+ class ProcessProjectGraphError extends Error {
237
+ constructor(pluginName, { cause }) {
238
+ super(`The "${pluginName}" plugin threw an error while processing the project graph:`, {
239
+ cause,
240
+ });
241
+ this.pluginName = pluginName;
242
+ this.name = this.constructor.name;
243
+ this.stack = `${this.message}\n ${cause.stack.split('\n').join('\n ')}`;
244
+ }
245
+ }
246
+ exports.ProcessProjectGraphError = ProcessProjectGraphError;
247
+ class CreateDependenciesError extends Error {
248
+ constructor(errors, partialProjectGraph) {
249
+ super('Failed to create dependencies. See above for errors');
250
+ this.errors = errors;
251
+ this.partialProjectGraph = partialProjectGraph;
252
+ this.name = this.constructor.name;
253
+ }
208
254
  }
255
+ exports.CreateDependenciesError = CreateDependenciesError;
209
256
  function readRootTsConfig() {
210
257
  try {
211
258
  const tsConfigPath = (0, typescript_1.getRootTsConfigPath)();
@@ -1,5 +1,8 @@
1
+ import { ProcessDependenciesError, ProcessProjectGraphError } from './build-project-graph';
1
2
  import { ProjectGraph } from '../config/project-graph';
2
3
  import { ProjectConfiguration, ProjectsConfigurations } from '../config/workspace-json-project-json';
4
+ import { ConfigurationSourceMaps, CreateNodesError, MergeNodesError } from './utils/project-configuration-utils';
5
+ import { DaemonProjectGraphError } from '../daemon/daemon-project-graph-error';
3
6
  /**
4
7
  * Synchronously reads the latest cached copy of the workspace's ProjectGraph.
5
8
  * @throws {Error} if there is no cached ProjectGraph to read from
@@ -12,8 +15,26 @@ export declare function readCachedProjectConfiguration(projectName: string): Pro
12
15
  export declare function readProjectsConfigurationFromProjectGraph(projectGraph: ProjectGraph): ProjectsConfigurations;
13
16
  export declare function buildProjectGraphAndSourceMapsWithoutDaemon(): Promise<{
14
17
  projectGraph: ProjectGraph;
15
- sourceMaps: import("./utils/project-configuration-utils").ConfigurationSourceMaps;
18
+ sourceMaps: ConfigurationSourceMaps;
16
19
  }>;
20
+ export declare class ProjectGraphError extends Error {
21
+ #private;
22
+ constructor(errors: Array<CreateNodesError | MergeNodesError | ProcessDependenciesError | ProcessProjectGraphError>, partialProjectGraph: ProjectGraph, partialSourceMaps: ConfigurationSourceMaps);
23
+ /**
24
+ * The daemon cannot throw errors which contain methods as they are not serializable.
25
+ *
26
+ * This method creates a new {@link ProjectGraphError} from a {@link DaemonProjectGraphError} with the methods based on the same serialized data.
27
+ */
28
+ static fromDaemonProjectGraphError(e: DaemonProjectGraphError): ProjectGraphError;
29
+ /**
30
+ * This gets the partial project graph despite the errors which occured.
31
+ * This partial project graph may be missing nodes, properties of nodes, or dependencies.
32
+ * This is useful mostly for visualization/debugging. It should not be used for running tasks.
33
+ */
34
+ getPartialProjectGraph(): ProjectGraph;
35
+ getPartialSourcemaps(): ConfigurationSourceMaps;
36
+ getErrors(): (ProcessDependenciesError | ProcessProjectGraphError | CreateNodesError)[];
37
+ }
17
38
  /**
18
39
  * Computes and returns a ProjectGraph.
19
40
  *
@@ -44,5 +65,5 @@ export declare function createProjectGraphAndSourceMapsAsync(opts?: {
44
65
  resetDaemonClient?: boolean;
45
66
  }): Promise<{
46
67
  projectGraph: ProjectGraph;
47
- sourceMaps: import("./utils/project-configuration-utils").ConfigurationSourceMaps;
68
+ sourceMaps: ConfigurationSourceMaps;
48
69
  }>;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
+ var _ProjectGraphError_errors, _ProjectGraphError_partialProjectGraph, _ProjectGraphError_partialSourceMaps;
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createProjectGraphAndSourceMapsAsync = exports.createProjectGraphAsync = exports.buildProjectGraphAndSourceMapsWithoutDaemon = exports.readProjectsConfigurationFromProjectGraph = exports.readCachedProjectConfiguration = exports.readCachedProjectGraph = void 0;
4
+ exports.createProjectGraphAndSourceMapsAsync = exports.createProjectGraphAsync = exports.ProjectGraphError = exports.buildProjectGraphAndSourceMapsWithoutDaemon = exports.readProjectsConfigurationFromProjectGraph = exports.readCachedProjectConfiguration = exports.readCachedProjectGraph = void 0;
5
+ const tslib_1 = require("tslib");
4
6
  const nx_deps_cache_1 = require("./nx-deps-cache");
5
7
  const build_project_graph_1 = require("./build-project-graph");
6
8
  const output_1 = require("../utils/output");
@@ -13,6 +15,7 @@ const perf_hooks_1 = require("perf_hooks");
13
15
  const retrieve_workspace_files_1 = require("./utils/retrieve-workspace-files");
14
16
  const nx_json_1 = require("../config/nx-json");
15
17
  const nx_plugin_1 = require("../utils/nx-plugin");
18
+ const project_configuration_utils_1 = require("./utils/project-configuration-utils");
16
19
  /**
17
20
  * Synchronously reads the latest cached copy of the workspace's ProjectGraph.
18
21
  * @throws {Error} if there is no cached ProjectGraph to read from
@@ -70,29 +73,127 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
70
73
  global.NX_GRAPH_CREATION = true;
71
74
  const nxJson = (0, nx_json_1.readNxJson)();
72
75
  perf_hooks_1.performance.mark('retrieve-project-configurations:start');
73
- const { projects, externalNodes, sourceMaps, projectRootMap } = await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(workspace_root_1.workspaceRoot, nxJson);
76
+ let configurationResult;
77
+ let projectConfigurationsError;
78
+ try {
79
+ configurationResult = await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(workspace_root_1.workspaceRoot, nxJson);
80
+ }
81
+ catch (e) {
82
+ if (e instanceof project_configuration_utils_1.ProjectConfigurationsError) {
83
+ projectConfigurationsError = e;
84
+ configurationResult = e.partialProjectConfigurationsResult;
85
+ }
86
+ else {
87
+ throw e;
88
+ }
89
+ }
90
+ const { projects, externalNodes, sourceMaps, projectRootMap } = configurationResult;
74
91
  perf_hooks_1.performance.mark('retrieve-project-configurations:end');
75
92
  perf_hooks_1.performance.mark('retrieve-workspace-files:start');
76
93
  const { allWorkspaceFiles, fileMap, rustReferences } = await (0, retrieve_workspace_files_1.retrieveWorkspaceFiles)(workspace_root_1.workspaceRoot, projectRootMap);
77
94
  perf_hooks_1.performance.mark('retrieve-workspace-files:end');
78
95
  const cacheEnabled = process.env.NX_CACHE_PROJECT_GRAPH !== 'false';
79
96
  perf_hooks_1.performance.mark('build-project-graph-using-project-file-map:start');
80
- const projectGraph = (await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, externalNodes, fileMap, allWorkspaceFiles, rustReferences, cacheEnabled ? (0, nx_deps_cache_1.readFileMapCache)() : null, cacheEnabled)).projectGraph;
97
+ let createDependenciesError;
98
+ let projectGraphResult;
99
+ try {
100
+ projectGraphResult = await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, externalNodes, fileMap, allWorkspaceFiles, rustReferences, cacheEnabled ? (0, nx_deps_cache_1.readFileMapCache)() : null);
101
+ }
102
+ catch (e) {
103
+ if (e instanceof build_project_graph_1.CreateDependenciesError) {
104
+ projectGraphResult = {
105
+ projectGraph: e.partialProjectGraph,
106
+ projectFileMapCache: null,
107
+ };
108
+ createDependenciesError = e;
109
+ }
110
+ else {
111
+ throw e;
112
+ }
113
+ }
114
+ const { projectGraph, projectFileMapCache } = projectGraphResult;
81
115
  perf_hooks_1.performance.mark('build-project-graph-using-project-file-map:end');
82
116
  (0, nx_plugin_1.unregisterPluginTSTranspiler)();
83
117
  delete global.NX_GRAPH_CREATION;
84
- return { projectGraph, sourceMaps };
118
+ const errors = [
119
+ ...(projectConfigurationsError?.errors ?? []),
120
+ ...(createDependenciesError?.errors ?? []),
121
+ ];
122
+ if (errors.length > 0) {
123
+ throw new ProjectGraphError(errors, projectGraph, sourceMaps);
124
+ }
125
+ else {
126
+ if (cacheEnabled) {
127
+ (0, nx_deps_cache_1.writeCache)(projectFileMapCache, projectGraph);
128
+ }
129
+ return { projectGraph, sourceMaps };
130
+ }
85
131
  }
86
132
  exports.buildProjectGraphAndSourceMapsWithoutDaemon = buildProjectGraphAndSourceMapsWithoutDaemon;
133
+ class ProjectGraphError extends Error {
134
+ constructor(errors, partialProjectGraph, partialSourceMaps) {
135
+ super(`Failed to process project graph.`);
136
+ _ProjectGraphError_errors.set(this, void 0);
137
+ _ProjectGraphError_partialProjectGraph.set(this, void 0);
138
+ _ProjectGraphError_partialSourceMaps.set(this, void 0);
139
+ this.name = this.constructor.name;
140
+ tslib_1.__classPrivateFieldSet(this, _ProjectGraphError_errors, errors, "f");
141
+ tslib_1.__classPrivateFieldSet(this, _ProjectGraphError_partialProjectGraph, partialProjectGraph, "f");
142
+ tslib_1.__classPrivateFieldSet(this, _ProjectGraphError_partialSourceMaps, partialSourceMaps, "f");
143
+ this.stack = `${this.message}\n ${errors
144
+ .map((error) => error.stack.split('\n').join('\n '))
145
+ .join('\n')}`;
146
+ }
147
+ /**
148
+ * The daemon cannot throw errors which contain methods as they are not serializable.
149
+ *
150
+ * This method creates a new {@link ProjectGraphError} from a {@link DaemonProjectGraphError} with the methods based on the same serialized data.
151
+ */
152
+ static fromDaemonProjectGraphError(e) {
153
+ return new ProjectGraphError(e.errors, e.projectGraph, e.sourceMaps);
154
+ }
155
+ /**
156
+ * This gets the partial project graph despite the errors which occured.
157
+ * This partial project graph may be missing nodes, properties of nodes, or dependencies.
158
+ * This is useful mostly for visualization/debugging. It should not be used for running tasks.
159
+ */
160
+ getPartialProjectGraph() {
161
+ return tslib_1.__classPrivateFieldGet(this, _ProjectGraphError_partialProjectGraph, "f");
162
+ }
163
+ getPartialSourcemaps() {
164
+ return tslib_1.__classPrivateFieldGet(this, _ProjectGraphError_partialSourceMaps, "f");
165
+ }
166
+ getErrors() {
167
+ return tslib_1.__classPrivateFieldGet(this, _ProjectGraphError_errors, "f");
168
+ }
169
+ }
170
+ exports.ProjectGraphError = ProjectGraphError;
171
+ _ProjectGraphError_errors = new WeakMap(), _ProjectGraphError_partialProjectGraph = new WeakMap(), _ProjectGraphError_partialSourceMaps = new WeakMap();
87
172
  function handleProjectGraphError(opts, e) {
88
173
  if (opts.exitOnError) {
89
- const lines = e.message.split('\n');
90
- output_1.output.error({
91
- title: lines[0],
92
- bodyLines: lines.slice(1),
93
- });
94
- if (process.env.NX_VERBOSE_LOGGING === 'true') {
95
- console.error(e);
174
+ const isVerbose = process.env.NX_VERBOSE_LOGGING === 'true';
175
+ if (e instanceof ProjectGraphError) {
176
+ let title = e.message;
177
+ if (isVerbose) {
178
+ title += ' See errors below.';
179
+ }
180
+ const bodyLines = isVerbose
181
+ ? [e.stack]
182
+ : ['Pass --verbose to see the stacktraces.'];
183
+ output_1.output.error({
184
+ title,
185
+ bodyLines: bodyLines,
186
+ });
187
+ }
188
+ else {
189
+ const lines = e.message.split('\n');
190
+ output_1.output.error({
191
+ title: lines[0],
192
+ bodyLines: lines.slice(1),
193
+ });
194
+ if (isVerbose) {
195
+ console.error(e);
196
+ }
96
197
  }
97
198
  process.exit(1);
98
199
  }
@@ -151,9 +252,6 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
151
252
  else {
152
253
  try {
153
254
  const projectGraphAndSourceMaps = await client_1.daemonClient.getProjectGraphAndSourceMaps();
154
- if (opts.resetDaemonClient) {
155
- client_1.daemonClient.reset();
156
- }
157
255
  perf_hooks_1.performance.mark('create-project-graph-async:end');
158
256
  perf_hooks_1.performance.measure('create-project-graph-async', 'create-project-graph-async:start', 'create-project-graph-async:end');
159
257
  return projectGraphAndSourceMaps;
@@ -186,6 +284,11 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
186
284
  }
187
285
  handleProjectGraphError(opts, e);
188
286
  }
287
+ finally {
288
+ if (opts.resetDaemonClient) {
289
+ client_1.daemonClient.reset();
290
+ }
291
+ }
189
292
  }
190
293
  }
191
294
  exports.createProjectGraphAndSourceMapsAsync = createProjectGraphAndSourceMapsAsync;
@@ -13,20 +13,43 @@ export declare function mergeProjectConfigurationIntoRootMap(projectRootMap: Map
13
13
  export type ConfigurationResult = {
14
14
  projects: Record<string, ProjectConfiguration>;
15
15
  externalNodes: Record<string, ProjectGraphExternalNode>;
16
- rootMap: Record<string, string>;
16
+ projectRootMap: Record<string, string>;
17
17
  sourceMaps: ConfigurationSourceMaps;
18
18
  };
19
19
  /**
20
20
  * Transforms a list of project paths into a map of project configurations.
21
21
  *
22
+ * @param root The workspace root
22
23
  * @param nxJson The NxJson configuration
23
24
  * @param workspaceFiles A list of non-ignored workspace files
24
25
  * @param plugins The plugins that should be used to infer project configuration
25
- * @param root The workspace root
26
26
  */
27
- export declare function buildProjectsConfigurationsFromProjectPathsAndPlugins(nxJson: NxJsonConfiguration, workspaceFiles: string[], // making this parameter allows devkit to pick up newly created projects
28
- plugins: LoadedNxPlugin[], root?: string): Promise<ConfigurationResult>;
27
+ export declare function createProjectConfigurations(root: string, nxJson: NxJsonConfiguration, workspaceFiles: string[], // making this parameter allows devkit to pick up newly created projects
28
+ plugins: LoadedNxPlugin[]): Promise<ConfigurationResult>;
29
29
  export declare function readProjectConfigurationsFromRootMap(projectRootMap: Map<string, ProjectConfiguration>): Record<string, ProjectConfiguration>;
30
+ export declare class ProjectConfigurationsError extends Error {
31
+ readonly errors: Array<MergeNodesError | CreateNodesError>;
32
+ readonly partialProjectConfigurationsResult: ConfigurationResult;
33
+ constructor(errors: Array<MergeNodesError | CreateNodesError>, partialProjectConfigurationsResult: ConfigurationResult);
34
+ }
35
+ export declare class CreateNodesError extends Error {
36
+ file: string;
37
+ pluginName: string;
38
+ constructor({ file, pluginName, error, }: {
39
+ file: string;
40
+ pluginName: string;
41
+ error: Error;
42
+ });
43
+ }
44
+ export declare class MergeNodesError extends Error {
45
+ file: string;
46
+ pluginName: string;
47
+ constructor({ file, pluginName, error, }: {
48
+ file: string;
49
+ pluginName: string;
50
+ error: Error;
51
+ });
52
+ }
30
53
  /**
31
54
  * Merges two targets.
32
55
  *