@nestjs/cli 11.0.17 → 11.0.19

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.
@@ -75,7 +75,7 @@ class BuildAction extends abstract_action_1.AbstractAction {
75
75
  const builder = isWebpackEnabled
76
76
  ? { type: 'webpack' }
77
77
  : (0, get_builder_1.getBuilder)(configuration, commandOptions, appName);
78
- await (0, delete_out_dir_1.deleteOutDirIfEnabled)(configuration, appName, outDir);
78
+ await (0, delete_out_dir_1.deleteOutDirIfEnabled)(configuration, appName, outDir, tsOptions);
79
79
  this.assetsManager.copyAssets(configuration, appName, outDir, watchAssetsMode);
80
80
  const typeCheck = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.typeCheck', appName, 'typeCheck', commandOptions);
81
81
  if (typeCheck && builder.type !== 'swc') {
@@ -61,7 +61,7 @@ const generateFiles = async (inputs) => {
61
61
  // Only overwrite if the appName is not the default- as it has already been loaded above
62
62
  generateSpec = (0, project_utils_1.shouldGenerateSpec)(configuration, schematic, selectedProjectName, specValue, specOptions.passedAsInput);
63
63
  generateFlat = (0, project_utils_1.shouldGenerateFlat)(configuration, selectedProjectName, flatValue);
64
- generateSpecFileSuffix = (0, project_utils_1.getSpecFileSuffix)(configuration, appName, specFileSuffixValue);
64
+ generateSpecFileSuffix = (0, project_utils_1.getSpecFileSuffix)(configuration, selectedProjectName, specFileSuffixValue);
65
65
  }
66
66
  }
67
67
  if (configuration.generateOptions?.baseDir) {
@@ -35,7 +35,7 @@ class InfoAction extends abstract_action_1.AbstractAction {
35
35
  }
36
36
  async displaySystemInformation() {
37
37
  console.info((0, ansis_1.green) `[System Information]`);
38
- console.info('OS Version :', (0, ansis_1.blue)((0, os_info_utils_1.default)((0, os_1.platform)(), (0, os_1.release)()) + (0, os_1.release)()));
38
+ console.info('OS Version :', (0, ansis_1.blue)((0, os_info_utils_1.default)((0, os_1.platform)(), (0, os_1.release)()) + ' ' + (0, os_1.release)()));
39
39
  console.info('NodeJS Version :', (0, ansis_1.blue)(process.version));
40
40
  await this.displayPackageManagerVersion();
41
41
  }
@@ -5,6 +5,7 @@ export declare class StartAction extends BuildAction {
5
5
  createOnSuccessHook(entryFile: string, sourceRoot: string, debugFlag: boolean | string | undefined, outDirName: string, binaryToRun: string, options: {
6
6
  shell: boolean;
7
7
  envFile?: string[];
8
+ watch?: boolean;
8
9
  }): () => void;
9
10
  private spawnChildProcess;
10
11
  }
@@ -39,6 +39,7 @@ class StartAction extends build_action_1.BuildAction {
39
39
  const onSuccess = this.createOnSuccessHook(entryFile, sourceRoot, debugFlag, outDir, binaryToRun, {
40
40
  shell: useShell,
41
41
  envFile,
42
+ watch: isWatchEnabled,
42
43
  });
43
44
  await this.runBuild(commandInputs, commandOptions, isWatchEnabled, isWatchAssetsEnabled, !!debugFlag, onSuccess);
44
45
  }
@@ -54,6 +55,18 @@ class StartAction extends build_action_1.BuildAction {
54
55
  createOnSuccessHook(entryFile, sourceRoot, debugFlag, outDirName, binaryToRun, options) {
55
56
  let childProcessRef;
56
57
  process.on('exit', () => childProcessRef && (0, tree_kill_1.treeKillSync)(childProcessRef.pid));
58
+ if (!options.watch) {
59
+ const signalHandler = (signal) => {
60
+ if (childProcessRef) {
61
+ childProcessRef.kill(signal);
62
+ }
63
+ else {
64
+ process.exit();
65
+ }
66
+ };
67
+ process.on('SIGINT', signalHandler);
68
+ process.on('SIGTERM', signalHandler);
69
+ }
57
70
  return () => {
58
71
  if (childProcessRef) {
59
72
  childProcessRef.removeAllListeners('exit');
@@ -4,6 +4,7 @@ exports.GenerateCommand = void 0;
4
4
  const ansis_1 = require("ansis");
5
5
  const Table = require("cli-table3");
6
6
  const schematics_1 = require("../lib/schematics");
7
+ const extra_args_warning_1 = require("../lib/utils/extra-args-warning");
7
8
  const load_configuration_1 = require("../lib/utils/load-configuration");
8
9
  const abstract_command_1 = require("./abstract.command");
9
10
  class GenerateCommand extends abstract_command_1.AbstractCommand {
@@ -26,6 +27,7 @@ class GenerateCommand extends abstract_command_1.AbstractCommand {
26
27
  })
27
28
  .option('-c, --collection [collectionName]', 'Schematics collection to use.')
28
29
  .action(async (schematic, name, path, command) => {
30
+ (0, extra_args_warning_1.exitIfExtraArgs)(command, 3);
29
31
  const options = [];
30
32
  options.push({ name: 'dry-run', value: !!command.dryRun });
31
33
  if (command.flat !== undefined) {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InfoCommand = void 0;
4
+ const extra_args_warning_1 = require("../lib/utils/extra-args-warning");
4
5
  const abstract_command_1 = require("./abstract.command");
5
6
  class InfoCommand extends abstract_command_1.AbstractCommand {
6
7
  load(program) {
@@ -8,7 +9,8 @@ class InfoCommand extends abstract_command_1.AbstractCommand {
8
9
  .command('info')
9
10
  .alias('i')
10
11
  .description('Display Nest project details.')
11
- .action(async () => {
12
+ .action(async (command) => {
13
+ (0, extra_args_warning_1.exitIfExtraArgs)(command, 0);
12
14
  await this.action.handle();
13
15
  });
14
16
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NewCommand = void 0;
4
4
  const schematics_1 = require("../lib/schematics");
5
+ const extra_args_warning_1 = require("../lib/utils/extra-args-warning");
5
6
  const abstract_command_1 = require("./abstract.command");
6
7
  class NewCommand extends abstract_command_1.AbstractCommand {
7
8
  load(program) {
@@ -18,6 +19,7 @@ class NewCommand extends abstract_command_1.AbstractCommand {
18
19
  .option('-c, --collection [collectionName]', 'Schematics collection to use', schematics_1.Collection.NESTJS)
19
20
  .option('--strict', 'Enables strict mode in TypeScript.', false)
20
21
  .action(async (name, command) => {
22
+ (0, extra_args_warning_1.exitIfExtraArgs)(command, 1);
21
23
  const options = [];
22
24
  const availableLanguages = ['js', 'ts', 'javascript', 'typescript'];
23
25
  options.push({ name: 'directory', value: command.directory });
@@ -2,12 +2,11 @@ import { Configuration } from '../configuration';
2
2
  export declare class AssetsManager {
3
3
  private watchAssetsKeyValue;
4
4
  private watchers;
5
- private actionInProgress;
5
+ private watcherReadyPromises;
6
6
  /**
7
- * Using on `nest build` to close file watch or the build process will not end
8
- * Interval like process
9
- * If no action has been taken recently close watchers
10
- * If action has been taken recently flag and try again
7
+ * Using on `nest build` to close file watch or the build process will not end.
8
+ * Waits for all watchers to complete their initial scan before closing them,
9
+ * ensuring all assets are copied regardless of system speed.
11
10
  */
12
11
  closeWatchers(): void;
13
12
  copyAssets(configuration: Required<Configuration>, appName: string | undefined, outDir: string, watchAssetsMode: boolean): void;
@@ -11,27 +11,17 @@ class AssetsManager {
11
11
  constructor() {
12
12
  this.watchAssetsKeyValue = {};
13
13
  this.watchers = [];
14
- this.actionInProgress = false;
14
+ this.watcherReadyPromises = [];
15
15
  }
16
16
  /**
17
- * Using on `nest build` to close file watch or the build process will not end
18
- * Interval like process
19
- * If no action has been taken recently close watchers
20
- * If action has been taken recently flag and try again
17
+ * Using on `nest build` to close file watch or the build process will not end.
18
+ * Waits for all watchers to complete their initial scan before closing them,
19
+ * ensuring all assets are copied regardless of system speed.
21
20
  */
22
21
  closeWatchers() {
23
- // Consider adjusting this for larger files
24
- const timeoutMs = 500;
25
- const closeFn = () => {
26
- if (this.actionInProgress) {
27
- this.actionInProgress = false;
28
- setTimeout(closeFn, timeoutMs);
29
- }
30
- else {
31
- this.watchers.forEach((watcher) => watcher.close());
32
- }
33
- };
34
- setTimeout(closeFn, timeoutMs);
22
+ Promise.all(this.watcherReadyPromises).then(() => {
23
+ this.watchers.forEach((watcher) => watcher.close());
24
+ });
35
25
  }
36
26
  copyAssets(configuration, appName, outDir, watchAssetsMode) {
37
27
  const assets = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.assets', appName) || [];
@@ -76,6 +66,7 @@ class AssetsManager {
76
66
  .on('change', (path) => this.actionOnFile({ ...option, path, action: 'change' }))
77
67
  .on('unlink', (path) => this.actionOnFile({ ...option, path, action: 'unlink' }));
78
68
  this.watchers.push(watcher);
69
+ this.watcherReadyPromises.push(new Promise((resolve) => watcher.on('ready', resolve)));
79
70
  }
80
71
  else {
81
72
  const matchedPaths = (0, glob_1.sync)(item.glob, {
@@ -112,8 +103,6 @@ class AssetsManager {
112
103
  }
113
104
  // Set path value to true for watching the first time
114
105
  this.watchAssetsKeyValue[assetCheckKey] = true;
115
- // Set action to true to avoid watches getting cutoff
116
- this.actionInProgress = true;
117
106
  const dest = (0, copy_path_resolve_1.copyPathResolve)(path, item.outDir, sourceRoot.split(path_1.sep).length);
118
107
  // Copy to output dir if file is changed or added
119
108
  if (action === 'change') {
@@ -34,10 +34,12 @@ class Compiler extends base_compiler_1.BaseCompiler {
34
34
  const afterDeclarations = plugins.afterDeclarationsHooks.map((hook) => hook(programRef));
35
35
  const emitResult = program.emit(undefined, undefined, undefined, undefined, {
36
36
  before: tsconfigPathsPlugin
37
- ? before.concat(tsconfigPathsPlugin)
37
+ ? [tsconfigPathsPlugin, ...before]
38
38
  : before,
39
39
  after,
40
- afterDeclarations,
40
+ afterDeclarations: tsconfigPathsPlugin
41
+ ? [tsconfigPathsPlugin, ...afterDeclarations]
42
+ : afterDeclarations,
41
43
  });
42
44
  const errorsCount = this.reportAfterCompilationDiagnostic(program, emitResult, tsBinary, formatHost);
43
45
  if (errorsCount) {
@@ -39,7 +39,7 @@ const swcDefaultsFactory = (tsOptions, configuration) => {
39
39
  includeDotfiles: false,
40
40
  quiet: false,
41
41
  watch: false,
42
- stripLeadingPaths: true,
42
+ stripLeadingPaths: !tsOptions?.rootDir,
43
43
  ...builderOptions,
44
44
  },
45
45
  };
@@ -1,2 +1,3 @@
1
+ import * as ts from 'typescript';
1
2
  import { Configuration } from '../../configuration';
2
- export declare function deleteOutDirIfEnabled(configuration: Required<Configuration>, appName: string | undefined, dirPath: string): Promise<void>;
3
+ export declare function deleteOutDirIfEnabled(configuration: Required<Configuration>, appName: string | undefined, dirPath: string, tsOptions?: ts.CompilerOptions): Promise<void>;
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deleteOutDirIfEnabled = deleteOutDirIfEnabled;
4
4
  const promises_1 = require("fs/promises");
5
5
  const get_value_or_default_1 = require("./get-value-or-default");
6
- async function deleteOutDirIfEnabled(configuration, appName, dirPath) {
6
+ async function deleteOutDirIfEnabled(configuration, appName, dirPath, tsOptions) {
7
7
  const isDeleteEnabled = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.deleteOutDir', appName);
8
8
  if (!isDeleteEnabled) {
9
9
  return;
10
10
  }
11
11
  await (0, promises_1.rm)(dirPath, { recursive: true, force: true });
12
+ if (tsOptions?.tsBuildInfoFile) {
13
+ await (0, promises_1.rm)(tsOptions.tsBuildInfoFile, { force: true });
14
+ }
12
15
  }
@@ -15,9 +15,14 @@ function getWebpackConfigPath(configuration, cmdOptions, appName) {
15
15
  return webpackPath;
16
16
  }
17
17
  const builder = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.builder', appName);
18
- webpackPath =
19
- typeof builder === 'object' && builder?.type === 'webpack'
20
- ? builder.options?.configPath
21
- : undefined;
22
- return webpackPath;
18
+ if (typeof builder === 'object' && builder?.type === 'webpack') {
19
+ const webpackConfigPath = builder.options?.configPath;
20
+ if (webpackConfigPath) {
21
+ return webpackConfigPath;
22
+ }
23
+ // If builder.type is 'webpack' but no config path is specified, return undefined
24
+ // to let webpack use its default behavior
25
+ return undefined;
26
+ }
27
+ return undefined;
23
28
  }
@@ -223,9 +223,11 @@ class SwcCompiler extends base_compiler_1.BaseCompiler {
223
223
  pollInterval: 10,
224
224
  },
225
225
  });
226
- for (const type of ['add', 'change']) {
227
- watcher.on(type, async () => onChange());
228
- }
226
+ watcher.on('ready', () => {
227
+ for (const type of ['add', 'change']) {
228
+ watcher.on(type, async () => onChange());
229
+ }
230
+ });
229
231
  }
230
232
  }
231
233
  exports.SwcCompiler = SwcCompiler;
@@ -56,6 +56,7 @@ class WatchCompiler extends base_compiler_1.BaseCompiler {
56
56
  const afterDeclarations = plugins.afterDeclarationsHooks.map((hook) => hook(program.getProgram()));
57
57
  if (tsconfigPathsPlugin) {
58
58
  before.unshift(tsconfigPathsPlugin);
59
+ afterDeclarations.unshift(tsconfigPathsPlugin);
59
60
  }
60
61
  transforms.before = before.concat(transforms.before || []);
61
62
  transforms.after = after.concat(transforms.after || []);
@@ -1,4 +1,4 @@
1
- export type Asset = 'string' | AssetEntry;
1
+ export type Asset = string | AssetEntry;
2
2
  export interface AssetEntry {
3
3
  glob: string;
4
4
  include?: string;
@@ -52,7 +52,7 @@ export interface CompilerOptions {
52
52
  */
53
53
  webpackConfigPath?: string;
54
54
  plugins?: string[] | PluginOptions[];
55
- assets?: string[];
55
+ assets?: Asset[];
56
56
  deleteOutDir?: boolean;
57
57
  manualRestart?: boolean;
58
58
  builder?: Builder;
@@ -0,0 +1,12 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Checks if extra positional arguments were passed to a command
4
+ * and exits with an error if so.
5
+ *
6
+ * Commander.js silently ignores extra positional arguments beyond what a command
7
+ * defines. This function detects that case and provides a clear error message.
8
+ *
9
+ * @param command - the Command instance received in the action handler
10
+ * @param expectedArgCount - number of positional arguments the command defines
11
+ */
12
+ export declare function exitIfExtraArgs(command: Command, expectedArgCount: number): void;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.exitIfExtraArgs = exitIfExtraArgs;
4
+ const ui_1 = require("../ui");
5
+ /**
6
+ * Checks if extra positional arguments were passed to a command
7
+ * and exits with an error if so.
8
+ *
9
+ * Commander.js silently ignores extra positional arguments beyond what a command
10
+ * defines. This function detects that case and provides a clear error message.
11
+ *
12
+ * @param command - the Command instance received in the action handler
13
+ * @param expectedArgCount - number of positional arguments the command defines
14
+ */
15
+ function exitIfExtraArgs(command, expectedArgCount) {
16
+ const parentArgs = command.parent?.args ?? [];
17
+ if (parentArgs.length > expectedArgCount) {
18
+ const extraArgs = parentArgs.slice(expectedArgCount);
19
+ console.error(`${ui_1.ERROR_PREFIX} Too many arguments. Unexpected extra argument(s): ${extraArgs.join(', ')}`);
20
+ console.error(`Run "nest ${command.name()} --help" for usage information.\n`);
21
+ process.exit(1);
22
+ }
23
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/cli",
3
- "version": "11.0.17",
3
+ "version": "11.0.19",
4
4
  "description": "Nest - modern, fast, powerful node.js web framework (@cli)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -38,9 +38,9 @@
38
38
  },
39
39
  "homepage": "https://github.com/nestjs/nest-cli#readme",
40
40
  "dependencies": {
41
- "@angular-devkit/core": "19.2.22",
42
- "@angular-devkit/schematics": "19.2.22",
43
- "@angular-devkit/schematics-cli": "19.2.22",
41
+ "@angular-devkit/core": "19.2.24",
42
+ "@angular-devkit/schematics": "19.2.24",
43
+ "@angular-devkit/schematics-cli": "19.2.24",
44
44
  "@inquirer/prompts": "7.10.1",
45
45
  "@nestjs/schematics": "^11.0.1",
46
46
  "ansis": "4.2.0",
@@ -54,40 +54,40 @@
54
54
  "tsconfig-paths": "4.2.0",
55
55
  "tsconfig-paths-webpack-plugin": "4.2.0",
56
56
  "typescript": "5.9.3",
57
- "webpack": "5.105.4",
57
+ "webpack": "5.106.0",
58
58
  "webpack-node-externals": "3.0.0"
59
59
  },
60
60
  "devDependencies": {
61
- "@commitlint/cli": "20.4.1",
62
- "@commitlint/config-angular": "20.4.1",
61
+ "@commitlint/cli": "20.5.0",
62
+ "@commitlint/config-angular": "20.5.0",
63
63
  "@swc/cli": "0.7.10",
64
64
  "@swc/core": "1.15.11",
65
65
  "@types/inquirer": "9.0.9",
66
66
  "@types/jest": "29.5.14",
67
- "@types/node": "24.10.13",
67
+ "@types/node": "24.12.2",
68
68
  "@types/node-emoji": "1.8.2",
69
69
  "@types/webpack-node-externals": "3.0.4",
70
- "@typescript-eslint/eslint-plugin": "8.55.0",
71
- "@typescript-eslint/parser": "8.55.0",
70
+ "@typescript-eslint/eslint-plugin": "8.58.1",
71
+ "@typescript-eslint/parser": "8.58.1",
72
72
  "delete-empty": "3.0.0",
73
- "eslint": "9.39.2",
73
+ "eslint": "10.2.0",
74
74
  "eslint-config-prettier": "10.1.8",
75
75
  "gulp": "5.0.1",
76
76
  "gulp-clean": "0.4.0",
77
77
  "husky": "9.1.7",
78
78
  "jest": "29.7.0",
79
- "lint-staged": "16.2.7",
79
+ "lint-staged": "16.4.0",
80
80
  "prettier": "3.8.1",
81
81
  "release-it": "19.2.4",
82
- "ts-jest": "29.4.6",
83
- "ts-loader": "9.5.4",
82
+ "ts-jest": "29.4.9",
83
+ "ts-loader": "9.5.7",
84
84
  "ts-node": "10.9.2"
85
85
  },
86
86
  "lint-staged": {
87
87
  "**/*.{ts,json}": []
88
88
  },
89
89
  "peerDependencies": {
90
- "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0",
90
+ "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0 || ^0.8.0",
91
91
  "@swc/core": "^1.3.62"
92
92
  },
93
93
  "peerDependenciesMeta": {