nx 22.7.0 → 23.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/src/config/workspace-json-project-json.d.ts +10 -0
  2. package/dist/src/daemon/server/handle-hash-tasks.js +1 -1
  3. package/dist/src/daemon/server/project-graph-incremental-recomputation.d.ts +1 -4
  4. package/dist/src/daemon/server/project-graph-incremental-recomputation.js +11 -20
  5. package/dist/src/executors/utils/convert-nx-executor.js +2 -2
  6. package/dist/src/hasher/create-task-hasher.js +1 -1
  7. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  8. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  9. package/dist/src/project-graph/build-project-graph.d.ts +2 -4
  10. package/dist/src/project-graph/build-project-graph.js +2 -7
  11. package/dist/src/project-graph/file-map-utils.d.ts +2 -4
  12. package/dist/src/project-graph/file-map-utils.js +0 -3
  13. package/dist/src/project-graph/plugins/get-plugins.d.ts +15 -0
  14. package/dist/src/project-graph/plugins/get-plugins.js +21 -3
  15. package/dist/src/project-graph/project-graph.js +7 -6
  16. package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.d.ts +40 -64
  17. package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.js +182 -411
  18. package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.d.ts +10 -4
  19. package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.js +22 -8
  20. package/dist/src/project-graph/utils/project-configuration/source-maps.d.ts +4 -61
  21. package/dist/src/project-graph/utils/project-configuration/source-maps.js +14 -59
  22. package/dist/src/project-graph/utils/project-configuration/target-defaults.d.ts +16 -0
  23. package/dist/src/project-graph/utils/project-configuration/target-defaults.js +117 -0
  24. package/dist/src/project-graph/utils/project-configuration/target-merging.d.ts +1 -4
  25. package/dist/src/project-graph/utils/project-configuration/target-merging.js +261 -136
  26. package/dist/src/project-graph/utils/project-configuration/target-normalization.js +0 -7
  27. package/dist/src/project-graph/utils/project-configuration/utils.d.ts +23 -0
  28. package/dist/src/project-graph/utils/project-configuration/utils.js +164 -0
  29. package/dist/src/project-graph/utils/project-configuration-utils.d.ts +33 -9
  30. package/dist/src/project-graph/utils/project-configuration-utils.js +153 -65
  31. package/dist/src/project-graph/utils/retrieve-workspace-files.d.ts +6 -3
  32. package/dist/src/project-graph/utils/retrieve-workspace-files.js +32 -13
  33. package/package.json +11 -11
@@ -260,4 +260,14 @@ export interface TargetConfiguration<T = any> {
260
260
  * is up to date.
261
261
  */
262
262
  syncGenerators?: string[];
263
+ /**
264
+ * Spread token used when merging target configurations. When set to `true`,
265
+ * base (inferred) values take priority over this target's values for any
266
+ * shared keys — effectively "only add new keys without overwriting inferred
267
+ * values". Keys that do not exist in the base target are still added.
268
+ *
269
+ * The position of `'...'` in the object's key order follows standard
270
+ * last-write-wins semantics with {@link https://nx.dev/reference/project-configuration#spread-token}.
271
+ */
272
+ '...'?: true;
263
273
  }
@@ -11,7 +11,7 @@ const configuration_1 = require("../../config/configuration");
11
11
  let storedProjectGraph = null;
12
12
  let storedHasher = null;
