@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.cjs
CHANGED
|
@@ -336,10 +336,19 @@ function followModuleForType(name, moduleSpecifier, fromFile, project, seen) {
|
|
|
336
336
|
}
|
|
337
337
|
return null;
|
|
338
338
|
}
|
|
339
|
+
var _findTypeCache = /* @__PURE__ */ new WeakMap();
|
|
339
340
|
function findType(name, sourceFile, project) {
|
|
341
|
+
let byKey = _findTypeCache.get(project);
|
|
342
|
+
if (byKey === void 0) {
|
|
343
|
+
byKey = /* @__PURE__ */ new Map();
|
|
344
|
+
_findTypeCache.set(project, byKey);
|
|
345
|
+
}
|
|
346
|
+
const key = `${sourceFile.getFilePath()}\0${name}`;
|
|
347
|
+
if (byKey.has(key)) return byKey.get(key) ?? null;
|
|
340
348
|
const local = findTypeInFile(name, sourceFile);
|
|
341
|
-
|
|
342
|
-
|
|
349
|
+
const result = local ?? resolveImportedType(name, sourceFile, project);
|
|
350
|
+
byKey.set(key, result);
|
|
351
|
+
return result;
|
|
343
352
|
}
|
|
344
353
|
var _NON_REF_NAMES = /* @__PURE__ */ new Set(["string", "number", "boolean", "void", "unknown", "any", "Date"]);
|
|
345
354
|
function _localDeclForKinds(name, file, kinds) {
|
|
@@ -376,6 +385,26 @@ function resolveTypeRef(nodeOrName, sourceFile, project, opts) {
|
|
|
376
385
|
if (_NON_REF_NAMES.has(refName)) return null;
|
|
377
386
|
name = refName;
|
|
378
387
|
}
|
|
388
|
+
return _resolveNamedRef(name, sourceFile, project, opts);
|
|
389
|
+
}
|
|
390
|
+
var _resolveNamedRefCache = /* @__PURE__ */ new WeakMap();
|
|
391
|
+
function _resolveNamedRef(name, sourceFile, project, opts) {
|
|
392
|
+
let byKey = _resolveNamedRefCache.get(project);
|
|
393
|
+
if (byKey === void 0) {
|
|
394
|
+
byKey = /* @__PURE__ */ new Map();
|
|
395
|
+
_resolveNamedRefCache.set(project, byKey);
|
|
396
|
+
}
|
|
397
|
+
const kindsKey = [...opts.kinds].sort().join(",");
|
|
398
|
+
const key = `${sourceFile.getFilePath()}\0${name}\0${kindsKey}\0${opts.allowBareSpecifier ? 1 : 0}`;
|
|
399
|
+
if (byKey.has(key)) {
|
|
400
|
+
const cached = byKey.get(key) ?? null;
|
|
401
|
+
return cached ? { ...cached } : null;
|
|
402
|
+
}
|
|
403
|
+
const computed = _computeNamedRef(name, sourceFile, project, opts);
|
|
404
|
+
byKey.set(key, computed);
|
|
405
|
+
return computed ? { ...computed } : null;
|
|
406
|
+
}
|
|
407
|
+
function _computeNamedRef(name, sourceFile, project, opts) {
|
|
379
408
|
if (_localDeclForKinds(name, sourceFile, opts.kinds)) {
|
|
380
409
|
return { name, filePath: sourceFile.getFilePath() };
|
|
381
410
|
}
|
|
@@ -453,10 +482,7 @@ function extractSchemaFromDto(classDecl, sourceFile, project) {
|
|
|
453
482
|
depth: 0
|
|
454
483
|
};
|
|
455
484
|
const root = buildObject(classDecl, sourceFile, ctx);
|
|
456
|
-
|
|
457
|
-
ctx.named.set(schemaName, { kind: "unknown", note: "recursive type \u2014 not expanded" });
|
|
458
|
-
}
|
|
459
|
-
return { root, named: ctx.named, warnings: ctx.warnings };
|
|
485
|
+
return { root, named: ctx.named, warnings: ctx.warnings, recursive: ctx.recursiveSchemas };
|
|
460
486
|
}
|
|
461
487
|
function buildObject(classDecl, classFile, ctx) {
|
|
462
488
|
const props = classDecl.getProperties();
|
|
@@ -476,7 +502,7 @@ function buildProperty(prop, classFile, ctx) {
|
|
|
476
502
|
const dec = (n) => decorators.get(n);
|
|
477
503
|
const typeNode = prop.getTypeNode();
|
|
478
504
|
const typeText = typeNode?.getText() ?? "unknown";
|
|
479
|
-
const isArrayType = !!typeNode &&
|
|
505
|
+
const isArrayType = !!typeNode && import_ts_morph2.Node.isArrayTypeNode(typeNode);
|
|
480
506
|
const typeRefName = resolveTypeFactoryName(dec("Type"));
|
|
481
507
|
if (has("ValidateNested") || typeRefName) {
|
|
482
508
|
const childName = typeRefName ?? singularClassName(typeText);
|
|
@@ -607,18 +633,27 @@ function baseFromType(typeText, isArrayType) {
|
|
|
607
633
|
}
|
|
608
634
|
}
|
|
609
635
|
function buildNestedReference(className, fromFile, ctx) {
|
|
610
|
-
if (ctx.visiting.has(className)
|
|
636
|
+
if (ctx.visiting.has(className)) {
|
|
611
637
|
const reserved = ctx.emittedClasses.get(className) ?? aliasFor(className, ctx);
|
|
612
638
|
ctx.emittedClasses.set(className, reserved);
|
|
613
639
|
ctx.recursiveSchemas.add(reserved);
|
|
614
640
|
if (!ctx.warnedDecorators.has(`recursive:${reserved}`)) {
|
|
615
641
|
ctx.warnedDecorators.add(`recursive:${reserved}`);
|
|
616
|
-
const msg = `${className} is a recursive type
|
|
642
|
+
const msg = `${className} is a recursive type; the generated schema validates it via a lazy self-reference.`;
|
|
617
643
|
ctx.warnings.push(msg);
|
|
618
644
|
console.warn(`[nestjs-codegen] ${msg}`);
|
|
619
645
|
}
|
|
620
646
|
return { kind: "lazyRef", name: reserved };
|
|
621
647
|
}
|
|
648
|
+
if (ctx.depth >= 8) {
|
|
649
|
+
if (!ctx.warnedDecorators.has(`deep:${className}`)) {
|
|
650
|
+
ctx.warnedDecorators.add(`deep:${className}`);
|
|
651
|
+
const msg = `${className} nesting is too deep to expand; the generated schema uses unknown for it.`;
|
|
652
|
+
ctx.warnings.push(msg);
|
|
653
|
+
console.warn(`[nestjs-codegen] ${msg}`);
|
|
654
|
+
}
|
|
655
|
+
return { kind: "unknown", note: "nesting too deep \u2014 not expanded" };
|
|
656
|
+
}
|
|
622
657
|
const existing = ctx.emittedClasses.get(className);
|
|
623
658
|
if (existing) return { kind: "ref", name: existing };
|
|
624
659
|
const schemaName = aliasFor(className, ctx);
|
|
@@ -744,17 +779,31 @@ var import_ts_morph4 = require("ts-morph");
|
|
|
744
779
|
var import_ts_morph3 = require("ts-morph");
|
|
745
780
|
|
|
746
781
|
// src/discovery/enum-resolution.ts
|
|
782
|
+
var _enumCache = /* @__PURE__ */ new WeakMap();
|
|
747
783
|
function resolveEnumValues(name, sourceFile, project) {
|
|
784
|
+
let byKey = _enumCache.get(project);
|
|
785
|
+
if (byKey === void 0) {
|
|
786
|
+
byKey = /* @__PURE__ */ new Map();
|
|
787
|
+
_enumCache.set(project, byKey);
|
|
788
|
+
}
|
|
789
|
+
const key = `${sourceFile.getFilePath()}\0${name}`;
|
|
790
|
+
if (byKey.has(key)) {
|
|
791
|
+
const cached = byKey.get(key) ?? null;
|
|
792
|
+
return cached ? { values: [...cached.values], numeric: cached.numeric } : null;
|
|
793
|
+
}
|
|
748
794
|
const resolved = findType(name, sourceFile, project);
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
const
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
795
|
+
let result = null;
|
|
796
|
+
if (resolved && resolved.kind === "enum") {
|
|
797
|
+
let numeric = true;
|
|
798
|
+
const values = resolved.members.map((m) => {
|
|
799
|
+
const parsed = JSON.parse(m);
|
|
800
|
+
if (typeof parsed === "string") numeric = false;
|
|
801
|
+
return String(parsed);
|
|
802
|
+
});
|
|
803
|
+
if (values.length > 0) result = { values, numeric };
|
|
804
|
+
}
|
|
805
|
+
byKey.set(key, result);
|
|
806
|
+
return result ? { values: [...result.values], numeric: result.numeric } : null;
|
|
758
807
|
}
|
|
759
808
|
|
|
760
809
|
// src/discovery/filter-field-types.ts
|
|
@@ -2947,6 +2996,8 @@ function buildFormsFileWithAdapter(routes, outDir, adapter, config) {
|
|
|
2947
2996
|
}
|
|
2948
2997
|
const { globalSchemas, renamesByEntry } = planNestedSchemas(entries);
|
|
2949
2998
|
const irNamed = /* @__PURE__ */ new Map();
|
|
2999
|
+
const irTypeAliases = /* @__PURE__ */ new Map();
|
|
3000
|
+
const irAnnotations = /* @__PURE__ */ new Map();
|
|
2950
3001
|
const decls = [];
|
|
2951
3002
|
const mapEntries = [];
|
|
2952
3003
|
let used = false;
|
|
@@ -2954,6 +3005,8 @@ function buildFormsFileWithAdapter(routes, outDir, adapter, config) {
|
|
|
2954
3005
|
if (src.schema) {
|
|
2955
3006
|
const r = adapter.renderModule(src.schema);
|
|
2956
3007
|
for (const [n, t] of r.namedNestedSchemas) irNamed.set(n, t);
|
|
3008
|
+
if (r.namedTypeAliases) for (const [n, t] of r.namedTypeAliases) irTypeAliases.set(n, t);
|
|
3009
|
+
if (r.namedAnnotations) for (const [n, a] of r.namedAnnotations) irAnnotations.set(n, a);
|
|
2957
3010
|
return { text: r.schemaText };
|
|
2958
3011
|
}
|
|
2959
3012
|
if (src.zodText) {
|
|
@@ -3027,7 +3080,13 @@ function buildFormsFileWithAdapter(routes, outDir, adapter, config) {
|
|
|
3027
3080
|
for (const [n, t] of irNamed) if (!allNested.has(n)) allNested.set(n, t);
|
|
3028
3081
|
if (allNested.size > 0) {
|
|
3029
3082
|
lines.push("// Hoisted nested schemas (shared across endpoints).");
|
|
3030
|
-
for (const [n,
|
|
3083
|
+
for (const [n, alias] of irTypeAliases) {
|
|
3084
|
+
if (allNested.has(n)) lines.push(`${alias};`);
|
|
3085
|
+
}
|
|
3086
|
+
for (const [n, t] of allNested) {
|
|
3087
|
+
const annotation = irAnnotations.get(n);
|
|
3088
|
+
lines.push(`const ${n}${annotation ? `: ${annotation}` : ""} = ${t};`);
|
|
3089
|
+
}
|
|
3031
3090
|
lines.push("");
|
|
3032
3091
|
}
|
|
3033
3092
|
lines.push(...decls);
|