nx 17.0.1 → 17.0.3

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 (41) hide show
  1. package/changelog-renderer/index.d.ts +43 -0
  2. package/changelog-renderer/index.js +180 -0
  3. package/package.json +12 -13
  4. package/schemas/nx-schema.json +141 -0
  5. package/src/adapter/ngcli-adapter.js +32 -0
  6. package/src/command-line/init/implementation/add-nx-to-monorepo.js +1 -0
  7. package/src/command-line/init/implementation/add-nx-to-nest.js +1 -0
  8. package/src/command-line/init/implementation/add-nx-to-npm-repo.js +1 -0
  9. package/src/command-line/init/implementation/utils.d.ts +1 -0
  10. package/src/command-line/init/implementation/utils.js +14 -1
  11. package/src/command-line/release/changelog.js +332 -75
  12. package/src/command-line/release/command-object.d.ts +1 -3
  13. package/src/command-line/release/command-object.js +3 -17
  14. package/src/command-line/release/config/config.d.ts +1 -1
  15. package/src/command-line/release/config/config.js +153 -50
  16. package/src/command-line/release/utils/markdown.d.ts +1 -4
  17. package/src/command-line/release/utils/markdown.js +3 -136
  18. package/src/command-line/release/utils/print-changes.d.ts +5 -1
  19. package/src/command-line/release/utils/print-changes.js +3 -2
  20. package/src/command-line/show/show.js +2 -0
  21. package/src/config/nx-json.d.ts +80 -3
  22. package/src/config/nx-json.js +1 -1
  23. package/src/config/project-graph.d.ts +1 -1
  24. package/src/daemon/client/client.js +0 -6
  25. package/src/daemon/server/outputs-tracking.d.ts +2 -2
  26. package/src/daemon/server/outputs-tracking.js +2 -2
  27. package/src/daemon/server/project-graph-incremental-recomputation.js +1 -28
  28. package/src/daemon/server/server.js +22 -58
  29. package/src/daemon/server/shutdown-utils.d.ts +0 -6
  30. package/src/daemon/server/shutdown-utils.js +1 -36
  31. package/src/daemon/server/watcher.d.ts +2 -6
  32. package/src/daemon/server/watcher.js +1 -92
  33. package/src/generators/utils/project-configuration.js +10 -8
  34. package/src/migrations/update-15-0-0/prefix-outputs.js +9 -9
  35. package/src/project-graph/project-graph.js +6 -1
  36. package/src/project-graph/utils/normalize-project-nodes.js +4 -1
  37. package/src/project-graph/utils/retrieve-workspace-files.js +3 -1
  38. package/src/tasks-runner/utils.js +8 -4
  39. package/src/utils/package-manager.d.ts +1 -0
  40. package/src/utils/package-manager.js +5 -2
  41. package/src/utils/params.js +19 -4
@@ -1,31 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.startServer = exports.handleResult = void 0;
4
- const workspace_root_1 = require("../../utils/workspace-root");
4
+ const fs_1 = require("fs");
5
5
  const net_1 = require("net");
6
6
  const path_1 = require("path");
7
7
  const perf_hooks_1 = require("perf_hooks");
8
- const socket_utils_1 = require("../socket-utils");
9
- const logger_1 = require("./logger");
10
- const shutdown_utils_1 = require("./shutdown-utils");
11
- const watcher_1 = require("./watcher");
12
- const project_graph_incremental_recomputation_1 = require("./project-graph-incremental-recomputation");
13
- const fs_1 = require("fs");
14
- const handle_request_project_graph_1 = require("./handle-request-project-graph");
15
- const handle_process_in_background_1 = require("./handle-process-in-background");
16
- const handle_outputs_tracking_1 = require("./handle-outputs-tracking");
8
+ const file_hasher_1 = require("../../hasher/file-hasher");
9
+ const native_1 = require("../../native");
17
10
  const consume_messages_from_socket_1 = require("../../utils/consume-messages-from-socket");
18
- const outputs_tracking_1 = require("./outputs-tracking");
19
- const handle_request_shutdown_1 = require("./handle-request-shutdown");
20
- const file_watcher_sockets_1 = require("./file-watching/file-watcher-sockets");
21
- const versions_1 = require("../../utils/versions");
22
11
  const fileutils_1 = require("../../utils/fileutils");
