@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.
- package/README.md +7 -15
- package/actions/abstract.action.d.ts +1 -2
- package/actions/abstract.action.js +1 -5
- package/actions/add.action.d.ts +3 -4
- package/actions/add.action.js +44 -53
- package/actions/build.action.d.ts +18 -11
- package/actions/build.action.js +172 -79
- package/actions/deploy.action.d.ts +6 -0
- package/actions/deploy.action.js +51 -0
- package/actions/generate.action.d.ts +3 -3
- package/actions/generate.action.js +61 -59
- package/actions/index.d.ts +9 -7
- package/actions/index.js +9 -23
- package/actions/info.action.d.ts +18 -28
- package/actions/info.action.js +80 -60
- package/actions/new.action.d.ts +3 -3
- package/actions/new.action.js +108 -104
- package/actions/start.action.d.ts +4 -7
- package/actions/start.action.js +40 -47
- package/actions/upgrade.action.d.ts +6 -0
- package/actions/upgrade.action.js +53 -0
- package/bin/nest.js +11 -10
- package/changes.json +9 -41
- package/commands/abstract.command.d.ts +3 -3
- package/commands/abstract.command.js +2 -5
- package/commands/add.command.d.ts +3 -3
- package/commands/add.command.js +17 -20
- package/commands/build.command.d.ts +3 -3
- package/commands/build.command.js +52 -56
- package/commands/command.input.js +1 -2
- package/commands/command.loader.d.ts +2 -2
- package/commands/command.loader.js +29 -22
- package/commands/context/add.context.d.ts +7 -0
- package/commands/context/add.context.js +1 -0
- package/commands/context/build.context.d.ts +17 -0
- package/commands/context/build.context.js +1 -0
- package/commands/context/deploy.context.d.ts +7 -0
- package/commands/context/deploy.context.js +1 -0
- package/commands/context/generate.context.d.ts +18 -0
- package/commands/context/generate.context.js +1 -0
- package/commands/context/index.d.ts +7 -0
- package/commands/context/index.js +7 -0
- package/commands/context/new.context.d.ts +19 -0
- package/commands/context/new.context.js +1 -0
- package/commands/context/start.context.d.ts +22 -0
- package/commands/context/start.context.js +1 -0
- package/commands/context/upgrade.context.d.ts +11 -0
- package/commands/context/upgrade.context.js +1 -0
- package/commands/deploy.command.d.ts +5 -0
- package/commands/deploy.command.js +22 -0
- package/commands/generate.command.d.ts +3 -3
- package/commands/generate.command.js +35 -66
- package/commands/index.d.ts +3 -2
- package/commands/index.js +3 -18
- package/commands/info.command.d.ts +3 -3
- package/commands/info.command.js +4 -8
- package/commands/new.command.d.ts +3 -3
- package/commands/new.command.js +34 -36
- package/commands/start.command.d.ts +3 -3
- package/commands/start.command.js +48 -73
- package/commands/upgrade.command.d.ts +5 -0
- package/commands/upgrade.command.js +32 -0
- package/lib/compiler/assets-manager.d.ts +20 -8
- package/lib/compiler/assets-manager.js +199 -63
- package/lib/compiler/base-compiler.d.ts +5 -5
- package/lib/compiler/base-compiler.js +10 -13
- package/lib/compiler/compiler.d.ts +6 -6
- package/lib/compiler/compiler.js +7 -9
- package/lib/compiler/defaults/rspack-defaults.d.ts +3 -0
- package/lib/compiler/defaults/rspack-defaults.js +179 -0
- package/lib/compiler/defaults/swc-defaults.d.ts +5 -2
- package/lib/compiler/defaults/swc-defaults.js +22 -6
- package/lib/compiler/defaults/webpack-defaults.d.ts +2 -2
- package/lib/compiler/defaults/webpack-defaults.js +59 -19
- package/lib/compiler/helpers/append-extension.js +3 -6
- package/lib/compiler/helpers/copy-path-resolve.js +2 -5
- package/lib/compiler/helpers/delete-out-dir.d.ts +1 -1
- package/lib/compiler/helpers/delete-out-dir.js +45 -10
- package/lib/compiler/helpers/get-builder.d.ts +9 -7
- package/lib/compiler/helpers/get-builder.js +3 -6
- package/lib/compiler/helpers/get-effective-root-dir.d.ts +16 -0
- package/lib/compiler/helpers/get-effective-root-dir.js +56 -0
- package/lib/compiler/helpers/get-rspack-config-path.d.ts +10 -0
- package/lib/compiler/helpers/get-rspack-config-path.js +19 -0
- package/lib/compiler/helpers/get-tsc-config.path.d.ts +2 -3
- package/lib/compiler/helpers/get-tsc-config.path.js +6 -9
- package/lib/compiler/helpers/get-value-or-default.d.ts +2 -3
- package/lib/compiler/helpers/get-value-or-default.js +3 -8
- package/lib/compiler/helpers/get-webpack-config-path.d.ts +2 -3
- package/lib/compiler/helpers/get-webpack-config-path.js +4 -7
- package/lib/compiler/helpers/glob.d.ts +19 -0
- package/lib/compiler/helpers/glob.js +185 -0
- package/lib/compiler/helpers/manual-restart.js +4 -8
- package/lib/compiler/helpers/path-confinement.d.ts +33 -0
- package/lib/compiler/helpers/path-confinement.js +63 -0
- package/lib/compiler/helpers/tsconfig-provider.d.ts +7 -6
- package/lib/compiler/helpers/tsconfig-provider.js +32 -13
- package/lib/compiler/hooks/tsconfig-paths.hook.js +13 -13
- package/lib/compiler/interfaces/readonly-visitor.interface.js +1 -2
- package/lib/compiler/plugins/plugin-metadata-generator.d.ts +37 -1
- package/lib/compiler/plugins/plugin-metadata-generator.js +113 -13
- package/lib/compiler/plugins/plugin-metadata-printer.d.ts +1 -1
- package/lib/compiler/plugins/plugin-metadata-printer.js +5 -9
- package/lib/compiler/plugins/plugins-loader.d.ts +2 -2
- package/lib/compiler/plugins/plugins-loader.js +12 -12
- package/lib/compiler/rspack-compiler.d.ts +21 -0
- package/lib/compiler/rspack-compiler.js +111 -0
- package/lib/compiler/swc/constants.d.ts +0 -1
- package/lib/compiler/swc/constants.js +9 -13
- package/lib/compiler/swc/forked-type-checker.js +13 -18
- package/lib/compiler/swc/swc-compiler.d.ts +13 -6
- package/lib/compiler/swc/swc-compiler.js +116 -70
- package/lib/compiler/swc/type-checker-host.js +31 -24
- package/lib/compiler/typescript-loader.js +7 -9
- package/lib/compiler/watch-compiler.d.ts +5 -5
- package/lib/compiler/watch-compiler.js +13 -15
- package/lib/compiler/watchers/recursive-directory-watcher.d.ts +37 -0
- package/lib/compiler/watchers/recursive-directory-watcher.js +334 -0
- package/lib/compiler/webpack-compiler.d.ts +6 -7
- package/lib/compiler/webpack-compiler.js +46 -23
- package/lib/configuration/configuration.d.ts +16 -3
- package/lib/configuration/configuration.js +1 -2
- package/lib/configuration/configuration.loader.d.ts +1 -1
- package/lib/configuration/configuration.loader.js +1 -2
- package/lib/configuration/defaults.d.ts +2 -1
- package/lib/configuration/defaults.js +8 -10
- package/lib/configuration/index.d.ts +3 -3
- package/lib/configuration/index.js +3 -19
- package/lib/configuration/nest-configuration.loader.d.ts +3 -3
- package/lib/configuration/nest-configuration.loader.js +28 -29
- package/lib/package-managers/abstract.package-manager.d.ts +4 -4
- package/lib/package-managers/abstract.package-manager.js +21 -32
- package/lib/package-managers/bun.package-manager.d.ts +7 -0
- package/lib/package-managers/bun.package-manager.js +22 -0
- package/lib/package-managers/index.d.ts +9 -8
- package/lib/package-managers/index.js +9 -24
- package/lib/package-managers/npm.package-manager.d.ts +2 -2
- package/lib/package-managers/npm.package-manager.js +6 -10
- package/lib/package-managers/package-manager-commands.js +1 -2
- package/lib/package-managers/package-manager.d.ts +2 -1
- package/lib/package-managers/package-manager.factory.d.ts +2 -2
- package/lib/package-managers/package-manager.factory.js +23 -20
- package/lib/package-managers/package-manager.js +3 -5
- package/lib/package-managers/pnpm.package-manager.d.ts +2 -2
- package/lib/package-managers/pnpm.package-manager.js +6 -10
- package/lib/package-managers/project.dependency.js +1 -2
- package/lib/package-managers/yarn.package-manager.d.ts +2 -2
- package/lib/package-managers/yarn.package-manager.js +6 -10
- package/lib/questions/questions.d.ts +5 -1
- package/lib/questions/questions.js +2 -7
- package/lib/readers/file-system.reader.d.ts +1 -1
- package/lib/readers/file-system.reader.js +6 -9
- package/lib/readers/index.d.ts +2 -2
- package/lib/readers/index.js +2 -18
- package/lib/readers/reader.js +3 -5
- package/lib/runners/abstract.runner.js +40 -21
- package/lib/runners/bun.runner.d.ts +4 -0
- package/lib/runners/bun.runner.js +6 -0
- package/lib/runners/git.runner.d.ts +1 -1
- package/lib/runners/git.runner.js +2 -6
- package/lib/runners/index.d.ts +3 -3
- package/lib/runners/index.js +3 -19
- package/lib/runners/mau.runner.d.ts +8 -0
- package/lib/runners/mau.runner.js +10 -0
- package/lib/runners/npm.runner.d.ts +1 -1
- package/lib/runners/npm.runner.js +2 -6
- package/lib/runners/pnpm.runner.d.ts +1 -1
- package/lib/runners/pnpm.runner.js +2 -6
- package/lib/runners/runner.d.ts +2 -1
- package/lib/runners/runner.factory.d.ts +7 -6
- package/lib/runners/runner.factory.js +18 -20
- package/lib/runners/runner.js +3 -5
- package/lib/runners/schematic.runner.d.ts +1 -1
- package/lib/runners/schematic.runner.js +5 -7
- package/lib/runners/yarn.runner.d.ts +1 -1
- package/lib/runners/yarn.runner.js +2 -6
- package/lib/schematics/abstract.collection.d.ts +3 -3
- package/lib/schematics/abstract.collection.js +3 -5
- package/lib/schematics/collection.factory.d.ts +2 -2
- package/lib/schematics/collection.factory.js +9 -13
- package/lib/schematics/collection.js +2 -5
- package/lib/schematics/custom.collection.d.ts +2 -2
- package/lib/schematics/custom.collection.js +4 -8
- package/lib/schematics/index.d.ts +4 -4
- package/lib/schematics/index.js +4 -20
- package/lib/schematics/nest.collection.d.ts +3 -3
- package/lib/schematics/nest.collection.js +113 -109
- package/lib/schematics/schematic.option.js +10 -9
- package/lib/ui/banner.js +1 -4
- package/lib/ui/emojis.d.ts +17 -17
- package/lib/ui/emojis.js +19 -22
- package/lib/ui/errors.js +1 -4
- package/lib/ui/index.d.ts +5 -5
- package/lib/ui/index.js +5 -21
- package/lib/ui/messages.d.ts +8 -0
- package/lib/ui/messages.js +23 -18
- package/lib/ui/prefixes.js +3 -6
- package/lib/utils/extra-args-warning.js +3 -6
- package/lib/utils/formatting.js +1 -4
- package/lib/utils/get-default-tsconfig-path.js +4 -7
- package/lib/utils/gracefully-exit-on-prompt-error.js +1 -4
- package/lib/utils/is-esm-project.d.ts +5 -0
- package/lib/utils/is-esm-project.js +16 -0
- package/lib/utils/is-interactive.d.ts +8 -0
- package/lib/utils/is-interactive.js +10 -0
- package/lib/utils/is-module-available.js +3 -4
- package/lib/utils/load-configuration.d.ts +1 -1
- package/lib/utils/load-configuration.js +4 -7
- package/lib/utils/local-binaries.d.ts +2 -2
- package/lib/utils/local-binaries.js +8 -11
- package/lib/utils/mau.d.ts +14 -0
- package/lib/utils/mau.js +46 -0
- package/lib/utils/os-info.utils.js +1 -4
- package/lib/utils/project-utils.d.ts +1 -3
- package/lib/utils/project-utils.js +16 -28
- package/lib/utils/remaining-flags.d.ts +2 -2
- package/lib/utils/remaining-flags.js +13 -8
- package/lib/utils/tree-kill.js +7 -10
- package/lib/utils/type-assertions.js +1 -4
- package/package.json +70 -83
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal synchronous glob over `fs` + `minimatch`, covering just the
|
|
3
|
+
* surface `assets-manager` needs: one pattern, one optional `ignore`
|
|
4
|
+
* pattern, and `dot`.
|
|
5
|
+
*
|
|
6
|
+
* This replaced the `glob` package (see nestjs/nest-cli#3520), and asset
|
|
7
|
+
* copying is expected to behave exactly as it did before that swap. Several
|
|
8
|
+
* rules below therefore look arbitrary in isolation — zero-segment trailing
|
|
9
|
+
* globstars, the symlink depth budget — but each one preserves a documented
|
|
10
|
+
* behavior that build configurations already depend on. The tests in
|
|
11
|
+
* `test/lib/compiler/helpers/glob.spec.ts` pin them.
|
|
12
|
+
*/
|
|
13
|
+
import { readdirSync, statSync } from 'fs';
|
|
14
|
+
import { minimatch } from 'minimatch';
|
|
15
|
+
/**
|
|
16
|
+
* Characters that make a path segment a pattern rather than a literal, under
|
|
17
|
+
* minimatch's default options (no extglob).
|
|
18
|
+
*
|
|
19
|
+
* Matches the literal chars `*`, `?`, `[`, `{` anywhere, plus `!`, `+`, `@`,
|
|
20
|
+
* `?`, or `*` immediately followed by `(` (an extglob-looking prefix, which
|
|
21
|
+
* minimatch still treats specially even without extglob enabled). Chars like
|
|
22
|
+
* `@`, `(`, `)`, `]`, `}` on their own are NOT magic here: treating them as
|
|
23
|
+
* such previously collapsed the literal base far above the real directory
|
|
24
|
+
* (e.g. an `@` in a username segment), causing `readdir` to walk huge trees
|
|
25
|
+
* and silently return no matches on the first unreadable subdirectory.
|
|
26
|
+
*/
|
|
27
|
+
const MAGIC_CHARS = /[*?[{]|[!+@?*]\(/;
|
|
28
|
+
const toPosix = (value) => value.replace(/\\/g, '/');
|
|
29
|
+
/**
|
|
30
|
+
* Splits a pattern into the literal prefix we can hand to `readdir` and the
|
|
31
|
+
* trailing segments that still need matching: `/src/a/*.hbs` -> `/src/a`.
|
|
32
|
+
*/
|
|
33
|
+
function splitPattern(pattern) {
|
|
34
|
+
const segments = pattern.split('/');
|
|
35
|
+
const magicIndex = segments.findIndex((segment) => MAGIC_CHARS.test(segment));
|
|
36
|
+
if (magicIndex === -1) {
|
|
37
|
+
return { base: pattern, rest: [] };
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
base: segments.slice(0, magicIndex).join('/') || '/',
|
|
41
|
+
rest: segments.slice(magicIndex),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A trailing globstar matches zero segments, so `a/**` must match `a`
|
|
46
|
+
* itself; `minimatch` alone does not. Expanding the suffix restores that for
|
|
47
|
+
* the include pattern, and for `ignore` it prunes the ignored directory
|
|
48
|
+
* itself rather than only its contents.
|
|
49
|
+
*/
|
|
50
|
+
function expandGlobstarSuffix(pattern) {
|
|
51
|
+
return pattern.endsWith('/**') ? [pattern, pattern.slice(0, -3)] : [pattern];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* How far below a symlinked directory a pattern can still reach.
|
|
55
|
+
*
|
|
56
|
+
* A globstar never recurses *through* a symlinked directory, but the
|
|
57
|
+
* explicit segments that follow the last one keep matching normally once
|
|
58
|
+
* there. So a pattern ending in a bare globstar stops at the symlink itself
|
|
59
|
+
* and gets a budget of 0; adding one more segment after it reaches a single
|
|
60
|
+
* level inside (budget 1), and two segments reach two levels (budget 2). A
|
|
61
|
+
* pattern with no globstar at all does no recursion of this kind, so its own
|
|
62
|
+
* depth is the only bound.
|
|
63
|
+
*
|
|
64
|
+
* Returning a finite number also bounds the walk: symlink cycles terminate
|
|
65
|
+
* because each crossing costs depth we can never regain.
|
|
66
|
+
*/
|
|
67
|
+
function symlinkDepthBudget(rest) {
|
|
68
|
+
for (let index = rest.length - 1; index >= 0; index--) {
|
|
69
|
+
if (rest[index].includes('**')) {
|
|
70
|
+
return rest.length - index - 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return rest.length;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Walks the directory tree rooted at `dir`, without using `fs`'s own
|
|
77
|
+
* `recursive` option so we can:
|
|
78
|
+
*
|
|
79
|
+
* - Skip an unreadable directory instead of failing the whole walk: one
|
|
80
|
+
* `EACCES` deep in an asset tree must not silently empty the result.
|
|
81
|
+
* - Stop descending once we are `budget` levels past a symlinked directory
|
|
82
|
+
* (see `symlinkDepthBudget`), which also makes symlink cycles terminate.
|
|
83
|
+
*
|
|
84
|
+
* `depth` is how many levels below the nearest symlinked ancestor an entry
|
|
85
|
+
* sits; 0 means it was reached without crossing one.
|
|
86
|
+
*/
|
|
87
|
+
function walk(dir, recursive, budget, depth = 0) {
|
|
88
|
+
let entries;
|
|
89
|
+
try {
|
|
90
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Unreadable or missing directory: contribute nothing here, but let
|
|
94
|
+
// sibling directories elsewhere in the walk still report their matches.
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
const results = entries.map((entry) => ({
|
|
98
|
+
parent: dir,
|
|
99
|
+
entry,
|
|
100
|
+
}));
|
|
101
|
+
if (!recursive) {
|
|
102
|
+
return results;
|
|
103
|
+
}
|
|
104
|
+
for (const entry of entries) {
|
|
105
|
+
const full = `${dir}/${entry.name}`;
|
|
106
|
+
// Below a symlink every further level costs budget; above one, plain
|
|
107
|
+
// directory recursion is unbounded.
|
|
108
|
+
if (entry.isDirectory()) {
|
|
109
|
+
const childDepth = depth === 0 ? 0 : depth + 1;
|
|
110
|
+
if (childDepth <= budget) {
|
|
111
|
+
results.push(...walk(full, true, budget, childDepth));
|
|
112
|
+
}
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
// `Dirent.isDirectory()` is false for a symlink (it reports on the link
|
|
116
|
+
// itself), so a symlinked directory only ever reaches this branch.
|
|
117
|
+
if (entry.isSymbolicLink() && depth + 1 <= budget) {
|
|
118
|
+
let stats;
|
|
119
|
+
try {
|
|
120
|
+
stats = statSync(full);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (stats.isDirectory()) {
|
|
126
|
+
results.push(...walk(full, true, budget, depth + 1));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return results;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Expands `pattern` to every matching path, with the type of each entry.
|
|
134
|
+
* See the file header for the compatibility rules this preserves.
|
|
135
|
+
*/
|
|
136
|
+
export function globEntriesSync(pattern, options = {}) {
|
|
137
|
+
const { ignore, dot = false } = options;
|
|
138
|
+
const normalized = toPosix(pattern);
|
|
139
|
+
const { base, rest } = splitPattern(normalized);
|
|
140
|
+
const includeMatchers = expandGlobstarSuffix(normalized);
|
|
141
|
+
const ignoreMatchers = ignore ? expandGlobstarSuffix(toPosix(ignore)) : [];
|
|
142
|
+
const accept = (candidate) => includeMatchers.some((matcher) => minimatch(candidate, matcher, { dot })) &&
|
|
143
|
+
!ignoreMatchers.some((matcher) => minimatch(candidate, matcher, { dot }));
|
|
144
|
+
// No wildcard anywhere: the pattern names one concrete path.
|
|
145
|
+
if (rest.length === 0) {
|
|
146
|
+
const stats = statSync(normalized, { throwIfNoEntry: false });
|
|
147
|
+
if (!stats || !accept(normalized)) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
return [
|
|
151
|
+
{
|
|
152
|
+
path: normalized,
|
|
153
|
+
isFile: stats.isFile(),
|
|
154
|
+
isDirectory: stats.isDirectory(),
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
// Only the immediate children of `base` can match a single trailing
|
|
159
|
+
// wildcard segment, so skip the deep walk in that (common) case.
|
|
160
|
+
const recursive = rest.length > 1 || rest.some((segment) => segment.includes('**'));
|
|
161
|
+
// An asset may be configured for a directory that does not exist, or one
|
|
162
|
+
// that turns out to be unreadable; `walk` reports no matches for it (and
|
|
163
|
+
// any nested directories that fail) rather than failing the whole build.
|
|
164
|
+
const walked = walk(base, recursive, symlinkDepthBudget(rest));
|
|
165
|
+
const matches = [];
|
|
166
|
+
// A trailing `**` matches zero segments, so `base` itself can be a result.
|
|
167
|
+
if (accept(base)) {
|
|
168
|
+
matches.push({ path: base, isFile: false, isDirectory: true });
|
|
169
|
+
}
|
|
170
|
+
for (const { parent, entry } of walked) {
|
|
171
|
+
const full = `${toPosix(parent)}/${entry.name}`;
|
|
172
|
+
if (accept(full)) {
|
|
173
|
+
matches.push({
|
|
174
|
+
path: full,
|
|
175
|
+
isFile: entry.isFile(),
|
|
176
|
+
isDirectory: entry.isDirectory(),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return matches;
|
|
181
|
+
}
|
|
182
|
+
/** Expands `pattern` to every matching path. */
|
|
183
|
+
export function globSync(pattern, options = {}) {
|
|
184
|
+
return globEntriesSync(pattern, options).map((entry) => entry.path);
|
|
185
|
+
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.listenForManualRestart = listenForManualRestart;
|
|
4
|
-
exports.displayManualRestartTip = displayManualRestartTip;
|
|
5
|
-
const ansis_1 = require("ansis");
|
|
6
|
-
function listenForManualRestart(callback) {
|
|
1
|
+
import { gray } from 'ansis';
|
|
2
|
+
export function listenForManualRestart(callback) {
|
|
7
3
|
const stdinListener = (data) => {
|
|
8
4
|
if (data.toString().trim() === 'rs') {
|
|
9
5
|
process.stdin.removeListener('data', stdinListener);
|
|
@@ -12,6 +8,6 @@ function listenForManualRestart(callback) {
|
|
|
12
8
|
};
|
|
13
9
|
process.stdin.on('data', stdinListener);
|
|
14
10
|
}
|
|
15
|
-
function displayManualRestartTip() {
|
|
16
|
-
console.log(`To restart at any time, enter ${
|
|
11
|
+
export function displayManualRestartTip() {
|
|
12
|
+
console.log(`To restart at any time, enter ${gray `rs`}.\n`);
|
|
17
13
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Configuration } from '../../configuration/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Whether paths are allowed to point outside of the project directory.
|
|
4
|
+
*
|
|
5
|
+
* Confinement is on by default: `compilerOptions.allowOutsidePaths` has to be
|
|
6
|
+
* set to `true` explicitly to build to (or delete) locations outside of the
|
|
7
|
+
* project, which some monorepo layouts legitimately rely on. See
|
|
8
|
+
* nestjs/nest-cli#3463.
|
|
9
|
+
*/
|
|
10
|
+
export declare function areOutsidePathsAllowed(configuration: Required<Configuration>, appName: string | undefined): boolean;
|
|
11
|
+
export interface PathConfinementOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Resolve symlinks before comparing. Required whenever the path is going to be
|
|
14
|
+
* *written through*: a lexical check alone accepts a path such as "dist" that
|
|
15
|
+
* is itself a symlink pointing outside of the project, and the write would
|
|
16
|
+
* land outside.
|
|
17
|
+
*
|
|
18
|
+
* Deletion does not need it — `fs.rm` unlinks a symlink instead of following
|
|
19
|
+
* it — and turning it on there would reject ordinary setups that legitimately
|
|
20
|
+
* symlink a directory inside the project (a workspace "node_modules", for
|
|
21
|
+
* instance), which is the regression that got the first attempt at this
|
|
22
|
+
* reverted. See nestjs/nest-cli#3460.
|
|
23
|
+
*/
|
|
24
|
+
resolveSymlinks?: boolean;
|
|
25
|
+
projectRoot?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolves `targetPath` against the project directory and asserts that it stays
|
|
29
|
+
* within it. Returns the resolved absolute path.
|
|
30
|
+
*
|
|
31
|
+
* @throws when the path resolves to the project directory itself or escapes it
|
|
32
|
+
*/
|
|
33
|
+
export declare function assertPathInsideProject(targetPath: string, propertyName: string, { resolveSymlinks, projectRoot, }?: PathConfinementOptions): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { realpathSync } from 'fs';
|
|
2
|
+
import { basename, dirname, isAbsolute, relative, resolve, sep } from 'path';
|
|
3
|
+
import { getValueOrDefault } from './get-value-or-default.js';
|
|
4
|
+
/**
|
|
5
|
+
* Whether paths are allowed to point outside of the project directory.
|
|
6
|
+
*
|
|
7
|
+
* Confinement is on by default: `compilerOptions.allowOutsidePaths` has to be
|
|
8
|
+
* set to `true` explicitly to build to (or delete) locations outside of the
|
|
9
|
+
* project, which some monorepo layouts legitimately rely on. See
|
|
10
|
+
* nestjs/nest-cli#3463.
|
|
11
|
+
*/
|
|
12
|
+
export function areOutsidePathsAllowed(configuration, appName) {
|
|
13
|
+
return (getValueOrDefault(configuration, 'compilerOptions.allowOutsidePaths', appName) ?? false);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolves `targetPath` against the project directory and asserts that it stays
|
|
17
|
+
* within it. Returns the resolved absolute path.
|
|
18
|
+
*
|
|
19
|
+
* @throws when the path resolves to the project directory itself or escapes it
|
|
20
|
+
*/
|
|
21
|
+
export function assertPathInsideProject(targetPath, propertyName, { resolveSymlinks = false, projectRoot = process.cwd(), } = {}) {
|
|
22
|
+
const resolvedPath = resolve(projectRoot, targetPath);
|
|
23
|
+
const comparableRoot = resolveSymlinks
|
|
24
|
+
? realpathOrClosestExisting(projectRoot)
|
|
25
|
+
: resolve(projectRoot);
|
|
26
|
+
const comparablePath = resolveSymlinks
|
|
27
|
+
? realpathOrClosestExisting(resolvedPath)
|
|
28
|
+
: resolvedPath;
|
|
29
|
+
const relativePath = relative(comparableRoot, comparablePath);
|
|
30
|
+
const isProjectRoot = relativePath === '';
|
|
31
|
+
const isOutsideProject = relativePath === '..' ||
|
|
32
|
+
relativePath.startsWith(`..${sep}`) ||
|
|
33
|
+
isAbsolute(relativePath);
|
|
34
|
+
if (isProjectRoot || isOutsideProject) {
|
|
35
|
+
throw new Error(`Refusing to use "${propertyName}" path outside of or equal to the project directory: ${targetPath}. ` +
|
|
36
|
+
`Set "compilerOptions.allowOutsidePaths" to true if this is intentional.`);
|
|
37
|
+
}
|
|
38
|
+
return resolvedPath;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolves symlinks in `targetPath`. Output paths routinely do not exist yet, so
|
|
42
|
+
* the closest existing ancestor is resolved instead and the remaining segments
|
|
43
|
+
* are appended back — enough to catch a symlinked ancestor while still working
|
|
44
|
+
* for a directory that is about to be created.
|
|
45
|
+
*/
|
|
46
|
+
function realpathOrClosestExisting(targetPath) {
|
|
47
|
+
let current = resolve(targetPath);
|
|
48
|
+
const trailingSegments = [];
|
|
49
|
+
for (;;) {
|
|
50
|
+
try {
|
|
51
|
+
return resolve(realpathSync(current), ...trailingSegments);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
const parent = dirname(current);
|
|
55
|
+
if (parent === current) {
|
|
56
|
+
// Reached the root without finding an existing path; nothing to resolve.
|
|
57
|
+
return resolve(targetPath);
|
|
58
|
+
}
|
|
59
|
+
trailingSegments.unshift(basename(current));
|
|
60
|
+
current = parent;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import { TypeScriptBinaryLoader } from '../typescript-loader';
|
|
2
|
+
import { TypeScriptBinaryLoader } from '../typescript-loader.js';
|
|
3
|
+
export type TsConfigProviderOutput = Pick<ts.ParsedCommandLine, 'options' | 'fileNames' | 'projectReferences'> & {
|
|
4
|
+
exclude: string[];
|
|
5
|
+
};
|
|
3
6
|
export declare class TsConfigProvider {
|
|
4
7
|
private readonly typescriptLoader;
|
|
5
8
|
constructor(typescriptLoader: TypeScriptBinaryLoader);
|
|
6
|
-
getByConfigFilename(configFilename: string):
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
projectReferences: readonly ts.ProjectReference[] | undefined;
|
|
10
|
-
};
|
|
9
|
+
getByConfigFilename(configFilename: string): TsConfigProviderOutput;
|
|
10
|
+
private parseExclude;
|
|
11
|
+
private normalizeExclude;
|
|
11
12
|
}
|
|
@@ -1,22 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const ui_1 = require("../../ui");
|
|
7
|
-
class TsConfigProvider {
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { dirname, isAbsolute, join, relative } from 'path';
|
|
3
|
+
import { CLI_ERRORS } from '../../ui/index.js';
|
|
4
|
+
export class TsConfigProvider {
|
|
5
|
+
typescriptLoader;
|
|
8
6
|
constructor(typescriptLoader) {
|
|
9
7
|
this.typescriptLoader = typescriptLoader;
|
|
10
8
|
}
|
|
11
9
|
getByConfigFilename(configFilename) {
|
|
12
|
-
const configPath =
|
|
13
|
-
if (!
|
|
14
|
-
throw new Error(
|
|
10
|
+
const configPath = join(process.cwd(), configFilename);
|
|
11
|
+
if (!existsSync(configPath)) {
|
|
12
|
+
throw new Error(CLI_ERRORS.MISSING_TYPESCRIPT(configFilename));
|
|
15
13
|
}
|
|
16
14
|
const tsBinary = this.typescriptLoader.load();
|
|
17
15
|
const parsedCmd = tsBinary.getParsedCommandLineOfConfigFile(configPath, undefined, tsBinary.sys);
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
if (!parsedCmd) {
|
|
17
|
+
throw new Error(`Could not parse TypeScript configuration file "${configFilename}". Please, ensure that the file contains valid JSON and compiler options.`);
|
|
18
|
+
}
|
|
19
|
+
const { options, fileNames, projectReferences, raw } = parsedCmd;
|
|
20
|
+
const exclude = this.normalizeExclude(this.parseExclude(raw?.exclude), configPath);
|
|
21
|
+
return { options, fileNames, projectReferences, exclude };
|
|
22
|
+
}
|
|
23
|
+
parseExclude(exclude) {
|
|
24
|
+
const passesTypeValidation = Array.isArray(exclude) &&
|
|
25
|
+
exclude.every((item) => typeof item === 'string');
|
|
26
|
+
if (!passesTypeValidation) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
return exclude;
|
|
30
|
+
}
|
|
31
|
+
normalizeExclude(exclude, configPath) {
|
|
32
|
+
const configDir = dirname(configPath);
|
|
33
|
+
const relativeConfigDir = relative(process.cwd(), configDir);
|
|
34
|
+
return exclude.map((pattern) => {
|
|
35
|
+
const normalized = isAbsolute(pattern)
|
|
36
|
+
? relative(process.cwd(), pattern)
|
|
37
|
+
: join(relativeConfigDir, pattern);
|
|
38
|
+
return normalized.replace(/\\/g, '/');
|
|
39
|
+
});
|
|
20
40
|
}
|
|
21
41
|
}
|
|
22
|
-
exports.TsConfigProvider = TsConfigProvider;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
function tsconfigPathsBeforeHookFactory(compilerOptions) {
|
|
9
|
-
const tsBinary = new typescript_loader_1.TypeScriptBinaryLoader().load();
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import { dirname, posix } from 'path';
|
|
3
|
+
import * as tsPaths from 'tsconfig-paths';
|
|
4
|
+
import { TypeScriptBinaryLoader } from '../typescript-loader.js';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
export function tsconfigPathsBeforeHookFactory(compilerOptions) {
|
|
7
|
+
const tsBinary = new TypeScriptBinaryLoader().load();
|
|
10
8
|
const { paths = {}, baseUrl = './' } = compilerOptions;
|
|
11
9
|
const matcher = tsPaths.createMatchPath(baseUrl, paths, ['main']);
|
|
12
10
|
return (ctx) => {
|
|
@@ -69,20 +67,22 @@ function getNotAliasedPath(sf, matcher, text) {
|
|
|
69
67
|
if (!result) {
|
|
70
68
|
return;
|
|
71
69
|
}
|
|
72
|
-
if (
|
|
70
|
+
if (process.platform === 'win32') {
|
|
73
71
|
result = result.replace(/\\/g, '/');
|
|
74
72
|
}
|
|
75
73
|
try {
|
|
76
74
|
// Installed packages (node modules) should take precedence over root files with the same name.
|
|
77
75
|
// Ref: https://github.com/nestjs/nest-cli/issues/838
|
|
78
76
|
const packagePath = require.resolve(text, {
|
|
79
|
-
paths: [process.cwd(), ...
|
|
77
|
+
paths: [process.cwd(), ...(require.resolve.paths(text) ?? [])],
|
|
80
78
|
});
|
|
81
79
|
if (packagePath) {
|
|
82
80
|
return text;
|
|
83
81
|
}
|
|
84
82
|
}
|
|
85
|
-
catch {
|
|
86
|
-
|
|
83
|
+
catch {
|
|
84
|
+
// package resolution failed, fall through to relative path
|
|
85
|
+
}
|
|
86
|
+
const resolvedPath = posix.relative(dirname(sf.fileName), result) || './';
|
|
87
87
|
return resolvedPath[0] === '.' ? resolvedPath : './' + resolvedPath;
|
|
88
88
|
}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import { ReadonlyVisitor } from '../interfaces/readonly-visitor.interface';
|
|
2
|
+
import { DeepPluginMeta, ReadonlyVisitor } from '../interfaces/readonly-visitor.interface.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns `true` when the consuming project uses an ESM-style module
|
|
5
|
+
* resolution strategy (`node16` / `nodenext`). Under those resolution
|
|
6
|
+
* modes, dynamic `import()` specifiers MUST include the file extension
|
|
7
|
+
* (typically `.js`) for the runtime resolver to find the module. Without
|
|
8
|
+
* the extension, executing the generated metadata file fails with
|
|
9
|
+
* `ERR_MODULE_NOT_FOUND`, and TypeScript reports a diagnostic.
|
|
10
|
+
*/
|
|
11
|
+
export declare function requiresExplicitImportExtensions(options: ts.CompilerOptions, tsBinary: typeof ts): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the same import path with `.js` appended when (and only when)
|
|
14
|
+
* the path is relative and does not already end in a recognized
|
|
15
|
+
* extension. Bare specifiers (e.g. `@nestjs/common`) and absolute paths
|
|
16
|
+
* are returned unchanged because the caller's resolver handles them.
|
|
17
|
+
*/
|
|
18
|
+
export declare function appendJsExtensionIfMissing(importPath: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Rewrites a single `await import("...")`-style string by appending the
|
|
21
|
+
* `.js` extension to the inner specifier when it is a relative path
|
|
22
|
+
* without an extension. Used to patch the visitor-supplied `typeImports`
|
|
23
|
+
* map values.
|
|
24
|
+
*/
|
|
25
|
+
export declare function rewriteAsyncImportString(target: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Walks the given `ts.CallExpression` tree and rewrites every dynamic
|
|
28
|
+
* `import("...")` whose specifier is a relative path missing an
|
|
29
|
+
* extension. Returns a new node when changes are required, or the input
|
|
30
|
+
* node unchanged otherwise.
|
|
31
|
+
*/
|
|
32
|
+
export declare function rewriteImportExpressionForNodeNext(expression: ts.CallExpression, tsBinary: typeof ts): ts.CallExpression;
|
|
33
|
+
/**
|
|
34
|
+
* Recursively walks the collected plugin metadata, rewriting every
|
|
35
|
+
* dynamic `import("./relative")` call expression to include the `.js`
|
|
36
|
+
* extension required by node16 / nodenext module resolution.
|
|
37
|
+
*/
|
|
38
|
+
export declare function rewriteCollectedMetadataForNodeNext(metadata: Record<string, Record<string, Array<[ts.CallExpression, DeepPluginMeta]>>>, tsBinary: typeof ts): void;
|
|
3
39
|
export interface PluginMetadataGenerateOptions {
|
|
4
40
|
/**
|
|
5
41
|
* The visitors to use to generate the metadata.
|
|
@@ -1,10 +1,97 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { FOUND_NO_ISSUES_GENERATING_METADATA } from '../swc/constants.js';
|
|
2
|
+
import { TypeCheckerHost } from '../swc/type-checker-host.js';
|
|
3
|
+
import { TypeScriptBinaryLoader } from '../typescript-loader.js';
|
|
4
|
+
import { PluginMetadataPrinter } from './plugin-metadata-printer.js';
|
|
5
|
+
/**
|
|
6
|
+
* Returns `true` when the consuming project uses an ESM-style module
|
|
7
|
+
* resolution strategy (`node16` / `nodenext`). Under those resolution
|
|
8
|
+
* modes, dynamic `import()` specifiers MUST include the file extension
|
|
9
|
+
* (typically `.js`) for the runtime resolver to find the module. Without
|
|
10
|
+
* the extension, executing the generated metadata file fails with
|
|
11
|
+
* `ERR_MODULE_NOT_FOUND`, and TypeScript reports a diagnostic.
|
|
12
|
+
*/
|
|
13
|
+
export function requiresExplicitImportExtensions(options, tsBinary) {
|
|
14
|
+
const moduleResolution = options.moduleResolution;
|
|
15
|
+
return (moduleResolution === tsBinary.ModuleResolutionKind.Node16 ||
|
|
16
|
+
moduleResolution === tsBinary.ModuleResolutionKind.NodeNext);
|
|
17
|
+
}
|
|
18
|
+
const RELATIVE_PATH_RE = /^\.\.?\//;
|
|
19
|
+
// Any common JS/TS-style extension that the user could have authored or
|
|
20
|
+
// that our rewrite would have already produced. Prevents double-appending.
|
|
21
|
+
const HAS_KNOWN_EXTENSION_RE = /\.(m?js|c?js|m?ts|c?ts|json|node)$/i;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the same import path with `.js` appended when (and only when)
|
|
24
|
+
* the path is relative and does not already end in a recognized
|
|
25
|
+
* extension. Bare specifiers (e.g. `@nestjs/common`) and absolute paths
|
|
26
|
+
* are returned unchanged because the caller's resolver handles them.
|
|
27
|
+
*/
|
|
28
|
+
export function appendJsExtensionIfMissing(importPath) {
|
|
29
|
+
if (!RELATIVE_PATH_RE.test(importPath)) {
|
|
30
|
+
return importPath;
|
|
31
|
+
}
|
|
32
|
+
if (HAS_KNOWN_EXTENSION_RE.test(importPath)) {
|
|
33
|
+
return importPath;
|
|
34
|
+
}
|
|
35
|
+
return `${importPath}.js`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Rewrites a single `await import("...")`-style string by appending the
|
|
39
|
+
* `.js` extension to the inner specifier when it is a relative path
|
|
40
|
+
* without an extension. Used to patch the visitor-supplied `typeImports`
|
|
41
|
+
* map values.
|
|
42
|
+
*/
|
|
43
|
+
export function rewriteAsyncImportString(target) {
|
|
44
|
+
return target.replace(/import\((['"])((?:\\\1|(?!\1).)*)\1\)/g, (match, quote, specifier) => `import(${quote}${appendJsExtensionIfMissing(specifier)}${quote})`);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Walks the given `ts.CallExpression` tree and rewrites every dynamic
|
|
48
|
+
* `import("...")` whose specifier is a relative path missing an
|
|
49
|
+
* extension. Returns a new node when changes are required, or the input
|
|
50
|
+
* node unchanged otherwise.
|
|
51
|
+
*/
|
|
52
|
+
export function rewriteImportExpressionForNodeNext(expression, tsBinary) {
|
|
53
|
+
const visit = (node) => {
|
|
54
|
+
if (tsBinary.isCallExpression(node) &&
|
|
55
|
+
node.expression.kind === tsBinary.SyntaxKind.ImportKeyword &&
|
|
56
|
+
node.arguments.length > 0 &&
|
|
57
|
+
tsBinary.isStringLiteralLike(node.arguments[0])) {
|
|
58
|
+
const original = node.arguments[0].text;
|
|
59
|
+
const rewritten = appendJsExtensionIfMissing(original);
|
|
60
|
+
if (rewritten !== original) {
|
|
61
|
+
const updatedArgs = [
|
|
62
|
+
tsBinary.factory.createStringLiteral(rewritten),
|
|
63
|
+
...node.arguments.slice(1),
|
|
64
|
+
];
|
|
65
|
+
return tsBinary.factory.updateCallExpression(node, node.expression, node.typeArguments, updatedArgs);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return tsBinary.visitEachChild(node, visit, undefined);
|
|
69
|
+
};
|
|
70
|
+
return visit(expression);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Recursively walks the collected plugin metadata, rewriting every
|
|
74
|
+
* dynamic `import("./relative")` call expression to include the `.js`
|
|
75
|
+
* extension required by node16 / nodenext module resolution.
|
|
76
|
+
*/
|
|
77
|
+
export function rewriteCollectedMetadataForNodeNext(metadata, tsBinary) {
|
|
78
|
+
for (const visitorKey of Object.keys(metadata)) {
|
|
79
|
+
const sections = metadata[visitorKey];
|
|
80
|
+
for (const sectionKey of Object.keys(sections)) {
|
|
81
|
+
const tuples = sections[sectionKey];
|
|
82
|
+
if (!Array.isArray(tuples)) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
for (let i = 0; i < tuples.length; i++) {
|
|
86
|
+
const [importExpr, meta] = tuples[i];
|
|
87
|
+
tuples[i] = [
|
|
88
|
+
rewriteImportExpressionForNodeNext(importExpr, tsBinary),
|
|
89
|
+
meta,
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
8
95
|
/**
|
|
9
96
|
* Generates plugins metadata by traversing the AST of the project.
|
|
10
97
|
* @example
|
|
@@ -20,11 +107,12 @@ const plugin_metadata_printer_1 = require("./plugin-metadata-printer");
|
|
|
20
107
|
* });
|
|
21
108
|
* ```
|
|
22
109
|
*/
|
|
23
|
-
class PluginMetadataGenerator {
|
|
110
|
+
export class PluginMetadataGenerator {
|
|
111
|
+
pluginMetadataPrinter = new PluginMetadataPrinter();
|
|
112
|
+
typeCheckerHost = new TypeCheckerHost();
|
|
113
|
+
typescriptLoader = new TypeScriptBinaryLoader();
|
|
114
|
+
tsBinary;
|
|
24
115
|
constructor() {
|
|
25
|
-
this.pluginMetadataPrinter = new plugin_metadata_printer_1.PluginMetadataPrinter();
|
|
26
|
-
this.typeCheckerHost = new type_checker_host_1.TypeCheckerHost();
|
|
27
|
-
this.typescriptLoader = new typescript_loader_1.TypeScriptBinaryLoader();
|
|
28
116
|
this.tsBinary = this.typescriptLoader.load();
|
|
29
117
|
}
|
|
30
118
|
generate(options) {
|
|
@@ -50,7 +138,7 @@ class PluginMetadataGenerator {
|
|
|
50
138
|
console.log(tsBinary.formatDiagnosticsWithColorAndContext(diagnostics, formatDiagnosticsHost));
|
|
51
139
|
}
|
|
52
140
|
else {
|
|
53
|
-
console.log(
|
|
141
|
+
console.log(FOUND_NO_ISSUES_GENERATING_METADATA);
|
|
54
142
|
}
|
|
55
143
|
}
|
|
56
144
|
};
|
|
@@ -75,10 +163,22 @@ class PluginMetadataGenerator {
|
|
|
75
163
|
...visitor.typeImports,
|
|
76
164
|
};
|
|
77
165
|
});
|
|
166
|
+
// Under `node16` / `nodenext` module resolution, dynamic `import()`
|
|
167
|
+
// specifiers must include explicit file extensions. The visitors emit
|
|
168
|
+
// bare relative specifiers (e.g. `import("./hello.dto")`), which are
|
|
169
|
+
// valid under classic / node10 resolution but break compilation and
|
|
170
|
+
// runtime under nodenext. When the consuming project uses an ESM-style
|
|
171
|
+
// resolver, rewrite both the metadata import call expressions and the
|
|
172
|
+
// typeImports map values to include the `.js` extension. See #3364.
|
|
173
|
+
if (requiresExplicitImportExtensions(programRef.getCompilerOptions(), this.tsBinary)) {
|
|
174
|
+
rewriteCollectedMetadataForNodeNext(collectedMetadata, this.tsBinary);
|
|
175
|
+
for (const key of Object.keys(typeImports)) {
|
|
176
|
+
typeImports[key] = rewriteAsyncImportString(typeImports[key]);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
78
179
|
this.pluginMetadataPrinter.print(collectedMetadata, typeImports, {
|
|
79
180
|
outputDir,
|
|
80
181
|
filename,
|
|
81
182
|
}, this.tsBinary);
|
|
82
183
|
}
|
|
83
184
|
}
|
|
84
|
-
exports.PluginMetadataGenerator = PluginMetadataGenerator;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import { DeepPluginMeta } from '../interfaces/readonly-visitor.interface';
|
|
2
|
+
import { DeepPluginMeta } from '../interfaces/readonly-visitor.interface.js';
|
|
3
3
|
export interface PluginMetadataPrintOptions {
|
|
4
4
|
outputDir: string;
|
|
5
5
|
filename?: string;
|