13
13
  async function handleHashTasks(payload) {
14
- const { error, projectGraph, allWorkspaceFiles, fileMap, rustReferences } = await (0, project_graph_incremental_recomputation_1.getCachedSerializedProjectGraphPromise)();
14
+ const { error, projectGraph, rustReferences } = await (0, project_graph_incremental_recomputation_1.getCachedSerializedProjectGraphPromise)();
15
15
  if (error) {
16
16
  throw error;
17
17
  }
@@ -1,5 +1,5 @@
1
1
  import { Socket } from 'net';
2
- import { FileData, FileMap, ProjectGraph } from '../../config/project-graph';
2
+ import { FileMap, ProjectGraph } from '../../config/project-graph';
3
3
  import { NxWorkspaceFilesExternals } from '../../native';
4
4
  import { FileMapCache } from '../../project-graph/nx-deps-cache';
5
5
  import { ConfigurationSourceMaps } from '../../project-graph/utils/project-configuration/source-maps';
@@ -7,8 +7,6 @@ interface SerializedProjectGraph {
7
7
  error: Error | null;
8
8
  projectGraph: ProjectGraph | null;
9
9
  projectFileMapCache: FileMapCache | null;
10
- fileMap: FileMap | null;
11
- allWorkspaceFiles: FileData[] | null;
12
10
  serializedProjectGraph: string | null;
13
11
  serializedSourceMaps: string | null;
14
12
  sourceMaps: ConfigurationSourceMaps | null;
@@ -16,7 +14,6 @@ interface SerializedProjectGraph {
16
14
  }
17
15
  export declare let fileMapWithFiles: {
18
16
  fileMap: FileMap;
19
- allWorkspaceFiles: FileData[];
20
17
  rustReferences: NxWorkspaceFilesExternals;
21
18
  } | undefined;
22
19
  export declare let currentProjectFileMapCache: FileMapCache | undefined;
@@ -54,12 +54,12 @@ async function getCachedSerializedProjectGraphPromise(socket) {
54
54
  // reset the wait time
55
55
  waitPeriod = 100;
56
56
  await resetInternalStateIfNxDepsMissing();
57
- const plugins = await (0, get_plugins_1.getPlugins)();
57
+ const separatedPlugins = await (0, get_plugins_1.getPluginsSeparated)();
58
58
  const previousPromise = cachedSerializedProjectGraphPromise;
59
59
  if (collectedUpdatedFiles.size == 0 && collectedDeletedFiles.size == 0) {
60
60
  if (!cachedSerializedProjectGraphPromise) {
61
61
  cachedSerializedProjectGraphPromise =
62
- processFilesAndCreateAndSerializeProjectGraph(plugins);
62
+ processFilesAndCreateAndSerializeProjectGraph(separatedPlugins);
63
63
  logger_1.serverLogger.log('No files changed, but no in-memory cached project graph found. Recomputing it...');
64
64
  }
65
65
  else {
@@ -69,7 +69,7 @@ async function getCachedSerializedProjectGraphPromise(socket) {
69
69
  else {
70
70
  logger_1.serverLogger.log(`Recomputing project graph because of ${collectedUpdatedFiles.size} updated and ${collectedDeletedFiles.size} deleted files.`);
71
71
  cachedSerializedProjectGraphPromise =
72
- processFilesAndCreateAndSerializeProjectGraph(plugins);
72
+ processFilesAndCreateAndSerializeProjectGraph(separatedPlugins);
73
73
  }
74
74
  const graphWasRecomputed = cachedSerializedProjectGraphPromise !== previousPromise;
75
75
  const result = await cachedSerializedProjectGraphPromise;
@@ -113,8 +113,6 @@ async function getCachedSerializedProjectGraphPromise(socket) {
113
113
  sourceMaps: null,
114
114
  projectGraph: null,
115
115
  projectFileMapCache: null,
116
- fileMap: null,
117
- allWorkspaceFiles: null,
118
116
  rustReferences: null,
119
117
  };
120
118
  }
@@ -153,7 +151,7 @@ function addUpdatedAndDeletedFiles(createdFiles, updatedFiles, deletedFiles) {
153
151
  waitPeriod = waitPeriod * 2;
154
152
  }
155
153
  cachedSerializedProjectGraphPromise =
156
- processFilesAndCreateAndSerializeProjectGraph(await (0, get_plugins_1.getPlugins)());
154
+ processFilesAndCreateAndSerializeProjectGraph(await (0, get_plugins_1.getPluginsSeparated)());
157
155
  const { projectGraph, sourceMaps, error } = await cachedSerializedProjectGraphPromise;
158
156
  if (createdFiles.length > 0) {
159
157
  (0, file_watcher_sockets_1.notifyFileWatcherSockets)(createdFiles, null, null);
@@ -210,7 +208,11 @@ function invalidateGraphCache() {
210
208
  // at its own Promise), takes the "reuse" branch, and awaits itself forever.
211
209
  cachedSerializedProjectGraphPromise = null;
212
210
  }
213
- async function processFilesAndCreateAndSerializeProjectGraph(plugins) {
211
+ async function processFilesAndCreateAndSerializeProjectGraph(separatedPlugins) {
212
+ const plugins = [
213
+ ...separatedPlugins.specifiedPlugins,
214
+ ...separatedPlugins.defaultPlugins,
215
+ ];
214
216
  const myGeneration = ++recomputationGeneration;
215
217
  // Helper to check if this recomputation is stale (a newer one has started)
216
218
  const isStale = () => myGeneration !== recomputationGeneration;
@@ -231,7 +233,7 @@ async function processFilesAndCreateAndSerializeProjectGraph(plugins) {
231
233
  let projectConfigurationsResult;
232
234
  let projectConfigurationsError;
233
235
  try {
234
- projectConfigurationsResult = await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(plugins, workspace_root_1.workspaceRoot, nxJson);
236
+ projectConfigurationsResult = await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(separatedPlugins, workspace_root_1.workspaceRoot, nxJson);
235
237
  }
236
238
  catch (e) {
237
239
  if (e instanceof error_types_1.ProjectConfigurationsError) {
@@ -277,9 +279,7 @@ async function processFilesAndCreateAndSerializeProjectGraph(plugins) {
277
279
  error: g.error,
278
280
  projectGraph: null,
279
281
  projectFileMapCache: null,
280
- fileMap: null,
281
282
  rustReferences: null,
282
- allWorkspaceFiles: null,
283
283
  serializedProjectGraph: null,
284
284
  serializedSourceMaps: null,
285
285
  sourceMaps: null,
@@ -291,9 +291,7 @@ async function processFilesAndCreateAndSerializeProjectGraph(plugins) {
291
291
  error: new error_types_1.DaemonProjectGraphError(errors, g.projectGraph, projectConfigurationsResult.sourceMaps),
292
292
  projectGraph: null,
293
293
  projectFileMapCache: null,
294
- fileMap: null,
295
294
  rustReferences: null,
296
- allWorkspaceFiles: null,
297
295
  serializedProjectGraph: null,
298
296
  serializedSourceMaps: null,
299
297
  sourceMaps: null,
@@ -308,9 +306,7 @@ async function processFilesAndCreateAndSerializeProjectGraph(plugins) {
308
306
  error: err,
309
307
  projectGraph: null,
310
308
  projectFileMapCache: null,
311
- fileMap: null,
312
309
  rustReferences: null,
313
- allWorkspaceFiles: null,
314
310
  serializedProjectGraph: null,
315
311
  serializedSourceMaps: null,
316
312
  sourceMaps: null,
@@ -334,9 +330,8 @@ async function createAndSerializeProjectGraph({ projects, sourceMaps, }) {
334
330
  try {
335
331
  perf_hooks_1.performance.mark('create-project-graph-start');
336
332
  const fileMap = copyFileMap(exports.fileMapWithFiles.fileMap);
337
- const allWorkspaceFiles = copyFileData(exports.fileMapWithFiles.allWorkspaceFiles);
338
333
  const rustReferences = exports.fileMapWithFiles.rustReferences;
339
- const { projectGraph, projectFileMapCache } = await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, knownExternalNodes, fileMap, allWorkspaceFiles, rustReferences, exports.currentProjectFileMapCache || (0, nx_deps_cache_1.readFileMapCache)(), await (0, get_plugins_1.getPlugins)(), sourceMaps);
334
+ const { projectGraph, projectFileMapCache } = await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, knownExternalNodes, fileMap, rustReferences, exports.currentProjectFileMapCache || (0, nx_deps_cache_1.readFileMapCache)(), await (0, get_plugins_1.getPlugins)(), sourceMaps);
340
335
  exports.currentProjectFileMapCache = projectFileMapCache;
341
336
  exports.currentProjectGraph = projectGraph;
342
337
  exports.currentSourceMaps = sourceMaps;
@@ -351,8 +346,6 @@ async function createAndSerializeProjectGraph({ projects, sourceMaps, }) {
351
346
  error: null,
352
347
  projectGraph,
353
348
  projectFileMapCache,
354
- fileMap,
355
- allWorkspaceFiles,
356
349
  serializedProjectGraph,
357
350
  serializedSourceMaps,
358
351
  sourceMaps,
@@ -365,8 +358,6 @@ async function createAndSerializeProjectGraph({ projects, sourceMaps, }) {
365
358
  error: e,
366
359
  projectGraph: null,
367
360
  projectFileMapCache: null,
368
- fileMap: null,
369
- allWorkspaceFiles: null,
370
361
  serializedProjectGraph: null,
371
362
  serializedSourceMaps: null,
372
363
  sourceMaps: null,
@@ -17,10 +17,10 @@ function convertNxExecutor(executor) {
17
17
  const builderFunction = (options, builderContext) => {
18
18
  const promise = async () => {
19
19
  const nxJsonConfiguration = (0, nx_json_1.readNxJson)(builderContext.workspaceRoot);
20
- const plugins = await (0, get_plugins_1.getPlugins)();
20
+ const separatedPlugins = await (0, get_plugins_1.getPluginsSeparated)();
21
21
  const projectsConfigurations = {
22
22
  version: 2,
23
- projects: (0, project_nodes_manager_1.readProjectConfigurationsFromRootMap)((await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(plugins, builderContext.workspaceRoot, nxJsonConfiguration)).projects),
23
+ projects: (0, project_nodes_manager_1.readProjectConfigurationsFromRootMap)((await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(separatedPlugins, builderContext.workspaceRoot, nxJsonConfiguration)).projects),
24
24
  };
25
25
  const context = {
26
26
  root: builderContext.workspaceRoot,
@@ -9,7 +9,7 @@ function createTaskHasher(projectGraph, nxJson, runnerOptions) {
9
9
  return new task_hasher_1.DaemonBasedTaskHasher(client_1.daemonClient, runnerOptions);
10
10
  }
11
11
  else {
12
- const { fileMap, allWorkspaceFiles, rustReferences } = (0, build_project_graph_1.getFileMap)();
12
+ const { rustReferences } = (0, build_project_graph_1.getFileMap)();
13
13
  return new task_hasher_1.InProcessTaskHasher(projectGraph, nxJson, rustReferences, runnerOptions);
14
14
  }
15
15
  }
Binary file
@@ -2,18 +2,16 @@ import { FileMap, ProjectGraph, ProjectGraphExternalNode } from '../config/proje
2
2
  import { ProjectConfiguration } from '../config/workspace-json-project-json';
3
3
  import { NxWorkspaceFilesExternals } from '../native';
4
4
  import { CreateMetadataError } from './error-types';
5
- import { FileData } from './file-utils';
6
5
  import { FileMapCache } from './nx-deps-cache';
7
6
  import { CreateMetadataContext } from './plugins';
8
7
  import type { LoadedNxPlugin } from './plugins/loaded-nx-plugin';
9
8
  import type { ConfigurationSourceMaps } from './utils/project-configuration/source-maps';
10
9
  export declare function getFileMap(): {
11
10
  fileMap: FileMap;
12
- allWorkspaceFiles: FileData[];
13
11
  rustReferences: NxWorkspaceFilesExternals | null;
14
12
  };
15
- export declare function hydrateFileMap(fileMap: FileMap, allWorkspaceFiles: FileData[], rustReferences: NxWorkspaceFilesExternals): void;
16
- export declare function buildProjectGraphUsingProjectFileMap(projectRootMap: Record<string, ProjectConfiguration>, externalNodes: Record<string, ProjectGraphExternalNode>, fileMap: FileMap, allWorkspaceFiles: FileData[], rustReferences: NxWorkspaceFilesExternals, fileMapCache: FileMapCache | null, plugins: LoadedNxPlugin[], sourceMap: ConfigurationSourceMaps): Promise<{
13
+ export declare function hydrateFileMap(fileMap: FileMap, rustReferences: NxWorkspaceFilesExternals): void;
14
+ export declare function buildProjectGraphUsingProjectFileMap(projectRootMap: Record<string, ProjectConfiguration>, externalNodes: Record<string, ProjectGraphExternalNode>, fileMap: FileMap, rustReferences: NxWorkspaceFilesExternals, fileMapCache: FileMapCache | null, plugins: LoadedNxPlugin[], sourceMap: ConfigurationSourceMaps): Promise<{
17
15
  projectGraph: ProjectGraph;
18
16
  projectFileMapCache: FileMapCache;
19
17
  }>;
@@ -23,13 +23,11 @@ const implicit_project_dependencies_1 = require("./utils/implicit-project-depend
23
23
  const normalize_project_nodes_1 = require("./utils/normalize-project-nodes");
24
24
  const target_merging_1 = require("./utils/project-configuration/target-merging");
25
25
  let storedFileMap = null;
26
- let storedAllWorkspaceFiles = null;
27
26
  let storedRustReferences = null;
28
27
  function getFileMap() {
29
28
  if (!!storedFileMap) {
30
29
  return {
31
30
  fileMap: storedFileMap,
32
- allWorkspaceFiles: storedAllWorkspaceFiles,
33
31
  rustReferences: storedRustReferences,
34
32
  };
35
33
  }
@@ -39,19 +37,16 @@ function getFileMap() {
39
37
  nonProjectFiles: [],
40
38
  projectFileMap: {},
41
39
  },
42
- allWorkspaceFiles: [],
43
40
  rustReferences: null,
44
41
  };
45
42
  }
46
43
  }
47
- function hydrateFileMap(fileMap, allWorkspaceFiles, rustReferences) {
44
+ function hydrateFileMap(fileMap, rustReferences) {
48
45
  storedFileMap = fileMap;
49
- storedAllWorkspaceFiles = allWorkspaceFiles;
50
46
  storedRustReferences = rustReferences;
51
47
  }
52
- async function buildProjectGraphUsingProjectFileMap(projectRootMap, externalNodes, fileMap, allWorkspaceFiles, rustReferences, fileMapCache, plugins, sourceMap) {
48
+ async function buildProjectGraphUsingProjectFileMap(projectRootMap, externalNodes, fileMap, rustReferences, fileMapCache, plugins, sourceMap) {
53
49
  storedFileMap = fileMap;
54
- storedAllWorkspaceFiles = allWorkspaceFiles;
55
50
  storedRustReferences = rustReferences;
56
51
  const projects = {};
57
52
  for (const root in projectRootMap) {
@@ -1,8 +1,7 @@
1
- import { FileData, FileMap, ProjectFileMap, ProjectGraph } from '../config/project-graph';
2
- import { ProjectConfiguration, ProjectsConfigurations } from '../config/workspace-json-project-json';
1
+ import type { FileData, FileMap, ProjectFileMap, ProjectGraph } from '../config/project-graph';
2
+ import type { ProjectConfiguration, ProjectsConfigurations } from '../config/workspace-json-project-json';
3
3
  import { NxWorkspaceFilesExternals } from '../native';
4
4
  export interface WorkspaceFileMap {
5
- allWorkspaceFiles: FileData[];
6
5
  fileMap: FileMap;
7
6
  }
8
7
  export declare function createProjectFileMapUsingProjectGraph(graph: ProjectGraph): Promise<ProjectFileMap>;
@@ -10,6 +9,5 @@ export declare function createFileMapUsingProjectGraph(graph: ProjectGraph): Pro
10
9
  export declare function createFileMap(projectsConfigurations: ProjectsConfigurations, allWorkspaceFiles: FileData[]): WorkspaceFileMap;
11
10
  export declare function updateFileMap(projectsConfigurations: Record<string, ProjectConfiguration>, rustReferences: NxWorkspaceFilesExternals, updatedFiles: Record<string, string>, deletedFiles: string[]): {
12
11
  fileMap: import("../native").FileMap;
13
- allWorkspaceFiles: FileData[];
14
12
  rustReferences: NxWorkspaceFilesExternals;
15
13
  };
@@ -7,7 +7,6 @@ exports.updateFileMap = updateFileMap;
7
7
  const workspace_context_1 = require("../utils/workspace-context");
8
8
  const workspace_root_1 = require("../utils/workspace-root");
9
9
  const project_graph_1 = require("./project-graph");
10
- const build_all_workspace_files_1 = require("./utils/build-all-workspace-files");
11
10
  const find_project_for_path_1 = require("./utils/find-project-for-path");
12
11
  async function createProjectFileMapUsingProjectGraph(graph) {
13
12
  return (await createFileMapUsingProjectGraph(graph)).fileMap.projectFileMap;
@@ -38,7 +37,6 @@ function createFileMap(projectsConfigurations, allWorkspaceFiles) {
38
37
  }
39
38
  }
40
39
  return {
41
- allWorkspaceFiles,
42
40
  fileMap: {
43
41
  projectFileMap,
44
42
  nonProjectFiles,
@@ -49,7 +47,6 @@ function updateFileMap(projectsConfigurations, rustReferences, updatedFiles, del
49
47
  const updates = (0, workspace_context_1.updateProjectFiles)(Object.fromEntries((0, find_project_for_path_1.createProjectRootMappingsFromProjectConfigurations)(projectsConfigurations)), rustReferences, updatedFiles, deletedFiles);
50
48
  return {
51
49
  fileMap: updates.fileMap,
52
- allWorkspaceFiles: (0, build_all_workspace_files_1.buildAllWorkspaceFiles)(updates.fileMap.projectFileMap, updates.fileMap.nonProjectFiles),
53
50
  rustReferences: updates.externalReferences,
54
51
  };
55
52
  }
@@ -1,5 +1,20 @@
1
1
  import type { LoadedNxPlugin } from './loaded-nx-plugin';
2
+ export interface SeparatedPlugins {
3
+ specifiedPlugins: LoadedNxPlugin[];
4
+ defaultPlugins: LoadedNxPlugin[];
5
+ }
6
+ /**
7
+ * Returns all plugins (specified + default) as a flat list.
8
+ * Specified plugins come first, followed by default plugins.
9
+ */
2
10
  export declare function getPlugins(root?: string): Promise<LoadedNxPlugin[]>;
11
+ /**
12
+ * Returns specified plugins (from nx.json) and default plugins (project.json,
13
+ * package.json, etc.) as separate arrays. This separation is needed for
14
+ * two-phase project configuration processing where target defaults are
15
+ * applied between specified and default plugin results.
16
+ */
17
+ export declare function getPluginsSeparated(root?: string): Promise<SeparatedPlugins>;
3
18
  export declare function getOnlyDefaultPlugins(root?: string): Promise<LoadedNxPlugin[]>;
4
19
  export declare function cleanupPlugins(): void;
5
20
  export declare function reasonToError(reason: unknown): Error;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPlugins = getPlugins;
4
+ exports.getPluginsSeparated = getPluginsSeparated;
4
5
  exports.getOnlyDefaultPlugins = getOnlyDefaultPlugins;
5
6
  exports.cleanupPlugins = cleanupPlugins;
6
7
  exports.reasonToError = reasonToError;
@@ -18,18 +19,33 @@ const transpiler_1 = require("./transpiler");
18
19
  */
19
20
  let currentPluginsConfigurationHash;
20
21
  let loadedPlugins;
22
+ let cachedSeparatedPlugins;
21
23
  let pendingPluginsPromise;
22
24
  let cleanupSpecifiedPlugins;
23
25
  const loadingMethod = (plugin, root, index) => (0, enabled_1.isIsolationEnabled)()
24
26
  ? (0, isolation_1.loadIsolatedNxPlugin)(plugin, root, index)
25
27
  : (0, in_process_loader_1.loadNxPlugin)(plugin, root, index);
28
+ /**
29
+ * Returns all plugins (specified + default) as a flat list.
30
+ * Specified plugins come first, followed by default plugins.
31
+ */
26
32
  async function getPlugins(root = workspace_root_1.workspaceRoot) {
33
+ const { specifiedPlugins, defaultPlugins } = await getPluginsSeparated(root);
34
+ return specifiedPlugins.concat(defaultPlugins);
35
+ }
36
+ /**
37
+ * Returns specified plugins (from nx.json) and default plugins (project.json,
38
+ * package.json, etc.) as separate arrays. This separation is needed for
39
+ * two-phase project configuration processing where target defaults are
40
+ * applied between specified and default plugin results.
41
+ */
42
+ async function getPluginsSeparated(root = workspace_root_1.workspaceRoot) {
27
43
  const pluginsConfiguration = (0, nx_json_1.readNxJson)(root).plugins ?? [];
28
44
  const pluginsConfigurationHash = (0, file_hasher_1.hashObject)(pluginsConfiguration);
29
45
  // If the plugins configuration has not changed, reuse the current plugins
30
- if (loadedPlugins &&
46
+ if (cachedSeparatedPlugins &&
31
47
  pluginsConfigurationHash === currentPluginsConfigurationHash) {
32
- return loadedPlugins;
48
+ return cachedSeparatedPlugins;
33
49
  }
34
50
  currentPluginsConfigurationHash = pluginsConfigurationHash;
35
51
  const results = await Promise.allSettled([
@@ -51,8 +67,9 @@ async function getPlugins(root = workspace_root_1.workspaceRoot) {
51
67
  if (errors.length > 0) {
52
68
  throw new AggregateError(errors, errors.map((e) => e.message).join('\n'));
53
69
  }
70
+ cachedSeparatedPlugins = { specifiedPlugins, defaultPlugins };
54
71
  loadedPlugins = specifiedPlugins.concat(defaultPlugins);
55
- return loadedPlugins;
72
+ return cachedSeparatedPlugins;
56
73
  }
57
74
  /**
58
75
  * Stuff for default NX Plugins.
@@ -87,6 +104,7 @@ function cleanupPlugins() {
87
104
  cleanupDefaultPlugins?.();
88
105
  pendingPluginsPromise = undefined;
89
106
  pendingDefaultPluginPromise = undefined;
107
+ cachedSeparatedPlugins = undefined;
90
108
  }
91
109
  /**
92
110
  * Stuff for generic loading
@@ -88,9 +88,10 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
88
88
  perf_hooks_1.performance.mark('retrieve-project-configurations:start');
89
89
  let configurationResult;
90
90
  let projectConfigurationsError;
91
- const plugins = await (0, get_plugins_1.getPlugins)();
91
+ const separatedPlugins = await (0, get_plugins_1.getPluginsSeparated)();
92
+ const plugins = separatedPlugins.specifiedPlugins.concat(separatedPlugins.defaultPlugins);
92
93
  try {
93
- configurationResult = await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(plugins, workspace_root_1.workspaceRoot, nxJson);
94
+ configurationResult = await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(separatedPlugins, workspace_root_1.workspaceRoot, nxJson);
94
95
  }
95
96
  catch (e) {
96
97
  if (e instanceof error_types_1.ProjectConfigurationsError) {
@@ -104,14 +105,14 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
104
105
  const { projects, externalNodes, sourceMaps, projectRootMap } = configurationResult;
105
106
  perf_hooks_1.performance.mark('retrieve-project-configurations:end');
106
107
  perf_hooks_1.performance.mark('retrieve-workspace-files:start');
107
- const { allWorkspaceFiles, fileMap, rustReferences } = await (0, retrieve_workspace_files_1.retrieveWorkspaceFiles)(workspace_root_1.workspaceRoot, projectRootMap);
108
+ const { fileMap, rustReferences } = await (0, retrieve_workspace_files_1.retrieveWorkspaceFiles)(workspace_root_1.workspaceRoot, projectRootMap);
108
109
  perf_hooks_1.performance.mark('retrieve-workspace-files:end');
109
110
  const cacheEnabled = process.env.NX_CACHE_PROJECT_GRAPH !== 'false';
110
111
  perf_hooks_1.performance.mark('build-project-graph-using-project-file-map:start');
111
112
  let projectGraphError;
112
113
  let projectGraphResult;
113
114
  try {
114
- projectGraphResult = await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, externalNodes, fileMap, allWorkspaceFiles, rustReferences, cacheEnabled ? (0, nx_deps_cache_1.readFileMapCache)() : null, plugins, sourceMaps);
115
+ projectGraphResult = await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, externalNodes, fileMap, rustReferences, cacheEnabled ? (0, nx_deps_cache_1.readFileMapCache)() : null, plugins, sourceMaps);
115
116
  }
116
117
  catch (e) {
117
118
  if ((0, error_types_1.isAggregateProjectGraphError)(e)) {
@@ -180,8 +181,8 @@ async function readCachedGraphAndHydrateFileMap(minimumComputedAt) {
180
181
  data.root,
181
182
  project,
182
183
  ]));
183
- const { allWorkspaceFiles, fileMap, rustReferences } = await (0, retrieve_workspace_files_1.retrieveWorkspaceFiles)(workspace_root_1.workspaceRoot, projectRootMap);
184
- (0, build_project_graph_1.hydrateFileMap)(fileMap, allWorkspaceFiles, rustReferences);
184
+ const { fileMap, rustReferences } = await (0, retrieve_workspace_files_1.retrieveWorkspaceFiles)(workspace_root_1.workspaceRoot, projectRootMap);
185
+ (0, build_project_graph_1.hydrateFileMap)(fileMap, rustReferences);
185
186
  return graph;
186
187
  }
187
188
  /**
@@ -1,74 +1,50 @@
1
1
  import { ProjectConfiguration } from '../../../config/workspace-json-project-json';
2
2
  /**
3
- * Manages deferred project name substitutions across the plugin result
4
- * merge phase of project graph construction.
5
- *
6
- * ### Why this exists
7
- *
8
- * When plugins return `createNodes` results, a node `A` may declare a
9
- * `dependsOn` or `inputs` entry that references another project `B` by
10
- * name. A *later* plugin is allowed to rename project `B` to `C`. After
11
- * all plugin results are merged into the root map, node `A` would still
12
- * hold a stale reference to the now-nonexistent name `B`.
3
+ * Sentinel placed in `inputs` / `dependsOn` for a pending project-name
4
+ * reference. `RootRef` carries the referenced project's root (resolved
5
+ * via nameMap lookup); `UsageRef` carries the raw written name (for
6
+ * forward refs, promoted to `RootRef` in place when the name is
7
+ * identified). `parent` + `key` let the final pass write the resolved
8
+ * name back; `targetPart` preserves the `:target` suffix from
9
+ * `dependsOn` strings.
10
+ */
11
+ export declare abstract class NameRef {
12
+ value: string;
13
+ parent: unknown;
14
+ key: string | undefined;
15
+ targetPart: string | undefined;
16
+ constructor(value: string, parent: unknown, key: string | undefined, targetPart: string | undefined);
17
+ }
18
+ export declare class RootRef extends NameRef {
19
+ }
20
+ export declare class UsageRef extends NameRef {
21
+ }
22
+ export declare function isNameRef(value: unknown): value is NameRef;
23
+ export declare function isRootRef(value: unknown): value is RootRef;
24
+ export declare function isUsageRef(value: unknown): value is UsageRef;
25
+ /**
26
+ * Replaces project-name refs in plugin results with in-place sentinels,
27
+ * then resolves them after all merging is done.
13
28
  *
14
- * This class solves that by:
15
- * 1. Receiving a live nameMap accessor (maintained by ProjectNodesManager)
16
- * for name root resolution and colon-delimited string parsing.
17
- * 2. Tracking dirty roots via {@link identifyProjectWithRoot} when a
18
- * project name changes at a root.
19
- * 3. Scanning each plugin's results for project-name references in
20
- * `inputs` and `dependsOn` ({@link registerSubstitutorsForNodeResults}).
21
- * 4. After all results are merged, applying the substitutors for every
22
- * renamed project so that references are updated to the final name
23
- * ({@link applySubstitutions}).
29
+ * Tracking by array position breaks once `'...'` spreads shuffle indices,
30
+ * so each ref becomes a sentinel object. Arrays spread-merge by pushing
31
+ * element references, so sentinel identity survives any downstream
32
+ * merges the final pass walks a flat registry and writes the resolved
33
+ * name back through each sentinel's `parent` back-reference. Orphaned
34
+ * sentinels (from arrays dropped by a full-replace) write harmlessly.
24
35
  */
25
36
  export declare class ProjectNameInNodePropsManager {
26
- private substitutorsByReferencedRoot;
27
- private substitutorsByArrayKey;
28
- private pendingSubstitutorsByName;
29
- private dirtyRoots;
30
37
  private getNameMap;
38
+ private allRefs;
39
+ private pendingByName;
31
40
  constructor(getNameMap?: () => Record<string, ProjectConfiguration>);
32
- private removeSubstitutorEntry;
33
- private clearSubstitutorAtIndex;
34
- private clearSubstitutorsFromIndex;
35
- private clearSubstitutorsFromSubIndex;
36
- private forEachTargetConfig;
37
- private registerProjectNameSubstitutor;
38
- /**
39
- * Scans `pluginResultProjects` for `inputs` and `dependsOn` entries that
40
- * reference another project by name, and registers substitutors so those
41
- * references are updated if the target project is later renamed.
42
- *
43
- * **Important**: call {@link identifyProjectWithRoot} for all projects in
44
- * this result (and all prior results) before calling this method, so that
45
- * referenced project names can be resolved to roots.
46
- *
47
- * @param pluginResultProjects Projects from a single plugin's createNodes call.
48
- */
49
- registerSubstitutorsForNodeResults(pluginResultProjects?: Record<string, Omit<ProjectConfiguration, 'root'> & Partial<ProjectConfiguration>>): void;
50
- private createInputsStringSubstitutor;
51
- private createInputsArraySubstitutor;
52
- private createDependsOnStringSubstitutor;
53
- private createDependsOnArraySubstitutor;
54
- private createDependsOnTargetStringSubstitutor;
55
- private registerSubstitutorsForInputs;
56
- private registerSubstitutorsForDependsOn;
57
- /**
58
- * Records that a project with `name` exists at the given `root`. Call
59
- * this during the merge phase whenever a project's name changes at a
60
- * root — **before** calling
61
- * {@link registerSubstitutorsForNodeResults} for that result.
62
- *
63
- * The nameMap (maintained externally by ProjectNodesManager) is always
64
- * current — this method only needs to mark the root as dirty and
65
- * promote any pending substitutors keyed by name.
66
- */
41
+ registerNameRefs(pluginResultProjects?: Record<string, Omit<ProjectConfiguration, 'root'> & Partial<ProjectConfiguration>>): void;
42
+ private processInputs;
43
+ private processDependsOn;
44
+ private processProjectsArray;
45
+ private createRef;
67
46
  identifyProjectWithRoot(root: string, name: string): void;
68
- /**
69
- * Executes all registered substitutors for renamed projects, updating
70
- * stale project name references in the final merged `rootMap`. Should be
71
- * called once after all plugin results have been merged.
72
- */
73
47
  applySubstitutions(rootMap: Record<string, ProjectConfiguration>): void;
48
+ private resolveFinalName;
49
+ private writeReplacement;
74
50
  }