nx 19.2.2 → 19.3.0-beta.0

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.
@@ -19,6 +19,7 @@ const nx_json_1 = require("../../config/nx-json");
19
19
  const daemon_socket_messenger_1 = require("./daemon-socket-messenger");
20
20
  const cache_1 = require("../cache");
21
21
  const error_types_1 = require("../../project-graph/error-types");
22
+ const dotenv_1 = require("../../utils/dotenv");
22
23
  const get_nx_workspace_files_1 = require("../message-types/get-nx-workspace-files");
23
24
  const get_context_file_data_1 = require("../message-types/get-context-file-data");
24
25
  const get_files_in_directory_1 = require("../message-types/get-files-in-directory");
@@ -40,6 +41,7 @@ class DaemonClient {
40
41
  this._daemonReady = null;
41
42
  this._out = null;
42
43
  this._err = null;
44
+ (0, dotenv_1.loadRootEnvFiles)(workspace_root_1.workspaceRoot);
43
45
  try {
44
46
  this.nxJson = (0, configuration_1.readNxJson)();
45
47
  }
@@ -42,7 +42,7 @@ export interface NormalizedRunCommandsOptions extends RunCommandsOptions {
42
42
  [k: string]: any;
43
43
  };
44
44
  unparsedCommandArgs?: {
45
- [k: string]: string | string[];
45
+ [k: string]: string;
46
46
  };
47
47
  args?: string;
48
48
  }
@@ -29,9 +29,7 @@ const propKeys = [
29
29
  'command',
30
30
  'commands',
31
31
  'color',
32
- 'no-color',
33
32
  'parallel',
34
- 'no-parallel',
35
33
  'readyWhen',
36
34
  'cwd',
37
35
  'args',
@@ -133,7 +131,6 @@ function normalizeOptions(options) {
133
131
  'parse-numbers': false,
134
132
  'parse-positional-numbers': false,
135
133
  'dot-notation': false,
136
- 'camel-case-expansion': false,
137
134
  },
138
135
  });
139
136
  options.unknownOptions = Object.keys(options)
