nx 21.2.0-beta.1 → 21.2.0-beta.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 (42) hide show
  1. package/README.md +1 -1
  2. package/bin/init-local.d.ts +1 -1
  3. package/bin/init-local.js +7 -1
  4. package/bin/nx.js +9 -6
  5. package/package.json +11 -11
  6. package/src/command-line/affected/command-object.js +1 -1
  7. package/src/command-line/graph/graph.d.ts +1 -0
  8. package/src/command-line/graph/graph.js +56 -11
  9. package/src/command-line/init/implementation/angular/legacy-angular-versions.js +23 -4
  10. package/src/command-line/migrate/migrate.js +10 -4
  11. package/src/command-line/release/changelog.js +15 -5
  12. package/src/command-line/release/version/release-group-processor.js +1 -1
  13. package/src/command-line/release/version/topological-sort.js +1 -1
  14. package/src/command-line/report/report.js +1 -1
  15. package/src/command-line/run/run-one.d.ts +10 -0
  16. package/src/command-line/run/run-one.js +16 -5
  17. package/src/core/graph/main.js +1 -1
  18. package/src/core/graph/styles.js +1 -1
  19. package/src/executors/run-commands/run-commands.impl.d.ts +2 -1
  20. package/src/executors/run-commands/run-commands.impl.js +5 -0
  21. package/src/native/index.d.ts +12 -2
  22. package/src/native/native-bindings.js +4 -1
  23. package/src/native/nx.wasi-browser.js +47 -40
  24. package/src/native/nx.wasi.cjs +47 -40
  25. package/src/native/nx.wasm32-wasi.wasm +0 -0
  26. package/src/nx-cloud/utilities/url-shorten.d.ts +1 -1
  27. package/src/nx-cloud/utilities/url-shorten.js +27 -26
  28. package/src/plugins/js/lock-file/pnpm-parser.js +11 -3
  29. package/src/plugins/js/lock-file/project-graph-pruning.d.ts +2 -1
  30. package/src/plugins/js/lock-file/project-graph-pruning.js +4 -0
  31. package/src/plugins/js/project-graph/affected/lock-file-changes.js +6 -3
  32. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +22 -12
  33. package/src/plugins/js/utils/register.d.ts +3 -2
  34. package/src/plugins/js/utils/register.js +36 -22
  35. package/src/plugins/js/utils/typescript.d.ts +2 -1
  36. package/src/plugins/js/utils/typescript.js +12 -7
  37. package/src/project-graph/plugins/transpiler.js +5 -5
  38. package/src/tasks-runner/run-command.js +12 -1
  39. package/src/tasks-runner/running-tasks/noop-child-process.d.ts +2 -1
  40. package/src/tasks-runner/running-tasks/noop-child-process.js +4 -1
  41. package/src/utils/nx-console-prompt.d.ts +1 -0
  42. package/src/utils/nx-console-prompt.js +50 -0
@@ -9,6 +9,7 @@ exports.registerTsConfigPaths = registerTsConfigPaths;
9
9
  exports.getTsNodeCompilerOptions = getTsNodeCompilerOptions;
10
10
  const path_1 = require("path");
11
11
  const logger_1 = require("../../../utils/logger");
12
+ const typescript_1 = require("./typescript");
12
13
  const swcNodeInstalled = packageIsInstalled('@swc-node/register');
13
14
  const tsNodeInstalled = packageIsInstalled('ts-node/register');
14
15
  let ts;
@@ -53,10 +54,10 @@ function registerTsProject(path, configFilename) {
53
54
  return () => { };
54
55
  }
55
56
  const tsConfigPath = configFilename ? (0, path_1.join)(path, configFilename) : path;
56
- const compilerOptions = readCompilerOptions(tsConfigPath);
57
+ const { compilerOptions, tsConfigRaw } = readCompilerOptions(tsConfigPath);
57
58
  const cleanupFunctions = [
58
59
  registerTsConfigPaths(tsConfigPath),
59
- registerTranspiler(compilerOptions),
60
+ registerTranspiler(compilerOptions, tsConfigRaw),
60
61
  ];
61
62
  // Add ESM support for `.ts` files.
62
63
  // NOTE: There is no cleanup function for this, as it's not possible to unregister the loader.
@@ -90,12 +91,16 @@ function getSwcTranspiler(compilerOptions) {
90
91
  const cleanupFn = register(compilerOptions);
91
92
  return typeof cleanupFn === 'function' ? cleanupFn : () => { };
92
93
  }
