nx 22.6.0 → 22.6.2

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 (201) hide show
  1. package/bin/nx.js +19 -11
  2. package/package.json +11 -12
  3. package/release/changelog-renderer/index.d.ts +2 -1
  4. package/release/changelog-renderer/index.d.ts.map +1 -1
  5. package/schemas/nx-schema.json +102 -0
  6. package/src/adapter/ngcli-adapter.d.ts +8 -5
  7. package/src/adapter/ngcli-adapter.d.ts.map +1 -1
  8. package/src/adapter/ngcli-adapter.js +33 -19
  9. package/src/ai/clone-ai-config-repo.d.ts.map +1 -1
  10. package/src/ai/clone-ai-config-repo.js +2 -0
  11. package/src/command-line/add/add.js +1 -1
  12. package/src/command-line/examples.d.ts +7 -0
  13. package/src/command-line/examples.d.ts.map +1 -1
  14. package/src/command-line/examples.js +29 -1
  15. package/src/command-line/exec/exec.js +3 -3
  16. package/src/command-line/format/format.js +3 -3
  17. package/src/command-line/generate/generate.d.ts.map +1 -1
  18. package/src/command-line/generate/generate.js +1 -1
  19. package/src/command-line/graph/graph.js +1 -1
  20. package/src/command-line/init/command-object.js +1 -21
  21. package/src/command-line/init/configure-plugins.js +1 -1
  22. package/src/command-line/init/implementation/angular/integrated-workspace.js +1 -1
  23. package/src/command-line/init/implementation/angular/legacy-angular-versions.js +2 -2
  24. package/src/command-line/init/implementation/deduce-default-base.js +5 -5
  25. package/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +2 -2
  26. package/src/command-line/init/implementation/dot-nx/nxw.js +1 -1
  27. package/src/command-line/init/implementation/utils.d.ts +1 -2
  28. package/src/command-line/init/implementation/utils.d.ts.map +1 -1
  29. package/src/command-line/init/implementation/utils.js +1 -15
  30. package/src/command-line/init/init-v1.d.ts +0 -3
  31. package/src/command-line/init/init-v1.d.ts.map +1 -1
  32. package/src/command-line/init/init-v1.js +1 -27
  33. package/src/command-line/init/init-v2.d.ts +0 -1
  34. package/src/command-line/init/init-v2.d.ts.map +1 -1
  35. package/src/command-line/init/init-v2.js +7 -35
  36. package/src/command-line/mcp/mcp.d.ts.map +1 -1
  37. package/src/command-line/mcp/mcp.js +2 -0
  38. package/src/command-line/migrate/migrate-ui-api.d.ts.map +1 -1
  39. package/src/command-line/migrate/migrate-ui-api.js +13 -0
  40. package/src/command-line/migrate/migrate.d.ts.map +1 -1
  41. package/src/command-line/migrate/migrate.js +41 -23
  42. package/src/command-line/migrate/run-migration-process.js +2 -0
  43. package/src/command-line/nx-cloud/connect/view-logs.js +1 -1
  44. package/src/command-line/nx-commands.js +65 -65
  45. package/src/command-line/release/config/version-plans.js +1 -1
  46. package/src/command-line/release/utils/exec-command.js +1 -1
  47. package/src/command-line/release/utils/launch-editor.js +2 -2
  48. package/src/command-line/release/utils/remote-release-clients/github.d.ts +1 -0
  49. package/src/command-line/release/utils/remote-release-clients/github.d.ts.map +1 -1
  50. package/src/command-line/release/utils/remote-release-clients/github.js +39 -2
  51. package/src/command-line/release/utils/remote-release-clients/gitlab.d.ts.map +1 -1
  52. package/src/command-line/release/utils/remote-release-clients/gitlab.js +1 -0
  53. package/src/command-line/release/version/release-group-processor.d.ts.map +1 -1
  54. package/src/command-line/release/version/release-group-processor.js +2 -4
  55. package/src/command-line/release/version.js +1 -1
  56. package/src/command-line/run/run-one.d.ts.map +1 -1
  57. package/src/command-line/run/run-one.js +1 -1
  58. package/src/command-line/run/run.d.ts.map +1 -1
  59. package/src/command-line/run/run.js +2 -2
  60. package/src/command-line/show/target.js +5 -2
  61. package/src/command-line/watch/watch.js +1 -1
  62. package/src/core/graph/main.js +1 -1
  63. package/src/daemon/client/client.d.ts +2 -2
  64. package/src/daemon/client/client.d.ts.map +1 -1
  65. package/src/daemon/client/client.js +3 -2
  66. package/src/daemon/client/generate-help-output.js +1 -1
  67. package/src/daemon/server/handle-configure-ai-agents.js +11 -4
  68. package/src/daemon/server/handle-hash-tasks.d.ts +1 -0
  69. package/src/daemon/server/handle-hash-tasks.d.ts.map +1 -1
  70. package/src/daemon/server/handle-hash-tasks.js +1 -1
  71. package/src/daemon/server/project-graph-incremental-recomputation.d.ts +1 -1
  72. package/src/daemon/server/project-graph-incremental-recomputation.d.ts.map +1 -1
  73. package/src/daemon/server/project-graph-listener-sockets.d.ts +1 -1
  74. package/src/daemon/server/project-graph-listener-sockets.d.ts.map +1 -1
  75. package/src/daemon/server/shutdown-utils.js +1 -1
  76. package/src/devkit-internals.d.ts +3 -2
  77. package/src/devkit-internals.d.ts.map +1 -1
  78. package/src/devkit-internals.js +5 -4
  79. package/src/executors/run-commands/run-commands.impl.d.ts.map +1 -1
  80. package/src/executors/run-commands/run-commands.impl.js +60 -7
  81. package/src/executors/run-commands/running-tasks.d.ts.map +1 -1
  82. package/src/executors/run-commands/running-tasks.js +1 -5
  83. package/src/executors/run-script/run-script.impl.js +1 -1
  84. package/src/executors/utils/convert-nx-executor.js +2 -2
  85. package/src/generators/utils/project-configuration.js +4 -4
  86. package/src/hasher/hash-plan-inspector.d.ts.map +1 -1
  87. package/src/hasher/hash-plan-inspector.js +1 -1
  88. package/src/hasher/native-task-hasher-impl.d.ts +2 -2
  89. package/src/hasher/native-task-hasher-impl.d.ts.map +1 -1
  90. package/src/hasher/native-task-hasher-impl.js +6 -6
  91. package/src/hasher/task-hasher.d.ts +4 -4
  92. package/src/hasher/task-hasher.d.ts.map +1 -1
  93. package/src/hasher/task-hasher.js +9 -6
  94. package/src/native/index.d.ts +1 -1
  95. package/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  96. package/src/native/nx.wasm32-wasi.wasm +0 -0
  97. package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +1 -1
  98. package/src/plugins/js/lock-file/bun-parser.js +1 -1
  99. package/src/plugins/js/lock-file/lock-file.d.ts.map +1 -1
  100. package/src/plugins/js/lock-file/lock-file.js +3 -1
  101. package/src/project-graph/build-project-graph.d.ts +1 -1
  102. package/src/project-graph/build-project-graph.d.ts.map +1 -1
  103. package/src/project-graph/build-project-graph.js +2 -2
  104. package/src/project-graph/error-types.d.ts +2 -1
  105. package/src/project-graph/error-types.d.ts.map +1 -1
  106. package/src/project-graph/file-utils.d.ts.map +1 -1
  107. package/src/project-graph/file-utils.js +4 -2
  108. package/src/project-graph/nx-deps-cache.d.ts +1 -1
  109. package/src/project-graph/nx-deps-cache.d.ts.map +1 -1
  110. package/src/project-graph/plugins/isolation/isolated-plugin.js +5 -5
  111. package/src/project-graph/project-graph.d.ts +2 -2
  112. package/src/project-graph/utils/project-configuration/name-substitution-manager.d.ts +23 -18
  113. package/src/project-graph/utils/project-configuration/name-substitution-manager.d.ts.map +1 -1
  114. package/src/project-graph/utils/project-configuration/name-substitution-manager.js +129 -87
  115. package/src/project-graph/utils/project-configuration/project-nodes-manager.d.ts +40 -0
  116. package/src/project-graph/utils/project-configuration/project-nodes-manager.d.ts.map +1 -0
  117. package/src/project-graph/utils/project-configuration/project-nodes-manager.js +264 -0
  118. package/src/project-graph/utils/project-configuration/target-merging.d.ts +32 -0
  119. package/src/project-graph/utils/project-configuration/target-merging.d.ts.map +1 -0
  120. package/src/project-graph/utils/project-configuration/target-merging.js +332 -0
  121. package/src/project-graph/utils/project-configuration/target-normalization.d.ts +13 -0
  122. package/src/project-graph/utils/project-configuration/target-normalization.d.ts.map +1 -0
  123. package/src/project-graph/utils/project-configuration/target-normalization.js +177 -0
  124. package/src/project-graph/utils/project-configuration-utils.d.ts +16 -41
  125. package/src/project-graph/utils/project-configuration-utils.d.ts.map +1 -1
  126. package/src/project-graph/utils/project-configuration-utils.js +56 -734
  127. package/src/tasks-runner/cache.js +1 -1
  128. package/src/tasks-runner/default-tasks-runner.js +1 -1
  129. package/src/tasks-runner/life-cycle.d.ts +4 -0
  130. package/src/tasks-runner/life-cycle.d.ts.map +1 -1
  131. package/src/tasks-runner/life-cycles/tui-summary-life-cycle.d.ts.map +1 -1
  132. package/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +4 -0
  133. package/src/tasks-runner/task-orchestrator.d.ts +12 -4
  134. package/src/tasks-runner/task-orchestrator.d.ts.map +1 -1
  135. package/src/tasks-runner/task-orchestrator.js +123 -68
  136. package/src/tasks-runner/tasks-schedule.d.ts +1 -1
  137. package/src/tasks-runner/tasks-schedule.d.ts.map +1 -1
  138. package/src/tasks-runner/tasks-schedule.js +14 -3
  139. package/src/tasks-runner/utils.d.ts +2 -2
  140. package/src/tasks-runner/utils.d.ts.map +1 -1
  141. package/src/tasks-runner/utils.js +5 -7
  142. package/src/utils/ab-testing.js +1 -1
  143. package/src/utils/analytics-prompt.d.ts.map +1 -1
  144. package/src/utils/analytics-prompt.js +2 -0
  145. package/src/utils/child-process.d.ts.map +1 -1
  146. package/src/utils/child-process.js +1 -2
  147. package/src/utils/command-line-utils.js +3 -3
  148. package/src/utils/default-base.js +1 -1
  149. package/src/utils/git-utils.d.ts.map +1 -1
  150. package/src/utils/git-utils.index-filter.js +2 -2
  151. package/src/utils/git-utils.js +6 -5
  152. package/src/utils/git-utils.tree-filter.js +1 -1
  153. package/src/utils/machine-id-cache.d.ts.map +1 -1
  154. package/src/utils/machine-id-cache.js +72 -2
  155. package/src/utils/package-json.js +2 -2
  156. package/src/utils/package-manager.d.ts.map +1 -1
  157. package/src/utils/package-manager.js +8 -13
  158. package/src/utils/provenance.d.ts.map +1 -1
  159. package/src/utils/provenance.js +2 -2
  160. package/src/utils/require-nx-key.js +1 -1
  161. package/src/utils/serialize-overrides-into-command-line.d.ts.map +1 -1
  162. package/src/utils/serialize-overrides-into-command-line.js +3 -4
  163. package/src/utils/shell-quoting.d.ts +11 -0
  164. package/src/utils/shell-quoting.d.ts.map +1 -0
  165. package/src/utils/shell-quoting.js +41 -0
  166. package/src/utils/split-target.d.ts +13 -2
  167. package/src/utils/split-target.d.ts.map +1 -1
  168. package/src/utils/split-target.js +180 -31
  169. package/src/command-line/init/implementation/react/add-craco-commands-to-package-scripts.d.ts +0 -2
  170. package/src/command-line/init/implementation/react/add-craco-commands-to-package-scripts.d.ts.map +0 -1
  171. package/src/command-line/init/implementation/react/add-craco-commands-to-package-scripts.js +0 -21
  172. package/src/command-line/init/implementation/react/add-vite-commands-to-package-scripts.d.ts +0 -2
  173. package/src/command-line/init/implementation/react/add-vite-commands-to-package-scripts.d.ts.map +0 -1
  174. package/src/command-line/init/implementation/react/add-vite-commands-to-package-scripts.js +0 -20
  175. package/src/command-line/init/implementation/react/check-for-custom-webpack-setup.d.ts +0 -2
  176. package/src/command-line/init/implementation/react/check-for-custom-webpack-setup.d.ts.map +0 -1
  177. package/src/command-line/init/implementation/react/check-for-custom-webpack-setup.js +0 -17
  178. package/src/command-line/init/implementation/react/check-for-uncommitted-changes.d.ts +0 -2
  179. package/src/command-line/init/implementation/react/check-for-uncommitted-changes.d.ts.map +0 -1
  180. package/src/command-line/init/implementation/react/check-for-uncommitted-changes.js +0 -20
  181. package/src/command-line/init/implementation/react/clean-up-files.d.ts +0 -2
  182. package/src/command-line/init/implementation/react/clean-up-files.d.ts.map +0 -1
  183. package/src/command-line/init/implementation/react/clean-up-files.js +0 -30
  184. package/src/command-line/init/implementation/react/index.d.ts +0 -5
  185. package/src/command-line/init/implementation/react/index.d.ts.map +0 -1
  186. package/src/command-line/init/implementation/react/index.js +0 -77
  187. package/src/command-line/init/implementation/react/read-name-from-package-json.d.ts +0 -2
  188. package/src/command-line/init/implementation/react/read-name-from-package-json.d.ts.map +0 -1
  189. package/src/command-line/init/implementation/react/read-name-from-package-json.js +0 -16
  190. package/src/command-line/init/implementation/react/rename-js-to-jsx.d.ts +0 -2
  191. package/src/command-line/init/implementation/react/rename-js-to-jsx.d.ts.map +0 -1
  192. package/src/command-line/init/implementation/react/rename-js-to-jsx.js +0 -22
  193. package/src/command-line/init/implementation/react/tsconfig-setup.d.ts +0 -2
  194. package/src/command-line/init/implementation/react/tsconfig-setup.d.ts.map +0 -1
  195. package/src/command-line/init/implementation/react/tsconfig-setup.js +0 -108
  196. package/src/command-line/init/implementation/react/write-vite-config.d.ts +0 -2
  197. package/src/command-line/init/implementation/react/write-vite-config.d.ts.map +0 -1
  198. package/src/command-line/init/implementation/react/write-vite-config.js +0 -53
  199. package/src/command-line/init/implementation/react/write-vite-index-html.d.ts +0 -2
  200. package/src/command-line/init/implementation/react/write-vite-index-html.d.ts.map +0 -1
  201. package/src/command-line/init/implementation/react/write-vite-index-html.js +0 -24
