nx 19.6.4 → 19.6.6

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 (43) hide show
  1. package/package.json +12 -12
  2. package/release/changelog-renderer/index.d.ts +1 -1
  3. package/release/changelog-renderer/index.js +46 -11
  4. package/schemas/nx-schema.json +5 -0
  5. package/src/command-line/import/command-object.js +4 -0
  6. package/src/command-line/import/import.d.ts +4 -0
  7. package/src/command-line/import/import.js +147 -12
  8. package/src/command-line/import/utils/prepare-source-repo.d.ts +1 -1
  9. package/src/command-line/import/utils/prepare-source-repo.js +31 -85
  10. package/src/command-line/release/changelog.js +53 -12
  11. package/src/command-line/release/command-object.d.ts +1 -0
  12. package/src/command-line/release/command-object.js +6 -1
  13. package/src/command-line/release/config/version-plans.d.ts +14 -1
  14. package/src/command-line/release/config/version-plans.js +33 -1
  15. package/src/command-line/release/plan-check.js +8 -61
  16. package/src/command-line/release/plan.js +131 -37
  17. package/src/command-line/release/release.js +1 -1
  18. package/src/command-line/release/utils/get-touched-projects-for-group.d.ts +7 -0
  19. package/src/command-line/release/utils/get-touched-projects-for-group.js +78 -0
  20. package/src/command-line/release/utils/git.d.ts +1 -1
  21. package/src/command-line/release/utils/git.js +46 -19
  22. package/src/command-line/release/version.js +1 -1
  23. package/src/command-line/yargs-utils/shared-options.d.ts +2 -1
  24. package/src/command-line/yargs-utils/shared-options.js +5 -0
  25. package/src/core/graph/main.js +1 -1
  26. package/src/daemon/server/sync-generators.d.ts +4 -0
  27. package/src/daemon/server/sync-generators.js +172 -52
  28. package/src/migrations/update-15-0-0/prefix-outputs.js +3 -18
  29. package/src/native/index.d.ts +4 -0
  30. package/src/native/native-bindings.js +2 -0
  31. package/src/native/nx.wasi-browser.js +42 -36
  32. package/src/native/nx.wasi.cjs +40 -36
  33. package/src/native/nx.wasm32-wasi.wasm +0 -0
  34. package/src/project-graph/plugins/isolation/plugin-pool.js +1 -1
  35. package/src/tasks-runner/run-command.js +4 -1
  36. package/src/tasks-runner/utils.d.ts +1 -8
  37. package/src/tasks-runner/utils.js +9 -12
  38. package/src/utils/command-line-utils.d.ts +1 -0
  39. package/src/utils/git-utils.d.ts +7 -10
  40. package/src/utils/git-utils.js +61 -44
  41. package/src/utils/sync-generators.d.ts +2 -2
  42. package/src/utils/squash.d.ts +0 -1
  43. package/src/utils/squash.js +0 -12
@@ -4,3 +4,7 @@ export declare function getCachedSyncGeneratorChanges(generators: string[]): Pro
4
4
  export declare function flushSyncGeneratorChangesToDisk(generators: string[]): Promise<void>;
5
5
  export declare function collectAndScheduleSyncGenerators(projectGraph: ProjectGraph): void;
6
6
  export declare function getCachedRegisteredSyncGenerators(): Promise<string[]>;
7
+ /**
8
+ * @internal
9
+ */
10
+ export declare function _getConflictingGeneratorGroups(results: SyncGeneratorChangesResult[]): string[][];
@@ -4,6 +4,7 @@ exports.getCachedSyncGeneratorChanges = getCachedSyncGeneratorChanges;
4
4
  exports.flushSyncGeneratorChangesToDisk = flushSyncGeneratorChangesToDisk;
5
5
  exports.collectAndScheduleSyncGenerators = collectAndScheduleSyncGenerators;
6
6
  exports.getCachedRegisteredSyncGenerators = getCachedRegisteredSyncGenerators;
7
+ exports._getConflictingGeneratorGroups = _getConflictingGeneratorGroups;
7
8
  const nx_json_1 = require("../../config/nx-json");
8
9
  const tree_1 = require("../../generators/tree");
9
10
  const file_hasher_1 = require("../../hasher/file-hasher");
@@ -24,7 +25,6 @@ let storedNxJsonHash;
24
25
  const log = (...messageParts) => {
25
26
  logger_1.serverLogger.log('[SYNC]:', ...messageParts);
26
27
  };
