@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/dist/cli/main.js CHANGED
@@ -1154,18 +1154,27 @@ function refRootIdentifier(refName) {
1154
1154
  function hasSource(src) {
1155
1155
  return !!(src.schema || src.zodText || src.zodRef);
1156
1156
  }
1157
+ function escapeRegExp(s) {
1158
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1159
+ }
1160
+ var wordBoundaryRegexCache = /* @__PURE__ */ new Map();
1161
+ function wordBoundaryRegex(token) {
1162
+ let re = wordBoundaryRegexCache.get(token);
1163
+ if (re === void 0) {
1164
+ re = new RegExp(`\\b${escapeRegExp(token)}\\b`, "g");
1165
+ wordBoundaryRegexCache.set(token, re);
1166
+ }
1167
+ return re;
1168
+ }
1157
1169
  function applyRenames(text, renames) {
1158
1170
  if (!renames || renames.size === 0) return text;
1159
1171
  let out = text;
1160
1172
  for (const [from, to] of renames) {
1161
1173
  if (from === to) continue;
1162
- out = out.replace(new RegExp(`\\b${escapeRegExp(from)}\\b`, "g"), to);
1174
+ out = out.replace(wordBoundaryRegex(from), to);
1163
1175
  }
1164
1176
  return out;
1165
1177
  }
1166
- function escapeRegExp(s) {
1167
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1168
- }
1169
1178
  function isSelfReferential(name, text) {
1170
1179
  return new RegExp(`\\b${escapeRegExp(name)}\\b`).test(text);
1171
1180
  }
@@ -1177,7 +1186,23 @@ function planNestedSchemas(entries) {
1177
1186
  const local = Object.entries(entry.nestedSchemas);
1178
1187
  if (local.length === 0) continue;
1179
1188
  const rename = /* @__PURE__ */ new Map();
1180
- for (const [name] of local) rename.set(name, name);
1189
+ const renameValues = /* @__PURE__ */ new Set();
1190
+ const setRename = (key, value) => {
1191
+ const prev = rename.get(key);
1192
+ rename.set(key, value);
1193
+ if (prev !== void 0 && prev !== value) {
1194
+ let stillUsed = false;
1195
+ for (const v of rename.values()) {
1196
+ if (v === prev) {
1197
+ stillUsed = true;
1198
+ break;
1199
+ }
1200
+ }
1201
+ if (!stillUsed) renameValues.delete(prev);
1202
+ }
1203
+ renameValues.add(value);
1204
+ };
1205
+ for (const [name] of local) setRename(name, name);
1181
1206
  const textFor = (name) => {
1182
1207
  const raw = entry.nestedSchemas?.[name] ?? "";
1183
1208
  return applyRenames(raw, rename);
@@ -1195,11 +1220,11 @@ function planNestedSchemas(entries) {
1195
1220
  if (existing === text) continue;
1196
1221
  let i = 2;
1197
1222
  let candidate = `${name}_${i}`;
1198
- while (globalSchemas.has(candidate) && globalSchemas.get(candidate) !== textFor(name) || [...rename.values()].includes(candidate)) {
1223
+ while (globalSchemas.has(candidate) && globalSchemas.get(candidate) !== textFor(name) || renameValues.has(candidate)) {
1199
1224
  i += 1;
1200
1225
  candidate = `${name}_${i}`;
1201
1226
  }
1202
- rename.set(name, candidate);
1227
+ setRename(name, candidate);
1203
1228
  changed = true;
1204
1229
  }
1205
1230
  }
@@ -2494,6 +2519,7 @@ function extractSchemaFromDto(classDecl, sourceFile, project) {
2494
2519
  warnings: [],
2495
2520
  warnedDecorators: /* @__PURE__ */ new Set(),
2496
2521
  emittedClasses: /* @__PURE__ */ new Map(),
2522
+ usedSchemaNames: /* @__PURE__ */ new Set(),
2497
2523
  visiting: /* @__PURE__ */ new Set(),
2498
2524
  recursiveSchemas: /* @__PURE__ */ new Set(),
2499
2525
  depth: 0,
@@ -2521,37 +2547,28 @@ function buildProperty(prop, classFile, ctx) {
2521
2547
  const typeNode = prop.getTypeNode();
2522
2548
  const typeText = typeNode?.getText() ?? "unknown";
2523
2549
  const isArrayType = !!typeNode && Node3.isArrayTypeNode(typeNode);
2550
+ const asField = (child) => applyPresence(
2551
+ has("IsArray") || isArrayType ? { kind: "array", element: child } : child,
2552
+ decorators
2553
+ );
2524
2554
  const discriminator = resolveDiscriminator(dec("Type"));
2525
2555
  if (discriminator) {
2526
2556
  const options = discriminator.subTypes.map(
2527
2557
  (name) => buildNestedReference(name, classFile, ctx)
2528
2558
  );
2529
- const unionNode = {
2530
- kind: "union",
2531
- options,
2532
- discriminator: discriminator.property
2533
- };
2534
- const wrapArray = has("IsArray") || isArrayType;
2535
- const node2 = wrapArray ? { kind: "array", element: unionNode } : unionNode;
2536
- return applyPresence(node2, decorators);
2559
+ return asField({ kind: "union", options, discriminator: discriminator.property });
2537
2560
  }
2538
2561
  const propTypeParam = singularClassName(typeText);
2539
2562
  if (propTypeParam && ctx.typeBindings.has(propTypeParam)) {
2540
2563
  const bound = ctx.typeBindings.get(propTypeParam);
2541
- const childNode = buildNestedReference(bound, classFile, ctx);
2542
- const wrapArray = has("IsArray") || isArrayType;
2543
- const node2 = wrapArray ? { kind: "array", element: childNode } : childNode;
2544
- return applyPresence(node2, decorators);
2564
+ return asField(buildNestedReference(bound, classFile, ctx));
2545
2565
  }
2546
2566
  const typeRefName = resolveTypeFactoryName(dec("Type"));
2547
2567
  if (has("ValidateNested") || typeRefName) {
2548
2568
  const typeArgs = genericTypeArgNames(typeNode);
2549
2569
  const childName = typeRefName ?? singularClassName(typeText);
2550
2570
  if (childName) {
2551
- const childNode = buildNestedReference(childName, classFile, ctx, typeArgs);
2552
- const wrapArray = has("IsArray") || isArrayType;
2553
- const node2 = wrapArray ? { kind: "array", element: childNode } : childNode;
2554
- return applyPresence(node2, decorators);
2571
+ return asField(buildNestedReference(childName, classFile, ctx, typeArgs));
2555
2572
  }
2556
2573
  }
2557
2574
  let base = baseFromType(typeText, isArrayType);
@@ -2679,6 +2696,7 @@ function buildNestedReference(className, fromFile, ctx, typeArgs = []) {
2679
2696
  if (ctx.visiting.has(cacheKey)) {
2680
2697
  const reserved = ctx.emittedClasses.get(cacheKey) ?? aliasFor(schemaBase, ctx);
2681
2698
  ctx.emittedClasses.set(cacheKey, reserved);
2699
+ ctx.usedSchemaNames.add(reserved);
2682
2700
  ctx.recursiveSchemas.add(reserved);
2683
2701
  if (!ctx.warnedDecorators.has(`recursive:${reserved}`)) {
2684
2702
  ctx.warnedDecorators.add(`recursive:${reserved}`);
@@ -2712,6 +2730,7 @@ function buildNestedReference(className, fromFile, ctx, typeArgs = []) {
2712
2730
  });
2713
2731
  for (const [k, v] of newBindings) ctx.typeBindings.set(k, v);
2714
2732
  ctx.emittedClasses.set(cacheKey, schemaName);
2733
+ ctx.usedSchemaNames.add(schemaName);
2715
2734
  ctx.visiting.add(cacheKey);
2716
2735
  ctx.depth += 1;
2717
2736
  const childNode = buildObject(resolved.decl, resolved.file, ctx);
@@ -2719,15 +2738,14 @@ function buildNestedReference(className, fromFile, ctx, typeArgs = []) {
2719
2738
  ctx.visiting.delete(cacheKey);
2720
2739
  for (const [k] of newBindings) ctx.typeBindings.delete(k);
2721
2740
  ctx.named.set(schemaName, childNode);
2741
+ ctx.usedSchemaNames.add(schemaName);
2722
2742
  return { kind: "ref", name: schemaName };
2723
2743
  }
2724
2744
  function aliasFor(className, ctx) {
2725
2745
  const baseName = `${className}Schema`;
2726
2746
  let candidate = baseName;
2727
2747
  let i = 1;
2728
- const used = new Set(ctx.named.keys());
2729
- for (const v of ctx.emittedClasses.values()) used.add(v);
2730
- while (used.has(candidate)) {
2748
+ while (ctx.usedSchemaNames.has(candidate)) {
2731
2749
  candidate = `${baseName}_${i}`;
2732
2750
  i += 1;
2733
2751
  }
@@ -4411,7 +4429,7 @@ async function watch(config, onChange) {
4411
4429
  }
4412
4430
 
4413
4431
  // src/index.ts
4414
- var VERSION = "0.5.0";
4432
+ var VERSION = "0.5.2";
4415
4433
 
4416
4434
  // src/cli/codegen.ts
4417
4435
  async function runCodegen(opts = {}) {