nx 19.0.0-beta.1 → 19.0.0-beta.10

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 (99) hide show
  1. package/.eslintrc.json +1 -1
  2. package/migrations.json +2 -25
  3. package/package.json +12 -12
  4. package/src/command-line/add/add.js +17 -16
  5. package/src/command-line/affected/affected.js +1 -1
  6. package/src/command-line/graph/graph.d.ts +11 -1
  7. package/src/command-line/graph/graph.js +97 -13
  8. package/src/command-line/init/implementation/react/index.js +1 -1
  9. package/src/command-line/release/changelog.js +1 -1
  10. package/src/command-line/release/command-object.js +2 -2
  11. package/src/command-line/release/publish.js +1 -1
  12. package/src/command-line/report/report.js +1 -1
  13. package/src/command-line/run/run-one.js +1 -1
  14. package/src/command-line/run-many/run-many.js +1 -1
  15. package/src/command-line/yargs-utils/shared-options.js +1 -1
  16. package/src/config/nx-json.d.ts +2 -2
  17. package/src/config/to-project-name.d.ts +5 -0
  18. package/src/config/to-project-name.js +13 -0
  19. package/src/core/graph/index.html +1 -2
  20. package/src/core/graph/main.js +1 -1
  21. package/src/core/graph/runtime.js +1 -1
  22. package/src/core/graph/styles.css +2 -2
  23. package/src/core/graph/styles.js +1 -1
  24. package/src/daemon/client/client.d.ts +2 -2
  25. package/src/daemon/client/client.js +21 -6
  26. package/src/daemon/server/project-graph-incremental-recomputation.js +8 -8
  27. package/src/daemon/server/shutdown-utils.js +7 -2
  28. package/src/daemon/tmp-dir.js +2 -2
  29. package/src/devkit-exports.d.ts +1 -5
  30. package/src/devkit-exports.js +1 -7
  31. package/src/devkit-internals.d.ts +2 -0
  32. package/src/devkit-internals.js +5 -1
  33. package/src/executors/run-commands/run-commands.impl.d.ts +2 -0
  34. package/src/executors/run-commands/run-commands.impl.js +69 -23
  35. package/src/executors/run-commands/schema.json +19 -2
  36. package/src/executors/utils/convert-nx-executor.js +2 -1
  37. package/src/generators/testing-utils/create-tree-with-empty-workspace.js +7 -0
  38. package/src/generators/utils/project-configuration.js +3 -8
  39. package/src/hasher/task-hasher.d.ts +4 -4
  40. package/src/native/index.d.ts +1 -1
  41. package/src/plugins/js/lock-file/pnpm-parser.js +109 -67
  42. package/src/plugins/package-json-workspaces/create-nodes.d.ts +1 -0
  43. package/src/plugins/package-json-workspaces/create-nodes.js +25 -20
  44. package/src/plugins/project-json/build-nodes/project-json.js +2 -2
  45. package/src/project-graph/affected/locators/workspace-projects.js +3 -1
  46. package/src/project-graph/build-project-graph.d.ts +8 -18
  47. package/src/project-graph/build-project-graph.js +86 -57
  48. package/src/project-graph/error-types.d.ts +31 -3
  49. package/src/project-graph/error-types.js +74 -2
  50. package/src/project-graph/file-utils.d.ts +2 -3
  51. package/src/project-graph/file-utils.js +5 -9
  52. package/src/project-graph/plugins/internal-api.d.ts +3 -2
  53. package/src/project-graph/plugins/internal-api.js +3 -0
  54. package/src/project-graph/plugins/isolation/messaging.d.ts +26 -3
  55. package/src/project-graph/plugins/isolation/plugin-pool.js +23 -1
  56. package/src/project-graph/plugins/isolation/plugin-worker.js +21 -0
  57. package/src/project-graph/plugins/loader.js +14 -6
  58. package/src/project-graph/plugins/public-api.d.ts +11 -1
  59. package/src/project-graph/plugins/utils.d.ts +2 -2
  60. package/src/project-graph/plugins/utils.js +19 -24
  61. package/src/project-graph/project-graph.d.ts +3 -0
  62. package/src/project-graph/project-graph.js +8 -7
  63. package/src/project-graph/utils/find-project-for-path.js +2 -3
  64. package/src/project-graph/utils/normalize-project-nodes.d.ts +1 -1
  65. package/src/project-graph/utils/normalize-project-nodes.js +8 -14
  66. package/src/project-graph/utils/project-configuration-utils.d.ts +23 -6
  67. package/src/project-graph/utils/project-configuration-utils.js +43 -20
  68. package/src/tasks-runner/create-task-graph.js +0 -1
  69. package/src/tasks-runner/life-cycles/dynamic-run-many-terminal-output-life-cycle.js +5 -1
  70. package/src/tasks-runner/life-cycles/dynamic-run-one-terminal-output-life-cycle.js +4 -0
  71. package/src/tasks-runner/pseudo-terminal.d.ts +2 -1
  72. package/src/tasks-runner/pseudo-terminal.js +8 -2
  73. package/src/tasks-runner/run-command.js +4 -4
  74. package/src/tasks-runner/utils.js +17 -0
  75. package/src/utils/assert-workspace-validity.js +2 -1
  76. package/src/utils/command-line-utils.d.ts +1 -1
  77. package/src/utils/nx-plugin.deprecated.d.ts +1 -1
  78. package/src/utils/nx-plugin.deprecated.js +1 -1
  79. package/src/utils/params.js +4 -0
  80. package/src/utils/perf-logging.js +3 -1
  81. package/src/command-line/repair.d.ts +0 -4
  82. package/src/command-line/repair.js +0 -7
  83. package/src/command-line/run-many.d.ts +0 -4
  84. package/src/command-line/run-many.js +0 -7
  85. package/src/command-line/run-one.d.ts +0 -4
  86. package/src/command-line/run-one.js +0 -7
  87. package/src/command-line/run.d.ts +0 -4
  88. package/src/command-line/run.js +0 -7
  89. package/src/command-line/watch.d.ts +0 -4
  90. package/src/command-line/watch.js +0 -7
  91. package/src/config/workspaces.d.ts +0 -18
  92. package/src/config/workspaces.js +0 -35
  93. package/src/core/graph/3rdpartylicenses.txt +0 -785
  94. package/src/migrations/update-15-1-0/set-project-names.d.ts +0 -2
  95. package/src/migrations/update-15-1-0/set-project-names.js +0 -34
  96. package/src/migrations/update-15-8-2/update-nxw.d.ts +0 -2
  97. package/src/migrations/update-15-8-2/update-nxw.js +0 -7
  98. package/src/utils/typescript.d.ts +0 -1
  99. package/src/utils/typescript.js +0 -5