12
+ const versions_1 = require("../../utils/versions");
13
+ const workspace_context_1 = require("../../utils/workspace-context");
14
+ const workspace_root_1 = require("../../utils/workspace-root");
23
15
  const cache_1 = require("../cache");
16
+ const socket_utils_1 = require("../socket-utils");
17
+ const file_watcher_sockets_1 = require("./file-watching/file-watcher-sockets");
24
18
  const handle_hash_tasks_1 = require("./handle-hash-tasks");
25
- const file_hasher_1 = require("../../hasher/file-hasher");
19
+ const handle_outputs_tracking_1 = require("./handle-outputs-tracking");
20
+ const handle_process_in_background_1 = require("./handle-process-in-background");
26
21
  const handle_request_file_data_1 = require("./handle-request-file-data");
27
- const workspace_context_1 = require("../../utils/workspace-context");
28
- const native_1 = require("../../native");
22
+ const handle_request_project_graph_1 = require("./handle-request-project-graph");
23
+ const handle_request_shutdown_1 = require("./handle-request-shutdown");
24
+ const logger_1 = require("./logger");
25
+ const outputs_tracking_1 = require("./outputs-tracking");
26
+ const project_graph_incremental_recomputation_1 = require("./project-graph-incremental-recomputation");
27
+ const shutdown_utils_1 = require("./shutdown-utils");
28
+ const watcher_1 = require("./watcher");
29
29
  let performanceObserver;
30
30
  let workspaceWatcherError;
31
31
  let outputsWatcherError;
@@ -55,7 +55,6 @@ const server = (0, net_1.createServer)(async (socket) => {
55
55
  });
56
56
  });
57
57
  registerProcessTerminationListeners();
58
- registerProcessServerJsonTracking();
59
58
  async function handleMessage(socket, data) {
60
59
  if (workspaceWatcherError) {
61
60
  await (0, shutdown_utils_1.respondWithErrorAndExit)(socket, `File watcher error in the workspace '${workspace_root_1.workspaceRoot}'.`, workspaceWatcherError);
@@ -147,19 +146,6 @@ function registerProcessTerminationListeners() {
147
146
  reason: 'received process SIGHUP',
148
147
  }));
149
148
  }
150
- async function registerProcessServerJsonTracking() {
151
- if (useNativeWatcher()) {
152
- return;
153
- }
154
- (0, shutdown_utils_1.storeProcessJsonSubscription)(await (0, watcher_1.subscribeToServerProcessJsonChanges)(async () => {
155
- if ((0, cache_1.getDaemonProcessIdSync)() !== process.pid) {
156
- await (0, shutdown_utils_1.handleServerProcessTermination)({
157
- server,
158
- reason: 'this process is no longer the current daemon',
159
- });
160
- }
161
- }));
162
- }
163
149
  let existingLockHash;
