@depup/nestjs__cli 11.0.24-depup.7 → 12.0.0-depup.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.
Files changed (220) hide show
  1. package/README.md +7 -15
  2. package/actions/abstract.action.d.ts +1 -2
  3. package/actions/abstract.action.js +1 -5
  4. package/actions/add.action.d.ts +3 -4
  5. package/actions/add.action.js +44 -53
  6. package/actions/build.action.d.ts +18 -11
  7. package/actions/build.action.js +172 -79
  8. package/actions/deploy.action.d.ts +6 -0
  9. package/actions/deploy.action.js +51 -0
  10. package/actions/generate.action.d.ts +3 -3
  11. package/actions/generate.action.js +61 -59
  12. package/actions/index.d.ts +9 -7
  13. package/actions/index.js +9 -23
  14. package/actions/info.action.d.ts +18 -28
  15. package/actions/info.action.js +80 -60
  16. package/actions/new.action.d.ts +3 -3
  17. package/actions/new.action.js +108 -104
  18. package/actions/start.action.d.ts +4 -7
  19. package/actions/start.action.js +40 -47
  20. package/actions/upgrade.action.d.ts +6 -0
  21. package/actions/upgrade.action.js +53 -0
  22. package/bin/nest.js +11 -10
  23. package/changes.json +9 -41
  24. package/commands/abstract.command.d.ts +3 -3
  25. package/commands/abstract.command.js +2 -5
  26. package/commands/add.command.d.ts +3 -3
  27. package/commands/add.command.js +17 -20
  28. package/commands/build.command.d.ts +3 -3
  29. package/commands/build.command.js +52 -56
  30. package/commands/command.input.js +1 -2
  31. package/commands/command.loader.d.ts +2 -2
  32. package/commands/command.loader.js +29 -22
  33. package/commands/context/add.context.d.ts +7 -0
  34. package/commands/context/add.context.js +1 -0
  35. package/commands/context/build.context.d.ts +17 -0
  36. package/commands/context/build.context.js +1 -0
  37. package/commands/context/deploy.context.d.ts +7 -0
  38. package/commands/context/deploy.context.js +1 -0
  39. package/commands/context/generate.context.d.ts +18 -0
  40. package/commands/context/generate.context.js +1 -0
  41. package/commands/context/index.d.ts +7 -0
  42. package/commands/context/index.js +7 -0
  43. package/commands/context/new.context.d.ts +19 -0
  44. package/commands/context/new.context.js +1 -0
  45. package/commands/context/start.context.d.ts +22 -0
  46. package/commands/context/start.context.js +1 -0
  47. package/commands/context/upgrade.context.d.ts +11 -0
  48. package/commands/context/upgrade.context.js +1 -0
  49. package/commands/deploy.command.d.ts +5 -0
  50. package/commands/deploy.command.js +22 -0
  51. package/commands/generate.command.d.ts +3 -3
  52. package/commands/generate.command.js +35 -66
  53. package/commands/index.d.ts +3 -2
  54. package/commands/index.js +3 -18
  55. package/commands/info.command.d.ts +3 -3
  56. package/commands/info.command.js +4 -8
  57. package/commands/new.command.d.ts +3 -3
  58. package/commands/new.command.js +34 -36
  59. package/commands/start.command.d.ts +3 -3
  60. package/commands/start.command.js +48 -73
  61. package/commands/upgrade.command.d.ts +5 -0
  62. package/commands/upgrade.command.js +32 -0
  63. package/lib/compiler/assets-manager.d.ts +20 -8
  64. package/lib/compiler/assets-manager.js +199 -63
  65. package/lib/compiler/base-compiler.d.ts +5 -5
  66. package/lib/compiler/base-compiler.js +10 -13
  67. package/lib/compiler/compiler.d.ts +6 -6
  68. package/lib/compiler/compiler.js +7 -9
  69. package/lib/compiler/defaults/rspack-defaults.d.ts +3 -0
  70. package/lib/compiler/defaults/rspack-defaults.js +179 -0
  71. package/lib/compiler/defaults/swc-defaults.d.ts +5 -2
  72. package/lib/compiler/defaults/swc-defaults.js +22 -6
  73. package/lib/compiler/defaults/webpack-defaults.d.ts +2 -2
  74. package/lib/compiler/defaults/webpack-defaults.js +59 -19
  75. package/lib/compiler/helpers/append-extension.js +3 -6
  76. package/lib/compiler/helpers/copy-path-resolve.js +2 -5
  77. package/lib/compiler/helpers/delete-out-dir.d.ts +1 -1
  78. package/lib/compiler/helpers/delete-out-dir.js +45 -10
  79. package/lib/compiler/helpers/get-builder.d.ts +9 -7
  80. package/lib/compiler/helpers/get-builder.js +3 -6
  81. package/lib/compiler/helpers/get-effective-root-dir.d.ts +16 -0
  82. package/lib/compiler/helpers/get-effective-root-dir.js +56 -0
  83. package/lib/compiler/helpers/get-rspack-config-path.d.ts +10 -0
  84. package/lib/compiler/helpers/get-rspack-config-path.js +19 -0
  85. package/lib/compiler/helpers/get-tsc-config.path.d.ts +2 -3
  86. package/lib/compiler/helpers/get-tsc-config.path.js +6 -9
  87. package/lib/compiler/helpers/get-value-or-default.d.ts +2 -3
  88. package/lib/compiler/helpers/get-value-or-default.js +3 -8
  89. package/lib/compiler/helpers/get-webpack-config-path.d.ts +2 -3
  90. package/lib/compiler/helpers/get-webpack-config-path.js +4 -7
  91. package/lib/compiler/helpers/glob.d.ts +19 -0
  92. package/lib/compiler/helpers/glob.js +185 -0
  93. package/lib/compiler/helpers/manual-restart.js +4 -8
  94. package/lib/compiler/helpers/path-confinement.d.ts +33 -0
  95. package/lib/compiler/helpers/path-confinement.js +63 -0
  96. package/lib/compiler/helpers/tsconfig-provider.d.ts +7 -6
  97. package/lib/compiler/helpers/tsconfig-provider.js +32 -13
  98. package/lib/compiler/hooks/tsconfig-paths.hook.js +13 -13
  99. package/lib/compiler/interfaces/readonly-visitor.interface.js +1 -2
  100. package/lib/compiler/plugins/plugin-metadata-generator.d.ts +37 -1
  101. package/lib/compiler/plugins/plugin-metadata-generator.js +113 -13
  102. package/lib/compiler/plugins/plugin-metadata-printer.d.ts +1 -1
  103. package/lib/compiler/plugins/plugin-metadata-printer.js +5 -9
  104. package/lib/compiler/plugins/plugins-loader.d.ts +2 -2
  105. package/lib/compiler/plugins/plugins-loader.js +12 -12
  106. package/lib/compiler/rspack-compiler.d.ts +21 -0
  107. package/lib/compiler/rspack-compiler.js +111 -0
  108. package/lib/compiler/swc/constants.d.ts +0 -1
  109. package/lib/compiler/swc/constants.js +9 -13
  110. package/lib/compiler/swc/forked-type-checker.js +13 -18
  111. package/lib/compiler/swc/swc-compiler.d.ts +13 -6
  112. package/lib/compiler/swc/swc-compiler.js +116 -70
  113. package/lib/compiler/swc/type-checker-host.js +31 -24
  114. package/lib/compiler/typescript-loader.js +7 -9
  115. package/lib/compiler/watch-compiler.d.ts +5 -5
  116. package/lib/compiler/watch-compiler.js +13 -15
  117. package/lib/compiler/watchers/recursive-directory-watcher.d.ts +37 -0
  118. package/lib/compiler/watchers/recursive-directory-watcher.js +334 -0
  119. package/lib/compiler/webpack-compiler.d.ts +6 -7
  120. package/lib/compiler/webpack-compiler.js +46 -23
  121. package/lib/configuration/configuration.d.ts +16 -3
  122. package/lib/configuration/configuration.js +1 -2
  123. package/lib/configuration/configuration.loader.d.ts +1 -1
  124. package/lib/configuration/configuration.loader.js +1 -2
  125. package/lib/configuration/defaults.d.ts +2 -1
  126. package/lib/configuration/defaults.js +8 -10
  127. package/lib/configuration/index.d.ts +3 -3
  128. package/lib/configuration/index.js +3 -19
  129. package/lib/configuration/nest-configuration.loader.d.ts +3 -3
  130. package/lib/configuration/nest-configuration.loader.js +28 -29
  131. package/lib/package-managers/abstract.package-manager.d.ts +4 -4
  132. package/lib/package-managers/abstract.package-manager.js +21 -32
  133. package/lib/package-managers/bun.package-manager.d.ts +7 -0
  134. package/lib/package-managers/bun.package-manager.js +22 -0
  135. package/lib/package-managers/index.d.ts +9 -8
  136. package/lib/package-managers/index.js +9 -24
  137. package/lib/package-managers/npm.package-manager.d.ts +2 -2
  138. package/lib/package-managers/npm.package-manager.js +6 -10
  139. package/lib/package-managers/package-manager-commands.js +1 -2
  140. package/lib/package-managers/package-manager.d.ts +2 -1
  141. package/lib/package-managers/package-manager.factory.d.ts +2 -2
  142. package/lib/package-managers/package-manager.factory.js +23 -20
  143. package/lib/package-managers/package-manager.js +3 -5
  144. package/lib/package-managers/pnpm.package-manager.d.ts +2 -2
  145. package/lib/package-managers/pnpm.package-manager.js +6 -10
  146. package/lib/package-managers/project.dependency.js +1 -2
  147. package/lib/package-managers/yarn.package-manager.d.ts +2 -2
  148. package/lib/package-managers/yarn.package-manager.js +6 -10
  149. package/lib/questions/questions.d.ts +5 -1
  150. package/lib/questions/questions.js +2 -7
  151. package/lib/readers/file-system.reader.d.ts +1 -1
  152. package/lib/readers/file-system.reader.js +6 -9
  153. package/lib/readers/index.d.ts +2 -2
  154. package/lib/readers/index.js +2 -18
  155. package/lib/readers/reader.js +3 -5
  156. package/lib/runners/abstract.runner.js +40 -21
  157. package/lib/runners/bun.runner.d.ts +4 -0
  158. package/lib/runners/bun.runner.js +6 -0
  159. package/lib/runners/git.runner.d.ts +1 -1
  160. package/lib/runners/git.runner.js +2 -6
  161. package/lib/runners/index.d.ts +3 -3
  162. package/lib/runners/index.js +3 -19
  163. package/lib/runners/mau.runner.d.ts +8 -0
  164. package/lib/runners/mau.runner.js +10 -0
  165. package/lib/runners/npm.runner.d.ts +1 -1
  166. package/lib/runners/npm.runner.js +2 -6
  167. package/lib/runners/pnpm.runner.d.ts +1 -1
  168. package/lib/runners/pnpm.runner.js +2 -6
  169. package/lib/runners/runner.d.ts +2 -1
  170. package/lib/runners/runner.factory.d.ts +7 -6
  171. package/lib/runners/runner.factory.js +18 -20
  172. package/lib/runners/runner.js +3 -5
  173. package/lib/runners/schematic.runner.d.ts +1 -1
  174. package/lib/runners/schematic.runner.js +5 -7
  175. package/lib/runners/yarn.runner.d.ts +1 -1
  176. package/lib/runners/yarn.runner.js +2 -6
  177. package/lib/schematics/abstract.collection.d.ts +3 -3
  178. package/lib/schematics/abstract.collection.js +3 -5
  179. package/lib/schematics/collection.factory.d.ts +2 -2
  180. package/lib/schematics/collection.factory.js +9 -13
  181. package/lib/schematics/collection.js +2 -5
  182. package/lib/schematics/custom.collection.d.ts +2 -2
  183. package/lib/schematics/custom.collection.js +4 -8
  184. package/lib/schematics/index.d.ts +4 -4
  185. package/lib/schematics/index.js +4 -20
  186. package/lib/schematics/nest.collection.d.ts +3 -3
  187. package/lib/schematics/nest.collection.js +113 -109
  188. package/lib/schematics/schematic.option.js +10 -9
  189. package/lib/ui/banner.js +1 -4
  190. package/lib/ui/emojis.d.ts +17 -17
  191. package/lib/ui/emojis.js +19 -22
  192. package/lib/ui/errors.js +1 -4
  193. package/lib/ui/index.d.ts +5 -5
  194. package/lib/ui/index.js +5 -21
  195. package/lib/ui/messages.d.ts +8 -0
  196. package/lib/ui/messages.js +23 -18
  197. package/lib/ui/prefixes.js +3 -6
  198. package/lib/utils/extra-args-warning.js +3 -6
  199. package/lib/utils/formatting.js +1 -4
  200. package/lib/utils/get-default-tsconfig-path.js +4 -7
  201. package/lib/utils/gracefully-exit-on-prompt-error.js +1 -4
  202. package/lib/utils/is-esm-project.d.ts +5 -0
  203. package/lib/utils/is-esm-project.js +16 -0
  204. package/lib/utils/is-interactive.d.ts +8 -0
  205. package/lib/utils/is-interactive.js +10 -0
  206. package/lib/utils/is-module-available.js +3 -4
  207. package/lib/utils/load-configuration.d.ts +1 -1
  208. package/lib/utils/load-configuration.js +4 -7
  209. package/lib/utils/local-binaries.d.ts +2 -2
  210. package/lib/utils/local-binaries.js +8 -11
  211. package/lib/utils/mau.d.ts +14 -0
  212. package/lib/utils/mau.js +46 -0
  213. package/lib/utils/os-info.utils.js +1 -4
  214. package/lib/utils/project-utils.d.ts +1 -3
  215. package/lib/utils/project-utils.js +16 -28
  216. package/lib/utils/remaining-flags.d.ts +2 -2
  217. package/lib/utils/remaining-flags.js +13 -8
  218. package/lib/utils/tree-kill.js +7 -10
  219. package/lib/utils/type-assertions.js +1 -4
  220. package/package.json +70 -83