27
- // TODO(leo): check conflicts and reuse the Tree where possible
28
28
  async function getCachedSyncGeneratorChanges(generators) {
29
29
  try {
30
30
  log('get sync generators changes on demand', generators);
@@ -36,51 +36,15 @@ async function getCachedSyncGeneratorChanges(generators) {
36
36
  }
37
37
  // reset the wait time
38
38
  waitPeriod = 100;
39
- let projects;
40
- let errored = false;
41
- const getProjectsConfigurations = async () => {
42
- if (projects || errored) {
43
- return projects;
44
- }
45
- const { projectGraph, error } = await (0, project_graph_incremental_recomputation_1.getCachedSerializedProjectGraphPromise)();
46
- projects = projectGraph
47
- ? (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph).projects
48
- : null;
49
- errored = error !== undefined;
50
- return projects;
51
- };
52
- return (await Promise.all(generators.map(async (generator) => {
53
- if (scheduledGenerators.has(generator) ||
54
- !syncGeneratorsCacheResultPromises.has(generator)) {
55
- // it's scheduled to run (there are pending changes to process) or
56
- // it's not scheduled and there's no cached result, so run it
57
- const projects = await getProjectsConfigurations();
58
- if (projects) {
59
- log(generator, 'already scheduled or not cached, running it now');
60
- runGenerator(generator, projects);
61
- }
62
- else {
63
- log(generator, 'already scheduled or not cached, project graph errored');
64
- /**
65
- * This should never happen. This is invoked imperatively, and by
66
- * the time it is invoked, the project graph would have already
67
- * been requested. If it errored, it would have been reported and
68
- * this wouldn't have been invoked. We handle it just in case.
69
- *
70
- * Since the project graph would be reported by the relevant
71
- * handlers separately, we just ignore the error, don't cache
72
- * any result and return an empty result, the next time this is
73
- * invoked the process will repeat until it eventually recovers
74
- * when the project graph is fixed.
75
- */
76
- return Promise.resolve({ changes: [], generatorName: generator });
77
- }
78
- }
79
- else {
80
- log(generator, 'not scheduled and has cached result, returning cached result');
81
- }
82
- return syncGeneratorsCacheResultPromises.get(generator);
83
- }))).flat();
39
+ const results = await getFromCacheOrRunGenerators(generators);
40
+ const conflicts = _getConflictingGeneratorGroups(results);
41
+ if (!conflicts.length) {
42
+ // there are no conflicts
43
+ return results;
44
+ }
45
+ // there are conflicts, so we need to re-run the conflicting generators
46
+ // using the same tree
47
+ return await processConflictingGenerators(conflicts, results);
84
48
  }
85
49
  catch (e) {
86
50
  console.error(e);
@@ -126,7 +90,7 @@ function collectAndScheduleSyncGenerators(projectGraph) {
126
90
  }
127
91
  const { projects } = (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph);
128
92
  for (const generator of scheduledGenerators) {
129
- runGenerator(generator, projects);
93
+ syncGeneratorsCacheResultPromises.set(generator, runGenerator(generator, projects));
130
94
  }
131
95
  await Promise.all(syncGeneratorsCacheResultPromises.values());
132
96
  }, waitPeriod);
@@ -143,6 +107,163 @@ async function getCachedRegisteredSyncGenerators() {
143
107
  }
144
108
  return [...registeredSyncGenerators];
145
109
  }
