nx 23.3.0-beta.1 → 23.3.0-beta.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 (51) hide show
  1. package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +0 -3
  2. package/dist/src/command-line/init/implementation/add-nx-to-nest.js +0 -3
  3. package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +0 -3
  4. package/dist/src/command-line/init/implementation/angular/index.js +0 -3
  5. package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +0 -3
  6. package/dist/src/command-line/init/implementation/utils.d.ts +0 -1
  7. package/dist/src/command-line/init/implementation/utils.js +0 -8
  8. package/dist/src/command-line/init/init-v2.js +0 -3
  9. package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +0 -10
  10. package/dist/src/core/graph/main.js +1 -1
  11. package/dist/src/daemon/client/client.d.ts +2 -0
  12. package/dist/src/daemon/client/client.js +7 -0
  13. package/dist/src/daemon/message-types/get-plugin-capabilities.d.ts +5 -0
  14. package/dist/src/daemon/message-types/get-plugin-capabilities.js +11 -0
  15. package/dist/src/daemon/server/handle-get-plugin-capabilities.d.ts +2 -0
  16. package/dist/src/daemon/server/handle-get-plugin-capabilities.js +13 -0
  17. package/dist/src/daemon/server/project-graph-incremental-recomputation.js +1 -1
  18. package/dist/src/daemon/server/server.js +5 -0
  19. package/dist/src/native/index.d.ts +20 -0
  20. package/dist/src/native/native-bindings.js +1 -0
  21. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  22. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  23. package/dist/src/project-graph/affected/locators/project-glob-changes.js +19 -26
  24. package/dist/src/project-graph/error-types.d.ts +5 -0
  25. package/dist/src/project-graph/error-types.js +44 -5
  26. package/dist/src/project-graph/file-utils.d.ts +2 -0
  27. package/dist/src/project-graph/file-utils.js +6 -1
  28. package/dist/src/project-graph/nx-deps-cache.d.ts +5 -2
  29. package/dist/src/project-graph/nx-deps-cache.js +4 -4
  30. package/dist/src/project-graph/plugins/get-plugins.d.ts +3 -1
  31. package/dist/src/project-graph/plugins/get-plugins.js +60 -82
  32. package/dist/src/project-graph/plugins/in-process-loader.d.ts +1 -1
  33. package/dist/src/project-graph/plugins/in-process-loader.js +1 -4
  34. package/dist/src/project-graph/plugins/isolation/index.d.ts +1 -1
  35. package/dist/src/project-graph/plugins/isolation/index.js +3 -1
  36. package/dist/src/project-graph/plugins/isolation/isolated-plugin.d.ts +8 -0
  37. package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +40 -5
  38. package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.d.ts +10 -1
  39. package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.js +67 -17
  40. package/dist/src/project-graph/plugins/loaded-nx-plugin.d.ts +2 -0
  41. package/dist/src/project-graph/plugins/loaded-nx-plugin.js +9 -0
  42. package/dist/src/project-graph/plugins/nx-plugin-capabilities.d.ts +6 -0
  43. package/dist/src/project-graph/plugins/nx-plugin-capabilities.js +28 -0
  44. package/dist/src/project-graph/plugins/tasks-execution-hooks.js +12 -0
  45. package/dist/src/project-graph/project-graph.js +41 -42
  46. package/dist/src/utils/ab-testing.d.ts +1 -1
  47. package/dist/src/utils/ab-testing.js +0 -4
  48. package/dist/src/utils/handle-errors.js +5 -43
  49. package/dist/src/utils/plugins/plugin-capabilities.js +7 -2
  50. package/dist/src/utils/serialize-overrides-into-command-line.js +2 -4
  51. package/package.json +11 -12
@@ -30,6 +30,7 @@ const workspace_context_1 = require("../utils/workspace-context");
30
30
  const build_project_graph_1 = require("./build-project-graph");
31
31
  const error_types_1 = require("./error-types");
32
32
  const nx_deps_cache_1 = require("./nx-deps-cache");
33
+ const nx_plugin_capabilities_1 = require("./plugins/nx-plugin-capabilities");
33
34
  const get_plugins_1 = require("./plugins/get-plugins");
34
35
  const retrieve_workspace_files_1 = require("./utils/retrieve-workspace-files");
35
36
  const handle_import_1 = require("../utils/handle-import");
@@ -40,16 +41,21 @@ const handle_import_1 = require("../utils/handle-import");
40
41
  * @throws {Error} if there is no cached ProjectGraph to read from
41
42
  */