@@ -1,231 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mergeProjectConfigurationIntoRootMap = mergeProjectConfigurationIntoRootMap;
4
- exports.mergeMetadata = mergeMetadata;
3
+ exports.readTargetDefaultsForTarget = exports.mergeTargetConfigurations = void 0;
5
4
  exports.createProjectConfigurationsWithPlugins = createProjectConfigurationsWithPlugins;
5
+ exports.mergeCreateNodesResults = mergeCreateNodesResults;
6
6
  exports.findMatchingConfigFiles = findMatchingConfigFiles;
7
- exports.readProjectConfigurationsFromRootMap = readProjectConfigurationsFromRootMap;
8
- exports.validateProject = validateProject;
9
- exports.mergeTargetDefaultWithTargetDefinition = mergeTargetDefaultWithTargetDefinition;
10
- exports.mergeTargetConfigurations = mergeTargetConfigurations;
11
- exports.isCompatibleTarget = isCompatibleTarget;
12
- exports.resolveNxTokensInOptions = resolveNxTokensInOptions;
13
- exports.readTargetDefaultsForTarget = readTargetDefaultsForTarget;
14
- exports.normalizeTarget = normalizeTarget;
15
- const fileutils_1 = require("../../utils/fileutils");
16
- const logger_1 = require("../../utils/logger");
17
7
  const workspace_root_1 = require("../../utils/workspace-root");
