@nestjs/cli 11.0.6 → 11.0.8

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.
@@ -21,7 +21,7 @@ jobs:
21
21
  build:
22
22
  working_directory: ~/nest
23
23
  docker:
24
- - image: cimg/node:22.3
24
+ - image: cimg/node:22.17.1
25
25
  steps:
26
26
  - checkout
27
27
  - restore_cache:
@@ -40,7 +40,7 @@ jobs:
40
40
  unit_tests:
41
41
  working_directory: ~/nest
42
42
  docker:
43
- - image: cimg/node:22.3
43
+ - image: cimg/node:22.17.1
44
44
  steps:
45
45
  - checkout
46
46
  - *restore-cache
@@ -9,6 +9,7 @@ const ui_1 = require("../lib/ui");
9
9
  const load_configuration_1 = require("../lib/utils/load-configuration");
10
10
  const project_utils_1 = require("../lib/utils/project-utils");
11
11
  const abstract_action_1 = require("./abstract.action");
12
+ const type_assertions_1 = require("../lib/utils/type-assertions");
12
13
  class GenerateAction extends abstract_action_1.AbstractAction {
13
14
  async handle(inputs, options) {
14
15
  await generateFiles(inputs.concat(options));
@@ -88,6 +89,7 @@ const mapSchematicOptions = (inputs) => {
88
89
  const options = [];
89
90
  inputs.forEach((input) => {
90
91
  if (!excludedInputNames.includes(input.name) && input.value !== undefined) {
92
+ (0, type_assertions_1.assertNonArray)(input.value);
91
93
  options.push(new schematics_1.SchematicOption(input.name, input.value));
92
94
  }
93
95
  });
@@ -50,7 +50,7 @@ class InfoAction extends abstract_action_1.AbstractAction {
50
50
  }
51
51
  async displayNestInformation() {
52
52
  this.displayCliVersion();
53
- console.info((0, ansis_1.green) `[Nest Platform Information`);
53
+ console.info((0, ansis_1.green) `[Nest Platform Information]`);
54
54
  await this.displayNestInformationFromPackage();
55
55
  }
56
56
  async displayNestInformationFromPackage() {
@@ -15,6 +15,7 @@ const ui_1 = require("../lib/ui");
15
15
  const formatting_1 = require("../lib/utils/formatting");
16
16
  const gracefully_exit_on_prompt_error_1 = require("../lib/utils/gracefully-exit-on-prompt-error");
17
17
  const abstract_action_1 = require("./abstract.action");
18
+ const type_assertions_1 = require("../lib/utils/type-assertions");
18
19
  class NewAction extends abstract_action_1.AbstractAction {
19
20
  async handle(inputs, options) {
20
21
  const directoryOption = options.find((option) => option.name === 'directory');
@@ -80,6 +81,7 @@ const generateApplicationFiles = async (args, options) => {
80
81
  const mapSchematicOptions = (options) => {
81
82
  return options.reduce((schematicOptions, option) => {
82
83
  if (option.name !== 'skip-install') {
84
+ (0, type_assertions_1.assertNonArray)(option.value);
83
85
  schematicOptions.push(new schematics_1.SchematicOption(option.name, option.value));
84
86
  }
85
87
  return schematicOptions;
@@ -4,7 +4,7 @@ export declare class StartAction extends BuildAction {
4
4
  handle(commandInputs: Input[], commandOptions: Input[]): Promise<void>;
5
5
  createOnSuccessHook(entryFile: string, sourceRoot: string, debugFlag: boolean | string | undefined, outDirName: string, binaryToRun: string, options: {
6
6
  shell: boolean;
7
- envFile?: string;
7
+ envFile?: string[];
8
8
  }): () => void;
9
9
  private spawnChildProcess;
10
10
  }
@@ -12,6 +12,7 @@ const defaults_1 = require("../lib/configuration/defaults");
12
12
  const ui_1 = require("../lib/ui");
13
13
  const tree_kill_1 = require("../lib/utils/tree-kill");
14
14
  const build_action_1 = require("./build.action");
15
+ const type_assertions_1 = require("../lib/utils/type-assertions");
15
16
  class StartAction extends build_action_1.BuildAction {
16
17
  async handle(commandInputs, commandOptions) {
17
18
  try {
@@ -26,6 +27,7 @@ class StartAction extends build_action_1.BuildAction {
26
27
  const watchAssetsModeOption = commandOptions.find((option) => option.name === 'watchAssets');
27
28
  const isWatchAssetsEnabled = !!(watchAssetsModeOption && watchAssetsModeOption.value);
28
29
  const debugFlag = debugModeOption && debugModeOption.value;
30
+ (0, type_assertions_1.assertNonArray)(debugFlag);
29
31
  const binaryToRun = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'exec', appName, 'exec', commandOptions, defaults_1.defaultConfiguration.exec);
30
32
  const { options: tsOptions } = this.tsConfigProvider.getByConfigFilename(pathToTsconfig);
31
33
  const outDir = tsOptions.outDir || defaults_1.defaultOutDir;
@@ -34,7 +36,7 @@ class StartAction extends build_action_1.BuildAction {
34
36
  const shellOption = commandOptions.find((option) => option.name === 'shell');
35
37
  const useShell = !!shellOption?.value;
36
38
  const envFileOption = commandOptions.find((option) => option.name === 'envFile');
37
- const envFile = envFileOption?.value;
39
+ const envFile = (envFileOption?.value ?? []);
38
40
  const onSuccess = this.createOnSuccessHook(entryFile, sourceRoot, debugFlag, outDir, binaryToRun, {
39
41
  shell: useShell,
40
42
  envFile,
@@ -102,8 +104,9 @@ class StartAction extends build_action_1.BuildAction {
102
104
  const inspectFlag = typeof debug === 'string' ? `--inspect=${debug}` : '--inspect';
103
105
  processArgs.unshift(inspectFlag);
104
106
  }
105
- if (options.envFile) {
106
- processArgs.unshift(`--env-file=${options.envFile}`);
107
+ if (options.envFile && options.envFile.length > 0) {
108
+ const envFileNodeArgs = options.envFile.map((envFilePath) => `--env-file=${envFilePath}`);
109
+ processArgs.unshift(envFileNodeArgs.join(' '));
107
110
  }
108
111
  processArgs.unshift('--enable-source-maps');
109
112
  return (0, child_process_1.spawn)(binaryToRun, processArgs, {
@@ -1,5 +1,5 @@
1
1
  export interface Input {
2
2
  name: string;
3
- value: boolean | string;
3
+ value: boolean | string | string[];
4
4
  options?: any;
5
5
  }
@@ -6,6 +6,9 @@ const remaining_flags_1 = require("../lib/utils/remaining-flags");
6
6
  const abstract_command_1 = require("./abstract.command");
7
7
  class StartCommand extends abstract_command_1.AbstractCommand {
8
8
  load(program) {
9
+ const collect = (value, previous) => {
10
+ return previous.concat([value]);
11
+ };
9
12
  program
10
13
  .command('start [app]')
11
14
  .allowUnknownOption()
@@ -25,7 +28,7 @@ class StartCommand extends abstract_command_1.AbstractCommand {
25
28
  .option('--preserveWatchOutput', 'Use "preserveWatchOutput" option when using tsc watch mode.')
26
29
  .option('--shell', "Spawn child processes within a shell (see node's child_process.spawn() method docs). Default: true.", true)
27
30
  .option('--no-shell', 'Do not spawn child processes within a shell.')
28
- .option('--env-file [path]', 'Path to an env file (.env) to be loaded into the environment.')
31
+ .option('--env-file [path]', 'Path to an env file (.env) to be loaded into the environment.', collect, [])
29
32
  .description('Run Nest application.')
30
33
  .action(async (app, command) => {
31
34
  const options = [];
@@ -20,5 +20,6 @@ export declare class SwcCompiler extends BaseCompiler {
20
20
  private getSwcRcFileContentIfExists;
21
21
  private deepMerge;
22
22
  private debounce;
23
+ private watchFilesInSrcDir;
23
24
  private watchFilesInOutDir;
24
25
  }
@@ -5,6 +5,7 @@ const ansis_1 = require("ansis");
5
5
  const child_process_1 = require("child_process");
6
6
  const chokidar = require("chokidar");
7
7
  const fs_1 = require("fs");
8
+ const promises_1 = require("fs/promises");
8
9
  const path = require("path");
9
10
  const path_1 = require("path");
10
11
  const ui_1 = require("../../ui");
@@ -107,14 +108,29 @@ class SwcCompiler extends base_compiler_1.BaseCompiler {
107
108
  const rootDir = process.cwd();
108
109
  swcOptions.jsc.baseUrl = path.join(rootDir, swcOptions.jsc.baseUrl);
109
110
  }
110
- await swcCli.default({
111
+ const swcCliOpts = {
111
112
  ...options,
112
113
  swcOptions,
113
114
  cliOptions: {
114
115
  ...options.cliOptions,
115
116
  watch: extras.watch,
116
117
  },
117
- });
118
+ };
119
+ if (extras.watch) {
120
+ // This is required since SWC no longer supports auto-compiling of newly added files in watch mode.
121
+ // We need to watch the source directory and trigger SWC compilation manually.
122
+ await this.watchFilesInSrcDir(options, async (file) => {
123
+ // Transpile newly added file
124
+ await swcCli.default({
125
+ ...swcCliOpts,
126
+ cliOptions: {
127
+ ...swcCliOpts.cliOptions,
128
+ filenames: [file],
129
+ },
130
+ });
131
+ });
132
+ }
133
+ await swcCli.default(swcCliOpts);
118
134
  }
119
135
  loadSwcCliBinary() {
120
136
  try {
@@ -172,6 +188,28 @@ class SwcCompiler extends base_compiler_1.BaseCompiler {
172
188
  timeout = setTimeout(callback, wait);
173
189
  };
174
190
  }
191
+ async watchFilesInSrcDir(options, onFileAdded) {
192
+ const srcDir = options.cliOptions?.filenames?.[0];
193
+ const isDirectory = await (0, promises_1.stat)(srcDir)
194
+ .then((stats) => stats.isDirectory())
195
+ .catch(() => false);
196
+ if (!srcDir || !isDirectory) {
197
+ // Skip watching if source directory is not a default "src" folder
198
+ // or any other specified directory
199
+ return;
200
+ }
201
+ const extensions = options.cliOptions?.extensions ?? ['ts'];
202
+ const watcher = chokidar.watch(srcDir, {
203
+ ignored: (file, stats) => (stats?.isFile() &&
204
+ extensions.includes(path.extname(file).slice(1))),
205
+ ignoreInitial: true,
206
+ awaitWriteFinish: {
207
+ stabilityThreshold: 50,
208
+ pollInterval: 10,
209
+ },
210
+ });
211
+ watcher.on('add', async (file) => onFileAdded(file));
212
+ }
175
213
  watchFilesInOutDir(options, onChange) {
176
214
  const dir = (0, path_1.isAbsolute)(options.cliOptions.outDir)
177
215
  ? options.cliOptions.outDir
@@ -0,0 +1 @@
1
+ export declare function assertNonArray<T>(value: T): asserts value is Exclude<T, any[]>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertNonArray = assertNonArray;
4
+ function assertNonArray(value) {
5
+ if (Array.isArray(value)) {
6
+ throw new TypeError('Expected a non-array value');
7
+ }
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/cli",
3
- "version": "11.0.6",
3
+ "version": "11.0.8",
4
4
  "description": "Nest - modern, fast, powerful node.js web framework (@cli)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -38,49 +38,49 @@
38
38
  },
39
39
  "homepage": "https://github.com/nestjs/nest-cli#readme",
40
40
  "dependencies": {
41
- "@angular-devkit/core": "19.2.6",
42
- "@angular-devkit/schematics": "19.2.6",
43
- "@angular-devkit/schematics-cli": "19.2.6",
44
- "@inquirer/prompts": "7.4.1",
41
+ "@angular-devkit/core": "19.2.15",
42
+ "@angular-devkit/schematics": "19.2.15",
43
+ "@angular-devkit/schematics-cli": "19.2.15",
44
+ "@inquirer/prompts": "7.7.1",
45
45
  "@nestjs/schematics": "^11.0.1",
46
- "ansis": "3.17.0",
46
+ "ansis": "4.1.0",
47
47
  "chokidar": "4.0.3",
48
48
  "cli-table3": "0.6.5",
49
49
  "commander": "4.1.1",
50
50
  "fork-ts-checker-webpack-plugin": "9.1.0",
51
- "glob": "11.0.1",
51
+ "glob": "11.0.3",
52
52
  "node-emoji": "1.11.0",
53
53
  "ora": "5.4.1",
54
54
  "tree-kill": "1.2.2",
55
55
  "tsconfig-paths": "4.2.0",
56
56
  "tsconfig-paths-webpack-plugin": "4.2.0",
57
- "typescript": "5.7.3",
58
- "webpack": "5.98.0",
57
+ "typescript": "5.8.3",
58
+ "webpack": "5.100.2",
59
59
  "webpack-node-externals": "3.0.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@commitlint/cli": "19.8.0",
63
- "@commitlint/config-angular": "19.8.0",
64
- "@swc/cli": "0.6.0",
65
- "@swc/core": "1.11.16",
66
- "@types/inquirer": "9.0.7",
62
+ "@commitlint/cli": "19.8.1",
63
+ "@commitlint/config-angular": "19.8.1",
64
+ "@swc/cli": "0.7.8",
65
+ "@swc/core": "1.13.2",
66
+ "@types/inquirer": "9.0.8",
67
67
  "@types/jest": "29.5.14",
68
- "@types/node": "22.14.0",
68
+ "@types/node": "22.16.5",
69
69
  "@types/node-emoji": "1.8.2",
70
70
  "@types/webpack-node-externals": "3.0.4",
71
- "@typescript-eslint/eslint-plugin": "8.29.0",
72
- "@typescript-eslint/parser": "8.29.0",
71
+ "@typescript-eslint/eslint-plugin": "8.38.0",
72
+ "@typescript-eslint/parser": "8.38.0",
73
73
  "delete-empty": "3.0.0",
74
- "eslint": "9.23.0",
75
- "eslint-config-prettier": "10.1.1",
76
- "gulp": "5.0.0",
74
+ "eslint": "9.32.0",
75
+ "eslint-config-prettier": "10.1.8",
76
+ "gulp": "5.0.1",
77
77
  "gulp-clean": "0.4.0",
78
78
  "husky": "9.1.7",
79
79
  "jest": "29.7.0",
80
- "lint-staged": "15.5.0",
81
- "prettier": "3.5.3",
82
- "release-it": "18.1.2",
83
- "ts-jest": "29.3.1",
80
+ "lint-staged": "16.1.2",
81
+ "prettier": "3.6.2",
82
+ "release-it": "19.0.4",
83
+ "ts-jest": "29.4.0",
84
84
  "ts-loader": "9.5.2",
85
85
  "ts-node": "10.9.2"
86
86
  },
@@ -88,7 +88,7 @@
88
88
  "**/*.{ts,json}": []
89
89
  },
90
90
  "peerDependencies": {
91
- "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0",
91
+ "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0",
92
92
  "@swc/core": "^1.3.62"
93
93
  },
94
94
  "peerDependenciesMeta": {