164
150
  function daemonIsOutdated() {
165
151
  return nxVersionChanged() || lockFileHashChanged();
@@ -295,30 +281,12 @@ async function startServer() {
295
281
  logger_1.serverLogger.log(`Started listening on: ${socket_utils_1.FULL_OS_SOCKET_PATH}`);
296
282
  // this triggers the storage of the lock file hash
297
283
  daemonIsOutdated();
298
- if (useNativeWatcher()) {
299
- if (!(0, shutdown_utils_1.getWatcherInstance)()) {
300
- (0, shutdown_utils_1.storeWatcherInstance)(await (0, watcher_1.watchWorkspace)(server, handleWorkspaceChanges));
301
- logger_1.serverLogger.watcherLog(`Subscribed to changes within: ${workspace_root_1.workspaceRoot} (native)`);
302
- }
303
- if (!(0, shutdown_utils_1.getOutputWatcherInstance)()) {
304
- (0, shutdown_utils_1.storeOutputWatcherInstance)(await (0, watcher_1.watchOutputFiles)(handleOutputsChanges));
305
- }
284
+ if (!(0, shutdown_utils_1.getWatcherInstance)()) {
285
+ (0, shutdown_utils_1.storeWatcherInstance)(await (0, watcher_1.watchWorkspace)(server, handleWorkspaceChanges));
286
+ logger_1.serverLogger.watcherLog(`Subscribed to changes within: ${workspace_root_1.workspaceRoot} (native)`);
306
287
  }
307
- else {
308
- if (!(0, shutdown_utils_1.getSourceWatcherSubscription)()) {
309
- (0, shutdown_utils_1.storeSourceWatcherSubscription)(await (0, watcher_1.subscribeToWorkspaceChanges)(server, handleWorkspaceChanges));
310
- logger_1.serverLogger.watcherLog(`Subscribed to changes within: ${workspace_root_1.workspaceRoot}`);
311
- }
312
- // temporary disable outputs tracking on linux
313
- const outputsTrackingIsEnabled = process.platform != 'linux';
314
- if (outputsTrackingIsEnabled) {
315
- if (!(0, shutdown_utils_1.getOutputsWatcherSubscription)()) {
316
- (0, shutdown_utils_1.storeOutputsWatcherSubscription)(await (0, watcher_1.subscribeToOutputsChanges)(handleOutputsChanges));
317
- }
318
- }
319
- else {
320
- (0, outputs_tracking_1.disableOutputsTracking)();
321
- }
288
+ if (!(0, shutdown_utils_1.getOutputWatcherInstance)()) {
289
+ (0, shutdown_utils_1.storeOutputWatcherInstance)(await (0, watcher_1.watchOutputFiles)(handleOutputsChanges));
322
290
  }
323
291
  return resolve(server);
324
292
  }
@@ -333,7 +301,3 @@ async function startServer() {
333
301
  });
334
302
  }
335
303
  exports.startServer = startServer;
336
- // TODO(cammisuli): remove with nx 16.6 (only our watcher will be supported)
337
- function useNativeWatcher() {
338
- return process.env.NX_NATIVE_WATCHER === 'true';
339
- }
@@ -1,13 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import type { Server, Socket } from 'net';
3
- import type { AsyncSubscription } from '@parcel/watcher';
4
3
  import type { Watcher } from '../../native';
5
4
  export declare const SERVER_INACTIVITY_TIMEOUT_MS: 10800000;
6
- export declare function getSourceWatcherSubscription(): AsyncSubscription;
7
- export declare function storeSourceWatcherSubscription(s: AsyncSubscription): void;
8
- export declare function getOutputsWatcherSubscription(): AsyncSubscription;
9
- export declare function storeOutputsWatcherSubscription(s: AsyncSubscription): void;
10
- export declare function storeProcessJsonSubscription(s: AsyncSubscription): void;
11
5
  export declare function storeWatcherInstance(instance: Watcher): void;
12
6
  export declare function getWatcherInstance(): Watcher;
13
7
  export declare function storeOutputWatcherInstance(instance: Watcher): void;
@@ -1,34 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.respondWithErrorAndExit = exports.respondToClient = exports.resetInactivityTimeout = exports.handleServerProcessTermination = exports.getOutputWatcherInstance = exports.storeOutputWatcherInstance = exports.getWatcherInstance = exports.storeWatcherInstance = exports.storeProcessJsonSubscription = exports.storeOutputsWatcherSubscription = exports.getOutputsWatcherSubscription = exports.storeSourceWatcherSubscription = exports.getSourceWatcherSubscription = exports.SERVER_INACTIVITY_TIMEOUT_MS = void 0;
3
+ exports.respondWithErrorAndExit = exports.respondToClient = exports.resetInactivityTimeout = exports.handleServerProcessTermination = exports.getOutputWatcherInstance = exports.storeOutputWatcherInstance = exports.getWatcherInstance = exports.storeWatcherInstance = exports.SERVER_INACTIVITY_TIMEOUT_MS = void 0;
4
4
  const workspace_root_1 = require("../../utils/workspace-root");
5
5
  const logger_1 = require("./logger");
6
6
  const socket_utils_1 = require("../socket-utils");
7
7
  const cache_1 = require("../cache");
8
8
  exports.SERVER_INACTIVITY_TIMEOUT_MS = 10800000; // 10800000 ms = 3 hours
9
- let sourceWatcherSubscription;
10
- let outputsWatcherSubscription;
11
- function getSourceWatcherSubscription() {
12
- return sourceWatcherSubscription;
13
- }
14
- exports.getSourceWatcherSubscription = getSourceWatcherSubscription;
15
- function storeSourceWatcherSubscription(s) {
16
- sourceWatcherSubscription = s;
17
- }
18
- exports.storeSourceWatcherSubscription = storeSourceWatcherSubscription;
19
- function getOutputsWatcherSubscription() {
20
- return outputsWatcherSubscription;
21
- }
22
- exports.getOutputsWatcherSubscription = getOutputsWatcherSubscription;
23
- function storeOutputsWatcherSubscription(s) {
24
- outputsWatcherSubscription = s;
25
- }
26
- exports.storeOutputsWatcherSubscription = storeOutputsWatcherSubscription;
27
- let processJsonSubscription;
28
- function storeProcessJsonSubscription(s) {
29
- processJsonSubscription = s;
30
- }
31
- exports.storeProcessJsonSubscription = storeProcessJsonSubscription;
32
9
  let watcherInstance;
33
10
  function storeWatcherInstance(instance) {
34
11
  watcherInstance = instance;
@@ -51,18 +28,6 @@ async function handleServerProcessTermination({ server, reason, }) {
51
28
  try {
52
29
  server.close();
53
30
  (0, cache_1.deleteDaemonJsonProcessCache)();
54
- if (sourceWatcherSubscription) {
55
- await sourceWatcherSubscription.unsubscribe();
56
- logger_1.serverLogger.watcherLog(`Unsubscribed from changes within: ${workspace_root_1.workspaceRoot} (sources)`);
57
- }
58
- if (outputsWatcherSubscription) {
59
- await outputsWatcherSubscription.unsubscribe();
60
- logger_1.serverLogger.watcherLog(`Unsubscribed from changes within: ${workspace_root_1.workspaceRoot} (outputs)`);
61
- }
62
- if (processJsonSubscription) {
63
- await processJsonSubscription.unsubscribe();
64
- logger_1.serverLogger.watcherLog(`Unsubscribed from changes within: ${workspace_root_1.workspaceRoot} (server-process.json)`);
65
- }
66
31
  if (watcherInstance) {
67
32
  await watcherInstance.stop();
68
33
  logger_1.serverLogger.watcherLog(`Stopping the watcher for ${workspace_root_1.workspaceRoot} (sources)`);
@@ -1,16 +1,12 @@
1
1
  /// <reference types="node" />
2
- import type { AsyncSubscription, Event } from '@parcel/watcher';
3
2
  import { Server } from 'net';
4
3
  import type { WatchEvent } from '../../native';
5
- export type FileWatcherCallback = (err: Error | string | null, changeEvents: Event[] | WatchEvent[] | null) => Promise<void>;
6
- export declare function subscribeToOutputsChanges(cb: FileWatcherCallback): Promise<AsyncSubscription>;
4
+ export type FileWatcherCallback = (err: Error | string | null, changeEvents: WatchEvent[] | null) => Promise<void>;
7
5
  export declare function watchWorkspace(server: Server, cb: FileWatcherCallback): Promise<import("../../native").Watcher>;
8
6
  export declare function watchOutputFiles(cb: FileWatcherCallback): Promise<import("../../native").Watcher>;
9
- export declare function subscribeToWorkspaceChanges(server: Server, cb: FileWatcherCallback): Promise<AsyncSubscription>;
10
- export declare function subscribeToServerProcessJsonChanges(cb: () => void): Promise<AsyncSubscription>;
11
7
  /**
12
8
  * NOTE: An event type of "create" will also apply to the case where the user has restored
13
9
  * an original version of a file after modifying/deleting it by using git, so we adjust
14
10
  * our log language accordingly.
15
11
  */
16
- export declare function convertChangeEventsToLogMessage(changeEvents: Event[]): string;
12
+ export declare function convertChangeEventsToLogMessage(changeEvents: WatchEvent[]): string;
@@ -1,42 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertChangeEventsToLogMessage = exports.subscribeToServerProcessJsonChanges = exports.subscribeToWorkspaceChanges = exports.watchOutputFiles = exports.watchWorkspace = exports.subscribeToOutputsChanges = void 0;
4
- /**
5
- * In addition to its native performance, another great advantage of `@parcel/watcher` is that it will
6
- * automatically take advantage of Facebook's watchman tool (https://facebook.github.io/watchman/) if
7
- * the user has it installed (but not require it if they don't).
8
- *
9
- * See https://github.com/parcel-bundler/watcher for more details.
10
- */
3
+ exports.convertChangeEventsToLogMessage = exports.watchOutputFiles = exports.watchWorkspace = void 0;
11
4
  const workspace_root_1 = require("../../utils/workspace-root");
12
5
  const path_1 = require("path");
13
6
  const socket_utils_1 = require("../socket-utils");
14
7
  const shutdown_utils_1 = require("./shutdown-utils");
15
8
  const path_2 = require("../../utils/path");
16
9
  const ignore_1 = require("../../utils/ignore");
17
- const os_1 = require("os");
18
10
  const cache_1 = require("../cache");
19
11
  const ALWAYS_IGNORE = [...(0, ignore_1.getAlwaysIgnore)(workspace_root_1.workspaceRoot), socket_utils_1.FULL_OS_SOCKET_PATH];
20
- async function subscribeToOutputsChanges(cb) {
21
- const watcher = await Promise.resolve().then(() => require('@parcel/watcher'));
22
- return await watcher.subscribe(workspace_root_1.workspaceRoot, (err, events) => {
23
- if (err) {
24
- return cb(err, null);
25
- }
26
- else {
27
- const workspaceRelativeEvents = [];
28
- for (const event of events) {
29
- const workspaceRelativeEvent = {
30
- type: event.type,
31
- path: (0, path_2.normalizePath)((0, path_1.relative)(workspace_root_1.workspaceRoot, event.path)),
32
- };
33
- workspaceRelativeEvents.push(workspaceRelativeEvent);
34
- }
35
- cb(null, workspaceRelativeEvents);
36
- }
37
- }, watcherOptions([...ALWAYS_IGNORE]));
38
- }
39
- exports.subscribeToOutputsChanges = subscribeToOutputsChanges;
40
12
  async function watchWorkspace(server, cb) {
41
13
  const { Watcher } = await Promise.resolve().then(() => require('../../native'));
42
14
  let relativeServerProcess = (0, path_2.normalizePath)((0, path_1.relative)(workspace_root_1.workspaceRoot, cache_1.serverProcessJsonPath));
@@ -83,60 +55,6 @@ async function watchOutputFiles(cb) {
83
55
  return watcher;
84
56
  }
85
57
  exports.watchOutputFiles = watchOutputFiles;
86
- async function subscribeToWorkspaceChanges(server, cb) {
87
- /**
88
- * The imports and exports of @nx/workspace are somewhat messy and far reaching across the repo (and beyond),
89
- * and so it is much safer for us to lazily load here `@parcel/watcher` so that its inclusion is not inadvertently
90
- * executed by packages which do not have its necessary native binaries available.
91
- */
92
- const watcher = await Promise.resolve().then(() => require('@parcel/watcher'));
93
- const ignoreObj = (0, ignore_1.getIgnoreObject)();
94
- return await watcher.subscribe(workspace_root_1.workspaceRoot, (err, events) => {
95
- if (err) {
96
- return cb(err, null);
97
- }
98
- let hasIgnoreFileUpdate = false;
99
- // Most of our utilities (ignore, hashing etc) require unix-style workspace relative paths
100
- const workspaceRelativeEvents = [];
101
- for (const event of events) {
102
- const workspaceRelativeEvent = {
103
- type: event.type,
104
- path: (0, path_2.normalizePath)((0, path_1.relative)(workspace_root_1.workspaceRoot, event.path)),
105
- };
106
- if (workspaceRelativeEvent.path.endsWith('.gitignore') ||
107
- workspaceRelativeEvent.path === '.nxignore') {
108
- hasIgnoreFileUpdate = true;
109
- }
110
- workspaceRelativeEvents.push(workspaceRelativeEvent);
111
- }
112
- // If the ignore files themselves have changed we need to dynamically update our cached ignoreGlobs
113
- if (hasIgnoreFileUpdate) {
114
- (0, shutdown_utils_1.handleServerProcessTermination)({
115
- server,
116
- reason: 'Stopping the daemon the set of ignored files changed.',
117
- });
118
- }
119
- const nonIgnoredEvents = workspaceRelativeEvents
120
- .filter(({ path }) => !!path)
121
- .filter(({ path }) => !ignoreObj.ignores(path));
122
- if (nonIgnoredEvents && nonIgnoredEvents.length > 0) {
123
- cb(null, nonIgnoredEvents);
124
- }
125
- }, watcherOptions((0, ignore_1.getIgnoredGlobs)(workspace_root_1.workspaceRoot)));
126
- }
127
- exports.subscribeToWorkspaceChanges = subscribeToWorkspaceChanges;
128
- // TODO: When we update @parcel/watcher to a version that handles negation globs, then this can be folded into the workspace watcher
129
- async function subscribeToServerProcessJsonChanges(cb) {
130
- const watcher = await Promise.resolve().then(() => require('@parcel/watcher'));
131
- return await watcher.subscribe((0, path_1.dirname)(cache_1.serverProcessJsonPath), (err, events) => {
132
- for (const event of events) {
133
- if (event.path === cache_1.serverProcessJsonPath) {
134
- cb();
135
- }
136
- }
137
- }, watcherOptions([]));
138
- }
139
- exports.subscribeToServerProcessJsonChanges = subscribeToServerProcessJsonChanges;
140
58
  /**
141
59
  * NOTE: An event type of "create" will also apply to the case where the user has restored
142
60
  * an original version of a file after modifying/deleting it by using git, so we adjust
@@ -179,12 +97,3 @@ function convertChangeEventsToLogMessage(changeEvents) {
179
97
  return `${numCreatedOrRestoredFiles} file(s) created or restored, ${numModifiedFiles} file(s) modified, ${numDeletedFiles} file(s) deleted`;
180
98
  }
181
99
  exports.convertChangeEventsToLogMessage = convertChangeEventsToLogMessage;
182
- function watcherOptions(ignore) {
183
- const options = {
184
- ignore,
185
- };
186
- if ((0, os_1.platform)() === 'win32') {
187
- options.backend = 'windows';
188
- }
189
- return options;
190
- }
@@ -143,16 +143,18 @@ function readAndCombineAllProjectConfigurations(tree) {
143
143
  const config = (0, project_json_1.buildProjectFromProjectJson)(json, projectFile);
144
144
  (0, project_configuration_utils_1.mergeProjectConfigurationIntoRootMap)(rootMap, config);
145
145
  }
146
- else {
146
+ else if ((0, path_1.basename)(projectFile) === 'package.json') {
147
147
  const packageJson = (0, json_1.readJson)(tree, projectFile);
148
148
  const config = (0, package_json_workspaces_1.buildProjectConfigurationFromPackageJson)(packageJson, projectFile, (0, nx_json_1.readNxJson)(tree));
149
- (0, project_configuration_utils_1.mergeProjectConfigurationIntoRootMap)(rootMap,
150
- // Inferred targets, tags, etc don't show up when running generators
151
- // This is to help avoid running into issues when trying to update the workspace
152
- {
153
- name: config.name,
154
- root: config.root,
155
- });
149
+ if (!rootMap.has(config.root)) {
150
+ (0, project_configuration_utils_1.mergeProjectConfigurationIntoRootMap)(rootMap,
151
+ // Inferred targets, tags, etc don't show up when running generators
152
+ // This is to help avoid running into issues when trying to update the workspace
153
+ {
154
+ name: config.name,
155
+ root: config.root,
156
+ });
157
+ }
156
158
  }
157
159
  }
158
160
  return (0, project_configuration_utils_1.readProjectConfigurationsFromRootMap)(rootMap);
@@ -3,8 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const format_changed_files_with_prettier_if_available_1 = require("../../generators/internal-utils/format-changed-files-with-prettier-if-available");
4
4
  const project_configuration_1 = require("../../generators/utils/project-configuration");
5
5
  const nx_json_1 = require("../../generators/utils/nx-json");
6
- const path_1 = require("../../utils/path");
7
- const path_2 = require("path");
6
+ const path_1 = require("path");
8
7
  const utils_1 = require("../../tasks-runner/utils");
9
8
  const json_1 = require("../../generators/utils/json");
10
9
  async function default_1(tree) {
@@ -29,8 +28,8 @@ async function default_1(tree) {
29
28
  (0, project_configuration_1.updateProjectConfiguration)(tree, projectName, project);
30
29
  }
31
30
  catch {
32
- if (tree.exists((0, path_2.join)(project.root, 'package.json'))) {
33
- (0, json_1.updateJson)(tree, (0, path_2.join)(project.root, 'package.json'), (json) => {
31
+ if (tree.exists((0, path_1.join)(project.root, 'package.json'))) {
32
+ (0, json_1.updateJson)(tree, (0, path_1.join)(project.root, 'package.json'), (json) => {
34
33
  for (const target of Object.values(json.nx?.targets ?? {})) {
35
34
  if (target.outputs) {
36
35
  try {
@@ -51,11 +50,12 @@ async function default_1(tree) {
51
50
  if (!target.outputs) {
52
51
  continue;
53
52
  }
54
- target.outputs = target.outputs.map((output) => {
55
- return /^{[\s\S]+}/.test(output)
56
- ? output
57
- : (0, path_1.joinPathFragments)('{workspaceRoot}', output);
58
- });
53
+ try {
54
+ (0, utils_1.validateOutputs)(target.outputs);
55
+ }
56
+ catch (e) {
57
+ target.outputs = (0, utils_1.transformLegacyOutputs)('{projectRoot}', e);
58
+ }
59
59
  }
60
60
  (0, nx_json_1.updateNxJson)(tree, nxJson);
61
61
  }
@@ -44,7 +44,12 @@ exports.readCachedProjectGraph = readCachedProjectGraph;
44
44
  function readCachedProjectConfiguration(projectName) {
45
45
  const graph = readCachedProjectGraph();
46
46
  const node = graph.nodes[projectName];
47
- return node.data;
47
+ try {
48
+ return node.data;
49
+ }
50
+ catch (e) {
51
+ throw new Error(`Cannot find project: '${projectName}' in your workspace.`);
52
+ }
48
53
  }
49
54
  exports.readCachedProjectConfiguration = readCachedProjectConfiguration;
50
55
  /**
@@ -6,7 +6,10 @@ const logger_1 = require("../../utils/logger");
6
6
  const project_configuration_utils_1 = require("../utils/project-configuration-utils");
7
7
  async function normalizeProjectNodes(ctx, builder, nxJson) {
8
8
  const toAdd = [];
9
- const projects = Object.keys(ctx.projects);
9
+ // Sorting projects by name to make sure that the order of projects in the graph is deterministic.
10
+ // This is important to ensure that expanded properties referencing projects (e.g. implicit dependencies)
11
+ // are also deterministic, and thus don't cause the calculated project configuration hash to shift.
12
+ const projects = Object.keys(ctx.projects).sort();
10
13
  // Used for expanding implicit dependencies (e.g. `@proj/*` or `tag:foo`)
11
14
  const partialProjectGraphNodes = projects.reduce((graph, project) => {
12
15
  const projectConfiguration = ctx.projects[project];
@@ -121,7 +121,9 @@ exports.retrieveProjectConfigurationsWithoutPluginInference = retrieveProjectCon
121
121
  function buildAllWorkspaceFiles(projectFileMap, globalFiles) {
122
122
  perf_hooks_1.performance.mark('get-all-workspace-files:start');
123
123
  let fileData = Object.values(projectFileMap).flat();
124
- fileData = fileData.concat(globalFiles);
124
+ fileData = fileData
125
+ .concat(globalFiles)
126
+ .sort((a, b) => a.file.localeCompare(b.file));
125
127
  perf_hooks_1.performance.mark('get-all-workspace-files:end');
126
128
  perf_hooks_1.performance.measure('get-all-workspace-files', 'get-all-workspace-files:start', 'get-all-workspace-files:end');
127
129
  return fileData;
@@ -80,7 +80,7 @@ class InvalidOutputsError extends Error {
80
80
  function validateOutputs(outputs) {
81
81
  const invalidOutputs = new Set();
82
82
  for (const output of outputs) {
83
- if (!/^{[\s\S]+}/.test(output)) {
83
+ if (!/^!?{[\s\S]+}/.test(output)) {
84
84
  invalidOutputs.add(output);
85
85
  }
86
86
  }
@@ -94,11 +94,15 @@ function transformLegacyOutputs(projectRoot, error) {
94
94
  if (!error.invalidOutputs.has(output)) {
95
95
  return output;
96
96
  }
97
- const relativePath = (0, fileutils_1.isRelativePath)(output)
97
+ let [isNegated, outputPath] = output.startsWith('!')
98
+ ? [true, output.substring(1)]
99
+ : [false, output];
100
+ const relativePath = (0, fileutils_1.isRelativePath)(outputPath)
98
101
  ? output
99
- : (0, path_1.relative)(projectRoot, output);
102
+ : (0, path_1.relative)(projectRoot, outputPath);
100
103
  const isWithinProject = !relativePath.startsWith('..');
101
- return (0, path_2.joinPathFragments)(isWithinProject ? '{projectRoot}' : '{workspaceRoot}', isWithinProject ? relativePath : output);
104
+ return ((isNegated ? '!' : '') +
105
+ (0, path_2.joinPathFragments)(isWithinProject ? '{projectRoot}' : '{workspaceRoot}', isWithinProject ? relativePath : outputPath));
102
106
  });
103
107
  }
104
108
  exports.transformLegacyOutputs = transformLegacyOutputs;
@@ -7,6 +7,7 @@ export interface PackageManagerCommands {
7
7
  addDev: string;
8
8
  rm: string;
9
9
  exec: string;
10
+ dlx: string;
10
11
  list: string;
11
12
  run: (script: string, args: string) => string;
12
13
  }
@@ -55,13 +55,14 @@ function getPackageManagerCommand(packageManager = detectPackageManager(), root
55
55
  addDev: useBerry ? 'yarn add -D' : 'yarn add -D -W',
56
56
  rm: 'yarn remove',
57
57
  exec: 'yarn',
58
+ dlx: useBerry ? 'yarn dlx' : 'yarn',
58
59
  run: (script, args) => `yarn ${script} ${args}`,
59
60
  list: useBerry ? 'yarn info --name-only' : 'yarn list',
60
61
  };
61
62
  },
62
63
  pnpm: () => {
63
64
  const pnpmVersion = getPackageManagerVersion('pnpm', root);
64
- const useExec = (0, semver_1.gte)(pnpmVersion, '6.13.0');
65
+ const modernPnpm = (0, semver_1.gte)(pnpmVersion, '6.13.0');
65
66
  const includeDoubleDashBeforeArgs = (0, semver_1.lt)(pnpmVersion, '7.0.0');
66
67
  const isPnpmWorkspace = (0, fs_1.existsSync)((0, path_1.join)(root, 'pnpm-workspace.yaml'));
67
68
  return {
@@ -70,7 +71,8 @@ function getPackageManagerCommand(packageManager = detectPackageManager(), root
70
71
  add: isPnpmWorkspace ? 'pnpm add -w' : 'pnpm add',
71
72
  addDev: isPnpmWorkspace ? 'pnpm add -Dw' : 'pnpm add -D',
72
73
  rm: 'pnpm rm',
73
- exec: useExec ? 'pnpm exec' : 'pnpx',
74
+ exec: modernPnpm ? 'pnpm exec' : 'pnpx',
75
+ dlx: modernPnpm ? 'pnpm dlx' : 'pnpx',
74
76
  run: (script, args) => includeDoubleDashBeforeArgs
75
77
  ? `pnpm run ${script} -- ${args}`
76
78
  : `pnpm run ${script} ${args}`,
@@ -87,6 +89,7 @@ function getPackageManagerCommand(packageManager = detectPackageManager(), root
87
89
  addDev: 'npm install -D',
88
90
  rm: 'npm rm',
89
91
  exec: 'npx',
92
+ dlx: 'npx',
90
93
  run: (script, args) => `npm run ${script} -- ${args}`,
91
94
  list: 'npm ls',
92
95
  };
@@ -532,10 +532,25 @@ function getPromptsForSchema(opts, schema, projectsConfigurations) {
532
532
  // Normalize x-prompt
533
533
  if (typeof v['x-prompt'] === 'string') {
534
534
  const message = v['x-prompt'];
535
- v['x-prompt'] = {
536
- type: v.type === 'boolean' ? 'confirm' : 'input',
537
- message,
538
- };
535
+ if (v.type === 'boolean') {
536
+ v['x-prompt'] = {
537
+ type: 'confirm',
538
+ message,
539
+ };
540
+ }
541
+ else if (v.type === 'array' && v.items?.enum) {
542
+ v['x-prompt'] = {
543
+ type: 'multiselect',
544
+ items: v.items.enum,
545
+ message,
546
+ };
547
+ }
548
+ else {
549
+ v['x-prompt'] = {
550
+ type: 'input',
551
+ message,
552
+ };
553
+ }
539
554
  }
540
555
  question.message = v['x-prompt'].message;
541
556
  question.validate = (s) => {