@@ -1,52 +1,54 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AssetsManager = void 0;
4
- const chokidar = require("chokidar");
5
- const fs_1 = require("fs");
6
- const glob_1 = require("glob");
7
- const path_1 = require("path");
8
- const copy_path_resolve_1 = require("./helpers/copy-path-resolve");
9
- const get_value_or_default_1 = require("./helpers/get-value-or-default");
10
- class AssetsManager {
11
- constructor() {
12
- this.watchAssetsKeyValue = {};
13
- this.watchers = [];
14
- this.actionInProgress = false;
15
- }
1
+ import * as chokidar from 'chokidar';
2
+ import { copyFileSync, mkdirSync, rmSync, statSync } from 'fs';
3
+ import { dirname, join, sep } from 'path';
4
+ import { ERROR_PREFIX } from '../ui/index.js';
5
+ import { copyPathResolve } from './helpers/copy-path-resolve.js';
6
+ import { globSync } from './helpers/glob.js';
7
+ import { getValueOrDefault } from './helpers/get-value-or-default.js';
8
+ import { areOutsidePathsAllowed, assertPathInsideProject, } from './helpers/path-confinement.js';
9
+ const ASSET_CHANGE_RESTART_DEBOUNCE_MS = 150;
10
+ export class AssetsManager {
11
+ watchAssetsKeyValue = {};
12
+ watchers = [];
13
+ watcherReadyPromises = [];
16
14
  /**
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
15
+ * Using on `nest build` to close file watch or the build process will not end.
16
+ * Waits for all watchers to complete their initial scan before closing them,
17
+ * ensuring all assets are copied regardless of system speed.
18
+ *
19
+ * Returns a Promise that resolves once every watcher has been closed.
20
+ * Callers (e.g. `build.action.ts`, `swc-compiler.ts`) `await` this method,
21
+ * so it must surface the underlying close work — otherwise `await` resolves
22
+ * immediately while file watchers stay open and the build process can race
23
+ * its own exit, leaving handles dangling.
21
24
  */
22
- 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);
25
+ async closeWatchers() {
26
+ await Promise.all(this.watcherReadyPromises);
27
+ await Promise.all(this.watchers.map((watcher) => watcher.close()));
35
28
  }
36
- copyAssets(configuration, appName, outDir, watchAssetsMode) {
37
- const assets = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.assets', appName) || [];
38
- if (assets.length <= 0) {
29
+ copyAssets(configuration, appName, outDir, watchAssetsMode, onSuccess, rootDir) {
30
+ const assets = getValueOrDefault(configuration, 'compilerOptions.assets', appName) || [];
31
+ const includeLibraryAssets = getValueOrDefault(configuration, 'compilerOptions.includeLibraryAssets', appName) || [];
32
+ const libraryAssets = this.collectLibraryAssets(configuration, includeLibraryAssets, outDir);
33
+ if (assets.length <= 0 && libraryAssets.length <= 0) {
39
34
  return;
40
35
  }
41
36
  try {
42
- let sourceRoot = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'sourceRoot', appName);
43
- sourceRoot = (0, path_1.join)(process.cwd(), sourceRoot);
37
+ let sourceRoot = getValueOrDefault(configuration, 'sourceRoot', appName);
38
+ sourceRoot = join(process.cwd(), sourceRoot);
39
+ // The asset path stripping must mirror how the TypeScript compiler emits
40
+ // files. When the effective rootDir (either explicit or computed from
41
+ // input files) differs from the configured `sourceRoot` — typically the
42
+ // case when `--path` points at a tsconfig with a different rootDir — we
43
+ // use that rootDir instead so copied assets stay aligned with the
44
+ // emitted JavaScript output. See nestjs/nest-cli#3387.
45
+ const stripRoot = rootDir ? join(rootDir) : sourceRoot;
44
46
  const filesToCopy = assets.map((item) => {
45
47
  let includePath = typeof item === 'string' ? item : item.include;
46
48
  let excludePath = typeof item !== 'string' && item.exclude ? item.exclude : undefined;
47
- includePath = (0, path_1.join)(sourceRoot, includePath).replace(/\\/g, '/');
49
+ includePath = join(sourceRoot, includePath).replace(/\\/g, '/');
48
50
  excludePath = excludePath
49
- ? (0, path_1.join)(sourceRoot, excludePath).replace(/\\/g, '/')
51
+ ? join(sourceRoot, excludePath).replace(/\\/g, '/')
50
52
  : undefined;
51
53
  return {
52
54
  outDir: typeof item !== 'string' ? item.outDir || outDir : outDir,
@@ -56,39 +58,120 @@ class AssetsManager {
56
58
  watchAssets: typeof item !== 'string' ? item.watchAssets : undefined,
57
59
  };
58
60
  });
59
- const isWatchEnabled = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.watchAssets', appName) || watchAssetsMode;
60
- for (const item of filesToCopy) {
61
+ const allFilesToCopy = [...filesToCopy, ...libraryAssets];
62
+ const isWatchEnabled = getValueOrDefault(configuration, 'compilerOptions.watchAssets', appName) || watchAssetsMode;
63
+ const confinePathsToProject = !areOutsidePathsAllowed(configuration, appName);
64
+ if (confinePathsToProject) {
65
+ // Validate the configured destinations once, before any watcher is
66
+ // registered, so that a misconfigured "outDir" surfaces as a single
67
+ // build error rather than as a failure per copied file.
68
+ const seenOutDirs = new Set();
69
+ for (const item of allFilesToCopy) {
70
+ if (item.outDir && !seenOutDirs.has(item.outDir)) {
71
+ seenOutDirs.add(item.outDir);
72
+ assertPathInsideProject(item.outDir, 'assets[].outDir', {
73
+ resolveSymlinks: true,
74
+ });
75
+ }
76
+ }
77
+ }
78
+ // Debounce onSuccess so that a burst of asset changes (e.g. a git
79
+ // checkout touching many files at once) only triggers a single restart.
80
+ let debouncedOnSuccess;
81
+ if (onSuccess) {
82
+ let pending;
83
+ debouncedOnSuccess = () => {
84
+ if (pending) {
85
+ clearTimeout(pending);
86
+ }
87
+ pending = setTimeout(() => {
88
+ pending = undefined;
89
+ onSuccess();
90
+ }, ASSET_CHANGE_RESTART_DEBOUNCE_MS);
91
+ };
92
+ }
93
+ for (const item of allFilesToCopy) {
94
+ // Library assets carry their own `_sourceRoot` so the per-library
95
+ // directory layout is preserved verbatim. For application assets we
96
+ // strip relative to the effective tsconfig rootDir (falls back to
97
+ // sourceRoot when no rootDir is supplied or computable).
98
+ const itemSourceRoot = item._sourceRoot || stripRoot;
61
99
  const option = {
62
100
  action: 'change',
63
101
  item,
64
102
  path: '',
65
- sourceRoot,
103
+ sourceRoot: itemSourceRoot,
66
104
  watchAssetsMode: isWatchEnabled,
105
+ confinePathsToProject,
67
106
  };
68
107
  if (isWatchEnabled || item.watchAssets) {
69
- // prettier-ignore
70
- const watcher = chokidar
71
- .watch((0, glob_1.sync)(item.glob, {
108
+ const matchedPaths = globSync(item.glob, {
72
109
  ignore: item.exclude,
73
110
  dot: true,
74
- }))
75
- .on('add', (path) => this.actionOnFile({ ...option, path, action: 'change' }))
76
- .on('change', (path) => this.actionOnFile({ ...option, path, action: 'change' }))
77
- .on('unlink', (path) => this.actionOnFile({ ...option, path, action: 'unlink' }));
111
+ });
112
+ // Chokidar does not emit the 'ready' event when given an empty
113
+ // array of paths, which causes closeWatchers() to hang forever
114
+ // on Promise.all(watcherReadyPromises). Skip the watcher and
115
+ // warn the user so the build can finish normally.
116
+ if (matchedPaths.length === 0) {
117
+ console.warn(`No files matched the asset pattern "${item.glob}". ` +
118
+ `Skipping watcher for this entry.`);
119
+ continue;
120
+ }
121
+ let ready = false;
122
+ // prettier-ignore
123
+ const watcher = chokidar
124
+ .watch(matchedPaths)
125
+ .on('add', (path) => {
126
+ this.safeActionOnFile({ ...option, path, action: 'change' });
127
+ if (ready && debouncedOnSuccess) {
128
+ debouncedOnSuccess();
129
+ }
130
+ })
131
+ .on('change', (path) => {
132
+ this.safeActionOnFile({ ...option, path, action: 'change' });
133
+ if (ready && debouncedOnSuccess) {
134
+ debouncedOnSuccess();
135
+ }
136
+ })
137
+ .on('unlink', (path) => {
138
+ this.safeActionOnFile({ ...option, path, action: 'unlink' });
139
+ if (ready && debouncedOnSuccess) {
140
+ debouncedOnSuccess();
141
+ }
142
+ });
143
+ let markSettled;
144
+ const settled = new Promise((resolve) => {
145
+ markSettled = resolve;
146
+ });
147
+ watcher.on('ready', () => {
148
+ ready = true;
149
+ markSettled();
150
+ });
151
+ // Without an 'error' listener chokidar rethrows as an uncaught
152
+ // exception (EMFILE, ENOSPC, EPERM on network shares), and the
153
+ // watcher never reaches 'ready' — which would leave closeWatchers()
154
+ // waiting on a promise that can no longer settle.
155
+ watcher.on('error', (error) => {
156
+ console.error(`${ERROR_PREFIX} Asset watcher failed for "${item.glob}". ` +
157
+ `${error instanceof Error ? error.message : String(error)}`);
158
+ markSettled();
159
+ });
78
160
  this.watchers.push(watcher);
161
+ this.watcherReadyPromises.push(settled);
79
162
  }
80
163
  else {
81
- const matchedPaths = (0, glob_1.sync)(item.glob, {
164
+ const matchedPaths = globSync(item.glob, {
82
165
  ignore: item.exclude,
83
166
  dot: true,
84
167
  });
85
168
  const files = item.glob.endsWith('*')
86
- ? matchedPaths.filter((matched) => (0, fs_1.statSync)(matched).isFile())
169
+ ? matchedPaths.filter((matched) => statSync(matched).isFile())
87
170
  : matchedPaths.flatMap((matched) => {
88
- if ((0, fs_1.statSync)(matched).isDirectory()) {
89
- return (0, glob_1.sync)(`${matched}/**/*`, {
171
+ if (statSync(matched).isDirectory()) {
172
+ return globSync(`${matched}/**/*`, {
90
173
  ignore: item.exclude,
91
- }).filter((file) => (0, fs_1.statSync)(file).isFile());
174
+ }).filter((file) => statSync(file).isFile());
92
175
  }
93
176
  return matched;
94
177
  });
@@ -99,11 +182,59 @@ class AssetsManager {
99
182
  }
100
183
  }
101
184
  catch (err) {
102
- throw new Error(`An error occurred during the assets copying process. ${err.message}`);
185
+ throw new Error(`An error occurred during the assets copying process. ${err.message}`, { cause: err });
186
+ }
187
+ }
188
+ collectLibraryAssets(configuration, libraryNames, outDir) {
189
+ if (!libraryNames.length || !configuration.projects) {
190
+ return [];
191
+ }
192
+ const result = [];
193
+ for (const libName of libraryNames) {
194
+ const libProject = configuration.projects[libName];
195
+ if (!libProject) {
196
+ continue;
197
+ }
198
+ const libAssets = libProject.compilerOptions?.assets;
199
+ if (!libAssets || libAssets.length <= 0) {
200
+ continue;
201
+ }
202
+ const libSourceRoot = join(process.cwd(), libProject.sourceRoot || libProject.root || '');
203
+ for (const item of libAssets) {
204
+ let includePath = typeof item === 'string' ? item : item.include;
205
+ let excludePath = typeof item !== 'string' && item.exclude ? item.exclude : undefined;
206
+ includePath = join(libSourceRoot, includePath).replace(/\\/g, '/');
207
+ excludePath = excludePath
208
+ ? join(libSourceRoot, excludePath).replace(/\\/g, '/')
209
+ : undefined;
210
+ const entry = {
211
+ outDir: typeof item !== 'string' ? item.outDir || outDir : outDir,
212
+ glob: includePath,
213
+ exclude: excludePath,
214
+ flat: typeof item !== 'string' ? item.flat : undefined,
215
+ watchAssets: typeof item !== 'string' ? item.watchAssets : undefined,
216
+ _sourceRoot: libSourceRoot,
217
+ };
218
+ result.push(entry);
219
+ }
220
+ }
221
+ return result;
222
+ }
223
+ /**
224
+ * Runs `actionOnFile` from a watcher callback. A rejected destination must not
225
+ * escalate into an uncaught exception: chokidar emits synchronously, so a
226
+ * throw here would tear down the whole watch session.
227
+ */
228
+ safeActionOnFile(option) {
229
+ try {
230
+ this.actionOnFile(option);
231
+ }
232
+ catch (err) {
233
+ console.error(`${ERROR_PREFIX} ${err instanceof Error ? err.message : String(err)}`);
103
234
  }
104
235
  }
105
236
  actionOnFile(option) {
106
- const { action, item, path, sourceRoot, watchAssetsMode } = option;
237
+ const { action, item, path, sourceRoot, watchAssetsMode, confinePathsToProject, } = option;
107
238
  const isWatchEnabled = watchAssetsMode || item.watchAssets;
108
239
  const assetCheckKey = path + (item.outDir ?? '');
109
240
  // Allow to do action for the first time before check watchMode
@@ -112,18 +243,23 @@ class AssetsManager {
112
243
  }
113
244
  // Set path value to true for watching the first time
114
245
  this.watchAssetsKeyValue[assetCheckKey] = true;
115
- // Set action to true to avoid watches getting cutoff
116
- this.actionInProgress = true;
117
- const dest = (0, copy_path_resolve_1.copyPathResolve)(path, item.outDir, sourceRoot.split(path_1.sep).length);
246
+ let dest = copyPathResolve(path, item.outDir, sourceRoot.split(sep).length);
247
+ // The destination is re-checked per file: the configured "outDir" is
248
+ // validated up front, but a symlinked directory *inside* it would still
249
+ // redirect an individual write out of the project.
250
+ if (confinePathsToProject) {
251
+ dest = assertPathInsideProject(dest, 'assets[].outDir', {
252
+ resolveSymlinks: true,
253
+ });
254
+ }
118
255
  // Copy to output dir if file is changed or added
119
256
  if (action === 'change') {
120
- (0, fs_1.mkdirSync)((0, path_1.dirname)(dest), { recursive: true });
121
- (0, fs_1.copyFileSync)(path, dest);
257
+ mkdirSync(dirname(dest), { recursive: true });
258
+ copyFileSync(path, dest);
122
259
  }
123
260
  else if (action === 'unlink') {
124
261
  // Remove from output dir if file is deleted
125
- (0, fs_1.rmSync)(dest, { force: true });
262
+ rmSync(dest, { force: true });
126
263
  }
127
264
  }
128
265
  }
129
- exports.AssetsManager = AssetsManager;
@@ -1,9 +1,9 @@
1
- import { Configuration } from '../configuration';
2
- import { PluginsLoader } from './plugins/plugins-loader';
1
+ import { Configuration } from '../configuration/index.js';
2
+ import { PluginsLoader } from './plugins/plugins-loader.js';
3
3
  export declare abstract class BaseCompiler<T = Record<string, any>> {
4
4
  private readonly pluginsLoader;
5
5
  constructor(pluginsLoader: PluginsLoader);
6
- abstract run(configuration: Required<Configuration>, tsConfigPath: string, appName: string | undefined, extras?: T, onSuccess?: () => void): any;
7
- loadPlugins(configuration: Required<Configuration>, tsConfigPath: string, appName: string | undefined): import("./plugins/plugins-loader").MultiNestCompilerPlugins;
8
- getPathToSource(configuration: Required<Configuration>, tsConfigPath: string, appName: string | undefined): string;
6
+ abstract run(configuration: Required<Configuration>, tsConfigPath: string, appName: string | undefined, extras?: T, onSuccess?: () => void): void | Promise<void>;
7
+ protected loadPlugins(configuration: Required<Configuration>, tsConfigPath: string, appName: string | undefined): import("./plugins/plugins-loader.js").MultiNestCompilerPlugins;
8
+ protected getPathToSource(configuration: Required<Configuration>, tsConfigPath: string, appName: string | undefined): string;
9
9
  }
@@ -1,26 +1,23 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseCompiler = void 0;
4
- const path_1 = require("path");
5
- const get_value_or_default_1 = require("./helpers/get-value-or-default");
6
- class BaseCompiler {
1
+ import { dirname, join, normalize, relative } from 'path';
2
+ import { getValueOrDefault } from './helpers/get-value-or-default.js';
3
+ export class BaseCompiler {
4
+ pluginsLoader;
7
5
  constructor(pluginsLoader) {
8
6
  this.pluginsLoader = pluginsLoader;
9
7
  }
10
8
  loadPlugins(configuration, tsConfigPath, appName) {
11
- const pluginsConfig = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.plugins', appName);
9
+ const pluginsConfig = getValueOrDefault(configuration, 'compilerOptions.plugins', appName);
12
10
  const pathToSource = this.getPathToSource(configuration, tsConfigPath, appName);
13
11
  const plugins = this.pluginsLoader.load(pluginsConfig, { pathToSource });
14
12
  return plugins;
15
13
  }
16
14
  getPathToSource(configuration, tsConfigPath, appName) {
17
- const sourceRoot = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'sourceRoot', appName, 'sourceRoot');
15
+ const sourceRoot = getValueOrDefault(configuration, 'sourceRoot', appName, 'sourceRoot');
18
16
  const cwd = process.cwd();
19
- const relativeRootPath = (0, path_1.dirname)((0, path_1.relative)(cwd, tsConfigPath));
20
- const pathToSource = (0, path_1.normalize)(sourceRoot).indexOf((0, path_1.normalize)(relativeRootPath)) >= 0
21
- ? (0, path_1.join)(cwd, sourceRoot)
22
- : (0, path_1.join)(cwd, relativeRootPath, sourceRoot);
17
+ const relativeRootPath = dirname(relative(cwd, tsConfigPath));
18
+ const pathToSource = normalize(sourceRoot).indexOf(normalize(relativeRootPath)) >= 0
19
+ ? join(cwd, sourceRoot)
20
+ : join(cwd, relativeRootPath, sourceRoot);
23
21
  return pathToSource;
24
22
  }
25
23
  }
26
- exports.BaseCompiler = BaseCompiler;
@@ -1,12 +1,12 @@
1
- import { Configuration } from '../configuration';
2
- import { BaseCompiler } from './base-compiler';
3
- import { TsConfigProvider } from './helpers/tsconfig-provider';
4
- import { PluginsLoader } from './plugins/plugins-loader';
5
- import { TypeScriptBinaryLoader } from './typescript-loader';
1
+ import { Configuration } from '../configuration/index.js';
2
+ import { BaseCompiler } from './base-compiler.js';
3
+ import { TsConfigProvider } from './helpers/tsconfig-provider.js';
4
+ import { PluginsLoader } from './plugins/plugins-loader.js';
5
+ import { TypeScriptBinaryLoader } from './typescript-loader.js';
6
6
  export declare class Compiler extends BaseCompiler {
7
7
  private readonly tsConfigProvider;
8
8
  private readonly typescriptLoader;
9
9
  constructor(pluginsLoader: PluginsLoader, tsConfigProvider: TsConfigProvider, typescriptLoader: TypeScriptBinaryLoader);
10
- run(configuration: Required<Configuration>, tsConfigPath: string, appName: string | undefined, _extras: any, onSuccess?: () => void): void;
10
+ run(configuration: Required<Configuration>, tsConfigPath: string, appName: string | undefined, _extras: unknown, onSuccess?: () => void): void;
11
11
  private reportAfterCompilationDiagnostic;
12
12
  }
@@ -1,10 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Compiler = void 0;
4
- const ts = require("typescript");
5
- const base_compiler_1 = require("./base-compiler");
6
- const tsconfig_paths_hook_1 = require("./hooks/tsconfig-paths.hook");
7
- class Compiler extends base_compiler_1.BaseCompiler {
1
+ import * as ts from 'typescript';
2
+ import { BaseCompiler } from './base-compiler.js';
3
+ import { tsconfigPathsBeforeHookFactory } from './hooks/tsconfig-paths.hook.js';
4
+ export class Compiler extends BaseCompiler {
5
+ tsConfigProvider;
6
+ typescriptLoader;
8
7
  constructor(pluginsLoader, tsConfigProvider, typescriptLoader) {
9
8
  super(pluginsLoader);
10
9
  this.tsConfigProvider = tsConfigProvider;
@@ -25,7 +24,7 @@ class Compiler extends base_compiler_1.BaseCompiler {
25
24
  options,
26
25
  });
27
26
  const plugins = this.loadPlugins(configuration, tsConfigPath, appName);
28
- const tsconfigPathsPlugin = (0, tsconfig_paths_hook_1.tsconfigPathsBeforeHookFactory)(options);
27
+ const tsconfigPathsPlugin = tsconfigPathsBeforeHookFactory(options);
29
28
  const programRef = program.getProgram
30
29
  ? program.getProgram()
31
30
  : program;
@@ -60,4 +59,3 @@ class Compiler extends base_compiler_1.BaseCompiler {
60
59
  return diagnostics.length;
61
60
  }
62
61
  }
63
- exports.Compiler = Compiler;
@@ -0,0 +1,3 @@
1
+ import type * as ts from 'typescript';
2
+ import { MultiNestCompilerPlugins } from '../plugins/plugins-loader.js';
3
+ export declare const rspackDefaultsFactory: (sourceRoot: string, relativeSourceRoot: string, entryFilename: string, isDebugEnabled: boolean | undefined, tsConfigFile: string | undefined, plugins: MultiNestCompilerPlugins, isEsm?: boolean, tsOptions?: ts.CompilerOptions) => Record<string, any>;
@@ -0,0 +1,179 @@
1
+ import { builtinModules, createRequire } from 'module';
2
+ import { join } from 'path';
3
+ import { defaultTsconfigFilename } from '../../configuration/defaults.js';
4
+ import { appendTsExtension } from '../helpers/append-extension.js';
5
+ const require = createRequire(import.meta.url);
6
+ function loadRspackDeps() {
7
+ try {
8
+ const rspack = require('@rspack/core');
9
+ const externals = require('webpack-node-externals');
10
+ const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin');
11
+ return { nodeExternals: externals, TsconfigPathsPlugin, rspack };
12
+ }
13
+ catch (e) {
14
+ if (e?.code !== 'MODULE_NOT_FOUND' && e?.code !== 'ERR_MODULE_NOT_FOUND') {
15
+ // Only the "package missing" branch is wrapped with install advice.
16
+ // Surfacing unrelated errors as "package not found" would mislead
17
+ // users into reinstalling perfectly valid dependencies.
18
+ throw e;
19
+ }
20
+ // Use a non-greedy match so error messages that contain multiple
21
+ // quoted paths (e.g. ESM "Cannot find package 'foo' imported from
22
+ // '/abs/path.mjs'") still extract the package name rather than the
23
+ // importing file path.
24
+ const pkg = e?.message?.match?.(/Cannot find.*?'([^']+)'/)?.[1] ??
25
+ 'webpack-node-externals';
26
+ throw new Error(`The "${pkg}" package is required when using the rspack compiler but could not be found. ` +
27
+ `Please install it:\n\n npm install --save-dev @rspack/core webpack-node-externals tsconfig-paths-webpack-plugin\n`, { cause: e });
28
+ }
29
+ }
30
+ export const rspackDefaultsFactory = (sourceRoot, relativeSourceRoot, entryFilename, isDebugEnabled = false, tsConfigFile = defaultTsconfigFilename, plugins, isEsm = false, tsOptions) => {
31
+ const { nodeExternals: externals, TsconfigPathsPlugin } = loadRspackDeps();
32
+ const isPluginRegistered = isAnyPluginRegistered(plugins);
33
+ const sourceMaps = tsOptions?.sourceMap || (tsOptions?.inlineSourceMap && 'inline');
34
+ const devtool = sourceMaps === 'inline'
35
+ ? 'inline-source-map'
36
+ : sourceMaps
37
+ ? 'source-map'
38
+ : false;
39
+ const rspackConfiguration = {
40
+ entry: appendTsExtension(join(sourceRoot, entryFilename)),
41
+ devtool,
42
+ target: 'node',
43
+ output: {
44
+ filename: join(relativeSourceRoot, `${entryFilename}.js`).replace(/\\/g, '/'),
45
+ ...(isEsm && {
46
+ module: true,
47
+ library: { type: 'module' },
48
+ chunkFormat: 'module',
49
+ chunkLoading: 'import',
50
+ }),
51
+ },
52
+ ...(isEsm && {
53
+ experiments: { outputModule: true, topLevelAwait: true },
54
+ }),
55
+ ignoreWarnings: [/^(?!CriticalDependenciesWarning$)/],
56
+ externals: [
57
+ externals(isEsm ? { importType: 'module' } : {}),
58
+ ...(isEsm
59
+ ? [
60
+ ({ request }, callback) => {
61
+ if (!request)
62
+ return callback();
63
+ const bare = request.startsWith('node:')
64
+ ? request.slice(5)
65
+ : request;
66
+ if (builtinModules.includes(bare)) {
67
+ return callback(null, `module ${request}`);
68
+ }
69
+ callback();
70
+ },
71
+ ]
72
+ : []),
73
+ ],
74
+ externalsPresets: { node: !isEsm },
75
+ module: {
76
+ rules: [
77
+ {
78
+ test: /\.tsx?$/,
79
+ use: [
80
+ {
81
+ loader: 'builtin:swc-loader',
82
+ options: {
83
+ jsc: {
84
+ parser: {
85
+ syntax: 'typescript',
86
+ decorators: true,
87
+ },
88
+ transform: {
89
+ legacyDecorator: true,
90
+ decoratorMetadata: true,
91
+ },
92
+ target: 'es2021',
93
+ },
94
+ sourceMaps,
95
+ },
96
+ },
97
+ ],
98
+ exclude: /node_modules/,
99
+ ...(isEsm && { type: 'javascript/esm' }),
100
+ },
101
+ ],
102
+ },
103
+ resolve: {
104
+ extensions: ['.tsx', '.ts', '.js'],
105
+ ...(isEsm && {
106
+ extensionAlias: {
107
+ '.js': ['.ts', '.js'],
108
+ '.mjs': ['.mts', '.mjs'],
109
+ },
110
+ }),
111
+ tsConfig: tsConfigFile,
112
+ plugins: [
113
+ new TsconfigPathsPlugin({
114
+ configFile: tsConfigFile,
115
+ }),
116
+ ],
117
+ },
118
+ mode: 'none',
119
+ optimization: {
120
+ nodeEnv: false,
121
+ },
122
+ node: {
123
+ __filename: false,
124
+ __dirname: false,
125
+ },
126
+ plugins: [],
127
+ };
128
+ // rspack has built-in IgnorePlugin (compatible with webpack's)
129
+ try {
130
+ const rspack = require('@rspack/core');
131
+ rspackConfiguration.plugins.push(new rspack.IgnorePlugin({
132
+ checkResource(resource) {
133
+ const lazyImports = [
134
+ '@nestjs/microservices',
135
+ '@nestjs/microservices/microservices-module',
136
+ '@nestjs/websockets/socket-module',
137
+ 'class-validator',
138
+ 'class-transformer',
139
+ 'class-transformer/storage',
140
+ ];
141
+ if (!lazyImports.includes(resource)) {
142
+ return false;
143
+ }
144
+ try {
145
+ require.resolve(resource, {
146
+ paths: [process.cwd()],
147
+ });
148
+ }
149
+ catch {
150
+ return true;
151
+ }
152
+ return false;
153
+ },
154
+ }));
155
+ }
156
+ catch {
157
+ // @rspack/core not available, skip IgnorePlugin
158
+ }
159
+ if (!isPluginRegistered) {
160
+ try {
161
+ const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
162
+ rspackConfiguration.plugins.push(new ForkTsCheckerWebpackPlugin({
163
+ typescript: {
164
+ configFile: tsConfigFile,
165
+ },
166
+ }));
167
+ }
168
+ catch {
169
+ // fork-ts-checker-webpack-plugin not available, skip
170
+ }
171
+ }
172
+ return rspackConfiguration;
173
+ };
174
+ function isAnyPluginRegistered(plugins) {
175
+ return ((plugins.afterHooks && plugins.afterHooks.length > 0) ||
176
+ (plugins.beforeHooks && plugins.beforeHooks.length > 0) ||
177
+ (plugins.afterDeclarationsHooks &&
178
+ plugins.afterDeclarationsHooks.length > 0));
179
+ }
@@ -1,6 +1,6 @@
1
1
  import * as ts from 'typescript';
2
- import { Configuration } from '../../configuration';
3
- export declare const swcDefaultsFactory: (tsOptions?: ts.CompilerOptions, configuration?: Configuration) => {
2
+ import { Configuration } from '../../configuration/index.js';
3
+ export declare const swcDefaultsFactory: (tsOptions?: ts.CompilerOptions, configuration?: Configuration, tsConfigExclude?: string[]) => {
4
4
  swcOptions: {
5
5
  sourceMaps: string | boolean | undefined;
6
6
  module: {
@@ -32,6 +32,7 @@ export declare const swcDefaultsFactory: (tsOptions?: ts.CompilerOptions, config
32
32
  extensions: string[];
33
33
  copyFiles: boolean;
34
34
  includeDotfiles: boolean;
35
+ ignore: string[] | undefined;
35
36
  quiet: boolean;
36
37
  watch: boolean;
37
38
  stripLeadingPaths: boolean;
@@ -44,6 +45,7 @@ export declare const swcDefaultsFactory: (tsOptions?: ts.CompilerOptions, config
44
45
  copyFiles: boolean;
45
46
  includeDotfiles: boolean;
46
47
  quiet: boolean;
48
+ ignore: string[] | undefined;
47
49
  watch: boolean;
48
50
  stripLeadingPaths: boolean;
49
51
  } | {
@@ -54,6 +56,7 @@ export declare const swcDefaultsFactory: (tsOptions?: ts.CompilerOptions, config
54
56
  extensions: string[];
55
57
  copyFiles: boolean;
56
58
  includeDotfiles: boolean;
59
+ ignore: string[] | undefined;
57
60
  quiet: boolean;
58
61
  watch: boolean;
59
62
  stripLeadingPaths: boolean;