93
- function getTsNodeTranspiler(compilerOptions) {
94
+ function getTsNodeTranspiler(compilerOptions, tsNodeOptions) {
94
95
  const { register } = require('ts-node');
95
96
  // ts-node doesn't provide a cleanup method
96
97
  const service = register({
98
+ ...tsNodeOptions,
97
99
  transpileOnly: true,
98
- compilerOptions: getTsNodeCompilerOptions(compilerOptions),
100
+ compilerOptions: getTsNodeCompilerOptions({
101
+ ...tsNodeOptions?.compilerOptions,
102
+ ...compilerOptions,
103
+ }),
99
104
  // we already read and provide the compiler options, so prevent ts-node from reading them again
100
105
  skipProject: true,
101
106
  });
@@ -165,21 +170,30 @@ function getTranspiler(compilerOptions, tsConfigRaw) {
165
170
  compilerOptions.target = ts.ScriptTarget.ES2021;
166
171
  compilerOptions.inlineSourceMap = true;
167
172
  compilerOptions.skipLibCheck = true;
173
+ let _getTranspiler;
174
+ let registrationKey = JSON.stringify(compilerOptions);
175
+ let tsNodeOptions;
176
+ if (swcNodeInstalled && !preferTsNode) {
177
+ _getTranspiler = getSwcTranspiler;
178
+ }
179
+ else if (tsNodeInstalled) {
180
+ // We can fall back on ts-node if it's available
181
+ _getTranspiler = getTsNodeTranspiler;
182
+ tsNodeOptions = filterRecognizedTsConfigTsNodeOptions(tsConfigRaw?.['ts-node']).recognized;
183
+ // include ts-node options in the registration key
184
+ registrationKey += JSON.stringify(tsNodeOptions);
185
+ }
186
+ else {
187
+ _getTranspiler = undefined;
188
+ }
168
189
  // Just return if transpiler was already registered before.
169
- const registrationKey = JSON.stringify(compilerOptions);
170
190
  const registrationEntry = registered.get(registrationKey);
171
191
  if (registered.has(registrationKey)) {
172
192
  registrationEntry.refCount++;
173
193
  return registrationEntry.cleanup;
174
194
  }
175
- const _getTranspiler = swcNodeInstalled && !preferTsNode
176
- ? getSwcTranspiler
177
- : tsNodeInstalled
178
- ? // We can fall back on ts-node if it's available
179
- getTsNodeTranspiler
180
- : undefined;
181
195
  if (_getTranspiler) {
182
- const transpilerCleanup = _getTranspiler(compilerOptions);
196
+ const transpilerCleanup = _getTranspiler(compilerOptions, tsNodeOptions);
183
197
  const currRegistrationEntry = {
184
198
  refCount: 1,
185
199
  cleanup: () => {
@@ -204,9 +218,9 @@ function getTranspiler(compilerOptions, tsConfigRaw) {
204
218
  *
205
219
  * @returns cleanup method
206
220
  */
207
- function registerTranspiler(compilerOptions) {
221
+ function registerTranspiler(compilerOptions, tsConfigRaw) {
208
222
  // Function to register transpiler that returns cleanup function
209
- const transpiler = getTranspiler(compilerOptions);
223
+ const transpiler = getTranspiler(compilerOptions, tsConfigRaw);
210
224
  if (!transpiler) {
211
225
  warnNoTranspiler();
212
226
  return () => { };
@@ -245,7 +259,9 @@ function registerTsConfigPaths(tsConfigPath) {
245
259
  function readCompilerOptions(tsConfigPath) {
246
260
  const preferTsNode = process.env.NX_PREFER_TS_NODE === 'true';
247
261
  if (swcNodeInstalled && !preferTsNode) {
248
- return readCompilerOptionsWithSwc(tsConfigPath);
262
+ return {
263
+ compilerOptions: readCompilerOptionsWithSwc(tsConfigPath),
264
+ };
249
265
  }
250
266
  else {
251
267
  return readCompilerOptionsWithTypescript(tsConfigPath);
@@ -261,16 +277,14 @@ function readCompilerOptionsWithSwc(tsConfigPath) {
261
277
  return compilerOptions;
262
278
  }
263
279
  function readCompilerOptionsWithTypescript(tsConfigPath) {
264
- if (!ts) {
265
- ts = require('typescript');
266
- }
267
- const { readConfigFile, parseJsonConfigFileContent, sys } = ts;
268
- const jsonContent = readConfigFile(tsConfigPath, sys.readFile);
269
- const { options } = parseJsonConfigFileContent(jsonContent.config, sys, (0, path_1.dirname)(tsConfigPath));
280
+ const { options, raw } = (0, typescript_1.readTsConfigWithoutFiles)(tsConfigPath);
270
281
  // This property is returned in compiler options for some reason, but not part of the typings.
271
282
  // ts-node fails on unknown props, so we have to remove it.
272
283
  delete options.configFilePath;
273
- return options;
284
+ return {
285
+ compilerOptions: options,
286
+ tsConfigRaw: raw,
287
+ };
274
288
  }
275
289
  function loadTsConfigPaths() {
276
290
  try {
@@ -1,6 +1,7 @@
1
1
  import type * as ts from 'typescript';
2
2
  import type { Node, SyntaxKind } from 'typescript';
3
- export declare function readTsConfig(tsConfigPath: string): ts.ParsedCommandLine;
3
+ export declare function readTsConfig(tsConfigPath: string, sys?: ts.System): ts.ParsedCommandLine;
4
+ export declare function readTsConfigWithoutFiles(tsConfigPath: string): ts.ParsedCommandLine;
4
5
  export declare function readTsConfigOptions(tsConfigPath: string): ts.CompilerOptions;
5
6
  /**
6
7
  * Find a module based on its import
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.readTsConfig = readTsConfig;
4
+ exports.readTsConfigWithoutFiles = readTsConfigWithoutFiles;
4
5
  exports.readTsConfigOptions = readTsConfigOptions;
5
6
  exports.resolveModuleByImport = resolveModuleByImport;
6
7
  exports.getRootTsConfigFileName = getRootTsConfigFileName;
@@ -11,25 +12,29 @@ const fs_1 = require("fs");
11
12
  const path_1 = require("path");
12
13
  const normalizedAppRoot = workspace_root_1.workspaceRoot.replace(/\\/g, '/');
13
14
  let tsModule;
14
- function readTsConfig(tsConfigPath) {
15
+ function readTsConfig(tsConfigPath, sys) {
15
16
  if (!tsModule) {
16
17
  tsModule = require('typescript');
17
18
  }
18
- const readResult = tsModule.readConfigFile(tsConfigPath, tsModule.sys.readFile);
19
- return tsModule.parseJsonConfigFileContent(readResult.config, tsModule.sys, (0, path_1.dirname)(tsConfigPath));
19
+ sys ??= tsModule.sys;
20
+ const readResult = tsModule.readConfigFile(tsConfigPath, sys.readFile);
21
+ return tsModule.parseJsonConfigFileContent(readResult.config, sys, (0, path_1.dirname)(tsConfigPath));
20
22
  }
21
- function readTsConfigOptions(tsConfigPath) {
23
+ function readTsConfigWithoutFiles(tsConfigPath) {
22
24
  if (!tsModule) {
23
25
  tsModule = require('typescript');
24
26
  }
25
- const readResult = tsModule.readConfigFile(tsConfigPath, tsModule.sys.readFile);
26
27
  // We only care about options, so we don't need to scan source files, and thus
27
28
  // `readDirectory` is stubbed for performance.
28
- const host = {
29
+ const sys = {
29
30
  ...tsModule.sys,
30
31
  readDirectory: () => [],
31
32
  };
32
- return tsModule.parseJsonConfigFileContent(readResult.config, host, (0, path_1.dirname)(tsConfigPath)).options;
33
+ return readTsConfig(tsConfigPath, sys);
34
+ }
35
+ function readTsConfigOptions(tsConfigPath) {
36
+ const { options } = readTsConfigWithoutFiles(tsConfigPath);
37
+ return options;
33
38
  }
34
39
  let compilerHost;
35
40
  /**
@@ -6,9 +6,9 @@ exports.pluginTranspilerIsRegistered = pluginTranspilerIsRegistered;
6
6
  exports.cleanupPluginTSTranspiler = cleanupPluginTSTranspiler;
7
7
  const node_fs_1 = require("node:fs");
8
8
  const posix_1 = require("node:path/posix");
9
- const workspace_root_1 = require("../../utils/workspace-root");
10
9
  const register_1 = require("../../plugins/js/utils/register");
11
10
  const typescript_1 = require("../../plugins/js/utils/typescript");
11
+ const workspace_root_1 = require("../../utils/workspace-root");
12
12
  exports.unregisterPluginTSTranspiler = null;
13
13
  /**
14
14
  * Register swc-node or ts-node if they are not currently registered
@@ -23,16 +23,16 @@ function registerPluginTSTranspiler() {
23
23
  if (!tsConfigName) {
24
24
  return;
25
25
  }
26
- const tsConfigOptions = tsConfigName
27
- ? (0, typescript_1.readTsConfigOptions)(tsConfigName)
26
+ const tsConfig = tsConfigName
27
+ ? (0, typescript_1.readTsConfigWithoutFiles)(tsConfigName)
28
28
  : {};
29
29
  const cleanupFns = [
30
30
  (0, register_1.registerTsConfigPaths)(tsConfigName),
31
31
  (0, register_1.registerTranspiler)({
32
32
  experimentalDecorators: true,
33
33
  emitDecoratorMetadata: true,
34
- ...tsConfigOptions,
35
- }),
34
+ ...tsConfig.options,
35
+ }, tsConfig.raw),
36
36
  ];
37
37
  exports.unregisterPluginTSTranspiler = () => {
38
38
  cleanupFns.forEach((fn) => fn?.());
@@ -142,7 +142,7 @@ async function getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, pr
142
142
  : chunk.toString());
143
143
  }
144
144
  else {
145
- (0, native_1.logInfo)(Buffer.isBuffer(chunk)
145
+ (0, native_1.logDebug)(Buffer.isBuffer(chunk)
146
146
  ? chunk.toString(encoding)
147
147
  : chunk.toString());
148
148
  }
@@ -772,6 +772,17 @@ function getRunner(nxArgs, nxJson) {
772
772
  }
773
773
  const defaultTasksRunnerPath = require.resolve('./default-tasks-runner');
774
774
  function getTasksRunnerPath(runner, nxJson) {
775
+ // If running inside of Codex, there will be no internet access, so we cannot use the cloud runner, regardless of other config.
776
+ // We can infer this scenario by checking for certain environment variables defined in their base image: https://github.com/openai/codex-universal
777
+ if (process.env.CODEX_ENV_NODE_VERSION) {
778
+ output_1.output.warn({
779
+ title: 'Codex environment detected, using default tasks runner',
780
+ bodyLines: [
781
+ 'Codex does not have internet access when it runs tasks, so Nx will use the default tasks runner and only leverage local caching.',
782
+ ],
783
+ });
784
+ return defaultTasksRunnerPath;
785
+ }
775
786
  const isCloudRunner =
776
787
  // No tasksRunnerOptions for given --runner
777
788
  nxJson.nxCloudAccessToken ||
@@ -11,5 +11,6 @@ export declare class NoopChildProcess implements RunningTask {
11
11
  terminalOutput: string;
12
12
  }>;
13
13
  kill(): void;
14
- onExit(cb: (code: number) => void): void;
14
+ onExit(cb: (code: number, terminalOutput: string) => void): void;
15
+ onOutput(cb: (terminalOutput: string) => void): void;
15
16
  }
@@ -13,7 +13,10 @@ class NoopChildProcess {
13
13
  return;
14
14
  }
15
15
  onExit(cb) {
16
- cb(this.results.code);
16
+ cb(this.results.code, this.results.terminalOutput);
17
+ }
18
+ onOutput(cb) {
19
+ cb(this.results.terminalOutput);
17
20
  }
18
21
  }
19
22
  exports.NoopChildProcess = NoopChildProcess;
@@ -0,0 +1 @@
1
+ export declare function ensureNxConsoleInstalled(): Promise<void>;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureNxConsoleInstalled = ensureNxConsoleInstalled;
4
+ const enquirer_1 = require("enquirer");
5
+ const os_1 = require("os");
6
+ const output_1 = require("./output");
7
+ const native_1 = require("../native");
8
+ async function ensureNxConsoleInstalled() {
9
+ const preferences = new native_1.NxConsolePreferences((0, os_1.homedir)());
10
+ let setting = preferences.getAutoInstallPreference();
11
+ const canInstallConsole = (0, native_1.canInstallNxConsole)();
12
+ // Noop
13
+ if (!canInstallConsole) {
14
+ return;
15
+ }
16
+ if (typeof setting !== 'boolean') {
17
+ setting = await promptForNxConsoleInstallation();
18
+ preferences.setAutoInstallPreference(setting);
19
+ }
20
+ if (setting) {
21
+ (0, native_1.installNxConsole)();
22
+ }
23
+ }
24
+ /**
25
+ * Prompts the user whether they want to automatically install the Nx Console extension
26
+ * and persists their preference using the NxConsolePreferences struct
27
+ */
28
+ async function promptForNxConsoleInstallation() {
29
+ try {
30
+ output_1.output.log({
31
+ title: "Enhance your developer experience with Nx Console, Nx's official editor extension",
32
+ bodyLines: [
33
+ '- Enable your AI assistant to do more by understanding your workspace',
34
+ '- Add IntelliSense for Nx configuration files',
35
+ '- Explore your workspace visually',
36
+ '- Generate code and execute tasks interactively',
37
+ ],
38
+ });
39
+ const { shouldInstallNxConsole } = await (0, enquirer_1.prompt)({
40
+ type: 'confirm',
41
+ name: 'shouldInstallNxConsole',
42
+ message: 'Install Nx Console? (you can uninstall anytime)',
43
+ initial: true,
44
+ });
45
+ return shouldInstallNxConsole;
46
+ }
47
+ catch (error) {
48
+ return false;
49
+ }
50
+ }