@dudousxd/nestjs-codegen 0.5.0 → 0.5.2
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 +12 -0
- package/dist/cli/main.cjs +45 -27
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +45 -27
- 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-B0mS84Jj.d.cts → index-_qRai4M3.d.cts} +1 -1
- package/dist/{index-B0mS84Jj.d.ts → index-_qRai4M3.d.ts} +1 -1
- package/dist/index.cjs +85 -27
- 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 +82 -27
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +44 -26
- 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 +44 -26
- package/dist/nest/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @dudousxd/nestjs-codegen
|
|
2
2
|
|
|
3
|
+
## 0.5.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f432450: Internal refactors (behavior-preserving): share `renderModule` across the zod/valibot adapters via a `createChainModuleRenderer` factory, and dedupe the nested-reference array-wrap + presence tail in `buildProperty` (`dto-to-ir`) behind a single `asField` closure.
|
|
8
|
+
|
|
9
|
+
## 0.5.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 7dee3f6: perf: faster generation — `aliasFor` uses a maintained in-use-name set (O(n²)→O(1) over nested DTOs) and `planNestedSchemas` caches compiled rename regexes + uses a maintained Set for membership instead of rebuilding arrays. Generated output is byte-identical.
|
|
14
|
+
|
|
3
15
|
## 0.5.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/dist/cli/main.cjs
CHANGED
|
@@ -1188,18 +1188,27 @@ function refRootIdentifier(refName) {
|
|
|
1188
1188
|
function hasSource(src) {
|
|
1189
1189
|
return !!(src.schema || src.zodText || src.zodRef);
|
|
1190
1190
|
}
|
|
1191
|
+
function escapeRegExp(s) {
|
|
1192
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1193
|
+
}
|
|
1194
|
+
var wordBoundaryRegexCache = /* @__PURE__ */ new Map();
|
|
1195
|
+
function wordBoundaryRegex(token) {
|
|
1196
|
+
let re = wordBoundaryRegexCache.get(token);
|
|
1197
|
+
if (re === void 0) {
|
|
1198
|
+
re = new RegExp(`\\b${escapeRegExp(token)}\\b`, "g");
|
|
1199
|
+
wordBoundaryRegexCache.set(token, re);
|
|
1200
|
+
}
|
|
1201
|
+
return re;
|
|
1202
|
+
}
|
|
1191
1203
|
function applyRenames(text, renames) {
|
|
1192
1204
|
if (!renames || renames.size === 0) return text;
|
|
1193
1205
|
let out = text;
|
|
1194
1206
|
for (const [from, to] of renames) {
|
|
1195
1207
|
if (from === to) continue;
|
|
1196
|
-
out = out.replace(
|
|
1208
|
+
out = out.replace(wordBoundaryRegex(from), to);
|
|
1197
1209
|
}
|
|
1198
1210
|
return out;
|
|
1199
1211
|
}
|
|
1200
|
-
function escapeRegExp(s) {
|
|
1201
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1202
|
-
}
|
|
1203
1212
|
function isSelfReferential(name, text) {
|
|
1204
1213
|
return new RegExp(`\\b${escapeRegExp(name)}\\b`).test(text);
|
|
1205
1214
|
}
|
|
@@ -1211,7 +1220,23 @@ function planNestedSchemas(entries) {
|
|
|
1211
1220
|
const local = Object.entries(entry.nestedSchemas);
|
|
1212
1221
|
if (local.length === 0) continue;
|
|
1213
1222
|
const rename = /* @__PURE__ */ new Map();
|
|
1214
|
-
|
|
1223
|
+
const renameValues = /* @__PURE__ */ new Set();
|
|
1224
|
+
const setRename = (key, value) => {
|
|
1225
|
+
const prev = rename.get(key);
|
|
1226
|
+
rename.set(key, value);
|
|
1227
|
+
if (prev !== void 0 && prev !== value) {
|
|
1228
|
+
let stillUsed = false;
|
|
1229
|
+
for (const v of rename.values()) {
|
|
1230
|
+
if (v === prev) {
|
|
1231
|
+
stillUsed = true;
|
|
1232
|
+
break;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
if (!stillUsed) renameValues.delete(prev);
|
|
1236
|
+
}
|
|
1237
|
+
renameValues.add(value);
|
|
1238
|
+
};
|
|
1239
|
+
for (const [name] of local) setRename(name, name);
|
|
1215
1240
|
const textFor = (name) => {
|
|
1216
1241
|
const raw = entry.nestedSchemas?.[name] ?? "";
|
|
1217
1242
|
return applyRenames(raw, rename);
|
|
@@ -1229,11 +1254,11 @@ function planNestedSchemas(entries) {
|
|
|
1229
1254
|
if (existing === text) continue;
|
|
1230
1255
|
let i = 2;
|
|
1231
1256
|
let candidate = `${name}_${i}`;
|
|
1232
|
-
while (globalSchemas.has(candidate) && globalSchemas.get(candidate) !== textFor(name) ||
|
|
1257
|
+
while (globalSchemas.has(candidate) && globalSchemas.get(candidate) !== textFor(name) || renameValues.has(candidate)) {
|
|
1233
1258
|
i += 1;
|
|
1234
1259
|
candidate = `${name}_${i}`;
|
|
1235
1260
|
}
|
|
1236
|
-
|
|
1261
|
+
setRename(name, candidate);
|
|
1237
1262
|
changed = true;
|
|
1238
1263
|
}
|
|
1239
1264
|
}
|
|
@@ -2518,6 +2543,7 @@ function extractSchemaFromDto(classDecl, sourceFile, project) {
|
|
|
2518
2543
|
warnings: [],
|
|
2519
2544
|
warnedDecorators: /* @__PURE__ */ new Set(),
|
|
2520
2545
|
emittedClasses: /* @__PURE__ */ new Map(),
|
|
2546
|
+
usedSchemaNames: /* @__PURE__ */ new Set(),
|
|
2521
2547
|
visiting: /* @__PURE__ */ new Set(),
|
|
2522
2548
|
recursiveSchemas: /* @__PURE__ */ new Set(),
|
|
2523
2549
|
depth: 0,
|
|
@@ -2545,37 +2571,28 @@ function buildProperty(prop, classFile, ctx) {
|
|
|
2545
2571
|
const typeNode = prop.getTypeNode();
|
|
2546
2572
|
const typeText = typeNode?.getText() ?? "unknown";
|
|
2547
2573
|
const isArrayType = !!typeNode && import_ts_morph4.Node.isArrayTypeNode(typeNode);
|
|
2574
|
+
const asField = (child) => applyPresence(
|
|
2575
|
+
has("IsArray") || isArrayType ? { kind: "array", element: child } : child,
|
|
2576
|
+
decorators
|
|
2577
|
+
);
|
|
2548
2578
|
const discriminator = resolveDiscriminator(dec("Type"));
|
|
2549
2579
|
if (discriminator) {
|
|
2550
2580
|
const options = discriminator.subTypes.map(
|
|
2551
2581
|
(name) => buildNestedReference(name, classFile, ctx)
|
|
2552
2582
|
);
|
|
2553
|
-
|
|
2554
|
-
kind: "union",
|
|
2555
|
-
options,
|
|
2556
|
-
discriminator: discriminator.property
|
|
2557
|
-
};
|
|
2558
|
-
const wrapArray = has("IsArray") || isArrayType;
|
|
2559
|
-
const node2 = wrapArray ? { kind: "array", element: unionNode } : unionNode;
|
|
2560
|
-
return applyPresence(node2, decorators);
|
|
2583
|
+
return asField({ kind: "union", options, discriminator: discriminator.property });
|
|
2561
2584
|
}
|
|
2562
2585
|
const propTypeParam = singularClassName(typeText);
|
|
2563
2586
|
if (propTypeParam && ctx.typeBindings.has(propTypeParam)) {
|
|
2564
2587
|
const bound = ctx.typeBindings.get(propTypeParam);
|
|
2565
|
-
|
|
2566
|
-
const wrapArray = has("IsArray") || isArrayType;
|
|
2567
|
-
const node2 = wrapArray ? { kind: "array", element: childNode } : childNode;
|
|
2568
|
-
return applyPresence(node2, decorators);
|
|
2588
|
+
return asField(buildNestedReference(bound, classFile, ctx));
|
|
2569
2589
|
}
|
|
2570
2590
|
const typeRefName = resolveTypeFactoryName(dec("Type"));
|
|
2571
2591
|
if (has("ValidateNested") || typeRefName) {
|
|
2572
2592
|
const typeArgs = genericTypeArgNames(typeNode);
|
|
2573
2593
|
const childName = typeRefName ?? singularClassName(typeText);
|
|
2574
2594
|
if (childName) {
|
|
2575
|
-
|
|
2576
|
-
const wrapArray = has("IsArray") || isArrayType;
|
|
2577
|
-
const node2 = wrapArray ? { kind: "array", element: childNode } : childNode;
|
|
2578
|
-
return applyPresence(node2, decorators);
|
|
2595
|
+
return asField(buildNestedReference(childName, classFile, ctx, typeArgs));
|
|
2579
2596
|
}
|
|
2580
2597
|
}
|
|
2581
2598
|
let base = baseFromType(typeText, isArrayType);
|
|
@@ -2703,6 +2720,7 @@ function buildNestedReference(className, fromFile, ctx, typeArgs = []) {
|
|
|
2703
2720
|
if (ctx.visiting.has(cacheKey)) {
|
|
2704
2721
|
const reserved = ctx.emittedClasses.get(cacheKey) ?? aliasFor(schemaBase, ctx);
|
|
2705
2722
|
ctx.emittedClasses.set(cacheKey, reserved);
|
|
2723
|
+
ctx.usedSchemaNames.add(reserved);
|
|
2706
2724
|
ctx.recursiveSchemas.add(reserved);
|
|
2707
2725
|
if (!ctx.warnedDecorators.has(`recursive:${reserved}`)) {
|
|
2708
2726
|
ctx.warnedDecorators.add(`recursive:${reserved}`);
|
|
@@ -2736,6 +2754,7 @@ function buildNestedReference(className, fromFile, ctx, typeArgs = []) {
|
|
|
2736
2754
|
});
|
|
2737
2755
|
for (const [k, v] of newBindings) ctx.typeBindings.set(k, v);
|
|
2738
2756
|
ctx.emittedClasses.set(cacheKey, schemaName);
|
|
2757
|
+
ctx.usedSchemaNames.add(schemaName);
|
|
2739
2758
|
ctx.visiting.add(cacheKey);
|
|
2740
2759
|
ctx.depth += 1;
|
|
2741
2760
|
const childNode = buildObject(resolved.decl, resolved.file, ctx);
|
|
@@ -2743,15 +2762,14 @@ function buildNestedReference(className, fromFile, ctx, typeArgs = []) {
|
|
|
2743
2762
|
ctx.visiting.delete(cacheKey);
|
|
2744
2763
|
for (const [k] of newBindings) ctx.typeBindings.delete(k);
|
|
2745
2764
|
ctx.named.set(schemaName, childNode);
|
|
2765
|
+
ctx.usedSchemaNames.add(schemaName);
|
|
2746
2766
|
return { kind: "ref", name: schemaName };
|
|
2747
2767
|
}
|
|
2748
2768
|
function aliasFor(className, ctx) {
|
|
2749
2769
|
const baseName = `${className}Schema`;
|
|
2750
2770
|
let candidate = baseName;
|
|
2751
2771
|
let i = 1;
|
|
2752
|
-
|
|
2753
|
-
for (const v of ctx.emittedClasses.values()) used.add(v);
|
|
2754
|
-
while (used.has(candidate)) {
|
|
2772
|
+
while (ctx.usedSchemaNames.has(candidate)) {
|
|
2755
2773
|
candidate = `${baseName}_${i}`;
|
|
2756
2774
|
i += 1;
|
|
2757
2775
|
}
|
|
@@ -4430,7 +4448,7 @@ async function watch(config, onChange) {
|
|
|
4430
4448
|
}
|
|
4431
4449
|
|
|
4432
4450
|
// src/index.ts
|
|
4433
|
-
var VERSION = "0.5.
|
|
4451
|
+
var VERSION = "0.5.2";
|
|
4434
4452
|
|
|
4435
4453
|
// src/cli/codegen.ts
|
|
4436
4454
|
async function runCodegen(opts = {}) {
|