18
- const name_substitution_manager_1 = require("./project-configuration/name-substitution-manager");
19
- const source_maps_1 = require("./project-configuration/source-maps");
8
+ const project_nodes_manager_1 = require("./project-configuration/project-nodes-manager");
9
+ const target_normalization_1 = require("./project-configuration/target-normalization");
20
10
  const minimatch_1 = require("minimatch");
21
- const node_fs_1 = require("node:fs");
22
- const path_1 = require("path");
23
11
  const perf_hooks_1 = require("perf_hooks");
24
- const executor_utils_1 = require("../../command-line/run/executor-utils");
25
- const to_project_name_1 = require("../../config/to-project-name");
26
12
  const delayed_spinner_1 = require("../../utils/delayed-spinner");
27
- const globs_1 = require("../../utils/globs");
28
13
  const error_types_1 = require("../error-types");
29
- function mergeProjectConfigurationIntoRootMap(projectRootMap, project, configurationSourceMaps, sourceInformation,
30
- // This function is used when reading project configuration
31
- // in generators, where we don't want to do this.
32
- skipTargetNormalization) {
33
- project.root = project.root === '' ? '.' : project.root;
34
- if (configurationSourceMaps && !configurationSourceMaps[project.root]) {
35
- configurationSourceMaps[project.root] = {};
36
- }
37
- const sourceMap = configurationSourceMaps?.[project.root];
38
- let matchingProject = projectRootMap[project.root];
39
- if (!matchingProject) {
40
- projectRootMap[project.root] = {
41
- root: project.root,
42
- };
43
- matchingProject = projectRootMap[project.root];
44
- if (sourceMap) {
45
- sourceMap[`root`] = sourceInformation;
46
- }
47
- }
48
- // This handles top level properties that are overwritten.
49
- // e.g. `srcRoot`, `projectType`, or other fields that shouldn't be extended
50
- // Note: `name` is set specifically here to keep it from changing. The name is
51
- // always determined by the first inference plugin to ID a project, unless it has
52
- // a project.json in which case it was already updated above.
53
- const updatedProjectConfiguration = {
54
- ...matchingProject,
55
- };
56
- for (const k in project) {
57
- if (![
58
- 'tags',
59
- 'implicitDependencies',
60
- 'generators',
61
- 'targets',
62
- 'metadata',
63
- 'namedInputs',
64
- ].includes(k)) {
65
- updatedProjectConfiguration[k] = project[k];
66
- if (sourceMap) {
67
- sourceMap[`${k}`] = sourceInformation;
68
- }
69
- }
70
- }
71
- // The next blocks handle properties that should be themselves merged (e.g. targets, tags, and implicit dependencies)
72
- if (project.tags) {
73
- updatedProjectConfiguration.tags = Array.from(new Set((matchingProject.tags ?? []).concat(project.tags)));
74
- if (sourceMap) {
75
- sourceMap['tags'] ??= sourceInformation;
76
- project.tags.forEach((tag) => {
77
- sourceMap[`tags.${tag}`] = sourceInformation;
78
- });
79
- }
80
- }
81
- if (project.implicitDependencies) {
82
- updatedProjectConfiguration.implicitDependencies = (matchingProject.implicitDependencies ?? []).concat(project.implicitDependencies);
83
- if (sourceMap) {
84
- sourceMap['implicitDependencies'] ??= sourceInformation;
85
- project.implicitDependencies.forEach((implicitDependency) => {
86
- sourceMap[`implicitDependencies.${implicitDependency}`] =
87
- sourceInformation;
88
- });
89
- }
90
- }
91
- if (project.generators) {
92
- // Start with generators config in new project.
93
- updatedProjectConfiguration.generators = { ...project.generators };
94
- if (sourceMap) {
95
- sourceMap['generators'] ??= sourceInformation;
96
- for (const generator in project.generators) {
97
- sourceMap[`generators.${generator}`] = sourceInformation;
98
- for (const property in project.generators[generator]) {
99
- sourceMap[`generators.${generator}.${property}`] = sourceInformation;
100
- }
101
- }
102
- }
103
- if (matchingProject.generators) {
104
- // For each generator that was already defined, shallow merge the options.
105
- // Project contains the new info, so it has higher priority.
106
- for (const generator in matchingProject.generators) {
107
- updatedProjectConfiguration.generators[generator] = {
108
- ...matchingProject.generators[generator],
109
- ...project.generators[generator],
110
- };
111
- }
112
- }
113
- }
114
- if (project.namedInputs) {
115
- updatedProjectConfiguration.namedInputs = {
116
- ...matchingProject.namedInputs,
117
- ...project.namedInputs,
118
- };
119
- if (sourceMap) {
120
- sourceMap['namedInputs'] ??= sourceInformation;
121
- for (const namedInput in project.namedInputs) {
122
- sourceMap[`namedInputs.${namedInput}`] = sourceInformation;
123
- }
124
- }
125
- }
126
- if (project.metadata) {
127
- updatedProjectConfiguration.metadata = mergeMetadata(sourceMap, sourceInformation, 'metadata', project.metadata, matchingProject.metadata);
128
- }
129
- if (project.targets) {
130
- // We merge the targets with special handling, so clear this back to the
131
- // targets as defined originally before merging.
132
- updatedProjectConfiguration.targets = matchingProject?.targets ?? {};
133
- if (sourceMap) {
134
- sourceMap['targets'] ??= sourceInformation;
135
- }
136
- // For each target defined in the new config
137
- for (const targetName in project.targets) {
138
- // Always set source map info for the target, but don't overwrite info already there
139
- // if augmenting an existing target.
140
- const target = project.targets?.[targetName];
141
- if (sourceMap) {
142
- sourceMap[(0, source_maps_1.targetSourceMapKey)(targetName)] = sourceInformation;
143
- }
144
- const normalizedTarget = skipTargetNormalization
145
- ? target
146
- : resolveCommandSyntacticSugar(target, project.root);
147
- let matchingTargets = [];
148
- if ((0, globs_1.isGlobPattern)(targetName)) {
149
- // find all targets matching the glob pattern
150
- // this will map atomized targets to the glob pattern same as it does for targetDefaults
151
- matchingTargets = Object.keys(updatedProjectConfiguration.targets).filter((key) => (0, minimatch_1.minimatch)(key, targetName));
152
- }
153
- // If no matching targets were found, we can assume that the target name is not (meant to be) a glob pattern
154
- if (!matchingTargets.length) {
155
- matchingTargets = [targetName];
156
- }
157
- for (const matchingTargetName of matchingTargets) {
158
- const mergedTarget = mergeTargetConfigurations(normalizedTarget, matchingProject.targets?.[matchingTargetName], sourceMap, sourceInformation, `targets.${matchingTargetName}`);
159
- updatedProjectConfiguration.targets[matchingTargetName] = mergedTarget;
160
- }
161
- }
162
- }
163
- projectRootMap[updatedProjectConfiguration.root] =
164
- updatedProjectConfiguration;
165
- const previousName = matchingProject?.name &&
166
- project.name &&
167
- matchingProject.name !== project.name
168
- ? matchingProject.name
169
- : undefined;
170
- return { previousName };
171
- }
172
- function mergeMetadata(sourceMap, sourceInformation, baseSourceMapPath, metadata, matchingMetadata) {
173
- const result = {
174
- ...(matchingMetadata ?? {}),
175
- };
176
- for (const [metadataKey, value] of Object.entries(metadata)) {
177
- const existingValue = matchingMetadata?.[metadataKey];
178
- if (Array.isArray(value) && Array.isArray(existingValue)) {
179
- const startIndex = result[metadataKey].length;
180
- result[metadataKey].push(...value);
181
- if (sourceMap) {
182
- (0, source_maps_1.recordSourceMapKeysByIndex)(sourceMap, `${baseSourceMapPath}.${metadataKey}`, result[metadataKey], sourceInformation, startIndex);
183
- }
184
- }
185
- else if (Array.isArray(value) && existingValue === undefined) {
186
- result[metadataKey] ??= value;
187
- if (sourceMap) {
188
- sourceMap[`${baseSourceMapPath}.${metadataKey}`] = sourceInformation;
189
- (0, source_maps_1.recordSourceMapKeysByIndex)(sourceMap, `${baseSourceMapPath}.${metadataKey}`, value, sourceInformation);
190
- }
191
- }
192
- else if (typeof value === 'object' && typeof existingValue === 'object') {
193
- for (const key in value) {
194
- const existingValue = matchingMetadata?.[metadataKey]?.[key];
195
- if (Array.isArray(value[key]) && Array.isArray(existingValue)) {
196
- const startIndex = result[metadataKey][key].length;
197
- result[metadataKey][key].push(...value[key]);
198
- if (sourceMap) {
199
- (0, source_maps_1.recordSourceMapKeysByIndex)(sourceMap, `${baseSourceMapPath}.${metadataKey}.${key}`, result[metadataKey][key], sourceInformation, startIndex);
200
- }
201
- }
202
- else {
203
- result[metadataKey][key] = value[key];
204
- if (sourceMap) {
205
- sourceMap[`${baseSourceMapPath}.${metadataKey}`] =
206
- sourceInformation;
207
- }
208
- }
209
- }
210
- }
211
- else {
212
- result[metadataKey] = value;
213
- if (sourceMap) {
214
- sourceMap[`${baseSourceMapPath}.${metadataKey}`] = sourceInformation;
215
- if (typeof value === 'object') {
216
- for (const k in value) {
217
- sourceMap[`${baseSourceMapPath}.${metadataKey}.${k}`] =
218
- sourceInformation;
219
- if (Array.isArray(value[k])) {
220
- (0, source_maps_1.recordSourceMapKeysByIndex)(sourceMap, `${baseSourceMapPath}.${metadataKey}.${k}`, value[k], sourceInformation);
221
- }
222
- }
223
- }
224
- }
225
- }
226
- }
227
- return result;
228
- }
14
+ var target_merging_1 = require("./project-configuration/target-merging");
15
+ Object.defineProperty(exports, "mergeTargetConfigurations", { enumerable: true, get: function () { return target_merging_1.mergeTargetConfigurations; } });
16
+ Object.defineProperty(exports, "readTargetDefaultsForTarget", { enumerable: true, get: function () { return target_merging_1.readTargetDefaultsForTarget; } });
229
17
  /**
230
18
  * Transforms a list of project paths into a map of project configurations.
231
19
  *
@@ -317,30 +105,55 @@ plugins) {
317
105
  }
318
106
  function mergeCreateNodesResults(results, nxJsonConfiguration, workspaceRoot, errors) {
319
107
  perf_hooks_1.performance.mark('createNodes:merge - start');
320
- const projectRootMap = {};
108
+ const nodesManager = new project_nodes_manager_1.ProjectNodesManager();
321
109
  const externalNodes = {};
322
- const projectNameManager = new name_substitution_manager_1.ProjectNameInNodePropsManager();
323
110
  const configurationSourceMaps = {};
324
- for (const result of results.flat()) {
325
- const [pluginName, file, nodes, pluginIndex] = result;
326
- const { projects: projectNodes, externalNodes: pluginExternalNodes } = nodes;
327
- const sourceInfo = [file, pluginName];
328
- for (const root in projectNodes) {
329
- // Handles `{projects: {'libs/foo': undefined}}`.
330
- if (!projectNodes[root]) {
331
- continue;
111
+ // Process each plugin's results in two phases:
112
+ // Phase 1: Merge all projects from this plugin into rootMap/nameMap
113
+ // Phase 2: Register substitutors for this plugin's results
114
+ //
115
+ // Per-plugin batching ensures that:
116
+ // - All same-plugin projects are in the nameMap before substitutor
117
+ // registration (fixes cross-file references like kafka-stream)
118
+ // - Later-plugin renames haven't occurred yet, so dependsOn strings
119
+ // that reference old names can still be resolved via the nameMap
120
+ for (const pluginResults of results) {
121
+ // Phase 1: Merge all projects from this plugin batch
122
+ for (const result of pluginResults) {
123
+ const [pluginName, file, nodes, pluginIndex] = result;
124
+ const { projects: projectNodes, externalNodes: pluginExternalNodes } = nodes;
125
+ const sourceInfo = [file, pluginName];
126
+ for (const root in projectNodes) {
127
+ // Handles `{projects: {'libs/foo': undefined}}`.
128
+ if (!projectNodes[root]) {
129
+ continue;
130
+ }
131
+ const project = {
132
+ root: root,
133
+ ...projectNodes[root],
134
+ };
135
+ try {
136
+ nodesManager.mergeProjectNode(project, configurationSourceMaps, sourceInfo);
137
+ }
138
+ catch (error) {
139
+ errors.push(new error_types_1.MergeNodesError({
140
+ file,
141
+ pluginName,
142
+ error,
143
+ pluginIndex,
144
+ }));
145
+ }
332
146
  }
333
- const project = {
334
- root: root,
335
- ...projectNodes[root],
336
- };
147
+ Object.assign(externalNodes, pluginExternalNodes);
148
+ }
149
+ // Phase 2: Register substitutors for this plugin batch. The nameMap
150
+ // now contains all projects from this plugin (and all prior plugins)
151
+ // so splitTargetFromConfigurations can resolve colon-delimited strings.
152
+ for (const result of pluginResults) {
153
+ const [pluginName, file, nodes, pluginIndex] = result;
154
+ const { projects: projectNodes } = nodes;
337
155
  try {
338
- const { previousName } = mergeProjectConfigurationIntoRootMap(projectRootMap, project, configurationSourceMaps, sourceInfo);
339
- // If this project's name changed, record the rename so substitutors
340
- // registered for the old name can fire during applySubstitutions.
341
- if (previousName) {
342
- projectNameManager.markDirty(root, previousName);
343
- }
156
+ nodesManager.registerSubstitutors(projectNodes);
344
157
  }
345
158
  catch (error) {
346
159
  errors.push(new error_types_1.MergeNodesError({
@@ -351,29 +164,13 @@ function mergeCreateNodesResults(results, nxJsonConfiguration, workspaceRoot, er
351
164
  }));
352
165
  }
353
166
  }
354
- // Register substitutors for any project-name references in this result's
355
- // targets. Substitutors are keyed by the referenced name (not by root),
356
- // so registration requires no lookup and is safe regardless of whether
357
- // the referenced project has been processed yet.
358
- try {
359
- projectNameManager.registerSubstitutorsForNodeResults(projectNodes);
360
- }
361
- catch (error) {
362
- errors.push(new error_types_1.MergeNodesError({
363
- file,
364
- pluginName,
365
- error,
366
- pluginIndex,
367
- }));
368
- }
369
- Object.assign(externalNodes, pluginExternalNodes);
370
167
  }
168
+ const projectRootMap = nodesManager.getRootMap();
371
169
  try {
372
- projectNameManager.applySubstitutions(projectRootMap);
373
- validateAndNormalizeProjectRootMap(workspaceRoot, projectRootMap, nxJsonConfiguration, configurationSourceMaps);
170
+ nodesManager.applySubstitutions();
171
+ (0, target_normalization_1.validateAndNormalizeProjectRootMap)(workspaceRoot, projectRootMap, nxJsonConfiguration, configurationSourceMaps);
374
172
  }
375
173
  catch (error) {
376
- const unknownErrors = [];
377
174
  let _errors = error instanceof AggregateError ? error.errors : [error];
378
175
  for (const e of _errors) {
379
176
  if ((0, error_types_1.isProjectsWithNoNameError)(e) ||
@@ -386,7 +183,7 @@ function mergeCreateNodesResults(results, nxJsonConfiguration, workspaceRoot, er
386
183
  }
387
184
  }
388
185
  }
389
- const rootMap = createRootMap(projectRootMap);
186
+ const rootMap = (0, project_nodes_manager_1.createRootMap)(projectRootMap);
390
187
  perf_hooks_1.performance.mark('createNodes:merge - end');
391
188
  perf_hooks_1.performance.measure('createNodes:merge', 'createNodes:merge - start', 'createNodes:merge - end');
392
189
  return { projectRootMap, externalNodes, rootMap, configurationSourceMaps };
@@ -449,478 +246,3 @@ function findMatchingConfigFiles(projectFiles, pattern, include, exclude) {
449
246
  }
450
247
  return matchingConfigFiles;
451
248
  }
452
- function readProjectConfigurationsFromRootMap(projectRootMap) {
453
- const projects = {};
454
- // If there are projects that have the same name, that is an error.
455
- // This object tracks name -> (all roots of projects with that name)
456
- // to provide better error messaging.
457
- const conflicts = new Map();
458
- const projectRootsWithNoName = [];
459
- for (const root in projectRootMap) {
460
- const project = projectRootMap[root];
461
- // We're setting `// targets` as a comment `targets` is empty due to Project Crystal.
462
- // Strip it before returning configuration for usage.
463
- if (project['// targets'])
464
- delete project['// targets'];
465
- try {
466
- validateProject(project, projects);
467
- projects[project.name] = project;
468
- }
469
- catch (e) {
470
- if ((0, error_types_1.isProjectWithNoNameError)(e)) {
471
- projectRootsWithNoName.push(e.projectRoot);
472
- }
473
- else if ((0, error_types_1.isProjectWithExistingNameError)(e)) {
474
- const rootErrors = conflicts.get(e.projectName) ?? [
475
- projects[e.projectName].root,
476
- ];
477
- rootErrors.push(e.projectRoot);
478
- conflicts.set(e.projectName, rootErrors);
479
- }
480
- else {
481
- throw e;
482
- }
483
- }
484
- }
485
- if (conflicts.size > 0) {
486
- throw new error_types_1.MultipleProjectsWithSameNameError(conflicts, projects);
487
- }
488
- if (projectRootsWithNoName.length > 0) {
489
- throw new error_types_1.ProjectsWithNoNameError(projectRootsWithNoName, projects);
490
- }
491
- return projects;
492
- }
493
- function validateAndNormalizeProjectRootMap(workspaceRoot, projectRootMap, nxJsonConfiguration, sourceMaps = {}) {
494
- // Name -> Project, used to validate that all projects have unique names
495
- const projects = {};
496
- // If there are projects that have the same name, that is an error.
497
- // This object tracks name -> (all roots of projects with that name)
498
- // to provide better error messaging.
499
- const conflicts = new Map();
500
- const projectRootsWithNoName = [];
501
- const validityErrors = [];
502
- for (const root in projectRootMap) {
503
- const project = projectRootMap[root];
504
- // We're setting `// targets` as a comment `targets` is empty due to Project Crystal.
505
- // Strip it before returning configuration for usage.
506
- if (project['// targets'])
507
- delete project['// targets'];
508
- // We initially did this in the project.json plugin, but
509
- // that resulted in project.json files without names causing
510
- // the resulting project to change names from earlier plugins...
511
- if (!project.name &&
512
- (0, node_fs_1.existsSync)((0, path_1.join)(workspaceRoot, project.root, 'project.json'))) {
513
- project.name = (0, to_project_name_1.toProjectName)((0, path_1.join)(root, 'project.json'));
514
- }
515
- try {
516
- validateProject(project, projects);
517
- projects[project.name] = project;
518
- }
519
- catch (e) {
520
- if ((0, error_types_1.isProjectWithNoNameError)(e)) {
521
- projectRootsWithNoName.push(e.projectRoot);
522
- }
523
- else if ((0, error_types_1.isProjectWithExistingNameError)(e)) {
524
- const rootErrors = conflicts.get(e.projectName) ?? [
525
- projects[e.projectName].root,
526
- ];
527
- rootErrors.push(e.projectRoot);
528
- conflicts.set(e.projectName, rootErrors);
529
- }
530
- else {
531
- throw e;
532
- }
533
- }
534
- }
535
- for (const root in projectRootMap) {
536
- const project = projectRootMap[root];
537
- try {
538
- normalizeTargets(project, sourceMaps, nxJsonConfiguration, workspaceRoot, projects);
539
- }
540
- catch (e) {
541
- if (e instanceof error_types_1.WorkspaceValidityError) {
542
- validityErrors.push(e);
543
- }
544
- else {
545
- throw e;
546
- }
547
- }
548
- }
549
- const errors = [];
550
- if (conflicts.size > 0) {
551
- errors.push(new error_types_1.MultipleProjectsWithSameNameError(conflicts, projects));
552
- }
553
- if (projectRootsWithNoName.length > 0) {
554
- errors.push(new error_types_1.ProjectsWithNoNameError(projectRootsWithNoName, projects));
555
- }
556
- if (validityErrors.length > 0) {
557
- errors.push(...validityErrors);
558
- }
559
- if (errors.length > 0) {
560
- throw new AggregateError(errors);
561
- }
562
- return projectRootMap;
563
- }
564
- function normalizeTargets(project, sourceMaps, nxJsonConfiguration, workspaceRoot,
565
- /**
566
- * Project configurations keyed by project name
567
- */
568
- projects) {
569
- const targetErrorMessage = [];
570
- for (const targetName in project.targets) {
571
- project.targets[targetName] = normalizeTarget(project.targets[targetName], project, workspaceRoot, projects, [project.root, targetName].join(':'));
572
- const projectSourceMaps = sourceMaps[project.root];
573
- const targetConfig = project.targets[targetName];
574
- const targetDefaults = deepClone(readTargetDefaultsForTarget(targetName, nxJsonConfiguration.targetDefaults, targetConfig.executor));
575
- // We only apply defaults if they exist
576
- if (targetDefaults && isCompatibleTarget(targetConfig, targetDefaults)) {
577
- project.targets[targetName] = mergeTargetDefaultWithTargetDefinition(targetName, project, normalizeTarget(targetDefaults, project, workspaceRoot, projects, ['nx.json[targetDefaults]', targetName].join(':')), projectSourceMaps);
578
- }
579
- const target = project.targets[targetName];
580
- if (
581
- // If the target has no executor or command, it doesn't do anything
582
- !target.executor &&
583
- !target.command) {
584
- // But it may have dependencies that do something
585
- if (target.dependsOn && target.dependsOn.length > 0) {
586
- target.executor = 'nx:noop';
587
- }
588
- else {
589
- // If it does nothing, and has no depenencies,
590
- // we can remove it.
591
- delete project.targets[targetName];
592
- }
593
- }
594
- if (target.cache && target.continuous) {
595
- targetErrorMessage.push(`- "${targetName}" has both "cache" and "continuous" set to true. Continuous targets cannot be cached. Please remove the "cache" property.`);
596
- }
597
- }
598
- if (targetErrorMessage.length > 0) {
599
- targetErrorMessage.unshift(`Errors detected in targets of project "${project.name}":`);
600
- throw new error_types_1.WorkspaceValidityError(targetErrorMessage.join('\n'));
601
- }
602
- }
603
- function validateProject(project,
604
- // name -> project
605
- knownProjects) {
606
- if (!project.name) {
607
- try {
608
- const { name } = (0, fileutils_1.readJsonFile)((0, path_1.join)(project.root, 'package.json'));
609
- if (!name) {
610
- throw new Error(`Project at ${project.root} has no name provided.`);
611
- }
612
- project.name = name;
613
- }
614
- catch {
615
- throw new error_types_1.ProjectWithNoNameError(project.root);
616
- }
617
- }
618
- else if (knownProjects[project.name] &&
619
- knownProjects[project.name].root !== project.root) {
620
- throw new error_types_1.ProjectWithExistingNameError(project.name, project.root);
621
- }
622
- }
623
- function targetDefaultShouldBeApplied(key, sourceMap) {
624
- const sourceInfo = sourceMap[key];
625
- if (!sourceInfo) {
626
- return true;
627
- }
628
- // The defined value of the target is from a plugin that
629
- // isn't part of Nx's core plugins, so target defaults are
630
- // applied on top of it.
631
- const [, plugin] = sourceInfo;
632
- return !plugin?.startsWith('nx/');
633
- }
634
- function deepClone(obj) {
635
- return structuredClone(obj);
636
- }
637
- function mergeTargetDefaultWithTargetDefinition(targetName, project, targetDefault, sourceMap) {
638
- const targetDefinition = project.targets[targetName] ?? {};
639
- const result = deepClone(targetDefinition);
640
- for (const key in targetDefault) {
641
- switch (key) {
642
- case 'options': {
643
- const normalizedDefaults = resolveNxTokensInOptions(targetDefault.options, project, targetName);
644
- for (const optionKey in normalizedDefaults) {
645
- const sourceMapKey = (0, source_maps_1.targetOptionSourceMapKey)(targetName, optionKey);
646
- if (targetDefinition.options[optionKey] === undefined ||
647
- targetDefaultShouldBeApplied(sourceMapKey, sourceMap)) {
648
- result.options[optionKey] = targetDefault.options[optionKey];
649
- sourceMap[sourceMapKey] = ['nx.json', 'nx/target-defaults'];
650
- }
651
- }
652
- break;
653
- }
654
- case 'configurations': {
655
- if (!result.configurations) {
656
- result.configurations = {};
657
- sourceMap[(0, source_maps_1.targetConfigurationsSourceMapKey)(targetName)] = [
658
- 'nx.json',
659
- 'nx/target-defaults',
660
- ];
661
- }
662
- for (const configuration in targetDefault.configurations) {
663
- if (!result.configurations[configuration]) {
664
- result.configurations[configuration] = {};
665
- sourceMap[(0, source_maps_1.targetConfigurationsSourceMapKey)(targetName, configuration)] = ['nx.json', 'nx/target-defaults'];
666
- }
667
- const normalizedConfigurationDefaults = resolveNxTokensInOptions(targetDefault.configurations[configuration], project, targetName);
668
- for (const configurationKey in normalizedConfigurationDefaults) {
669
- const sourceMapKey = (0, source_maps_1.targetConfigurationsSourceMapKey)(targetName, configuration, configurationKey);
670
- if (targetDefinition.configurations?.[configuration]?.[configurationKey] === undefined ||
671
- targetDefaultShouldBeApplied(sourceMapKey, sourceMap)) {
672
- result.configurations[configuration][configurationKey] =
673
- targetDefault.configurations[configuration][configurationKey];
674
- sourceMap[sourceMapKey] = ['nx.json', 'nx/target-defaults'];
675
- }
676
- }
677
- }
678
- break;
679
- }
680
- default: {
681
- const sourceMapKey = `targets.${targetName}.${key}`;
682
- if (targetDefinition[key] === undefined ||
683
- targetDefaultShouldBeApplied(sourceMapKey, sourceMap)) {
684
- result[key] = targetDefault[key];
685
- sourceMap[sourceMapKey] = ['nx.json', 'nx/target-defaults'];
686
- }
687
- break;
688
- }
689
- }
690
- }
691
- return result;
692
- }
693
- /**
694
- * Merges two targets.
695
- *
696
- * Most properties from `target` will overwrite any properties from `baseTarget`.
697
- * Options and configurations are treated differently - they are merged together if the executor definition is compatible.
698
- *
699
- * @param target The target definition with higher priority
700
- * @param baseTarget The target definition that should be overwritten. Can be undefined, in which case the target is returned as-is.
701
- * @param projectConfigSourceMap The source map to be filled with metadata about where each property came from
702
- * @param sourceInformation The metadata about where the new target was defined
703
- * @param targetIdentifier The identifier for the target to merge, used for source map
704
- * @returns A merged target configuration
705
- */
706
- function mergeTargetConfigurations(target, baseTarget, projectConfigSourceMap, sourceInformation, targetIdentifier) {
707
- const { configurations: defaultConfigurations, options: defaultOptions, ...baseTargetProperties } = baseTarget ?? {};
708
- // Target is "compatible", e.g. executor is defined only once or is the same
709
- // in both places. This means that it is likely safe to merge
710
- const isCompatible = isCompatibleTarget(baseTarget ?? {}, target);
711
- if (!isCompatible && projectConfigSourceMap) {
712
- // if the target is not compatible, we will simply override the options
713
- // we have to delete old entries from the source map
714
- for (const key in projectConfigSourceMap) {
715
- if (key.startsWith(`${targetIdentifier}`)) {
716
- delete projectConfigSourceMap[key];
717
- }
718
- }
719
- }
720
- // merge top level properties if they're compatible
721
- const result = {
722
- ...(isCompatible ? baseTargetProperties : {}),
723
- ...target,
724
- };
725
- // record top level properties in source map
726
- if (projectConfigSourceMap) {
727
- projectConfigSourceMap[targetIdentifier] = sourceInformation;
728
- // record root level target properties to source map
729
- for (const targetProperty in target) {
730
- const targetPropertyId = `${targetIdentifier}.${targetProperty}`;
731
- projectConfigSourceMap[targetPropertyId] = sourceInformation;
732
- }
733
- }
734
- // merge options if there are any
735
- // if the targets aren't compatible, we simply discard the old options during the merge
736
- if (target.options || defaultOptions) {
737
- result.options = mergeOptions(target.options, isCompatible ? defaultOptions : undefined, projectConfigSourceMap, sourceInformation, targetIdentifier);
738
- }
739
- // merge configurations if there are any
740
- // if the targets aren't compatible, we simply discard the old configurations during the merge
741
- if (target.configurations || defaultConfigurations) {
742
- result.configurations = mergeConfigurations(target.configurations, isCompatible ? defaultConfigurations : undefined, projectConfigSourceMap, sourceInformation, targetIdentifier);
743
- }
744
- if (target.metadata) {
745
- result.metadata = mergeMetadata(projectConfigSourceMap, sourceInformation, `${targetIdentifier}.metadata`, target.metadata, baseTarget?.metadata);
746
- }
747
- return result;
748
- }
749
- /**
750
- * Checks if targets options are compatible - used when merging configurations
751
- * to avoid merging options for @nx/js:tsc into something like @nx/webpack:webpack.
752
- *
753
- * If the executors are both specified and don't match, the options aren't considered
754
- * "compatible" and shouldn't be merged.
755
- */
756
- function isCompatibleTarget(a, b) {
757
- const oneHasNoExecutor = !a.executor || !b.executor;
758
- const bothHaveSameExecutor = a.executor === b.executor;
759
- if (oneHasNoExecutor)
760
- return true;
761
- if (!bothHaveSameExecutor)
762
- return false;
763
- const isRunCommands = a.executor === 'nx:run-commands';
764
- if (isRunCommands) {
765
- const aCommand = a.options?.command ?? a.options?.commands?.join(' && ');
766
- const bCommand = b.options?.command ?? b.options?.commands?.join(' && ');
767
- const oneHasNoCommand = !aCommand || !bCommand;
768
- const hasSameCommand = aCommand === bCommand;
769
- return oneHasNoCommand || hasSameCommand;
770
- }
771
- const isRunScript = a.executor === 'nx:run-script';
772
- if (isRunScript) {
773
- const aScript = a.options?.script;
774
- const bScript = b.options?.script;
775
- const oneHasNoScript = !aScript || !bScript;
776
- const hasSameScript = aScript === bScript;
777
- return oneHasNoScript || hasSameScript;
778
- }
779
- return true;
780
- }
781
- function mergeConfigurations(newConfigurations, baseConfigurations, projectConfigSourceMap, sourceInformation, targetIdentifier) {
782
- const mergedConfigurations = {};
783
- const configurations = new Set([
784
- ...Object.keys(baseConfigurations ?? {}),
785
- ...Object.keys(newConfigurations ?? {}),
786
- ]);
787
- for (const configuration of configurations) {
788
- mergedConfigurations[configuration] = {
789
- ...(baseConfigurations?.[configuration] ?? {}),
790
- ...(newConfigurations?.[configuration] ?? {}),
791
- };
792
- }
793
- // record new configurations & configuration properties in source map
794
- if (projectConfigSourceMap) {
795
- for (const newConfiguration in newConfigurations) {
796
- projectConfigSourceMap[`${targetIdentifier}.configurations.${newConfiguration}`] = sourceInformation;
797
- for (const configurationProperty in newConfigurations[newConfiguration]) {
798
- projectConfigSourceMap[`${targetIdentifier}.configurations.${newConfiguration}.${configurationProperty}`] = sourceInformation;
799
- }
800
- }
801
- }
802
- return mergedConfigurations;
803
- }
804
- function mergeOptions(newOptions, baseOptions, projectConfigSourceMap, sourceInformation, targetIdentifier) {
805
- const mergedOptions = {
806
- ...(baseOptions ?? {}),
807
- ...(newOptions ?? {}),
808
- };
809
- // record new options & option properties in source map
810
- if (projectConfigSourceMap) {
811
- for (const newOption in newOptions) {
812
- projectConfigSourceMap[`${targetIdentifier}.options.${newOption}`] =
813
- sourceInformation;
814
- }
815
- }
816
- return mergedOptions;
817
- }
818
- function resolveNxTokensInOptions(object, project, key) {
819
- const result = Array.isArray(object) ? [...object] : { ...object };
820
- for (let [opt, value] of Object.entries(object ?? {})) {
821
- if (typeof value === 'string') {
822
- const workspaceRootMatch = /^(\{workspaceRoot\}\/?)/.exec(value);
823
- if (workspaceRootMatch?.length) {
824
- value = value.replace(workspaceRootMatch[0], '');
825
- }
826
- if (value.includes('{workspaceRoot}')) {
827
- throw new Error(`${logger_1.NX_PREFIX} The {workspaceRoot} token is only valid at the beginning of an option. (${key})`);
828
- }
829
- value = value.replace(/\{projectRoot\}/g, project.root);
830
- result[opt] = value.replace(/\{projectName\}/g, project.name);
831
- }
832
- else if (typeof value === 'object' && value) {
833
- result[opt] = resolveNxTokensInOptions(value, project, [key, opt].join('.'));
834
- }
835
- }
836
- return result;
837
- }
838
- function readTargetDefaultsForTarget(targetName, targetDefaults, executor) {
839
- if (executor && targetDefaults?.[executor]) {
840
- // If an executor is defined in project.json, defaults should be read
841
- // from the most specific key that matches that executor.
842
- // e.g. If executor === run-commands, and the target is named build:
843
- // Use, use nx:run-commands if it is present
844
- // If not, use build if it is present.
845
- return targetDefaults?.[executor];
846
- }
847
- else if (targetDefaults?.[targetName]) {
848
- // If the executor is not defined, the only key we have is the target name.
849
- return targetDefaults?.[targetName];
850
- }
851
- let matchingTargetDefaultKey = null;
852
- for (const key in targetDefaults ?? {}) {
853
- if ((0, globs_1.isGlobPattern)(key) && (0, minimatch_1.minimatch)(targetName, key)) {
854
- if (!matchingTargetDefaultKey ||
855
- matchingTargetDefaultKey.length < key.length) {
856
- matchingTargetDefaultKey = key;
857
- }
858
- }
859
- }
860
- if (matchingTargetDefaultKey) {
861
- return targetDefaults[matchingTargetDefaultKey];
862
- }
863
- return null;
864
- }
865
- function createRootMap(projectRootMap) {
866
- const map = {};
867
- for (const projectRoot in projectRootMap) {
868
- const projectName = projectRootMap[projectRoot].name;
869
- map[projectRoot] = projectName;
870
- }
871
- return map;
872
- }
873
- function resolveCommandSyntacticSugar(target, key) {
874
- const { command, ...config } = target ?? {};
875
- if (!command) {
876
- return target;
877
- }
878
- if (config.executor) {
879
- throw new Error(`${logger_1.NX_PREFIX} Project at ${key} should not have executor and command both configured.`);
880
- }
881
- else {
882
- return {
883
- ...config,
884
- executor: 'nx:run-commands',
885
- options: {
886
- ...config.options,
887
- command: command,
888
- },
889
- };
890
- }
891
- }
892
- /**
893
- * Expand's `command` syntactic sugar, replaces tokens in options, and adds information from executor schema.
894
- * @param target The target to normalize
895
- * @param project The project that the target belongs to
896
- * @returns The normalized target configuration
897
- */
898
- function normalizeTarget(target, project, workspaceRoot, projectsMap, errorMsgKey) {
899
- target = {
900
- ...target,
901
- configurations: {
902
- ...target.configurations,
903
- },
904
- };
905
- target = resolveCommandSyntacticSugar(target, project.root);
906
- target.options = resolveNxTokensInOptions(target.options, project, errorMsgKey);
907
- for (const configuration in target.configurations) {
908
- target.configurations[configuration] = resolveNxTokensInOptions(target.configurations[configuration], project, `${project.root}:${target}:${configuration}`);
909
- }
910
- target.parallelism ??= true;
911
- if (target.executor && !('continuous' in target)) {
912
- try {
913
- const [executorNodeModule, executorName] = (0, executor_utils_1.parseExecutor)(target.executor);
914
- const { schema } = (0, executor_utils_1.getExecutorInformation)(executorNodeModule, executorName, workspaceRoot, projectsMap);
915
- if (schema.continuous) {
916
- target.continuous ??= schema.continuous;
917
- }
918
- }
919
- catch (e) {
920
- // If the executor is not found, we assume that it is not a valid executor.
921
- // This means that we should not set the continuous property.
922
- // We could throw an error here, but it would be better to just ignore it.
923
- }
924
- }
925
- return target;
926
- }