110
+ async function getFromCacheOrRunGenerators(generators) {
111
+ let projects;
112
+ let errored = false;
113
+ const getProjectsConfigurations = async () => {
114
+ if (projects || errored) {
115
+ return projects;
116
+ }
117
+ const { projectGraph, error } = await (0, project_graph_incremental_recomputation_1.getCachedSerializedProjectGraphPromise)();
118
+ projects = projectGraph
119
+ ? (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph).projects
120
+ : null;
121
+ errored = error !== undefined;
122
+ return projects;
123
+ };
124
+ return (await Promise.all(generators.map(async (generator) => {
125
+ if (scheduledGenerators.has(generator) ||
126
+ !syncGeneratorsCacheResultPromises.has(generator)) {
127
+ // it's scheduled to run (there are pending changes to process) or
128
+ // it's not scheduled and there's no cached result, so run it
129
+ const projects = await getProjectsConfigurations();
130
+ if (projects) {
131
+ log(generator, 'already scheduled or not cached, running it now');
132
+ syncGeneratorsCacheResultPromises.set(generator, runGenerator(generator, projects));
133
+ }
134
+ else {
135
+ log(generator, 'already scheduled or not cached, project graph errored');
136
+ /**
137
+ * This should never happen. This is invoked imperatively, and by
138
+ * the time it is invoked, the project graph would have already
139
+ * been requested. If it errored, it would have been reported and
140
+ * this wouldn't have been invoked. We handle it just in case.
141
+ *
142
+ * Since the project graph would be reported by the relevant
143
+ * handlers separately, we just ignore the error, don't cache
144
+ * any result and return an empty result, the next time this is
145
+ * invoked the process will repeat until it eventually recovers
146
+ * when the project graph is fixed.
147
+ */
148
+ return Promise.resolve({ changes: [], generatorName: generator });
149
+ }
150
+ }
151
+ else {
152
+ log(generator, 'not scheduled and has cached result, returning cached result');
153
+ }
154
+ return syncGeneratorsCacheResultPromises.get(generator);
155
+ }))).flat();
156
+ }
157
+ async function runConflictingGenerators(tree, generators) {
158
+ const { projectGraph } = await (0, project_graph_incremental_recomputation_1.getCachedSerializedProjectGraphPromise)();
159
+ const projects = projectGraph
160
+ ? (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph).projects
161
+ : null;
162
+ if (!projects) {
163
+ /**
164
+ * This should never happen. This is invoked imperatively, and by
165
+ * the time it is invoked, the project graph would have already
166
+ * been requested. If it errored, it would have been reported and
167
+ * this wouldn't have been invoked. We handle it just in case.
168
+ *
169
+ * Since the project graph would be reported by the relevant
170
+ * handlers separately, we just ignore the error.
171
+ */
172
+ return generators.map((generator) => ({
173
+ changes: [],
174
+ generatorName: generator,
175
+ }));
176
+ }
177
+ // we need to run conflicting generators sequentially because they use the same tree
178
+ const results = [];
179
+ for (const generator of generators) {
180
+ log(generator, 'running it now');
181
+ results.push(await runGenerator(generator, projects, tree));
182
+ }
183
+ return results;
184
+ }
185
+ async function processConflictingGenerators(conflicts, initialResults) {
186
+ const conflictRunResults = (await Promise.all(conflicts.map((generators) => {
187
+ const [firstGenerator, ...generatorsToRun] = generators;
188
+ // it must exists because the conflicts were identified from the initial results
189
+ const firstGeneratorResult = initialResults.find((r) => r.generatorName === firstGenerator);
190
+ const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, false, `running sync generators ${generators.join(',')}`);
191
+ // pre-apply the changes from the first generator to avoid running it
192
+ for (const change of firstGeneratorResult.changes) {
193
+ if (change.type === 'CREATE' || change.type === 'UPDATE') {
194
+ tree.write(change.path, change.content, change.options);
195
+ }
196
+ else if (change.type === 'DELETE') {
197
+ tree.delete(change.path);
198
+ }
199
+ }
200
+ /**
201
+ * We don't cache the results of conflicting generators because they
202
+ * use the same tree, so some files might contain results from multiple
203
+ * generators and we don't have guarantees that the same combination of
204
+ * generators will run together.
205
+ */
206
+ return runConflictingGenerators(tree, generatorsToRun);
207
+ }))).flat();
208
+ /**
209
+ * The order of the results from the re-run generators is important because
210
+ * the last result from a group of conflicting generators will contain the
211
+ * changes from the previous conflicting generators. So, instead of replacing
212
+ * in-place the initial results, we first add the results from the re-run
213
+ * generators, and then add the initial results that were not from a
214
+ * conflicting generator.
215
+ */
216
+ const results = [...conflictRunResults];
217
+ for (const result of initialResults) {
218
+ if (conflictRunResults.every((r) => r.generatorName !== result.generatorName)) {
219
+ // this result is not from a conflicting generator, so we add it to the
220
+ // results
221
+ results.push(result);
222
+ }
223
+ }
224
+ return results;
225
+ }
226
+ /**
227
+ * @internal
228
+ */
229
+ function _getConflictingGeneratorGroups(results) {
230
+ const changedFileToGeneratorMap = new Map();
231
+ for (const result of results) {
232
+ for (const change of result.changes) {
233
+ if (!changedFileToGeneratorMap.has(change.path)) {
234
+ changedFileToGeneratorMap.set(change.path, new Set());
235
+ }
236
+ changedFileToGeneratorMap.get(change.path).add(result.generatorName);
237
+ }
238
+ }
239
+ const conflicts = [];
240
+ for (const generatorSet of changedFileToGeneratorMap.values()) {
241
+ if (generatorSet.size === 1) {
242
+ // no conflicts
243
+ continue;
244
+ }
245
+ if (conflicts.length === 0) {
246
+ // there are no conflicts yet, so we just add the first group
247
+ conflicts.push(new Set(generatorSet));
248
+ continue;
249
+ }
250
+ // identify if any of the current generator sets intersect with any of the
251
+ // existing conflict groups
252
+ const generatorsArray = Array.from(generatorSet);
253
+ const existingConflictGroup = conflicts.find((group) => generatorsArray.some((generator) => group.has(generator)));
254
+ if (existingConflictGroup) {
255
+ // there's an intersecting group, so we merge the two
256
+ for (const generator of generatorsArray) {
257
+ existingConflictGroup.add(generator);
258
+ }
259
+ }
260
+ else {
261
+ // there's no intersecting group, so we create a new one
262
+ conflicts.push(new Set(generatorsArray));
263
+ }
264
+ }
265
+ return conflicts.map((group) => Array.from(group));
266
+ }
146
267
  function collectAllRegisteredSyncGenerators(projectGraph) {
147
268
  const projectGraphHash = hashProjectGraph(projectGraph);
148
269
  if (storedProjectGraphHash !== projectGraphHash) {
@@ -183,16 +304,15 @@ function collectAllRegisteredSyncGenerators(projectGraph) {
183
304
  }
184
305
  }
185
306
  }
186
- function runGenerator(generator, projects) {
307
+ function runGenerator(generator, projects, tree) {
187
308
  log('running scheduled generator', generator);
188
309
  // remove it from the scheduled set
189
310
  scheduledGenerators.delete(generator);
190
- const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, false, `running sync generator ${generator}`);
191
- // run the generator and cache the result
192
- syncGeneratorsCacheResultPromises.set(generator, (0, sync_generators_1.runSyncGenerator)(tree, generator, projects).then((result) => {
311
+ tree ??= new tree_1.FsTree(workspace_root_1.workspaceRoot, false, `running sync generator ${generator}`);
312
+ return (0, sync_generators_1.runSyncGenerator)(tree, generator, projects).then((result) => {
193
313
  log(generator, 'changes:', result.changes.map((c) => c.path).join(', '));
194
314
  return result;
195
- }));
315
+ });
196
316
  }
