@dudousxd/nestjs-codegen 0.3.0 → 0.4.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 +33 -0
- package/dist/cli/main.cjs +79 -20
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +79 -20
- package/dist/cli/main.js.map +1 -1
- package/dist/extension/index.d.cts +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/{index-oH5t7x4G.d.cts → index-DA4uySjo.d.cts} +29 -1
- package/dist/{index-oH5t7x4G.d.ts → index-DA4uySjo.d.ts} +29 -1
- package/dist/index.cjs +130 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -4
- package/dist/index.d.ts +29 -4
- package/dist/index.js +129 -20
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +78 -19
- 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 +78 -19
- package/dist/nest/index.js.map +1 -1
- package/package.json +2 -2
package/dist/nest/index.d.cts
CHANGED
package/dist/nest/index.d.ts
CHANGED
package/dist/nest/index.js
CHANGED
|
@@ -310,10 +310,19 @@ function followModuleForType(name, moduleSpecifier, fromFile, project, seen) {
|
|
|
310
310
|
}
|
|
311
311
|
return null;
|
|
312
312
|
}
|
|
313
|
+
var _findTypeCache = /* @__PURE__ */ new WeakMap();
|
|
313
314
|
function findType(name, sourceFile, project) {
|
|
315
|
+
let byKey = _findTypeCache.get(project);
|
|
316
|
+
if (byKey === void 0) {
|
|
317
|
+
byKey = /* @__PURE__ */ new Map();
|
|
318
|
+
_findTypeCache.set(project, byKey);
|
|
319
|
+
}
|
|
320
|
+
const key = `${sourceFile.getFilePath()}\0${name}`;
|
|
321
|
+
if (byKey.has(key)) return byKey.get(key) ?? null;
|
|
314
322
|
const local = findTypeInFile(name, sourceFile);
|
|
315
|
-
|
|
316
|
-
|
|
323
|
+
const result = local ?? resolveImportedType(name, sourceFile, project);
|
|
324
|
+
byKey.set(key, result);
|
|
325
|
+
return result;
|
|
317
326
|
}
|
|
318
327
|
var _NON_REF_NAMES = /* @__PURE__ */ new Set(["string", "number", "boolean", "void", "unknown", "any", "Date"]);
|
|
319
328
|
function _localDeclForKinds(name, file, kinds) {
|
|
@@ -350,6 +359,26 @@ function resolveTypeRef(nodeOrName, sourceFile, project, opts) {
|
|
|
350
359
|
if (_NON_REF_NAMES.has(refName)) return null;
|
|
351
360
|
name = refName;
|
|
352
361
|
}
|
|
362
|
+
return _resolveNamedRef(name, sourceFile, project, opts);
|
|
363
|
+
}
|
|
364
|
+
var _resolveNamedRefCache = /* @__PURE__ */ new WeakMap();
|
|
365
|
+
function _resolveNamedRef(name, sourceFile, project, opts) {
|
|
366
|
+
let byKey = _resolveNamedRefCache.get(project);
|
|
367
|
+
if (byKey === void 0) {
|
|
368
|
+
byKey = /* @__PURE__ */ new Map();
|
|
369
|
+
_resolveNamedRefCache.set(project, byKey);
|
|
370
|
+
}
|
|
371
|
+
const kindsKey = [...opts.kinds].sort().join(",");
|
|
372
|
+
const key = `${sourceFile.getFilePath()}\0${name}\0${kindsKey}\0${opts.allowBareSpecifier ? 1 : 0}`;
|
|
373
|
+
if (byKey.has(key)) {
|
|
374
|
+
const cached = byKey.get(key) ?? null;
|
|
375
|
+
return cached ? { ...cached } : null;
|
|
376
|
+
}
|
|
377
|
+
const computed = _computeNamedRef(name, sourceFile, project, opts);
|
|
378
|
+
byKey.set(key, computed);
|
|
379
|
+
return computed ? { ...computed } : null;
|
|
380
|
+
}
|
|
381
|
+
function _computeNamedRef(name, sourceFile, project, opts) {
|
|
353
382
|
if (_localDeclForKinds(name, sourceFile, opts.kinds)) {
|
|
354
383
|
return { name, filePath: sourceFile.getFilePath() };
|
|
355
384
|
}
|
|
@@ -427,10 +456,7 @@ function extractSchemaFromDto(classDecl, sourceFile, project) {
|
|
|
427
456
|
depth: 0
|
|
428
457
|
};
|
|
429
458
|
const root = buildObject(classDecl, sourceFile, ctx);
|
|
430
|
-
|
|
431
|
-
ctx.named.set(schemaName, { kind: "unknown", note: "recursive type \u2014 not expanded" });
|
|
432
|
-
}
|
|
433
|
-
return { root, named: ctx.named, warnings: ctx.warnings };
|
|
459
|
+
return { root, named: ctx.named, warnings: ctx.warnings, recursive: ctx.recursiveSchemas };
|
|
434
460
|
}
|
|
435
461
|
function buildObject(classDecl, classFile, ctx) {
|
|
436
462
|
const props = classDecl.getProperties();
|
|
@@ -450,7 +476,7 @@ function buildProperty(prop, classFile, ctx) {
|
|
|
450
476
|
const dec = (n) => decorators.get(n);
|
|
451
477
|
const typeNode = prop.getTypeNode();
|
|
452
478
|
const typeText = typeNode?.getText() ?? "unknown";
|
|
453
|
-
const isArrayType = !!typeNode &&
|
|
479
|
+
const isArrayType = !!typeNode && Node2.isArrayTypeNode(typeNode);
|
|
454
480
|
const typeRefName = resolveTypeFactoryName(dec("Type"));
|
|
455
481
|
if (has("ValidateNested") || typeRefName) {
|
|
456
482
|
const childName = typeRefName ?? singularClassName(typeText);
|
|
@@ -581,18 +607,27 @@ function baseFromType(typeText, isArrayType) {
|
|
|
581
607
|
}
|
|
582
608
|
}
|
|
583
609
|
function buildNestedReference(className, fromFile, ctx) {
|
|
584
|
-
if (ctx.visiting.has(className)
|
|
610
|
+
if (ctx.visiting.has(className)) {
|
|
585
611
|
const reserved = ctx.emittedClasses.get(className) ?? aliasFor(className, ctx);
|
|
586
612
|
ctx.emittedClasses.set(className, reserved);
|
|
587
613
|
ctx.recursiveSchemas.add(reserved);
|
|
588
614
|
if (!ctx.warnedDecorators.has(`recursive:${reserved}`)) {
|
|
589
615
|
ctx.warnedDecorators.add(`recursive:${reserved}`);
|
|
590
|
-
const msg = `${className} is a recursive type
|
|
616
|
+
const msg = `${className} is a recursive type; the generated schema validates it via a lazy self-reference.`;
|
|
591
617
|
ctx.warnings.push(msg);
|
|
592
618
|
console.warn(`[nestjs-codegen] ${msg}`);
|
|
593
619
|
}
|
|
594
620
|
return { kind: "lazyRef", name: reserved };
|
|
595
621
|
}
|
|
622
|
+
if (ctx.depth >= 8) {
|
|
623
|
+
if (!ctx.warnedDecorators.has(`deep:${className}`)) {
|
|
624
|
+
ctx.warnedDecorators.add(`deep:${className}`);
|
|
625
|
+
const msg = `${className} nesting is too deep to expand; the generated schema uses unknown for it.`;
|
|
626
|
+
ctx.warnings.push(msg);
|
|
627
|
+
console.warn(`[nestjs-codegen] ${msg}`);
|
|
628
|
+
}
|
|
629
|
+
return { kind: "unknown", note: "nesting too deep \u2014 not expanded" };
|
|
630
|
+
}
|
|
596
631
|
const existing = ctx.emittedClasses.get(className);
|
|
597
632
|
if (existing) return { kind: "ref", name: existing };
|
|
598
633
|
const schemaName = aliasFor(className, ctx);
|
|
@@ -723,17 +758,31 @@ import {
|
|
|
723
758
|
} from "ts-morph";
|
|
724
759
|
|
|
725
760
|
// src/discovery/enum-resolution.ts
|
|
761
|
+
var _enumCache = /* @__PURE__ */ new WeakMap();
|
|
726
762
|
function resolveEnumValues(name, sourceFile, project) {
|
|
763
|
+
let byKey = _enumCache.get(project);
|
|
764
|
+
if (byKey === void 0) {
|
|
765
|
+
byKey = /* @__PURE__ */ new Map();
|
|
766
|
+
_enumCache.set(project, byKey);
|
|
767
|
+
}
|
|
768
|
+
const key = `${sourceFile.getFilePath()}\0${name}`;
|
|
769
|
+
if (byKey.has(key)) {
|
|
770
|
+
const cached = byKey.get(key) ?? null;
|
|
771
|
+
return cached ? { values: [...cached.values], numeric: cached.numeric } : null;
|
|
772
|
+
}
|
|
727
773
|
const resolved = findType(name, sourceFile, project);
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
774
|
+
let result = null;
|
|
775
|
+
if (resolved && resolved.kind === "enum") {
|
|
776
|
+
let numeric = true;
|
|
777
|
+
const values = resolved.members.map((m) => {
|
|
778
|
+
const parsed = JSON.parse(m);
|
|
779
|
+
if (typeof parsed === "string") numeric = false;
|
|
780
|
+
return String(parsed);
|
|
781
|
+
});
|
|
782
|
+
if (values.length > 0) result = { values, numeric };
|
|
783
|
+
}
|
|
784
|
+
byKey.set(key, result);
|
|
785
|
+
return result ? { values: [...result.values], numeric: result.numeric } : null;
|
|
737
786
|
}
|
|
738
787
|
|
|
739
788
|
// src/discovery/filter-field-types.ts
|
|
@@ -2926,6 +2975,8 @@ function buildFormsFileWithAdapter(routes, outDir, adapter, config) {
|
|
|
2926
2975
|
}
|
|
2927
2976
|
const { globalSchemas, renamesByEntry } = planNestedSchemas(entries);
|
|
2928
2977
|
const irNamed = /* @__PURE__ */ new Map();
|
|
2978
|
+
const irTypeAliases = /* @__PURE__ */ new Map();
|
|
2979
|
+
const irAnnotations = /* @__PURE__ */ new Map();
|
|
2929
2980
|
const decls = [];
|
|
2930
2981
|
const mapEntries = [];
|
|
2931
2982
|
let used = false;
|
|
@@ -2933,6 +2984,8 @@ function buildFormsFileWithAdapter(routes, outDir, adapter, config) {
|
|
|
2933
2984
|
if (src.schema) {
|
|
2934
2985
|
const r = adapter.renderModule(src.schema);
|
|
2935
2986
|
for (const [n, t] of r.namedNestedSchemas) irNamed.set(n, t);
|
|
2987
|
+
if (r.namedTypeAliases) for (const [n, t] of r.namedTypeAliases) irTypeAliases.set(n, t);
|
|
2988
|
+
if (r.namedAnnotations) for (const [n, a] of r.namedAnnotations) irAnnotations.set(n, a);
|
|
2936
2989
|
return { text: r.schemaText };
|
|
2937
2990
|
}
|
|
2938
2991
|
if (src.zodText) {
|
|
@@ -3006,7 +3059,13 @@ function buildFormsFileWithAdapter(routes, outDir, adapter, config) {
|
|
|
3006
3059
|
for (const [n, t] of irNamed) if (!allNested.has(n)) allNested.set(n, t);
|
|
3007
3060
|
if (allNested.size > 0) {
|
|
3008
3061
|
lines.push("// Hoisted nested schemas (shared across endpoints).");
|
|
3009
|
-
for (const [n,
|
|
3062
|
+
for (const [n, alias] of irTypeAliases) {
|
|
3063
|
+
if (allNested.has(n)) lines.push(`${alias};`);
|
|
3064
|
+
}
|
|
3065
|
+
for (const [n, t] of allNested) {
|
|
3066
|
+
const annotation = irAnnotations.get(n);
|
|
3067
|
+
lines.push(`const ${n}${annotation ? `: ${annotation}` : ""} = ${t};`);
|
|
3068
|
+
}
|
|
3010
3069
|
lines.push("");
|
|
3011
3070
|
}
|
|
3012
3071
|
lines.push(...decls);
|