42
43
  function readCachedProjectGraph(minimumComputedAt) {
43
- const projectGraphCache = (0, nx_deps_cache_1.readProjectGraphCache)(minimumComputedAt);
44
- if (!projectGraphCache) {
45
- const angularSpecificError = (0, fileutils_1.fileExists)(`${workspace_root_1.workspaceRoot}/angular.json`)
46
- ? (0, strip_indents_1.stripIndents) `
44
+ const cached = (0, nx_deps_cache_1.readProjectGraphCache)(minimumComputedAt);
45
+ if (!cached) {
46
+ throw noCachedProjectGraphError();
47
+ }
48
+ return cached.projectGraph;
49
+ }
50
+ function noCachedProjectGraphError() {
51
+ const angularSpecificError = (0, fileutils_1.fileExists)(`${workspace_root_1.workspaceRoot}/angular.json`)
52
+ ? (0, strip_indents_1.stripIndents) `
47
53
  Make sure invoke 'node ./decorate-angular-cli.js' in your postinstall script.
48
54
  The decorated CLI will compute the project graph.
49
55
  'ng --help' should say 'Smart Monorepos · Fast Builds'.
50
56
  `
51
- : '';
52
- throw new Error((0, strip_indents_1.stripIndents) `
57
+ : '';
58
+ return new Error((0, strip_indents_1.stripIndents) `
53
59
  [readCachedProjectGraph] ERROR: No cached ProjectGraph is available.
54
60
 
55
61
  If you are leveraging \`readCachedProjectGraph()\` directly then you will need to refactor your usage to first ensure that
@@ -59,8 +65,6 @@ function readCachedProjectGraph(minimumComputedAt) {
59
65
 
60
66
  ${angularSpecificError}
61
67
  `);
62
- }
63
- return projectGraphCache;
64
68
  }