@@ -297,21 +294,20 @@ function interpolateArgsIntoCommand(command, opts, forwardAllArgs) {
297
294
  else if (forwardAllArgs) {
298
295
  let args = '';
299
296
  if (Object.keys(opts.unknownOptions ?? {}).length > 0) {
300
- const unknownOptionsArgs = Object.keys(opts.unknownOptions)
301
- .filter((k) => typeof opts.unknownOptions[k] !== 'object' &&
302
- opts.parsedArgs[k] === opts.unknownOptions[k])
303
- .map((k) => `--${k}=${opts.unknownOptions[k]}`)
304
- .map(wrapArgIntoQuotesIfNeeded)
305
- .join(' ');
306
- if (unknownOptionsArgs) {
307
- args += ` ${unknownOptionsArgs}`;
308
- }
297
+ args +=
298
+ ' ' +
299
+ Object.keys(opts.unknownOptions)
300
+ .filter((k) => typeof opts.unknownOptions[k] !== 'object' &&
301
+ opts.parsedArgs[k] === opts.unknownOptions[k])
302
+ .map((k) => `--${k}=${opts.unknownOptions[k]}`)
303
+ .map(wrapArgIntoQuotesIfNeeded)
304
+ .join(' ');
309
305
  }
310
306
  if (opts.args) {
311
307
  args += ` ${opts.args}`;
312
308
  }
313
309
  if (opts.__unparsed__?.length > 0) {
314
- const filterdParsedOptions = filterPropKeysFromUnParsedOptions(opts.__unparsed__, opts.parsedArgs);
310
+ const filterdParsedOptions = filterPropKeysFromUnParsedOptions(opts.__unparsed__, opts.unparsedCommandArgs);
315
311
  if (filterdParsedOptions.length > 0) {
316
312
  args += ` ${filterdParsedOptions
317
313
  .map(wrapArgIntoQuotesIfNeeded)
@@ -339,14 +335,13 @@ function parseArgs(unparsedCommandArgs, unknownOptions, args) {
339
335
  * @param unparsedCommandArgs e.g. { prop1: 'value1', prop2: 'value2', args: 'test'}
340
336
  * @returns filtered options that are not part of the propKeys array e.g. ['--prop1', 'value1', '--prop2=value2']
341
337
  */
342
- function filterPropKeysFromUnParsedOptions(__unparsed__, parseArgs = {}) {
338
+ function filterPropKeysFromUnParsedOptions(__unparsed__, unparsedCommandArgs = {}) {
343
339
  const parsedOptions = [];
344
340
  for (let index = 0; index < __unparsed__.length; index++) {
345
341
  const element = __unparsed__[index];
346
342
  if (element.startsWith('--')) {
347
343
  const key = element.replace('--', '');
348
344
  if (element.includes('=')) {
349
- // key can be in the format of --key=value or --key.subkey=value (e.g. env.foo=bar)
350
345
  if (!propKeys.includes(key.split('=')[0].split('.')[0])) {
351
346
  // check if the key is part of the propKeys array
352
347
  parsedOptions.push(element);
@@ -356,8 +351,7 @@ function filterPropKeysFromUnParsedOptions(__unparsed__, parseArgs = {}) {
356
351
  // check if the next element is a value for the key
357
352
  if (propKeys.includes(key)) {
358
353
  if (index + 1 < __unparsed__.length &&
359
- parseArgs[key] &&
360
- __unparsed__[index + 1].toString() === parseArgs[key].toString()) {
354
+ __unparsed__[index + 1] === unparsedCommandArgs[key]) {
361
355
  index++; // skip the next element
362
356
  }
363
357
  }
@@ -10,7 +10,7 @@ exports.hashArray = hashArray;
10
10
  function hashObject(obj) {
11
11
  const { hashArray } = require('../native');
12
12
  const parts = [];
13
- for (const key of Object.keys(obj ?? {}).sort()) {
13
+ for (const key of Object.keys(obj).sort()) {
14
14
  parts.push(key);
15
15
  parts.push(JSON.stringify(obj[key]));
16
16
  }
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TargetProjectLocator = exports.isBuiltinModuleImport = void 0;
4
4
  const node_module_1 = require("node:module");
5
5
  const node_path_1 = require("node:path");
6
- const semver_1 = require("semver");
7
6
  const find_project_for_path_1 = require("../../../../project-graph/utils/find-project-for-path");
8
7
  const fileutils_1 = require("../../../../utils/fileutils");
9
8
  const workspace_root_1 = require("../../../../utils/workspace-root");
@@ -139,8 +138,7 @@ class TargetProjectLocator {
139
138
  this.npmResolutionCache.set(npmImportForProject, externalNodeName);
140
139
  return externalNodeName;
141
140
  }
142
- const version = (0, semver_1.clean)(externalPackageJson.version);
143
- const npmProjectKey = `npm:${externalPackageJson.name}@${version}`;
141
+ const npmProjectKey = `npm:${externalPackageJson.name}@${externalPackageJson.version}`;
144
142
  const matchingExternalNode = this.npmProjects[npmProjectKey];
145
143
  if (!matchingExternalNode) {
146
144
  return null;
@@ -38,16 +38,7 @@ function buildPackageJsonWorkspacesMatcher(workspaceRoot, readJson) {
38
38
  positivePatterns.push('**/package.json');
39
39
  }
40
40
  return (p) => positivePatterns.some((positive) => (0, minimatch_1.minimatch)(p, positive)) &&
41
- /**
42
- * minimatch will return true if the given p is NOT excluded by the negative pattern.
43
- *
44
- * For example if the negative pattern is "!packages/vite", then the given p "packages/vite" will return false,
45
- * the given p "packages/something-else/package.json" will return true.
46
- *
47
- * Therefore, we need to ensure that every negative pattern returns true to validate that the given p is not
48
- * excluded by any of the negative patterns.
49
- */
50
- negativePatterns.every((negative) => (0, minimatch_1.minimatch)(p, negative));
41
+ !negativePatterns.some((negative) => (0, minimatch_1.minimatch)(p, negative));
51
42
  }
52
43
  exports.buildPackageJsonWorkspacesMatcher = buildPackageJsonWorkspacesMatcher;
53
44
  function createNodeFromPackageJson(pkgJsonPath, root) {
@@ -161,16 +161,6 @@ class AggregateCreateNodesError extends Error {
161
161
  this.errors = errors;
162
162
  this.partialResults = partialResults;
163
163
  this.name = this.constructor.name;
164
- if (
165
- // Errors should be an array
166
- !Array.isArray(errors) ||
167
- !errors.every(
168
- // Where every element is a tuple
169
- (errorTuple) => Array.isArray(errorTuple) &&
170
- // That has a length of 2
171
- errorTuple.length === 2)) {
172
- throw new Error('AggregateCreateNodesError must be constructed with an array of tuples where the first element is a filename or undefined and the second element is the underlying error.');
173
- }
174
164
  }
175
165
  }
176
166
  exports.AggregateCreateNodesError = AggregateCreateNodesError;
@@ -45,7 +45,7 @@ class LoadedNxPlugin {
45
45
  throw e;
46
46
  }
47
47
  // The underlying plugin errored out. We can't know any partial results.
48
- throw new error_types_1.AggregateCreateNodesError([[null, e]], []);
48
+ throw new error_types_1.AggregateCreateNodesError([null, e], []);
49
49
  }
50
50
  finally {
51
51
  performance.mark(`${plugin.name}:createNodes - end`);
@@ -76,29 +76,11 @@ function normalizeImplicitDependencies(source, implicitDependencies, projects) {
76
76
  if (!implicitDependencies?.length) {
77
77
  return implicitDependencies ?? [];
78
78
  }
79
- // Implicit dependencies handle negatives in a different
80
- // way from most other `projects` fields. This is because
81
- // they are used for multiple purposes.
82
- const positivePatterns = [];
83
- const negativePatterns = [];
84
- for (const dep of implicitDependencies) {
85
- if (dep.startsWith('!')) {
86
- negativePatterns.push(dep);
87
- }
88
- else {
89
- positivePatterns.push(dep);
90
- }
91
- }
92
- // Finds all projects that match a positive pattern and are not excluded by a negative pattern
93
- const deps = positivePatterns.length
94
- ? (0, find_matching_projects_1.findMatchingProjects)(positivePatterns.concat(negativePatterns), projects).filter((x) => x !== source)
95
- : [];
96
- // Expands negative patterns to equal project names
97
- const alwaysIgnoredDeps = (0, find_matching_projects_1.findMatchingProjects)(negativePatterns.map((x) => x.slice(1)), projects);
98
- // We return the matching deps, but keep the negative patterns in the list
99
- // so that they can be processed later by implicit-project-dependencies.ts
100
- // This is what allows using a negative implicit dep to remove a dependency
101
- // detected by createDependencies.
102
- return deps.concat(alwaysIgnoredDeps.map((x) => '!' + x));
79
+ const matches = (0, find_matching_projects_1.findMatchingProjects)(implicitDependencies, projects);
80
+ return (matches
81
+ .filter((x) => x !== source)
82
+ // implicit dependencies that start with ! should hang around, to be processed by
83
+ // implicit-project-dependencies.ts after explicit deps are added to graph.
84
+ .concat(implicitDependencies.filter((x) => x.startsWith('!'))));
103
85
  }
104
86
  exports.normalizeImplicitDependencies = normalizeImplicitDependencies;
@@ -245,15 +245,7 @@ plugins) {
245
245
  e
246
246
  : // This represents a single plugin erroring out with a hard error.
247
247
  new error_types_1.AggregateCreateNodesError([[null, e]], []);
248
- const innerErrors = error.errors;
249
- for (const [file, e] of innerErrors) {
250
- if (file) {
251
- errorBodyLines.push(` - ${file}: ${e.message}`);
252
- }
253
- else {
254
- errorBodyLines.push(` - ${e.message}`);
255
- }
256
- }
248
+ errorBodyLines.push(...error.errors.map(([file, e]) => ` - ${file}: ${e.message}`));
257
249
  error.message = errorBodyLines.join('\n');
258
250
  // This represents a single plugin erroring out with a hard error.
259
251
  errors.push(error);
@@ -9,12 +9,12 @@ import { LoadedNxPlugin } from '../plugins/internal-api';
9
9
  * @param nxJson
10
10
  */
11
11
  export declare function retrieveWorkspaceFiles(workspaceRoot: string, projectRootMap: Record<string, string>): Promise<{
12
- allWorkspaceFiles: import("nx/src/devkit-exports").FileData[];
12
+ allWorkspaceFiles: import("../file-utils").FileData[];
13
13
  fileMap: {
14
14
  projectFileMap: ProjectFiles;
15
- nonProjectFiles: import("nx/src/native").FileData[];
15
+ nonProjectFiles: import("../../native").FileData[];
16
16
  };
17
- rustReferences: import("nx/src/native").NxWorkspaceFilesExternals;
17
+ rustReferences: import("../../native").NxWorkspaceFilesExternals;
18
18
  }>;
19
19
  /**
20
20
  * Walk through the workspace and return `ProjectConfigurations`. Only use this if the projectFileMap is not needed.
@@ -64,26 +64,7 @@ class ProcessTasks {
64
64
  ? overrides
65
65
  : { __overrides_unparsed__: [] };
66
66
  if (dependencyConfig.projects) {
67
- /** LERNA SUPPORT START - Remove in v20 */
68
- // Lerna uses `dependencies` in `prepNxOptions`, so we need to maintain
69
- // support for it until lerna can be updated to use the syntax.
70
- //
71
- // This should have been removed in v17, but the updates to lerna had not
72
- // been made yet.
73
- //
74
- // TODO(@agentender): Remove this part in v20
75
- if (typeof dependencyConfig.projects === 'string') {
76
- if (dependencyConfig.projects === 'self') {
77
- this.processTasksForSingleProject(task, task.target.project, dependencyConfig, configuration, taskOverrides, overrides);
78
- continue;
79
- }
80
- else if (dependencyConfig.projects === 'dependencies') {
81
- this.processTasksForDependencies(projectUsedToDeriveDependencies, dependencyConfig, configuration, task, taskOverrides, overrides);
82
- continue;
83
- }
84
- }
85
- /** LERNA SUPPORT END - Remove in v17 */
86
- this.processTasksForMatchingProjects(dependencyConfig, configuration, task, taskOverrides, overrides);
67
+ this.processTasksForMatchingProjects(dependencyConfig, projectUsedToDeriveDependencies, configuration, task, taskOverrides, overrides);
87
68
  }
88
69
  else if (dependencyConfig.dependencies) {
89
70
  this.processTasksForDependencies(projectUsedToDeriveDependencies, dependencyConfig, configuration, task, taskOverrides, overrides);
@@ -93,21 +74,41 @@ class ProcessTasks {
93
74
  }
94
75
  }
95
76
  }
96
- processTasksForMatchingProjects(dependencyConfig, configuration, task, taskOverrides, overrides) {
77
+ processTasksForMatchingProjects(dependencyConfig, projectUsedToDeriveDependencies, configuration, task, taskOverrides, overrides) {
97
78
  const targetProjectSpecifiers = typeof dependencyConfig.projects === 'string'
98
79
  ? [dependencyConfig.projects]
99
80
  : dependencyConfig.projects;
100
- const matchingProjects = (0, find_matching_projects_1.findMatchingProjects)(targetProjectSpecifiers, this.projectGraph.nodes);
101
- if (matchingProjects.length === 0) {
102
- output_1.output.warn({
103
- title: `\`dependsOn\` is misconfigured for ${task.target.project}:${task.target.target}`,
104
- bodyLines: [
105
- `Project patterns "${targetProjectSpecifiers}" does not match any projects.`,
106
- ],
107
- });
108
- }
109
- for (const projectName of matchingProjects) {
110
- this.processTasksForSingleProject(task, projectName, dependencyConfig, configuration, taskOverrides, overrides);
81
+ for (const projectSpecifier of targetProjectSpecifiers) {
82
+ // Lerna uses `dependencies` in `prepNxOptions`, so we need to maintain
83
+ // support for it until lerna can be updated to use the syntax.
84
+ // TODO(@agentender): Remove this part in v17
85
+ if (projectSpecifier === 'dependencies' &&
86
+ !this.projectGraph.nodes[projectSpecifier]) {
87
+ this.processTasksForDependencies(projectUsedToDeriveDependencies, dependencyConfig, configuration, task, taskOverrides, overrides);
88
+ }
89
+ else {
90
+ // Since we need to maintain support for dependencies, it is more coherent
91
+ // that we also support self.
92
+ // TODO(@agentender): Remove this part in v17
93
+ const matchingProjects =
94
+ /** LERNA SUPPORT START - Remove in v17 */
95
+ projectSpecifier === 'self' &&
96
+ !this.projectGraph.nodes[projectSpecifier]
97
+ ? [task.target.project]
98
+ : /** LERNA SUPPORT END */
99
+ (0, find_matching_projects_1.findMatchingProjects)([projectSpecifier], this.projectGraph.nodes);
100
+ if (matchingProjects.length === 0) {
101
+ output_1.output.warn({
102
+ title: `\`dependsOn\` is misconfigured for ${task.target.project}:${task.target.target}`,
103
+ bodyLines: [
104
+ `Project pattern "${projectSpecifier}" does not match any projects.`,
105
+ ],
106
+ });
107
+ }
108
+ for (const projectName of matchingProjects) {
109
+ this.processTasksForSingleProject(task, projectName, dependencyConfig, configuration, taskOverrides, overrides);
110
+ }
111
+ }
111
112
  }
112
113
  }
113
114
  processTasksForSingleProject(task, projectName, dependencyConfig, configuration, taskOverrides, overrides) {
@@ -31,7 +31,7 @@ declare const messageOptions: {
31
31
  }];
32
32
  };