197
317
  function hashProjectGraph(projectGraph) {
198
318
  const stringifiedProjects = Object.entries(projectGraph.nodes)
@@ -18,12 +18,7 @@ async function default_1(tree) {
18
18
  if (!target.outputs) {
19
19
  continue;
20
20
  }
21
- try {
22
- (0, utils_1.validateOutputs)(target.outputs);
23
- }
24
- catch (e) {
25
- target.outputs = (0, utils_1.transformLegacyOutputs)(project.root, e);
26
- }
21
+ target.outputs = (0, utils_1.transformLegacyOutputs)(project.root, target.outputs);
27
22
  }
28
23
  try {
29
24
  (0, project_configuration_1.updateProjectConfiguration)(tree, projectName, project);
@@ -33,12 +28,7 @@ async function default_1(tree) {
33
28
  (0, json_1.updateJson)(tree, (0, path_1.join)(project.root, 'package.json'), (json) => {
34
29
  for (const target of Object.values(json.nx?.targets ?? {})) {
35
30
  if (target.outputs) {
36
- try {
37
- (0, utils_1.validateOutputs)(target.outputs);
38
- }
39
- catch (e) {
40
- target.outputs = (0, utils_1.transformLegacyOutputs)(project.root, e);
41
- }
31
+ target.outputs = (0, utils_1.transformLegacyOutputs)(project.root, target.outputs);
42
32
  }
43
33
  }
44
34
  return json;
@@ -51,12 +41,7 @@ async function default_1(tree) {
51
41
  if (!target.outputs) {
52
42
  continue;
53
43
  }
54
- try {
55
- (0, utils_1.validateOutputs)(target.outputs);
56
- }
57
- catch (e) {
58
- target.outputs = (0, utils_1.transformLegacyOutputs)('{projectRoot}', e);
59
- }
44
+ target.outputs = (0, utils_1.transformLegacyOutputs)('{projectRoot}', target.outputs);
60
45
  }
61
46
  (0, nx_json_1.updateNxJson)(tree, nxJson);
62
47
  }
@@ -124,6 +124,8 @@ export declare export function getBinaryTarget(): string
124
124
  */
125
125
  export declare export function getFilesForOutputs(directory: string, entries: Array<string>): Array<string>
126
126
 
127
+ export declare export function getTransformableOutputs(outputs: Array<string>): Array<string>
128
+
127
129
  export declare export function hashArray(input: Array<string>): string
128
130
 
129
131
  export interface HashDetails {
@@ -222,6 +224,8 @@ export interface UpdatedWorkspaceFiles {
222
224
  externalReferences: NxWorkspaceFilesExternals
223
225
  }
224
226
 
227
+ export declare export function validateOutputs(outputs: Array<string>): void
228
+
225
229
  export interface WatchEvent {
226
230
  path: string
227
231
  type: EventType
@@ -374,10 +374,12 @@ module.exports.expandOutputs = nativeBinding.expandOutputs
374
374
  module.exports.findImports = nativeBinding.findImports
375
375
  module.exports.getBinaryTarget = nativeBinding.getBinaryTarget
376
376
  module.exports.getFilesForOutputs = nativeBinding.getFilesForOutputs
377
+ module.exports.getTransformableOutputs = nativeBinding.getTransformableOutputs
377
378
  module.exports.hashArray = nativeBinding.hashArray
378
379
  module.exports.hashFile = nativeBinding.hashFile
379
380
  module.exports.IS_WASM = nativeBinding.IS_WASM
380
381
  module.exports.remove = nativeBinding.remove
381
382
  module.exports.testOnlyTransferFileMap = nativeBinding.testOnlyTransferFileMap
382
383
  module.exports.transferProjectGraph = nativeBinding.transferProjectGraph
384
+ module.exports.validateOutputs = nativeBinding.validateOutputs
383
385
  module.exports.WorkspaceErrors = nativeBinding.WorkspaceErrors
@@ -14,7 +14,7 @@ const __wasi = new __WASI({
14
14
  const __emnapiContext = __emnapiGetDefaultContext()
15
15
 
16
16
  const __sharedMemory = new WebAssembly.Memory({
17
- initial: 16384,
17
+ initial: 1024,
18
18
  maximum: 32768,
19
19
  shared: true,
20
20
  })
@@ -55,41 +55,44 @@ function __napi_rs_initialize_modules(__napiInstance) {
55
55
  __napiInstance.exports['__napi_register__get_files_for_outputs_1']?.()
56
56
  __napiInstance.exports['__napi_register__remove_2']?.()
57
57
  __napiInstance.exports['__napi_register__copy_3']?.()
58
- __napiInstance.exports['__napi_register__hash_array_4']?.()
59
- __napiInstance.exports['__napi_register__hash_file_5']?.()
60
- __napiInstance.exports['__napi_register__ImportResult_struct_6']?.()
61
- __napiInstance.exports['__napi_register__find_imports_7']?.()
62
- __napiInstance.exports['__napi_register__transfer_project_graph_8']?.()
63
- __napiInstance.exports['__napi_register__ExternalNode_struct_9']?.()
64
- __napiInstance.exports['__napi_register__Target_struct_10']?.()
65
- __napiInstance.exports['__napi_register__Project_struct_11']?.()
66
- __napiInstance.exports['__napi_register__ProjectGraph_struct_12']?.()
67
- __napiInstance.exports['__napi_register__HashPlanner_struct_13']?.()
68
- __napiInstance.exports['__napi_register__HashPlanner_impl_17']?.()
69
- __napiInstance.exports['__napi_register__HashDetails_struct_18']?.()
70
- __napiInstance.exports['__napi_register__HasherOptions_struct_19']?.()
71
- __napiInstance.exports['__napi_register__TaskHasher_struct_20']?.()
72
- __napiInstance.exports['__napi_register__TaskHasher_impl_23']?.()
73
- __napiInstance.exports['__napi_register__Task_struct_24']?.()
74
- __napiInstance.exports['__napi_register__TaskTarget_struct_25']?.()
75
- __napiInstance.exports['__napi_register__TaskGraph_struct_26']?.()
76
- __napiInstance.exports['__napi_register__FileData_struct_27']?.()
77
- __napiInstance.exports['__napi_register__InputsInput_struct_28']?.()
78
- __napiInstance.exports['__napi_register__FileSetInput_struct_29']?.()
79
- __napiInstance.exports['__napi_register__RuntimeInput_struct_30']?.()
80
- __napiInstance.exports['__napi_register__EnvironmentInput_struct_31']?.()
81
- __napiInstance.exports['__napi_register__ExternalDependenciesInput_struct_32']?.()
82
- __napiInstance.exports['__napi_register__DepsOutputsInput_struct_33']?.()
83
- __napiInstance.exports['__napi_register__NxJson_struct_34']?.()
84
- __napiInstance.exports['__napi_register__WorkspaceContext_struct_35']?.()
85
- __napiInstance.exports['__napi_register__WorkspaceContext_impl_44']?.()
86
- __napiInstance.exports['__napi_register__WorkspaceErrors_45']?.()
87
- __napiInstance.exports['__napi_register__NxWorkspaceFiles_struct_46']?.()
88
- __napiInstance.exports['__napi_register__NxWorkspaceFilesExternals_struct_47']?.()
89
- __napiInstance.exports['__napi_register__UpdatedWorkspaceFiles_struct_48']?.()
90
- __napiInstance.exports['__napi_register__FileMap_struct_49']?.()
91
- __napiInstance.exports['__napi_register____test_only_transfer_file_map_50']?.()
92
- __napiInstance.exports['__napi_register__IS_WASM_51']?.()
58
+ __napiInstance.exports['__napi_register__validate_outputs_4']?.()
59
+ __napiInstance.exports['__napi_register__get_transformable_outputs_5']?.()
60
+ __napiInstance.exports['__napi_register__hash_array_6']?.()
61
+ __napiInstance.exports['__napi_register__hash_file_7']?.()
62
+ __napiInstance.exports['__napi_register__IS_WASM_8']?.()
63
+ __napiInstance.exports['__napi_register__get_binary_target_9']?.()
64
+ __napiInstance.exports['__napi_register__ImportResult_struct_10']?.()
65
+ __napiInstance.exports['__napi_register__find_imports_11']?.()
66
+ __napiInstance.exports['__napi_register__transfer_project_graph_12']?.()
67
+ __napiInstance.exports['__napi_register__ExternalNode_struct_13']?.()
68
+ __napiInstance.exports['__napi_register__Target_struct_14']?.()
69
+ __napiInstance.exports['__napi_register__Project_struct_15']?.()
70
+ __napiInstance.exports['__napi_register__ProjectGraph_struct_16']?.()
71
+ __napiInstance.exports['__napi_register__HashPlanner_struct_17']?.()
72
+ __napiInstance.exports['__napi_register__HashPlanner_impl_21']?.()
73
+ __napiInstance.exports['__napi_register__HashDetails_struct_22']?.()
74
+ __napiInstance.exports['__napi_register__HasherOptions_struct_23']?.()
75
+ __napiInstance.exports['__napi_register__TaskHasher_struct_24']?.()
76
+ __napiInstance.exports['__napi_register__TaskHasher_impl_27']?.()
77
+ __napiInstance.exports['__napi_register__Task_struct_28']?.()
78
+ __napiInstance.exports['__napi_register__TaskTarget_struct_29']?.()
79
+ __napiInstance.exports['__napi_register__TaskGraph_struct_30']?.()
80
+ __napiInstance.exports['__napi_register__FileData_struct_31']?.()
81
+ __napiInstance.exports['__napi_register__InputsInput_struct_32']?.()
82
+ __napiInstance.exports['__napi_register__FileSetInput_struct_33']?.()
83
+ __napiInstance.exports['__napi_register__RuntimeInput_struct_34']?.()
84
+ __napiInstance.exports['__napi_register__EnvironmentInput_struct_35']?.()
85
+ __napiInstance.exports['__napi_register__ExternalDependenciesInput_struct_36']?.()
86
+ __napiInstance.exports['__napi_register__DepsOutputsInput_struct_37']?.()
87
+ __napiInstance.exports['__napi_register__NxJson_struct_38']?.()
88
+ __napiInstance.exports['__napi_register__WorkspaceContext_struct_39']?.()
89
+ __napiInstance.exports['__napi_register__WorkspaceContext_impl_48']?.()
90
+ __napiInstance.exports['__napi_register__WorkspaceErrors_49']?.()
91
+ __napiInstance.exports['__napi_register__NxWorkspaceFiles_struct_50']?.()
92
+ __napiInstance.exports['__napi_register__NxWorkspaceFilesExternals_struct_51']?.()
93
+ __napiInstance.exports['__napi_register__UpdatedWorkspaceFiles_struct_52']?.()
94
+ __napiInstance.exports['__napi_register__FileMap_struct_53']?.()
95
+ __napiInstance.exports['__napi_register____test_only_transfer_file_map_54']?.()
93
96
  }
94
97
  export const HashPlanner = __napiModule.exports.HashPlanner
95
98
  export const ImportResult = __napiModule.exports.ImportResult
@@ -98,11 +101,14 @@ export const WorkspaceContext = __napiModule.exports.WorkspaceContext
98
101
  export const copy = __napiModule.exports.copy
99
102
  export const expandOutputs = __napiModule.exports.expandOutputs
100
103
  export const findImports = __napiModule.exports.findImports
104
+ export const getBinaryTarget = __napiModule.exports.getBinaryTarget
101
105
  export const getFilesForOutputs = __napiModule.exports.getFilesForOutputs
106
+ export const getTransformableOutputs = __napiModule.exports.getTransformableOutputs
102
107
  export const hashArray = __napiModule.exports.hashArray
103
108
  export const hashFile = __napiModule.exports.hashFile
104
109
  export const IS_WASM = __napiModule.exports.IS_WASM
105
110
  export const remove = __napiModule.exports.remove
106
111
  export const testOnlyTransferFileMap = __napiModule.exports.testOnlyTransferFileMap
107
112
  export const transferProjectGraph = __napiModule.exports.transferProjectGraph
113
+ export const validateOutputs = __napiModule.exports.validateOutputs
108
114
  export const WorkspaceErrors = __napiModule.exports.WorkspaceErrors
@@ -86,42 +86,44 @@ function __napi_rs_initialize_modules(__napiInstance) {
86
86
  __napiInstance.exports['__napi_register__get_files_for_outputs_1']?.()
87
87
  __napiInstance.exports['__napi_register__remove_2']?.()
88
88
  __napiInstance.exports['__napi_register__copy_3']?.()
89
- __napiInstance.exports['__napi_register__hash_array_4']?.()
90
- __napiInstance.exports['__napi_register__hash_file_5']?.()
91
- __napiInstance.exports['__napi_register__IS_WASM_6']?.()
92
- __napiInstance.exports['__napi_register__get_binary_target_7']?.()
93
- __napiInstance.exports['__napi_register__ImportResult_struct_8']?.()
94
- __napiInstance.exports['__napi_register__find_imports_9']?.()
95
- __napiInstance.exports['__napi_register__transfer_project_graph_10']?.()
96
- __napiInstance.exports['__napi_register__ExternalNode_struct_11']?.()
97
- __napiInstance.exports['__napi_register__Target_struct_12']?.()
98
- __napiInstance.exports['__napi_register__Project_struct_13']?.()
99
- __napiInstance.exports['__napi_register__ProjectGraph_struct_14']?.()
100
- __napiInstance.exports['__napi_register__HashPlanner_struct_15']?.()
101
- __napiInstance.exports['__napi_register__HashPlanner_impl_19']?.()
102
- __napiInstance.exports['__napi_register__HashDetails_struct_20']?.()
103
- __napiInstance.exports['__napi_register__HasherOptions_struct_21']?.()
104
- __napiInstance.exports['__napi_register__TaskHasher_struct_22']?.()
105
- __napiInstance.exports['__napi_register__TaskHasher_impl_25']?.()
106
- __napiInstance.exports['__napi_register__Task_struct_26']?.()
107
- __napiInstance.exports['__napi_register__TaskTarget_struct_27']?.()
108
- __napiInstance.exports['__napi_register__TaskGraph_struct_28']?.()
109
- __napiInstance.exports['__napi_register__FileData_struct_29']?.()
110
- __napiInstance.exports['__napi_register__InputsInput_struct_30']?.()
111
- __napiInstance.exports['__napi_register__FileSetInput_struct_31']?.()
112
- __napiInstance.exports['__napi_register__RuntimeInput_struct_32']?.()
113
- __napiInstance.exports['__napi_register__EnvironmentInput_struct_33']?.()
114
- __napiInstance.exports['__napi_register__ExternalDependenciesInput_struct_34']?.()
115
- __napiInstance.exports['__napi_register__DepsOutputsInput_struct_35']?.()
116
- __napiInstance.exports['__napi_register__NxJson_struct_36']?.()
117
- __napiInstance.exports['__napi_register__WorkspaceContext_struct_37']?.()
118
- __napiInstance.exports['__napi_register__WorkspaceContext_impl_46']?.()
119
- __napiInstance.exports['__napi_register__WorkspaceErrors_47']?.()
120
- __napiInstance.exports['__napi_register__NxWorkspaceFiles_struct_48']?.()
121
- __napiInstance.exports['__napi_register__NxWorkspaceFilesExternals_struct_49']?.()
122
- __napiInstance.exports['__napi_register__UpdatedWorkspaceFiles_struct_50']?.()
123
- __napiInstance.exports['__napi_register__FileMap_struct_51']?.()
124
- __napiInstance.exports['__napi_register____test_only_transfer_file_map_52']?.()
89
+ __napiInstance.exports['__napi_register__validate_outputs_4']?.()
90
+ __napiInstance.exports['__napi_register__get_transformable_outputs_5']?.()
91
+ __napiInstance.exports['__napi_register__hash_array_6']?.()
92
+ __napiInstance.exports['__napi_register__hash_file_7']?.()
93
+ __napiInstance.exports['__napi_register__IS_WASM_8']?.()
94
+ __napiInstance.exports['__napi_register__get_binary_target_9']?.()
95
+ __napiInstance.exports['__napi_register__ImportResult_struct_10']?.()
96
+ __napiInstance.exports['__napi_register__find_imports_11']?.()
97
+ __napiInstance.exports['__napi_register__transfer_project_graph_12']?.()
98
+ __napiInstance.exports['__napi_register__ExternalNode_struct_13']?.()
99
+ __napiInstance.exports['__napi_register__Target_struct_14']?.()
100
+ __napiInstance.exports['__napi_register__Project_struct_15']?.()
101
+ __napiInstance.exports['__napi_register__ProjectGraph_struct_16']?.()
102
+ __napiInstance.exports['__napi_register__HashPlanner_struct_17']?.()
103
+ __napiInstance.exports['__napi_register__HashPlanner_impl_21']?.()
104
+ __napiInstance.exports['__napi_register__HashDetails_struct_22']?.()
105
+ __napiInstance.exports['__napi_register__HasherOptions_struct_23']?.()
106
+ __napiInstance.exports['__napi_register__TaskHasher_struct_24']?.()
107
+ __napiInstance.exports['__napi_register__TaskHasher_impl_27']?.()
108
+ __napiInstance.exports['__napi_register__Task_struct_28']?.()
109
+ __napiInstance.exports['__napi_register__TaskTarget_struct_29']?.()
110
+ __napiInstance.exports['__napi_register__TaskGraph_struct_30']?.()
111
+ __napiInstance.exports['__napi_register__FileData_struct_31']?.()
112
+ __napiInstance.exports['__napi_register__InputsInput_struct_32']?.()
113
+ __napiInstance.exports['__napi_register__FileSetInput_struct_33']?.()
114
+ __napiInstance.exports['__napi_register__RuntimeInput_struct_34']?.()
115
+ __napiInstance.exports['__napi_register__EnvironmentInput_struct_35']?.()
116
+ __napiInstance.exports['__napi_register__ExternalDependenciesInput_struct_36']?.()
117
+ __napiInstance.exports['__napi_register__DepsOutputsInput_struct_37']?.()
118
+ __napiInstance.exports['__napi_register__NxJson_struct_38']?.()
119
+ __napiInstance.exports['__napi_register__WorkspaceContext_struct_39']?.()
120
+ __napiInstance.exports['__napi_register__WorkspaceContext_impl_48']?.()
121
+ __napiInstance.exports['__napi_register__WorkspaceErrors_49']?.()
122
+ __napiInstance.exports['__napi_register__NxWorkspaceFiles_struct_50']?.()
123
+ __napiInstance.exports['__napi_register__NxWorkspaceFilesExternals_struct_51']?.()
124
+ __napiInstance.exports['__napi_register__UpdatedWorkspaceFiles_struct_52']?.()
125
+ __napiInstance.exports['__napi_register__FileMap_struct_53']?.()
126
+ __napiInstance.exports['__napi_register____test_only_transfer_file_map_54']?.()
125
127
  }
126
128
  module.exports.HashPlanner = __napiModule.exports.HashPlanner
127
129
  module.exports.ImportResult = __napiModule.exports.ImportResult
@@ -132,10 +134,12 @@ module.exports.expandOutputs = __napiModule.exports.expandOutputs
132
134
  module.exports.findImports = __napiModule.exports.findImports
133
135
  module.exports.getBinaryTarget = __napiModule.exports.getBinaryTarget
134
136
  module.exports.getFilesForOutputs = __napiModule.exports.getFilesForOutputs
137
+ module.exports.getTransformableOutputs = __napiModule.exports.getTransformableOutputs
135
138
  module.exports.hashArray = __napiModule.exports.hashArray
136
139
  module.exports.hashFile = __napiModule.exports.hashFile
137
140
  module.exports.IS_WASM = __napiModule.exports.IS_WASM
138
141
  module.exports.remove = __napiModule.exports.remove
139
142
  module.exports.testOnlyTransferFileMap = __napiModule.exports.testOnlyTransferFileMap
140
143
  module.exports.transferProjectGraph = __napiModule.exports.transferProjectGraph
144
+ module.exports.validateOutputs = __napiModule.exports.validateOutputs
141
145
  module.exports.WorkspaceErrors = __napiModule.exports.WorkspaceErrors
Binary file
@@ -273,7 +273,7 @@ async function startPluginWorker() {
273
273
  socket,
274
274
  });
275
275
  }
276
- else if (attempts > 1000) {
276
+ else if (attempts > 10000) {
277
277
  // daemon fails to start, the process probably exited
278
278
  // we print the logs and exit the client
279
279
  reject('Failed to start plugin worker.');
@@ -118,6 +118,9 @@ async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs
118
118
  }
119
119
  async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions) {
120
120
  let taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
121
+ if (nxArgs.skipSync) {
122
+ return { projectGraph, taskGraph };
123
+ }
121
124
  // collect unique syncGenerators from the tasks
122
125
  const uniqueSyncGenerators = new Set();
123
126
  for (const { target } of Object.values(taskGraph.tasks)) {
@@ -141,7 +144,7 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
141
144
  }
142
145
  const outOfSyncTitle = 'The workspace is out of sync';
143
146
  const resultBodyLines = [...(0, sync_generators_1.syncGeneratorResultsToMessageLines)(results), ''];
144
- const fixMessage = 'You can manually run `nx sync` to update your workspace or you can set `sync.applyChanges` to `true` in your `nx.json` to apply the changes automatically when running tasks.';
147
+ const fixMessage = 'You can manually run `nx sync` to update your workspace or you can set `sync.applyChanges` to `true` in your `nx.json` to apply the changes automatically when running tasks in interactive environments.';
145
148
  const willErrorOnCiMessage = 'Please note that this will be an error on CI.';
146
149
  if ((0, is_ci_1.isCI)() || !process.stdout.isTTY) {
147
150
  // If the user is running in CI or is running in a non-TTY environment we
@@ -21,14 +21,8 @@ export declare function getOutputs(p: Record<string, ProjectGraphProjectNode>, t
21
21
  export declare function normalizeTargetDependencyWithStringProjects(dependencyConfig: TargetDependencyConfig): Omit<TargetDependencyConfig, 'projects'> & {
22
22
  projects: string[];
23
23
  };
24
- declare class InvalidOutputsError extends Error {
25
- outputs: string[];
26
- invalidOutputs: Set<string>;
27
- constructor(outputs: string[], invalidOutputs: Set<string>);
28
- private static createMessage;
29
- }
30
24
  export declare function validateOutputs(outputs: string[]): void;
31
- export declare function transformLegacyOutputs(projectRoot: string, error: InvalidOutputsError): string[];
25
+ export declare function transformLegacyOutputs(projectRoot: string, outputs: string[]): string[];
32
26
  /**
33
27
  * @deprecated Pass the target and overrides instead. This will be removed in v20.
34
28
  */
@@ -61,4 +55,3 @@ export declare function isCacheableTask(task: Task, options: {
61
55
  cacheableTargets?: string[] | null;
62
56
  }): boolean;
63
57
  export declare function unparse(options: Object): string[];
64
- export {};
@@ -37,6 +37,7 @@ const project_graph_1 = require("../project-graph/project-graph");
37
37
  const find_matching_projects_1 = require("../utils/find-matching-projects");
38
38
  const minimatch_1 = require("minimatch");
39
39
  const globs_1 = require("../utils/globs");
40
+ const native_1 = require("../native");
40
41
  function getDependencyConfigs({ project, target }, extraTargetDependencies, projectGraph, allTargetNames) {
41
42
  const dependencyConfigs = (projectGraph.nodes[project].data?.targets[target]?.dependsOn ??
42
43
  // This is passed into `run-command` from programmatic invocations
@@ -177,19 +178,15 @@ function assertOutputsAreValidType(outputs) {
177
178
  }
178
179
  function validateOutputs(outputs) {
179
180
  assertOutputsAreValidType(outputs);
180
- const invalidOutputs = new Set();
181
- for (const output of outputs) {
182
- if (!/^!?{[\s\S]+}/.test(output)) {
183
- invalidOutputs.add(output);
184
- }
185
- }
186
- if (invalidOutputs.size > 0) {
187
- throw new InvalidOutputsError(outputs, invalidOutputs);
188
- }
181
+ (0, native_1.validateOutputs)(outputs);
189
182
  }
190
- function transformLegacyOutputs(projectRoot, error) {
191
- return error.outputs.map((output) => {
192
- if (!error.invalidOutputs.has(output)) {
183
+ function transformLegacyOutputs(projectRoot, outputs) {
184
+ const transformableOutputs = new Set((0, native_1.getTransformableOutputs)(outputs));
185
+ if (transformableOutputs.size === 0) {
186
+ return outputs;
187
+ }
188
+ return outputs.map((output) => {
189
+ if (!transformableOutputs.has(output)) {
193
190
  return output;
194
191
  }
195
192
  let [isNegated, outputPath] = output.startsWith('!')