@dudousxd/nestjs-codegen 0.16.0 → 0.17.1
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/CHANGELOG.md +37 -0
- package/dist/cli/main.cjs +142 -97
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +83 -38
- package/dist/cli/main.js.map +1 -1
- package/dist/extension/index.cjs.map +1 -1
- package/dist/extension/index.d.cts +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/extension/index.js.map +1 -1
- package/dist/{index-LQNP7Ms3.d.cts → index-DCF9QSPY.d.cts} +24 -0
- package/dist/{index-LQNP7Ms3.d.ts → index-DCF9QSPY.d.ts} +24 -0
- package/dist/index.cjs +105 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +77 -32
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +105 -60
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +1 -1
- package/dist/nest/index.d.ts +1 -1
- package/dist/nest/index.js +77 -32
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
package/dist/nest/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _nestjs_common from '@nestjs/common';
|
|
2
2
|
import { DynamicModule, OnApplicationBootstrap, OnModuleDestroy, ExecutionContext } from '@nestjs/common';
|
|
3
|
-
import { U as UserConfig } from '../index-
|
|
3
|
+
import { U as UserConfig } from '../index-DCF9QSPY.cjs';
|
|
4
4
|
import 'ts-morph';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/nest/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _nestjs_common from '@nestjs/common';
|
|
2
2
|
import { DynamicModule, OnApplicationBootstrap, OnModuleDestroy, ExecutionContext } from '@nestjs/common';
|
|
3
|
-
import { U as UserConfig } from '../index-
|
|
3
|
+
import { U as UserConfig } from '../index-DCF9QSPY.js';
|
|
4
4
|
import 'ts-morph';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/nest/index.js
CHANGED
|
@@ -141,7 +141,7 @@ function applyDefaults(userConfig, cwd) {
|
|
|
141
141
|
// src/generate-manifest.ts
|
|
142
142
|
import { createHash } from "crypto";
|
|
143
143
|
import { readFile as readFile4, readdir, writeFile as writeFile10 } from "fs/promises";
|
|
144
|
-
import { join as join16, relative as
|
|
144
|
+
import { join as join16, relative as relative7 } from "path";
|
|
145
145
|
import fg3 from "fast-glob";
|
|
146
146
|
|
|
147
147
|
// src/generate.ts
|
|
@@ -475,9 +475,10 @@ function inferExpressionType(node) {
|
|
|
475
475
|
|
|
476
476
|
// src/emit/emit-api.ts
|
|
477
477
|
import { mkdir, writeFile } from "fs/promises";
|
|
478
|
-
import { isAbsolute as isAbsolute2, join as join4, relative as
|
|
478
|
+
import { isAbsolute as isAbsolute2, join as join4, relative as relative4 } from "path";
|
|
479
479
|
|
|
480
480
|
// src/extension/registry.ts
|
|
481
|
+
import { relative as relative3, resolve as resolve2 } from "path";
|
|
481
482
|
import { Project as Project2 } from "ts-morph";
|
|
482
483
|
function resolveApiSlots(extensions) {
|
|
483
484
|
let layer;
|
|
@@ -510,7 +511,7 @@ function mergeExclusive(target, incoming, {
|
|
|
510
511
|
target.set(key, { value, owner });
|
|
511
512
|
}
|
|
512
513
|
}
|
|
513
|
-
function createExtensionContext(config, getRoutes) {
|
|
514
|
+
function createExtensionContext(config, getRoutes, trackedInputs) {
|
|
514
515
|
let project;
|
|
515
516
|
return {
|
|
516
517
|
cwd: config.codegen.cwd,
|
|
@@ -519,6 +520,13 @@ function createExtensionContext(config, getRoutes) {
|
|
|
519
520
|
get routes() {
|
|
520
521
|
return getRoutes();
|
|
521
522
|
},
|
|
523
|
+
trackInput(...paths) {
|
|
524
|
+
if (!trackedInputs) return;
|
|
525
|
+
for (const path of paths) {
|
|
526
|
+
if (!path) continue;
|
|
527
|
+
trackedInputs.add(relative3(config.codegen.cwd, resolve2(config.codegen.cwd, path)));
|
|
528
|
+
}
|
|
529
|
+
},
|
|
522
530
|
project() {
|
|
523
531
|
if (!project) {
|
|
524
532
|
project = new Project2({
|
|
@@ -686,7 +694,7 @@ function rawResponseType(c, outDir) {
|
|
|
686
694
|
return c.contractSource.response;
|
|
687
695
|
}
|
|
688
696
|
if (c.controllerRef) {
|
|
689
|
-
let relPath =
|
|
697
|
+
let relPath = relative4(outDir, c.controllerRef.filePath).replace(/\.ts$/, "");
|
|
690
698
|
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
691
699
|
return `Awaited<ReturnType<import('${relPath}').${c.controllerRef.className}['${c.controllerRef.methodName}']>>`;
|
|
692
700
|
}
|
|
@@ -1012,6 +1020,11 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
1012
1020
|
config: {},
|
|
1013
1021
|
project: () => {
|
|
1014
1022
|
throw new Error("ExtensionContext.project() is unavailable in standalone emitApi.");
|
|
1023
|
+
},
|
|
1024
|
+
// No manifest is written on the standalone path, so there is nothing for
|
|
1025
|
+
// tracked dependencies to be recorded into — accept and discard them
|
|
1026
|
+
// rather than making every caller supply a sink.
|
|
1027
|
+
trackInput: () => {
|
|
1015
1028
|
}
|
|
1016
1029
|
};
|
|
1017
1030
|
const importsByFile = /* @__PURE__ */ new Map();
|
|
@@ -1068,7 +1081,7 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
1068
1081
|
for (const [filePath, names] of importsByFile) {
|
|
1069
1082
|
let relPath;
|
|
1070
1083
|
if (isAbsolute2(filePath)) {
|
|
1071
|
-
relPath =
|
|
1084
|
+
relPath = relative4(outDir, filePath).replace(/\.ts$/, "");
|
|
1072
1085
|
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
1073
1086
|
} else {
|
|
1074
1087
|
relPath = filePath;
|
|
@@ -1182,7 +1195,7 @@ async function emitCache(pages, outDir) {
|
|
|
1182
1195
|
|
|
1183
1196
|
// src/emit/emit-forms.ts
|
|
1184
1197
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
1185
|
-
import { join as join6, relative as
|
|
1198
|
+
import { join as join6, relative as relative5 } from "path";
|
|
1186
1199
|
async function emitForms(routes, outDir, config, adapter) {
|
|
1187
1200
|
if (config && config.enabled === false) return false;
|
|
1188
1201
|
const content = buildFormsFileWithAdapter(routes, outDir, adapter, config);
|
|
@@ -1201,7 +1214,7 @@ function deriveBaseName(routeName) {
|
|
|
1201
1214
|
return { method, full };
|
|
1202
1215
|
}
|
|
1203
1216
|
function relImport(outDir, filePath) {
|
|
1204
|
-
let relPath =
|
|
1217
|
+
let relPath = relative5(outDir, filePath).replace(/\.ts$/, "");
|
|
1205
1218
|
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
1206
1219
|
return relPath;
|
|
1207
1220
|
}
|
|
@@ -1949,7 +1962,7 @@ async function emitOpenApi(routes, outDir, opts = {}) {
|
|
|
1949
1962
|
|
|
1950
1963
|
// src/emit/emit-pages.ts
|
|
1951
1964
|
import { mkdir as mkdir7, writeFile as writeFile7 } from "fs/promises";
|
|
1952
|
-
import { join as join10, relative as
|
|
1965
|
+
import { join as join10, relative as relative6 } from "path";
|
|
1953
1966
|
async function emitPages(pages, outDir, _options = {}) {
|
|
1954
1967
|
await mkdir7(outDir, { recursive: true });
|
|
1955
1968
|
const pageNameUnion = pages.length > 0 ? pages.map((p) => JSON.stringify(p.name)).join(" | ") : "never";
|
|
@@ -1989,7 +2002,7 @@ ${propsBody}
|
|
|
1989
2002
|
`;
|
|
1990
2003
|
}
|
|
1991
2004
|
function buildAugmentationType(page, outDir) {
|
|
1992
|
-
let importPath =
|
|
2005
|
+
let importPath = relative6(outDir, page.absolutePath).replace(/\.(tsx?|vue|svelte)$/, "");
|
|
1993
2006
|
if (!importPath.startsWith(".")) {
|
|
1994
2007
|
importPath = `./${importPath}`;
|
|
1995
2008
|
}
|
|
@@ -2133,8 +2146,8 @@ function driftGuardMessage(outDir, previousEntryPoint, currentEntryPoint, differ
|
|
|
2133
2146
|
}
|
|
2134
2147
|
async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
2135
2148
|
setCodegenDebug(config.debug);
|
|
2136
|
-
const inputsHash = await computeInputsHash(config);
|
|
2137
2149
|
const manifest = await readManifest(config.codegen.outDir);
|
|
2150
|
+
const inputsHash = await computeInputsHash(config, manifest?.extraInputs ?? []);
|
|
2138
2151
|
if (await isManifestFresh(config.codegen.outDir, manifest, inputsHash)) {
|
|
2139
2152
|
console.log(`[nestjs-codegen] ${config.codegen.outDir} up to date, skipped`);
|
|
2140
2153
|
return;
|
|
@@ -2155,7 +2168,8 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
|
2155
2168
|
}
|
|
2156
2169
|
const extensions = config.extensions ?? [];
|
|
2157
2170
|
let routes = inputRoutes;
|
|
2158
|
-
const
|
|
2171
|
+
const trackedInputs = /* @__PURE__ */ new Set();
|
|
2172
|
+
const ctx = createExtensionContext(config, () => routes, trackedInputs);
|
|
2159
2173
|
if (extensions.length > 0) {
|
|
2160
2174
|
routes = await applyTransformRoutes(routes, extensions, ctx);
|
|
2161
2175
|
}
|
|
@@ -2215,13 +2229,16 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
|
2215
2229
|
}
|
|
2216
2230
|
}
|
|
2217
2231
|
const outputFiles = await listOutputFiles(config.codegen.outDir);
|
|
2232
|
+
const extraInputs = [...trackedInputs].sort();
|
|
2233
|
+
const recordedHash = extraInputs.length > 0 ? await computeInputsHash(config, extraInputs) : inputsHash;
|
|
2218
2234
|
await writeManifest(config.codegen.outDir, {
|
|
2219
2235
|
version: VERSION,
|
|
2220
|
-
hash:
|
|
2236
|
+
hash: recordedHash,
|
|
2221
2237
|
entryPoint,
|
|
2222
2238
|
configHash,
|
|
2223
2239
|
configKeyHashes,
|
|
2224
|
-
files: outputFiles
|
|
2240
|
+
files: outputFiles,
|
|
2241
|
+
...extraInputs.length > 0 ? { extraInputs } : {}
|
|
2225
2242
|
});
|
|
2226
2243
|
}
|
|
2227
2244
|
|
|
@@ -2231,7 +2248,7 @@ import { join as join15 } from "path";
|
|
|
2231
2248
|
import chokidar from "chokidar";
|
|
2232
2249
|
|
|
2233
2250
|
// src/discovery/contracts-fast.ts
|
|
2234
|
-
import { join as join13, resolve as
|
|
2251
|
+
import { join as join13, resolve as resolve4 } from "path";
|
|
2235
2252
|
import fg2 from "fast-glob";
|
|
2236
2253
|
import {
|
|
2237
2254
|
Node as Node9,
|
|
@@ -2251,7 +2268,7 @@ import {
|
|
|
2251
2268
|
|
|
2252
2269
|
// src/discovery/type-ref-resolution.ts
|
|
2253
2270
|
import { readFileSync } from "fs";
|
|
2254
|
-
import { dirname as dirname3, resolve as
|
|
2271
|
+
import { dirname as dirname3, resolve as resolve3 } from "path";
|
|
2255
2272
|
import {
|
|
2256
2273
|
Node as Node2
|
|
2257
2274
|
} from "ts-morph";
|
|
@@ -2308,9 +2325,9 @@ function resolveModuleSpecifier(moduleSpecifier, sourceFile, project) {
|
|
|
2308
2325
|
const dir = dirname3(sourceFile.getFilePath());
|
|
2309
2326
|
const noExt = moduleSpecifier.replace(/\.(js|ts)$/, "");
|
|
2310
2327
|
return [
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2328
|
+
resolve3(dir, `${noExt}.ts`),
|
|
2329
|
+
resolve3(dir, `${moduleSpecifier}.ts`),
|
|
2330
|
+
resolve3(dir, moduleSpecifier, "index.ts")
|
|
2314
2331
|
];
|
|
2315
2332
|
}
|
|
2316
2333
|
const ctx = _ctxFor(project);
|
|
@@ -2331,8 +2348,8 @@ function resolveModuleSpecifier(moduleSpecifier, sourceFile, project) {
|
|
|
2331
2348
|
const rest = moduleSpecifier.slice(prefix.length);
|
|
2332
2349
|
const candidates = [];
|
|
2333
2350
|
for (const mapping of mappings) {
|
|
2334
|
-
const resolved =
|
|
2335
|
-
candidates.push(`${resolved}.ts`,
|
|
2351
|
+
const resolved = resolve3(baseUrl, mapping.replace("*", rest));
|
|
2352
|
+
candidates.push(`${resolved}.ts`, resolve3(resolved, "index.ts"));
|
|
2336
2353
|
}
|
|
2337
2354
|
dbg(" resolved candidates:", candidates);
|
|
2338
2355
|
return candidates;
|
|
@@ -3979,6 +3996,19 @@ function resolveParamClass(method, decoratorName, sourceFile, project) {
|
|
|
3979
3996
|
|
|
3980
3997
|
// src/discovery/heritage.ts
|
|
3981
3998
|
import { Node as Node7, Project as Project3 } from "ts-morph";
|
|
3999
|
+
function resolveHeritageCall(node) {
|
|
4000
|
+
if (!node) return void 0;
|
|
4001
|
+
const expr = unwrapExpression(node);
|
|
4002
|
+
if (Node7.isCallExpression(expr)) return expr;
|
|
4003
|
+
if (!Node7.isIdentifier(expr)) return void 0;
|
|
4004
|
+
const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find(
|
|
4005
|
+
(n) => n !== void 0 && Node7.isVariableDeclaration(n)
|
|
4006
|
+
);
|
|
4007
|
+
const init = decl?.getInitializer();
|
|
4008
|
+
if (!init) return void 0;
|
|
4009
|
+
const unwrapped = unwrapExpression(init);
|
|
4010
|
+
return Node7.isCallExpression(unwrapped) ? unwrapped : void 0;
|
|
4011
|
+
}
|
|
3982
4012
|
function unwrapExpression(node) {
|
|
3983
4013
|
let current = node;
|
|
3984
4014
|
while (Node7.isAsExpression(current) || Node7.isSatisfiesExpression(current) || Node7.isParenthesizedExpression(current) || Node7.isTypeAssertion(current)) {
|
|
@@ -4006,8 +4036,8 @@ function resolveReturnedClass(factoryDecl) {
|
|
|
4006
4036
|
return void 0;
|
|
4007
4037
|
}
|
|
4008
4038
|
function resolveInheritedMethods(cls) {
|
|
4009
|
-
const expr = cls.getExtends()?.getExpression();
|
|
4010
|
-
if (!expr
|
|
4039
|
+
const expr = resolveHeritageCall(cls.getExtends()?.getExpression());
|
|
4040
|
+
if (!expr) return void 0;
|
|
4011
4041
|
const callee = expr.getExpression();
|
|
4012
4042
|
if (!Node7.isIdentifier(callee)) return void 0;
|
|
4013
4043
|
const factoryDecl = callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node7.isFunctionDeclaration(n));
|
|
@@ -4184,7 +4214,7 @@ function parseDefineContractCall(callExpr) {
|
|
|
4184
4214
|
|
|
4185
4215
|
// src/discovery/contracts-fast.ts
|
|
4186
4216
|
function resolveTsconfigPath(cwd, tsconfig) {
|
|
4187
|
-
return tsconfig ?
|
|
4217
|
+
return tsconfig ? resolve4(tsconfig) : join13(cwd, "tsconfig.json");
|
|
4188
4218
|
}
|
|
4189
4219
|
function createDiscoveryProject(tsconfigPath) {
|
|
4190
4220
|
try {
|
|
@@ -4263,7 +4293,7 @@ var PersistentDiscovery = class _PersistentDiscovery {
|
|
|
4263
4293
|
async rediscover(changedPaths) {
|
|
4264
4294
|
if (changedPaths) {
|
|
4265
4295
|
for (const p of changedPaths) {
|
|
4266
|
-
const abs =
|
|
4296
|
+
const abs = resolve4(p);
|
|
4267
4297
|
const sf = this.project.getSourceFile(abs);
|
|
4268
4298
|
if (sf) {
|
|
4269
4299
|
await sf.refreshFromFileSystem();
|
|
@@ -4543,9 +4573,11 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4543
4573
|
factoryFilePath: inherited.factoryFilePath,
|
|
4544
4574
|
classArgs: inherited.classArgs
|
|
4545
4575
|
} : void 0;
|
|
4576
|
+
const ownMethods = cls.getMethods();
|
|
4577
|
+
const ownNames = new Set(ownMethods.map((m) => m.getName()));
|
|
4546
4578
|
const methods = [
|
|
4547
|
-
...
|
|
4548
|
-
...(inherited?.methods ?? []).map((method) => ({ method, mixin: mixinBinding }))
|
|
4579
|
+
...ownMethods.map((method) => ({ method, mixin: mixinBinding })),
|
|
4580
|
+
...(inherited?.methods ?? []).filter((method) => !ownNames.has(method.getName())).map((method) => ({ method, mixin: mixinBinding }))
|
|
4549
4581
|
];
|
|
4550
4582
|
for (const { method, mixin } of methods) {
|
|
4551
4583
|
const verb = resolveVerb(method);
|
|
@@ -4771,7 +4803,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
4771
4803
|
}
|
|
4772
4804
|
|
|
4773
4805
|
// src/index.ts
|
|
4774
|
-
var VERSION = "0.
|
|
4806
|
+
var VERSION = "0.17.1";
|
|
4775
4807
|
|
|
4776
4808
|
// src/generate-manifest.ts
|
|
4777
4809
|
var MANIFEST_FILE = ".codegen-manifest.json";
|
|
@@ -4795,6 +4827,9 @@ function isManifestShape(value) {
|
|
|
4795
4827
|
if (candidate.configKeyHashes !== void 0 && !isStringRecord(candidate.configKeyHashes)) {
|
|
4796
4828
|
return false;
|
|
4797
4829
|
}
|
|
4830
|
+
if (candidate.extraInputs !== void 0 && (!Array.isArray(candidate.extraInputs) || !candidate.extraInputs.every((entry) => typeof entry === "string"))) {
|
|
4831
|
+
return false;
|
|
4832
|
+
}
|
|
4798
4833
|
if (!Array.isArray(candidate.files)) return false;
|
|
4799
4834
|
return candidate.files.every((entry) => typeof entry === "string");
|
|
4800
4835
|
}
|
|
@@ -4834,21 +4869,30 @@ async function discoverInputFiles(config) {
|
|
|
4834
4869
|
const matched = await fg3(globs, { cwd, absolute: true, onlyFiles: true });
|
|
4835
4870
|
return [...new Set(matched)].sort();
|
|
4836
4871
|
}
|
|
4837
|
-
async function computeInputsHash(config) {
|
|
4872
|
+
async function computeInputsHash(config, extraInputs = []) {
|
|
4838
4873
|
const hash = createHash("sha256");
|
|
4839
4874
|
hash.update(`version:${VERSION}
|
|
4840
4875
|
`);
|
|
4841
4876
|
hash.update(`config:${serializeConfig(config)}
|
|
4842
4877
|
`);
|
|
4843
|
-
const inputFiles = await discoverInputFiles(config);
|
|
4844
4878
|
const cwd = config.codegen.cwd;
|
|
4845
|
-
|
|
4879
|
+
const globbed = await discoverInputFiles(config);
|
|
4880
|
+
const globbedRelative = new Set(globbed.map((file) => relative7(cwd, file)));
|
|
4881
|
+
const extra = [...new Set(extraInputs)].filter((file) => !globbedRelative.has(file)).sort();
|
|
4882
|
+
for (const file of globbed) {
|
|
4846
4883
|
const contents = await readFile4(file, "utf8");
|
|
4847
|
-
hash.update(`file:${
|
|
4884
|
+
hash.update(`file:${relative7(cwd, file)}
|
|
4848
4885
|
`);
|
|
4849
4886
|
hash.update(contents);
|
|
4850
4887
|
hash.update("\n");
|
|
4851
4888
|
}
|
|
4889
|
+
for (const file of extra) {
|
|
4890
|
+
const contents = await readFile4(join16(cwd, file), "utf8").catch(() => null);
|
|
4891
|
+
hash.update(`extra:${file}
|
|
4892
|
+
`);
|
|
4893
|
+
hash.update(contents ?? "\0missing");
|
|
4894
|
+
hash.update("\n");
|
|
4895
|
+
}
|
|
4852
4896
|
return hash.digest("hex");
|
|
4853
4897
|
}
|
|
4854
4898
|
async function readManifest(outDir) {
|
|
@@ -4862,6 +4906,7 @@ async function readManifest(outDir) {
|
|
|
4862
4906
|
...parsed.entryPoint ? { entryPoint: parsed.entryPoint } : {},
|
|
4863
4907
|
...parsed.configHash ? { configHash: parsed.configHash } : {},
|
|
4864
4908
|
...parsed.configKeyHashes ? { configKeyHashes: parsed.configKeyHashes } : {},
|
|
4909
|
+
...parsed.extraInputs ? { extraInputs: parsed.extraInputs } : {},
|
|
4865
4910
|
files: parsed.files
|
|
4866
4911
|
};
|
|
4867
4912
|
} catch {
|
|
@@ -4884,7 +4929,7 @@ async function listOutputFiles(outDir) {
|
|
|
4884
4929
|
if (entry.isDirectory()) {
|
|
4885
4930
|
await walk(abs);
|
|
4886
4931
|
} else if (entry.isFile()) {
|
|
4887
|
-
const rel =
|
|
4932
|
+
const rel = relative7(outDir, abs);
|
|
4888
4933
|
if (rel === MANIFEST_FILE || rel === LOCK_FILE2) continue;
|
|
4889
4934
|
found.push(rel);
|
|
4890
4935
|
}
|