33
33
  export type MessageKey = keyof typeof messageOptions;
34
- export type MessageData = (typeof messageOptions)[MessageKey][number];
34
+ export type MessageData = typeof messageOptions[MessageKey][number];
35
35
  export declare class PromptMessages {
36
36
  private selectedMessages;
37
37
  getPrompt(key: MessageKey): MessageData;
@@ -22,15 +22,6 @@ function findMatchingProjects(patterns = [], projects) {
22
22
  }
23
23
  const projectNames = Object.keys(projects);
24
24
  const matchedProjects = new Set();
25
- // If the first pattern is an exclude pattern,
26
- // we add a wildcard pattern at the first to select
27
- // all projects, except the ones that match the exclude pattern.
28
- // e.g. ['!tag:someTag', 'project2'] will match all projects except
29
- // the ones with the tag 'someTag', and also match the project 'project2',
30
- // regardless of its tags.
31
- if (isExcludePattern(patterns[0])) {
32
- patterns.unshift('*');
33
- }
34
25
  for (const stringPattern of patterns) {
35
26
  if (!stringPattern.length) {
36
27
  continue;
@@ -148,11 +139,8 @@ function addMatchingProjectsByTag(projectNames, projects, pattern, matchedProjec
148
139
  }
149
140
  }
150
141
  }
151
- function isExcludePattern(pattern) {
152
- return pattern.startsWith('!');
153
- }
154
142
  function parseStringPattern(pattern, projects) {
155
- const isExclude = isExcludePattern(pattern);
143
+ const isExclude = pattern.startsWith('!');
156
144
  // Support for things like: `!{type}:value`
157
145
  if (isExclude) {
158
146
  pattern = pattern.substring(1);