65
69
  function readCachedProjectConfiguration(projectName) {
66
70
  const graph = readCachedProjectGraph();
@@ -86,6 +90,8 @@ function readProjectsConfigurationFromProjectGraph(projectGraph) {
86
90
  }
87
91
  async function buildProjectGraphAndSourceMapsWithoutDaemon() {
88
92
  preventRecursionInGraphConstruction();
93
+ // Answer from the plugins loaded below, not an earlier cached graph's rows.
94
+ (0, nx_plugin_capabilities_1.noteGraphReadFromCache)(undefined);
89
95
  global.NX_GRAPH_CREATION = true;
90
96
  const nxJson = (0, nx_json_1.readNxJson)();
91
97
  (0, workspace_context_1.refreshWorkspaceContext)(workspace_root_1.workspaceRoot);
@@ -138,7 +144,12 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
138
144
  ...(projectGraphError?.errors ?? []),
139
145
  ];
140
146
  if (cacheEnabled) {
141
- (0, nx_deps_cache_1.writeCache)(projectFileMapCache, projectGraph, sourceMaps, errors);
147
+ const computedAt = Date.now();
148
+ // Before the graph, so a cached graph never lacks its row.
149
+ if (errors.length === 0) {
150
+ (0, nx_plugin_capabilities_1.getNxPluginCapabilitiesStore)()?.record(computedAt, plugins.map((plugin) => plugin.capabilities()));
151
+ }
152
+ (0, nx_deps_cache_1.writeCache)(projectFileMapCache, projectGraph, sourceMaps, errors, computedAt);
142
153
  }
143
154
  if (errors.length > 0) {
144
155
  throw new error_types_1.ProjectGraphError(errors, projectGraph, sourceMaps);
@@ -151,14 +162,7 @@ function handleProjectGraphError(opts, e) {
151
162
  if (opts.exitOnError) {
152
163
  const isVerbose = process.env.NX_VERBOSE_LOGGING === 'true';
153
164
  if (e instanceof error_types_1.ProjectGraphError) {
154
- let title = e.message;
155
- const bodyLines = isVerbose
156
- ? [e.stack]
157
- : ['Pass --verbose to see the stacktraces.'];
158
- output_1.output.error({
159
- title,
160
- bodyLines: bodyLines,
161
- });
165
+ output_1.output.error((0, error_types_1.formatProjectGraphError)(e, isVerbose));
162
166
  }
163
167
  else if (typeof e.message === 'string') {
164
168
  const lines = e.message.split('\n');
@@ -180,7 +184,12 @@ function handleProjectGraphError(opts, e) {
180
184
  }
181
185
  }
182
186
  async function readCachedGraphAndHydrateFileMap(minimumComputedAt) {
183
- const graph = readCachedProjectGraph(minimumComputedAt);
187
+ const cached = (0, nx_deps_cache_1.readProjectGraphCache)(minimumComputedAt);
188
+ if (!cached) {
189
+ throw noCachedProjectGraphError();
190
+ }
191
+ const graph = cached.projectGraph;
192
+ (0, nx_plugin_capabilities_1.noteGraphReadFromCache)(cached.computedAt);
184
193
  const projectRootMap = Object.fromEntries(Object.entries(graph.nodes).map(([project, { data }]) => [
185
194
  data.root,
186
195
  project,
@@ -262,45 +271,33 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
262
271
  const lock = !native_1.IS_WASM
263
272
  ? new native_1.FileLock((0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'project-graph.lock'))
264
273
  : null;
265
- let locked = lock?.locked;
266
- while (locked) {
274
+ let holdingLock = lock?.tryLock() ?? false;
275
+ while (lock && !holdingLock) {
267
276
  logger_1.logger.verbose('Waiting for graph construction in another process to complete');
268
277
  const spinner = new delayed_spinner_1.DelayedSpinner('Waiting for graph construction in another process to complete');
269
278
  const start = Date.now();
270
- await lock.wait();
271
- spinner.cleanup();
272
- // Note: This will currently throw if any of the caches are missing...
273
- // It would be nice if one of the processes that was waiting for the lock
274
- // could pick up the slack and build the graph if it's missing, but
275
- // we wouldn't want either of the below to happen:
276
- // - All of the waiting processes to build the graph
277
- // - Even one of the processes building the graph on a legitimate error
278
279
  try {
279
- // Ensuring that computedAt was after this process started
280
- // waiting for the graph to complete, means that the graph
281
- // was computed by the process was already working.
280
+ await lock.wait();
281
+ // A graph computed after this process started waiting is the holder's.
282
282
  const graph = await readCachedGraphAndHydrateFileMap(start);
283
283
  const sourceMaps = (0, nx_deps_cache_1.readSourceMapsCache)();
284
284
  if (!sourceMaps) {
285
285
  throw new Error('The project graph was computed in another process, but the source maps are missing.');
286
286
  }
287
- return {
288
- projectGraph: graph,
289
- sourceMaps,
290
- };
287
+ return { projectGraph: graph, sourceMaps };
291
288
  }
292
289
  catch (e) {
293
- // If the error is that the cached graph is stale after unlock,
294
- // the process that was working on the graph must have been canceled,
295
- // so we will fall through to the normal flow to ensure
296
- // its created by one of the processes that was waiting
297
290
  if (!(e instanceof error_types_1.StaleProjectGraphCacheError)) {
298
291
  throw e;
299
292
  }
293
+ // The holder stopped without writing a graph: build it here, or wait for
294
+ // whoever took the lock first.
295
+ holdingLock = lock.tryLock();
296
+ }
297
+ finally {
298
+ spinner.cleanup();
300
299
  }
301
- locked = lock.check();
302
300
  }
303
- lock?.lock();
304
301
  try {
305
302
  const res = await buildProjectGraphAndSourceMapsWithoutDaemon();
306
303
  perf_hooks_1.performance.measure('createProjectGraphAsync >> retrieve-project-configurations', 'retrieve-project-configurations:start', 'retrieve-project-configurations:end');
@@ -325,7 +322,9 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
325
322
  handleProjectGraphError(opts, e);
326
323
  }
327
324
  finally {
328
- lock?.unlock();
325
+ if (holdingLock) {
326
+ lock.unlock();
327
+ }
329
328
  }
330
329
  }
331
330
  else {
@@ -28,7 +28,7 @@ export interface RecordStatMetaError {
28
28
  [key: string]: string | boolean;
29
29
  }
30
30
  export type RecordStatMeta = RecordStatMetaStart | RecordStatMetaComplete | RecordStatMetaError;
31
- export type MessageOptionKey = 'yes' | 'skip' | 'never';
31
+ export type MessageOptionKey = 'yes' | 'skip';
32
32
  interface MessageData {
33
33
  code: string;
34
34
  message: string;
@@ -4,13 +4,11 @@ exports.messages = exports.PromptMessages = exports.NX_CLOUD_DEMO_URL = exports.
4
4
  exports.nxCloudHyperlink = nxCloudHyperlink;
5
5
  exports.nxCloudDemoHyperlink = nxCloudDemoHyperlink;
6
6
  exports.recordStat = recordStat;
7
- const tslib_1 = require("tslib");
8
7
  const node_child_process_1 = require("node:child_process");
9
8
  const is_ci_1 = require("./is-ci");
10
9
  const package_manager_1 = require("./package-manager");
11
10
  const get_cloud_options_1 = require("../nx-cloud/utilities/get-cloud-options");
12
11
  const terminal_link_1 = require("./terminal-link");
13
- const pc = tslib_1.__importStar(require("picocolors"));
14
12
  exports.NX_CLOUD_URL = 'https://nx.dev/nx-cloud';
15
13
  exports.NX_CLOUD_DEMO_URL = 'https://cloud.nx.app/demo/intro';
16
14
  /**
@@ -39,7 +37,6 @@ const messageOptions = {
39
37
  choices: [
40
38
  { value: 'yes', name: 'Yes' },
41
39
  { value: 'skip', name: 'Skip for now' },
42
- { value: 'never', name: pc.dim("No, don't ask again") },
43
40
  ],
44
41
  footer: '\nFree for small teams. Remote caching and task distribution. 2-minute setup:',
45
42
  },
@@ -50,7 +47,6 @@ const messageOptions = {
50
47
  choices: [
51
48
  { value: 'yes', name: 'Yes' },
52
49
  { value: 'skip', name: 'Skip for now' },
53
- { value: 'never', name: pc.dim("No, don't ask again") },
54
50
  ],
55
51
  footer: '\nLearn about it at',
56
52
  hint: `\n(it's free and can be disabled any time)`,
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleErrors = handleErrors;
4
+ const error_types_1 = require("../project-graph/error-types");
4
5
  const logger_1 = require("./logger");
5
6
  const output_1 = require("./output");
6
7
  const handle_import_1 = require("./handle-import");
@@ -17,35 +18,9 @@ async function handleErrors(isVerbose, fn) {
17
18
  if (err.constructor.name === 'UnsuccessfulWorkflowExecution') {
18
19
  logger_1.logger.error('The generator workflow failed. See above.');
19
20
  }
20
- else if (err.name === 'ProjectGraphError') {
21
- const projectGraphError = err;
22
- let title = projectGraphError.message;
23
- if (projectGraphError.cause &&
24
- typeof projectGraphError.cause === 'object' &&
25
- 'message' in projectGraphError.cause) {
26
- title += ' ' + projectGraphError.cause.message + '.';
27
- }
28
- output_1.output.error({
29
- title,
30
- bodyLines: isVerbose
31
- ? formatErrorStackAndCause(projectGraphError, isVerbose)
32
- : projectGraphError.getErrors().map((e) => e.message),
33
- });
34
- }
35
- else if (err.name === 'ProjectConfigurationsError') {
36
- const projectConfigurationsError = err;
37
- let title = projectConfigurationsError.message;
38
- if (projectConfigurationsError.cause &&
39
- typeof projectConfigurationsError.cause === 'object' &&
40
- 'message' in projectConfigurationsError.cause) {
41
- title += ' ' + projectConfigurationsError.cause.message + '.';
42
- }
43
- output_1.output.error({
44
- title,
45
- bodyLines: isVerbose
46
- ? formatErrorStackAndCause(projectConfigurationsError, isVerbose)
47
- : projectConfigurationsError.errors.map((e) => e.message),
48
- });
21
+ else if (err.name === 'ProjectGraphError' ||
22
+ err.name === 'ProjectConfigurationsError') {
23
+ output_1.output.error((0, error_types_1.formatProjectGraphError)(err, isVerbose));
49
24
  }
50
25
  else if (err.name === 'MinReleaseAgeViolationError') {
51
26
  // A cooldown violation already carries a user-shaped headline plus
@@ -59,7 +34,7 @@ async function handleErrors(isVerbose, fn) {
59
34
  const lines = (err.message ? err.message : err.toString()).split('\n');
60
35
  const bodyLines = lines.slice(1);
61
36
  if (isVerbose) {
62
- bodyLines.push(...formatErrorStackAndCause(err, isVerbose));
37
+ bodyLines.push((0, error_types_1.formatErrorStackAndCause)(err));
63
38
  }
64
39
  else if (err.stack) {
65
40
  bodyLines.push('Pass --verbose to see the stacktrace.');
@@ -76,16 +51,3 @@ async function handleErrors(isVerbose, fn) {
76
51
  return 1;
77
52
  }
78
53
  }
79
- function formatErrorStackAndCause(error, verbose) {
80
- return [
81
- verbose ? error.stack || error.message : error.message,
82
- ...(error.cause && typeof error.cause === 'object'
83
- ? [
84
- 'Caused by:',
85
- verbose && 'stack' in error.cause
86
- ? error.cause.stack.toString()
87
- : error.cause.toString(),
88
- ]
89
- : []),
90
- ];
91
- }
@@ -63,12 +63,17 @@ async function tryGetModule(packageJson, workspaceRoot) {
63
63
  packageJson['nx-migrations'] ??
64
64
  packageJson['schematics'] ??
65
65
  packageJson['builders']) {
66
- const [pluginPromise] = (0, in_process_loader_1.loadNxPlugin)(packageJson.name, workspaceRoot);
67
- return await pluginPromise;
66
+ return await (0, in_process_loader_1.loadNxPlugin)(packageJson.name, workspaceRoot);
68
67
  }
69
68
  else {
70
69
  return {
71
70
  name: packageJson.name,
71
+ capabilities: () => ({
72
+ hasCreateDependencies: false,
73
+ hasCreateMetadata: false,
74
+ hasPreTasksExecution: false,
75
+ hasPostTasksExecution: false,
76
+ }),
72
77
  };
73
78
  }
74
79
  }
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.serializeOverridesIntoCommandLine = serializeOverridesIntoCommandLine;
4
- const flat_1 = require("flat");
5
4
  const shell_quoting_1 = require("./shell-quoting");
6
5
  function serializeOverridesIntoCommandLine(options) {
7
6
  const unparsed = options._ ? [...options._] : [];
@@ -24,9 +23,8 @@ function serializeOption(key, value, unparsed) {
24
23
  value.forEach((item) => serializeOption(key, item, unparsed));
25
24
  }
26
25
  else if (Object.prototype.toString.call(value) === '[object Object]') {
27
- const flattened = (0, flat_1.flatten)(value, { safe: true });
28
- for (const flattenedKey in flattened) {
29
- serializeOption(`${key}.${flattenedKey}`, flattened[flattenedKey], unparsed);
26
+ for (const nestedKey of Object.keys(value)) {
27
+ serializeOption(`${key}.${nestedKey}`, value[nestedKey], unparsed);
30
28
  }
31
29
  }
32
30
  else if (typeof value === 'string' &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "23.3.0-beta.1",
3
+ "version": "23.3.0-beta.2",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
@@ -100,7 +100,6 @@
100
100
  "fast-string-width": "3.0.2",
101
101
  "fast-wrap-ansi": "0.2.0",
102
102
  "figures": "3.2.0",
103
- "flat": "5.0.2",
104
103
  "follow-redirects": "1.16.0",
105
104
  "form-data": "4.0.6",
106
105
  "fs-constants": "1.0.0",
@@ -185,16 +184,16 @@
185
184
  }
186
185
  },
187
186
  "optionalDependencies": {
188
- "@nx/nx-darwin-arm64": "23.3.0-beta.1",
189
- "@nx/nx-darwin-x64": "23.3.0-beta.1",
190
- "@nx/nx-freebsd-x64": "23.3.0-beta.1",
191
- "@nx/nx-linux-arm-gnueabihf": "23.3.0-beta.1",
192
- "@nx/nx-linux-arm64-gnu": "23.3.0-beta.1",
193
- "@nx/nx-linux-arm64-musl": "23.3.0-beta.1",
194
- "@nx/nx-linux-x64-gnu": "23.3.0-beta.1",
195
- "@nx/nx-linux-x64-musl": "23.3.0-beta.1",
196
- "@nx/nx-win32-arm64-msvc": "23.3.0-beta.1",
197
- "@nx/nx-win32-x64-msvc": "23.3.0-beta.1"
187
+ "@nx/nx-darwin-arm64": "23.3.0-beta.2",
188
+ "@nx/nx-darwin-x64": "23.3.0-beta.2",
189
+ "@nx/nx-freebsd-x64": "23.3.0-beta.2",
190
+ "@nx/nx-linux-arm-gnueabihf": "23.3.0-beta.2",
191
+ "@nx/nx-linux-arm64-gnu": "23.3.0-beta.2",
192
+ "@nx/nx-linux-arm64-musl": "23.3.0-beta.2",
193
+ "@nx/nx-linux-x64-gnu": "23.3.0-beta.2",
194
+ "@nx/nx-linux-x64-musl": "23.3.0-beta.2",
195
+ "@nx/nx-win32-arm64-msvc": "23.3.0-beta.2",
196
+ "@nx/nx-win32-x64-msvc": "23.3.0-beta.2"
198
197
  },
199
198
  "nx-migrations": {
200
199
  "migrations": "./migrations.json",