@@ -8,7 +8,6 @@ const package_json_1 = require("../../utils/package-json");
8
8
  const fileutils_1 = require("../../utils/fileutils");
9
9
  const workspace_root_1 = require("../../utils/workspace-root");
10
10
  const node_fs_1 = require("node:fs");
11
- const typescript_1 = require("../../utils/typescript");
12
11
  const register_1 = require("../../plugins/js/utils/register");
13
12
  const find_project_for_path_1 = require("../utils/find-project-for-path");
14
13
  const path_1 = require("../../utils/path");
@@ -19,6 +18,7 @@ const utils_1 = require("./utils");
19
18
  const internal_api_1 = require("./internal-api");
20
19
  const error_types_1 = require("../error-types");
21
20
  const path = require("node:path/posix");
21
+ const typescript_1 = require("../../plugins/js/utils/typescript");
22
22
  function readPluginPackageJson(pluginName, projects, paths = (0, installation_directory_1.getNxRequirePaths)()) {
23
23
  try {
24
24
  const result = (0, package_json_1.readModulePackageJsonWithoutFallbacks)(pluginName, paths);
@@ -32,6 +32,9 @@ function readPluginPackageJson(pluginName, projects, paths = (0, installation_di
32
32
  const localPluginPath = resolveLocalNxPlugin(pluginName, projects);
33
33
  if (localPluginPath) {
34
34
  const localPluginPackageJson = path.join(localPluginPath.path, 'package.json');
35
+ if (!exports.unregisterPluginTSTranspiler) {
36
+ registerPluginTSTranspiler();
37
+ }
35
38
  return {
36
39
  path: localPluginPackageJson,
37
40
  json: (0, fileutils_1.readJsonFile)(localPluginPackageJson),
@@ -77,22 +80,27 @@ function registerPluginTSTranspiler() {
77
80
  }
78
81
  exports.registerPluginTSTranspiler = registerPluginTSTranspiler;
79
82
  function lookupLocalPlugin(importPath, projects, root = workspace_root_1.workspaceRoot) {
80
- const plugin = findNxProjectForImportPath(importPath, projects, root);
81
- if (!plugin) {
83
+ const projectConfig = findNxProjectForImportPath(importPath, projects, root);
84
+ if (!projectConfig) {
82
85
  return null;
83
86
  }
84
- const projectConfig = projects[plugin];
85
87
  return { path: path.join(root, projectConfig.root), projectConfig };
86
88
  }
87
89
  function findNxProjectForImportPath(importPath, projects, root = workspace_root_1.workspaceRoot) {
88
90
  const tsConfigPaths = readTsConfigPaths(root);
89
91
  const possiblePaths = tsConfigPaths[importPath]?.map((p) => (0, path_1.normalizePath)(path.relative(root, path.join(root, p))));
90
92
  if (possiblePaths?.length) {
91
- const projectRootMappings = (0, find_project_for_path_1.createProjectRootMappingsFromProjectConfigurations)(projects);
93
+ const projectRootMappings = new Map();
94
+ const projectNameMap = new Map();
95
+ for (const projectRoot in projects) {
96
+ const project = projects[projectRoot];
97
+ projectRootMappings.set(project.root, project.name);
98
+ projectNameMap.set(project.name, project);
99
+ }
92
100
  for (const tsConfigPath of possiblePaths) {
93
101
  const nxProject = (0, find_project_for_path_1.findProjectForPath)(tsConfigPath, projectRootMappings);
94
102
  if (nxProject) {
95
- return nxProject;
103
+ return projectNameMap.get(nxProject);
96
104
  }
97
105
  }
98
106
  logger_1.logger.verbose('Unable to find local plugin', possiblePaths, projectRootMappings);
@@ -12,7 +12,7 @@ export interface CreateNodesContext {
12
12
  /**
13
13
  * The subset of configuration files which match the createNodes pattern
14
14
  */
15
- readonly configFiles: string[];
15
+ readonly configFiles: readonly string[];
16
16
  }
17
17
  /**
18
18
  * A function which parses a configuration file into a set of nodes.
@@ -68,6 +68,12 @@ export interface CreateDependenciesContext {
68
68
  * Use {@link validateDependency} to validate dependencies
69
69
  */
70
70
  export type CreateDependencies<T = unknown> = (options: T | undefined, context: CreateDependenciesContext) => RawProjectGraphDependency[] | Promise<RawProjectGraphDependency[]>;
71
+ export type CreateMetadataContext = {
72
+ readonly nxJsonConfiguration: NxJsonConfiguration;
73
+ readonly workspaceRoot: string;
74
+ };
75
+ export type ProjectsMetadata = Record<string, Pick<ProjectConfiguration, 'metadata'>>;
76
+ export type CreateMetadata<T = unknown> = (graph: ProjectGraph, options: T | undefined, context: CreateMetadataContext) => ProjectsMetadata | Promise<ProjectsMetadata>;
71
77
  /**
72
78
  * A plugin for Nx which creates nodes and dependencies for the {@link ProjectGraph}
73
79
  */
@@ -82,6 +88,10 @@ export type NxPluginV2<TOptions = unknown> = {
82
88
  * Provides a function to analyze files to create dependencies for the {@link ProjectGraph}
83
89
  */
84
90
  createDependencies?: CreateDependencies<TOptions>;
91
+ /**
92
+ * Provides a function to create metadata for the {@link ProjectGraph}
93
+ */
94
+ createMetadata?: CreateMetadata<TOptions>;
85
95
  };
86
96
  /**
87
97
  * A plugin for Nx
@@ -1,7 +1,7 @@
1
1
  import type { NxPluginV1 } from '../../utils/nx-plugin.deprecated';
2
2
  import type { CreateNodesResultWithContext, LoadedNxPlugin, NormalizedPlugin } from './internal-api';
3
- import type { CreateNodesContext, NxPlugin, NxPluginV2 } from './public-api';
3
+ import { type CreateNodesContext, type NxPlugin, type NxPluginV2 } from './public-api';
4
4
  export declare function isNxPluginV2(plugin: NxPlugin): plugin is NxPluginV2;
5
5
  export declare function isNxPluginV1(plugin: NxPlugin | LoadedNxPlugin): plugin is NxPluginV1;
6
6
  export declare function normalizeNxPlugin(plugin: NxPlugin): NormalizedPlugin;
7
- export declare function runCreateNodesInParallel(configFiles: string[], plugin: NormalizedPlugin, options: unknown, context: CreateNodesContext): Promise<CreateNodesResultWithContext[]>;
7
+ export declare function runCreateNodesInParallel(configFiles: readonly string[], plugin: NormalizedPlugin, options: unknown, context: CreateNodesContext): Promise<CreateNodesResultWithContext[]>;
@@ -2,9 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runCreateNodesInParallel = exports.normalizeNxPlugin = exports.isNxPluginV1 = exports.isNxPluginV2 = void 0;
4
4
  const node_path_1 = require("node:path");
5
- const workspaces_1 = require("../../config/workspaces");
5
+ const to_project_name_1 = require("../../config/to-project-name");
6
6
  const globs_1 = require("../../utils/globs");
7
7
  const error_types_1 = require("../error-types");
8
+ const perf_hooks_1 = require("perf_hooks");
8
9
  function isNxPluginV2(plugin) {
9
10
  return 'createNodes' in plugin || 'createDependencies' in plugin;
10
11
  }
@@ -27,7 +28,7 @@ function normalizeNxPlugin(plugin) {
27
28
  return {
28
29
  projects: {
29
30
  [root]: {
30
- name: (0, workspaces_1.toProjectName)(configFilePath),
31
+ name: (0, to_project_name_1.toProjectName)(configFilePath),
31
32
  targets: plugin.registerProjectTargets?.(configFilePath),
32
33
  },
33
34
  },
@@ -40,37 +41,31 @@ function normalizeNxPlugin(plugin) {
40
41
  }
41
42
  exports.normalizeNxPlugin = normalizeNxPlugin;
42
43
  async function runCreateNodesInParallel(configFiles, plugin, options, context) {
43
- performance.mark(`${plugin.name}:createNodes - start`);
44
+ perf_hooks_1.performance.mark(`${plugin.name}:createNodes - start`);
44
45
  const errors = [];
45
46
  const results = [];
46
- const promises = configFiles.map((file) => {
47
- performance.mark(`${plugin.name}:createNodes:${file} - start`);
48
- // Result is either static or a promise, using Promise.resolve lets us
49
- // handle both cases with same logic
50
- const value = Promise.resolve(plugin.createNodes[1](file, options, context));
51
- return value
52
- .catch((e) => {
53
- performance.mark(`${plugin.name}:createNodes:${file} - end`);
47
+ const promises = configFiles.map(async (file) => {
48
+ try {
49
+ const value = await plugin.createNodes[1](file, options, context);
50
+ if (value) {
51
+ results.push({
52
+ ...value,
53
+ file,
54
+ pluginName: plugin.name,
55
+ });
56
+ }
57
+ }
58
+ catch (e) {
54
59
  errors.push(new error_types_1.CreateNodesError({
55
60
  error: e,
56
61
  pluginName: plugin.name,
57
62
  file,
58
63
  }));
59
- return null;
60
- })
61
- .then((r) => {
62
- performance.mark(`${plugin.name}:createNodes:${file} - end`);
63
- performance.measure(`${plugin.name}:createNodes:${file}`, `${plugin.name}:createNodes:${file} - start`, `${plugin.name}:createNodes:${file} - end`);
64
- // Existing behavior is to ignore null results of
65
- // createNodes function.
66
- if (r) {
67
- results.push({ ...r, file, pluginName: plugin.name });
68
- }
69
- });
64
+ }
70
65
  });
71
66
  await Promise.all(promises).then(() => {
72
- performance.mark(`${plugin.name}:createNodes - end`);
73
- performance.measure(`${plugin.name}:createNodes`, `${plugin.name}:createNodes - start`, `${plugin.name}:createNodes - end`);
67
+ perf_hooks_1.performance.mark(`${plugin.name}:createNodes - end`);
68
+ perf_hooks_1.performance.measure(`${plugin.name}:createNodes`, `${plugin.name}:createNodes - start`, `${plugin.name}:createNodes - end`);
74
69
  });
75
70
  if (errors.length > 0) {
76
71
  throw new error_types_1.AggregateCreateNodesError(plugin.name, errors, results);
@@ -14,6 +14,9 @@ export declare function buildProjectGraphAndSourceMapsWithoutDaemon(): Promise<{
14
14
  projectGraph: ProjectGraph;
15
15
  sourceMaps: import("./utils/project-configuration-utils").ConfigurationSourceMaps;
16
16
  }>;
17
+ export declare function handleProjectGraphError(opts: {
18
+ exitOnError: boolean;
19
+ }, e: any): void;
17
20
  /**
18
21
  * Computes and returns a ProjectGraph.
19
22
  *
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createProjectGraphAndSourceMapsAsync = exports.createProjectGraphAsync = exports.buildProjectGraphAndSourceMapsWithoutDaemon = exports.readProjectsConfigurationFromProjectGraph = exports.readCachedProjectConfiguration = exports.readCachedProjectGraph = void 0;
3
+ exports.createProjectGraphAndSourceMapsAsync = exports.createProjectGraphAsync = exports.handleProjectGraphError = exports.buildProjectGraphAndSourceMapsWithoutDaemon = exports.readProjectsConfigurationFromProjectGraph = exports.readCachedProjectConfiguration = exports.readCachedProjectGraph = void 0;
4
4
  const perf_hooks_1 = require("perf_hooks");
5
5
  const nx_json_1 = require("../config/nx-json");
6
6
  const client_1 = require("../daemon/client/client");
@@ -10,8 +10,8 @@ const output_1 = require("../utils/output");
10
10
  const strip_indents_1 = require("../utils/strip-indents");
11
11
  const workspace_root_1 = require("../utils/workspace-root");
12
12
  const build_project_graph_1 = require("./build-project-graph");
13
- const nx_deps_cache_1 = require("./nx-deps-cache");
14
13
  const error_types_1 = require("./error-types");
14
+ const nx_deps_cache_1 = require("./nx-deps-cache");
15
15
  const internal_api_1 = require("./plugins/internal-api");
16
16
  const retrieve_workspace_files_1 = require("./utils/retrieve-workspace-files");
17
17
  /**
@@ -92,18 +92,18 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
92
92
  perf_hooks_1.performance.mark('retrieve-workspace-files:end');
93
93
  const cacheEnabled = process.env.NX_CACHE_PROJECT_GRAPH !== 'false';
94
94
  perf_hooks_1.performance.mark('build-project-graph-using-project-file-map:start');
95
- let createDependenciesError;
95
+ let projectGraphError;
96
96
  let projectGraphResult;
97
97
  try {
98
- projectGraphResult = await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, externalNodes, fileMap, allWorkspaceFiles, rustReferences, cacheEnabled ? (0, nx_deps_cache_1.readFileMapCache)() : null, plugins);
98
+ projectGraphResult = await (0, build_project_graph_1.buildProjectGraphUsingProjectFileMap)(projects, externalNodes, fileMap, allWorkspaceFiles, rustReferences, cacheEnabled ? (0, nx_deps_cache_1.readFileMapCache)() : null, plugins, sourceMaps);
99
99
  }
100
100
  catch (e) {
101
- if (e instanceof build_project_graph_1.CreateDependenciesError) {
101
+ if ((0, error_types_1.isAggregateProjectGraphError)(e)) {
102
102
  projectGraphResult = {
103
103
  projectGraph: e.partialProjectGraph,
104
104
  projectFileMapCache: null,
105
105
  };
106
- createDependenciesError = e;
106
+ projectGraphError = e;
107
107
  }
108
108
  else {
109
109
  throw e;
@@ -117,7 +117,7 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
117
117
  delete global.NX_GRAPH_CREATION;
118
118
  const errors = [
119
119
  ...(projectConfigurationsError?.errors ?? []),
120
- ...(createDependenciesError?.errors ?? []),
120
+ ...(projectGraphError?.errors ?? []),
121
121
  ];
122
122
  if (errors.length > 0) {
123
123
  throw new error_types_1.ProjectGraphError(errors, projectGraph, sourceMaps);
@@ -162,6 +162,7 @@ function handleProjectGraphError(opts, e) {
162
162
  throw e;
163
163
  }
164
164
  }
165
+ exports.handleProjectGraphError = handleProjectGraphError;
165
166
  /**
166
167
  * Computes and returns a ProjectGraph.
167
168
  *
@@ -9,9 +9,8 @@ const path_2 = require("../../utils/path");
9
9
  */
10
10
  function createProjectRootMappingsFromProjectConfigurations(projects) {
11
11
  const projectRootMappings = new Map();
12
- for (const projectName of Object.keys(projects)) {
13
- const root = projects[projectName].root;
14
- projectRootMappings.set(normalizeProjectRoot(root), projectName);
12
+ for (const { name, root } of Object.values(projects)) {
13
+ projectRootMappings.set(normalizeProjectRoot(root), name);
15
14
  }
16
15
  return projectRootMappings;
17
16
  }
@@ -2,7 +2,7 @@ import { ProjectGraphProjectNode } from '../../config/project-graph';
2
2
  import { ProjectGraphBuilder } from '../project-graph-builder';
3
3
  import { ProjectConfiguration, TargetConfiguration } from '../../config/workspace-json-project-json';
4
4
  import { CreateDependenciesContext } from '../plugins';
5
- export declare function normalizeProjectNodes(ctx: CreateDependenciesContext, builder: ProjectGraphBuilder): Promise<void>;
5
+ export declare function normalizeProjectNodes({ projects }: CreateDependenciesContext, builder: ProjectGraphBuilder): Promise<void>;
6
6
  /**
7
7
  * Apply target defaults and normalization
8
8
  */
@@ -2,16 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizeImplicitDependencies = exports.normalizeProjectTargets = exports.normalizeProjectNodes = void 0;
4
4
  const find_matching_projects_1 = require("../../utils/find-matching-projects");
5
- const project_configuration_utils_1 = require("../utils/project-configuration-utils");
6
- async function normalizeProjectNodes(ctx, builder) {
7
- const toAdd = [];
5
+ async function normalizeProjectNodes({ projects }, builder) {
8
6
  // Sorting projects by name to make sure that the order of projects in the graph is deterministic.
9
7
  // This is important to ensure that expanded properties referencing projects (e.g. implicit dependencies)
10
8
  // are also deterministic, and thus don't cause the calculated project configuration hash to shift.
11
- const projects = Object.keys(ctx.projects).sort();
9
+ const sortedProjectNames = Object.keys(projects).sort();
12
10
  // Used for expanding implicit dependencies (e.g. `@proj/*` or `tag:foo`)
13
- const partialProjectGraphNodes = projects.reduce((graph, project) => {
14
- const projectConfiguration = ctx.projects[project];
11
+ const partialProjectGraphNodes = sortedProjectNames.reduce((graph, project) => {
12
+ const projectConfiguration = projects[project];
15
13
  graph[project] = {
16
14
  name: project,
17
15
  type: projectConfiguration.projectType === 'library' ? 'lib' : 'app', // missing fallback to `e2e`
@@ -21,8 +19,9 @@ async function normalizeProjectNodes(ctx, builder) {
21
19
  };
22
20
  return graph;
23
21
  }, {});
24
- for (const key of projects) {
25
- const p = ctx.projects[key];
22
+ const toAdd = [];
23
+ for (const key of sortedProjectNames) {
24
+ const p = projects[key];
26
25
  p.implicitDependencies = normalizeImplicitDependencies(key, p.implicitDependencies, partialProjectGraphNodes);
27
26
  p.targets = normalizeProjectTargets(p, key);
28
27
  // TODO: remove in v16
@@ -31,7 +30,7 @@ async function normalizeProjectNodes(ctx, builder) {
31
30
  ? 'e2e'
32
31
  : 'app'
33
32
  : 'lib';
34
- const tags = ctx.projects?.[key]?.tags || [];
33
+ const tags = p.tags || [];
35
34
  toAdd.push({
36
35
  name: key,
37
36
  type: projectType,
@@ -69,11 +68,6 @@ function normalizeProjectTargets(project, projectName) {
69
68
  delete targets[target];
70
69
  continue;
71
70
  }
72
- targets[target].options = (0, project_configuration_utils_1.resolveNxTokensInOptions)(targets[target].options, project, `${projectName}:${target}`);
73
- targets[target].configurations ??= {};
74
- for (const configuration in targets[target].configurations) {
75
- targets[target].configurations[configuration] = (0, project_configuration_utils_1.resolveNxTokensInOptions)(targets[target].configurations[configuration], project, `${projectName}:${target}:${configuration}`);
76
- }
77
71
  }
78
72
  return targets;
79
73
  }
@@ -1,20 +1,36 @@
1
1
  import { NxJsonConfiguration, TargetDefaults } from '../../config/nx-json';
2
2
  import { ProjectGraphExternalNode } from '../../config/project-graph';
3
- import { ProjectConfiguration, TargetConfiguration } from '../../config/workspace-json-project-json';
3
+ import { ProjectConfiguration, ProjectMetadata, TargetConfiguration, TargetMetadata } from '../../config/workspace-json-project-json';
4
4
  import { ONLY_MODIFIES_EXISTING_TARGET } from '../../plugins/target-defaults/symbols';
5
5
  import { LoadedNxPlugin } from '../plugins/internal-api';
6
- export type SourceInformation = [file: string, plugin: string];
6
+ export type SourceInformation = [file: string | null, plugin: string];
7
7
  export type ConfigurationSourceMaps = Record<string, Record<string, SourceInformation>>;
8
- export declare function mergeProjectConfigurationIntoRootMap(projectRootMap: Map<string, ProjectConfiguration>, project: ProjectConfiguration & {
8
+ export declare function mergeProjectConfigurationIntoRootMap(projectRootMap: Record<string, ProjectConfiguration>, project: ProjectConfiguration & {
9
9
  targets?: Record<string, TargetConfiguration & {
10
10
  [ONLY_MODIFIES_EXISTING_TARGET]?: boolean;
11
11
  }>;
12
- }, configurationSourceMaps?: ConfigurationSourceMaps, sourceInformation?: SourceInformation, skipCommandNormalization?: boolean): void;
12
+ }, configurationSourceMaps?: ConfigurationSourceMaps, sourceInformation?: SourceInformation, skipTargetNormalization?: boolean): void;
13
+ export declare function mergeMetadata<T = ProjectMetadata | TargetMetadata>(sourceMap: Record<string, [file: string, plugin: string]>, sourceInformation: [file: string, plugin: string], baseSourceMapPath: string, metadata: T, matchingMetadata?: T): T;
13
14
  export type ConfigurationResult = {
14
- projects: Record<string, ProjectConfiguration>;
15
+ /**
16
+ * A map of project configurations, keyed by project root.
17
+ */
18
+ projects: {
19
+ [projectRoot: string]: ProjectConfiguration;
20
+ };
21
+ /**
22
+ * Node Name -> Node info
23
+ */
15
24
  externalNodes: Record<string, ProjectGraphExternalNode>;
25
+ /**
26
+ * Project Root -> Project Name
27
+ */
16
28
  projectRootMap: Record<string, string>;
17
29
  sourceMaps: ConfigurationSourceMaps;
30
+ /**
31
+ * The list of files that were used to create project configurations
32
+ */
33
+ matchingProjectFiles: string[];
18
34
  };
19
35
  /**
20
36
  * Transforms a list of project paths into a map of project configurations.
@@ -26,7 +42,7 @@ export type ConfigurationResult = {
26
42
  */
27
43
  export declare function createProjectConfigurations(root: string, nxJson: NxJsonConfiguration, projectFiles: string[], // making this parameter allows devkit to pick up newly created projects
28
44
  plugins: LoadedNxPlugin[]): Promise<ConfigurationResult>;
29
- export declare function readProjectConfigurationsFromRootMap(projectRootMap: Map<string, ProjectConfiguration>): Record<string, ProjectConfiguration>;
45
+ export declare function readProjectConfigurationsFromRootMap(projectRootMap: Record<string, ProjectConfiguration>): Record<string, ProjectConfiguration>;
30
46
  /**
31
47
  * Merges two targets.
32
48
  *
@@ -51,3 +67,4 @@ export declare function mergeTargetConfigurations(target: TargetConfiguration, b
51
67
  export declare function isCompatibleTarget(a: TargetConfiguration, b: TargetConfiguration): boolean;
52
68
  export declare function resolveNxTokensInOptions<T extends Object | Array<unknown>>(object: T, project: ProjectConfiguration, key: string): T;
53
69
  export declare function readTargetDefaultsForTarget(targetName: string, targetDefaults: TargetDefaults, executor?: string): TargetDefaults[string];
70
+ export declare function normalizeTarget(target: TargetConfiguration, project: ProjectConfiguration): TargetConfiguration<any>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readTargetDefaultsForTarget = exports.resolveNxTokensInOptions = exports.isCompatibleTarget = exports.mergeTargetConfigurations = exports.readProjectConfigurationsFromRootMap = exports.createProjectConfigurations = exports.mergeProjectConfigurationIntoRootMap = void 0;
3
+ exports.normalizeTarget = exports.readTargetDefaultsForTarget = exports.resolveNxTokensInOptions = exports.isCompatibleTarget = exports.mergeTargetConfigurations = exports.readProjectConfigurationsFromRootMap = exports.createProjectConfigurations = exports.mergeMetadata = exports.mergeProjectConfigurationIntoRootMap = void 0;
4
4
  const logger_1 = require("../../utils/logger");
5
5
  const fileutils_1 = require("../../utils/fileutils");
6
6
  const workspace_root_1 = require("../../utils/workspace-root");
@@ -12,17 +12,17 @@ const error_types_1 = require("../error-types");
12
12
  function mergeProjectConfigurationIntoRootMap(projectRootMap, project, configurationSourceMaps, sourceInformation,
13
13
  // This function is used when reading project configuration
14
14
  // in generators, where we don't want to do this.
15
- skipCommandNormalization) {
15
+ skipTargetNormalization) {
16
16
  if (configurationSourceMaps && !configurationSourceMaps[project.root]) {
17
17
  configurationSourceMaps[project.root] = {};
18
18
  }
19
19
  const sourceMap = configurationSourceMaps?.[project.root];
20
- let matchingProject = projectRootMap.get(project.root);
20
+ let matchingProject = projectRootMap[project.root];
21
21
  if (!matchingProject) {
22
- projectRootMap.set(project.root, {
22
+ projectRootMap[project.root] = {
23
23
  root: project.root,
24
- });
25
- matchingProject = projectRootMap.get(project.root);
24
+ };
25
+ matchingProject = projectRootMap[project.root];
26
26
  if (sourceMap) {
27
27
  sourceMap[`root`] = sourceInformation;
28
28
  }
@@ -129,16 +129,18 @@ skipCommandNormalization) {
129
129
  !matchingProject.targets?.[targetName]) {
130
130
  continue;
131
131
  }
132
- const mergedTarget = mergeTargetConfigurations(skipCommandNormalization
132
+ const normalizedTarget = skipTargetNormalization
133
133
  ? target
134
- : resolveCommandSyntacticSugar(target, project.root), matchingProject.targets?.[targetName], sourceMap, sourceInformation, `targets.${targetName}`);
134
+ : normalizeTarget(target, project);
135
+ const mergedTarget = mergeTargetConfigurations(normalizedTarget, matchingProject.targets?.[targetName], sourceMap, sourceInformation, `targets.${targetName}`);
135
136
  // We don't want the symbol to live on past the merge process
136
137
  if (mergedTarget?.[symbols_1.ONLY_MODIFIES_EXISTING_TARGET])
137
138
  delete mergedTarget?.[symbols_1.ONLY_MODIFIES_EXISTING_TARGET];
138
139
  updatedProjectConfiguration.targets[targetName] = mergedTarget;
139
140
  }
140
141
  }
141
- projectRootMap.set(updatedProjectConfiguration.root, updatedProjectConfiguration);
142
+ projectRootMap[updatedProjectConfiguration.root] =
143
+ updatedProjectConfiguration;
142
144
  }
143
145
  exports.mergeProjectConfigurationIntoRootMap = mergeProjectConfigurationIntoRootMap;
144
146
  function mergeMetadata(sourceMap, sourceInformation, baseSourceMapPath, metadata, matchingMetadata) {
@@ -210,6 +212,7 @@ function mergeMetadata(sourceMap, sourceInformation, baseSourceMapPath, metadata
210
212
  }
211
213
  return result;
212
214
  }
215
+ exports.mergeMetadata = mergeMetadata;
213
216
  /**
214
217
  * Transforms a list of project paths into a map of project configurations.
215
218
  *
@@ -264,7 +267,7 @@ plugins) {
264
267
  }
265
268
  return Promise.all(results).then((results) => {
266
269
  perf_hooks_1.performance.mark('createNodes:merge - start');
267
- const projectRootMap = new Map();
270
+ const projectRootMap = {};
268
271
  const externalNodes = {};
269
272
  const configurationSourceMaps = {};
270
273
  for (const result of results.flat()) {
@@ -291,14 +294,17 @@ plugins) {
291
294
  }
292
295
  Object.assign(externalNodes, pluginExternalNodes);
293
296
  }
294
- let projects;
295
297
  try {
296
- projects = readProjectConfigurationsFromRootMap(projectRootMap);
298
+ // We still call this just to assert that the root map
299
+ // only contains valid project names. This is a safety check.
300
+ //
301
+ // The signature itself can't be changed as we need it to return
302
+ // project configurations for use in devkit.
303
+ readProjectConfigurationsFromRootMap(projectRootMap);
297
304
  }
298
305
  catch (e) {
299
306
  if ((0, error_types_1.isProjectsWithNoNameError)(e) ||
300
307
  (0, error_types_1.isProjectsWithConflictingNamesError)(e)) {
301
- projects = e.projects;
302
308
  errors.push(e);
303
309
  }
304
310
  else {
@@ -312,18 +318,20 @@ plugins) {
312
318
  perf_hooks_1.performance.measure('build-project-configs', 'build-project-configs:start', 'build-project-configs:end');
313
319
  if (errors.length === 0) {
314
320
  return {
315
- projects,
321
+ projects: projectRootMap,
316
322
  externalNodes,
317
323
  projectRootMap: rootMap,
318
324
  sourceMaps: configurationSourceMaps,
325
+ matchingProjectFiles: projectFiles,
319
326
  };
320
327
  }
321
328
  else {
322
329
  throw new error_types_1.ProjectConfigurationsError(errors, {
323
- projects,
330
+ projects: projectRootMap,
324
331
  externalNodes,
325
332
  projectRootMap: rootMap,
326
333
  sourceMaps: configurationSourceMaps,
334
+ matchingProjectFiles: projectFiles,
327
335
  });
328
336
  }
329
337
  });
@@ -336,7 +344,8 @@ function readProjectConfigurationsFromRootMap(projectRootMap) {
336
344
  // to provide better error messaging.
337
345
  const conflicts = new Map();
338
346
  const projectRootsWithNoName = [];
339
- for (const [root, configuration] of projectRootMap.entries()) {
347
+ for (const root in projectRootMap) {
348
+ const configuration = projectRootMap[root];
340
349
  // We're setting `// targets` as a comment `targets` is empty due to Project Crystal.
341
350
  // Strip it before returning configuration for usage.
342
351
  if (configuration['// targets'])
@@ -344,6 +353,9 @@ function readProjectConfigurationsFromRootMap(projectRootMap) {
344
353
  if (!configuration.name) {
345
354
  try {
346
355
  const { name } = (0, fileutils_1.readJsonFile)((0, path_1.join)(root, 'package.json'));
356
+ if (!name) {
357
+ throw new Error("No name found for project at '" + root + "'.");
358
+ }
347
359
  configuration.name = name;
348
360
  }
349
361
  catch {
@@ -388,7 +400,7 @@ function mergeTargetConfigurations(target, baseTarget, projectConfigSourceMap, s
388
400
  const { configurations: defaultConfigurations, options: defaultOptions, ...baseTargetProperties } = baseTarget ?? {};
389
401
  // Target is "compatible", e.g. executor is defined only once or is the same
390
402
  // in both places. This means that it is likely safe to merge
391
- const isCompatible = isCompatibleTarget(baseTargetProperties, target);
403
+ const isCompatible = isCompatibleTarget(baseTarget ?? {}, target);
392
404
  // If the targets are not compatible, we would normally overwrite the old target
393
405
  // with the new one. However, we have a special case for targets that have the
394
406
  // ONLY_MODIFIES_EXISTING_TARGET symbol set. This prevents the merged target
@@ -451,8 +463,8 @@ function isCompatibleTarget(a, b) {
451
463
  return false;
452
464
  const isRunCommands = a.executor === 'nx:run-commands';
453
465
  if (isRunCommands) {
454
- const aCommand = a.options?.command ?? a.options?.commands.join(' && ');
455
- const bCommand = b.options?.command ?? b.options?.commands.join(' && ');
466
+ const aCommand = a.options?.command ?? a.options?.commands?.join(' && ');
467
+ const bCommand = b.options?.command ?? b.options?.commands?.join(' && ');
456
468
  const oneHasNoCommand = !aCommand || !bCommand;
457
469
  const hasSameCommand = aCommand === bCommand;
458
470
  return oneHasNoCommand || hasSameCommand;
@@ -544,7 +556,8 @@ function readTargetDefaultsForTarget(targetName, targetDefaults, executor) {
544
556
  exports.readTargetDefaultsForTarget = readTargetDefaultsForTarget;
545
557
  function createRootMap(projectRootMap) {
546
558
  const map = {};
547
- for (const [projectRoot, { name: projectName }] of projectRootMap) {
559
+ for (const projectRoot in projectRootMap) {
560
+ const projectName = projectRootMap[projectRoot].name;
548
561
  map[projectRoot] = projectName;
549
562
  }
550
563
  return map;
@@ -568,3 +581,13 @@ function resolveCommandSyntacticSugar(target, key) {
568
581
  };
569
582
  }
570
583
  }
584
+ function normalizeTarget(target, project) {
585
+ target = resolveCommandSyntacticSugar(target, project.root);
586
+ target.options = resolveNxTokensInOptions(target.options, project, `${project.root}:${target}`);
587
+ target.configurations ??= {};
588
+ for (const configuration in target.configurations) {
589
+ target.configurations[configuration] = resolveNxTokensInOptions(target.configurations[configuration], project, `${project.root}:${target}:${configuration}`);
590
+ }
591
+ return target;
592
+ }
593
+ exports.normalizeTarget = normalizeTarget;
@@ -170,7 +170,6 @@ class ProcessTasks {
170
170
  projectRoot: project.data.root,
171
171
  overrides: interpolatedOverrides,
172
172
  outputs: (0, utils_1.getOutputs)(this.projectGraph.nodes, qualifiedTarget, interpolatedOverrides),
173
- // TODO(v19): Remove cast here after typing is moved back onto TargetConfiguration
174
173
  cache: project.data.targets[target].cache,
175
174
  };
176
175
  }
@@ -24,6 +24,10 @@ const EXTENDED_LEFT_PAD = ` `;
24
24
  */
25
25
  async function createRunManyDynamicOutputRenderer({ projectNames, tasks, args, overrides, }) {
26
26
  cliCursor.hide();
27
+ // Show the cursor again after the process exits
28
+ process.on('exit', () => {
29
+ cliCursor.show();
30
+ });
27
31
  let resolveRenderIsDonePromise;
28
32
  const renderIsDone = new Promise((resolve) => (resolveRenderIsDonePromise = resolve)).then(() => {
29
33
  clearRenderInterval();
@@ -261,7 +265,7 @@ async function createRunManyDynamicOutputRenderer({ projectNames, tasks, args, o
261
265
  '',
262
266
  `${failedTasksForPrinting
263
267
  .map((t) => `${EXTENDED_LEFT_PAD}${output_1.output.colors.red('-')} ${output_1.output.formatCommand(t.toString())}`)
264
- .join('\n ')}`,
268
+ .join('\n')}`,
265
269
  ];
266
270
  if (failedTasks.size > numFailedToPrint) {
267
271
  failureSummaryRows.push(output_1.output.dim(`${EXTENDED_LEFT_PAD}...and ${failedTasks.size - numFailedToPrint} more...`));
@@ -24,6 +24,10 @@ const EXTENDED_LEFT_PAD = ` `;
24
24
  */
25
25
  async function createRunOneDynamicOutputRenderer({ initiatingProject, tasks, args, overrides, }) {
26
26
  cliCursor.hide();
27
+ // Show the cursor again after the process exits
28
+ process.on('exit', () => {
29
+ cliCursor.show();
30
+ });
27
31
  let resolveRenderIsDonePromise;
28
32
  const renderIsDone = new Promise((resolve) => (resolveRenderIsDonePromise = resolve)).then(() => {
29
33
  clearRenderInterval();
@@ -11,10 +11,11 @@ export declare class PseudoTerminal {
11
11
  static isSupported(): boolean;
12
12
  constructor(rustPseudoTerminal: RustPseudoTerminal);
13
13
  init(): Promise<void>;
14
- runCommand(command: string, { cwd, jsEnv, quiet, }?: {
14
+ runCommand(command: string, { cwd, jsEnv, quiet, tty, }?: {
15
15
  cwd?: string;
16
16
  jsEnv?: Record<string, string>;
17
17
  quiet?: boolean;
18
+ tty?: boolean;
18
19
  }): PseudoTtyProcess;
19
20
  fork(id: string, script: string, { cwd, jsEnv, quiet, }: {
20
21
  cwd?: string;
@@ -32,8 +32,8 @@ class PseudoTerminal {
32
32
  await this.pseudoIPC.init();
33
33
  this.initialized = true;
34
34
  }
35
- runCommand(command, { cwd, jsEnv, quiet, } = {}) {
36
- return new PseudoTtyProcess(this.rustPseudoTerminal.runCommand(command, cwd, jsEnv, quiet));
35
+ runCommand(command, { cwd, jsEnv, quiet, tty, } = {}) {
36
+ return new PseudoTtyProcess(this.rustPseudoTerminal.runCommand(command, cwd, jsEnv, quiet, tty));
37
37
  }
38
38
  async fork(id, script, { cwd, jsEnv, quiet, }) {
39
39
  if (!this.initialized) {
@@ -142,6 +142,12 @@ function supportedPtyPlatform() {
142
142
  if (process.platform !== 'win32') {
143
143
  return true;
144
144
  }
145
+ // TODO: Re-enable Windows support when it's stable
146
+ // Currently, there's an issue with control chars.
147
+ // See: https://github.com/nrwl/nx/issues/22358
148
+ if (process.env.NX_WINDOWS_PTY_SUPPORT !== 'true') {
149
+ return false;
150
+ }
145
151
  let windowsVersion = os.release().split('.');
146
152
  let windowsBuild = windowsVersion[2];
147
153
  if (!windowsBuild) {