@dudousxd/nestjs-codegen 0.17.0 → 0.17.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.
@@ -2292,7 +2292,7 @@ var import_fast_glob2 = __toESM(require("fast-glob"), 1);
2292
2292
  var import_ts_morph10 = require("ts-morph");
2293
2293
 
2294
2294
  // src/discovery/dto-type-resolver.ts
2295
- var import_ts_morph7 = require("ts-morph");
2295
+ var import_ts_morph8 = require("ts-morph");
2296
2296
 
2297
2297
  // src/discovery/dto-to-ir.ts
2298
2298
  var import_ts_morph4 = require("ts-morph");
@@ -3048,7 +3048,7 @@ function inSchemaFromDecorator(decorator) {
3048
3048
  }
3049
3049
 
3050
3050
  // src/discovery/filter-for.ts
3051
- var import_ts_morph6 = require("ts-morph");
3051
+ var import_ts_morph7 = require("ts-morph");
3052
3052
 
3053
3053
  // src/discovery/filter-field-types.ts
3054
3054
  var import_ts_morph5 = require("ts-morph");
@@ -3267,6 +3267,123 @@ function toFilterFieldType(name, r) {
3267
3267
  return ft;
3268
3268
  }
3269
3269
 
3270
+ // src/discovery/heritage.ts
3271
+ var import_ts_morph6 = require("ts-morph");
3272
+ function resolveHeritageCall(node) {
3273
+ if (!node) return void 0;
3274
+ const expr = unwrapExpression(node);
3275
+ if (import_ts_morph6.Node.isCallExpression(expr)) return expr;
3276
+ if (!import_ts_morph6.Node.isIdentifier(expr)) return void 0;
3277
+ const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find(
3278
+ (n) => n !== void 0 && import_ts_morph6.Node.isVariableDeclaration(n)
3279
+ );
3280
+ const init = decl?.getInitializer();
3281
+ if (!init) return void 0;
3282
+ const unwrapped = unwrapExpression(init);
3283
+ return import_ts_morph6.Node.isCallExpression(unwrapped) ? unwrapped : void 0;
3284
+ }
3285
+ function unwrapExpression(node) {
3286
+ let current = node;
3287
+ while (import_ts_morph6.Node.isAsExpression(current) || import_ts_morph6.Node.isSatisfiesExpression(current) || import_ts_morph6.Node.isParenthesizedExpression(current) || import_ts_morph6.Node.isTypeAssertion(current)) {
3288
+ current = current.getExpression();
3289
+ }
3290
+ return current;
3291
+ }
3292
+ function resolveReturnedClass(factoryDecl) {
3293
+ const body = factoryDecl.getBody();
3294
+ if (!body) return void 0;
3295
+ const returns = body.getDescendants().filter((n) => import_ts_morph6.Node.isReturnStatement(n));
3296
+ for (const ret of returns) {
3297
+ const expr = ret.getExpression();
3298
+ if (!expr) continue;
3299
+ const inner = unwrapExpression(expr);
3300
+ if (import_ts_morph6.Node.isClassExpression(inner)) {
3301
+ return inner;
3302
+ }
3303
+ if (import_ts_morph6.Node.isIdentifier(inner)) {
3304
+ const name = inner.getText();
3305
+ const decl = body.getDescendants().find((n) => import_ts_morph6.Node.isClassDeclaration(n) && n.getName() === name);
3306
+ if (decl) return decl;
3307
+ }
3308
+ }
3309
+ return void 0;
3310
+ }
3311
+ function resolveFactoryDeclaration(call) {
3312
+ const callee = call.getExpression();
3313
+ if (!import_ts_morph6.Node.isIdentifier(callee)) return void 0;
3314
+ return callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => import_ts_morph6.Node.isFunctionDeclaration(n));
3315
+ }
3316
+ function resolveFactoryStaticClass(node) {
3317
+ if (!import_ts_morph6.Node.isPropertyAccessExpression(node)) return void 0;
3318
+ const call = resolveHeritageCall(node.getExpression());
3319
+ if (!call) return void 0;
3320
+ const factoryDecl = resolveFactoryDeclaration(call);
3321
+ if (!factoryDecl) return void 0;
3322
+ const returnedClass = resolveReturnedClass(factoryDecl);
3323
+ if (!returnedClass) return void 0;
3324
+ const staticProp = returnedClass.getStaticProperties().find((p) => p.getName() === node.getName());
3325
+ if (!staticProp || !import_ts_morph6.Node.isPropertyDeclaration(staticProp)) return void 0;
3326
+ const init = staticProp.getInitializer();
3327
+ if (!init) return void 0;
3328
+ const inner = unwrapExpression(init);
3329
+ if (import_ts_morph6.Node.isClassExpression(inner)) return inner;
3330
+ if (!import_ts_morph6.Node.isIdentifier(inner)) return void 0;
3331
+ return inner.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && import_ts_morph6.Node.isClassDeclaration(n));
3332
+ }
3333
+ function resolveInheritedMethods(cls) {
3334
+ const expr = resolveHeritageCall(cls.getExtends()?.getExpression());
3335
+ if (!expr) return void 0;
3336
+ const callee = expr.getExpression();
3337
+ if (!import_ts_morph6.Node.isIdentifier(callee)) return void 0;
3338
+ const factoryDecl = resolveFactoryDeclaration(expr);
3339
+ if (!factoryDecl) return void 0;
3340
+ const returnedClass = resolveReturnedClass(factoryDecl);
3341
+ if (!returnedClass) return void 0;
3342
+ const classArgs = [];
3343
+ for (const arg of expr.getArguments()) {
3344
+ if (!import_ts_morph6.Node.isIdentifier(arg)) continue;
3345
+ const decl = arg.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => import_ts_morph6.Node.isClassDeclaration(n));
3346
+ if (decl) {
3347
+ classArgs.push({
3348
+ name: decl.getName() ?? arg.getText(),
3349
+ filePath: decl.getSourceFile().getFilePath()
3350
+ });
3351
+ }
3352
+ }
3353
+ return {
3354
+ methods: returnedClass.getMethods(),
3355
+ factoryName: callee.getText(),
3356
+ factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
3357
+ classArgs
3358
+ };
3359
+ }
3360
+ var mixinTypeProject;
3361
+ function getMixinTypeProject() {
3362
+ mixinTypeProject ??= new import_ts_morph6.Project({
3363
+ skipAddingFilesFromTsConfig: true,
3364
+ compilerOptions: { strict: true }
3365
+ });
3366
+ return mixinTypeProject;
3367
+ }
3368
+ function clearMixinTypeProject() {
3369
+ mixinTypeProject = void 0;
3370
+ }
3371
+ function resolveInstantiatedReturnType(cls, methodName) {
3372
+ const filePath = cls.getSourceFile().getFilePath();
3373
+ const className = cls.getName();
3374
+ if (!className) return void 0;
3375
+ const project = getMixinTypeProject();
3376
+ const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
3377
+ const typedCls = sourceFile?.getClass(className);
3378
+ if (!typedCls) return void 0;
3379
+ const prop = typedCls.getType().getProperty(methodName);
3380
+ if (!prop) return void 0;
3381
+ const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
3382
+ if (!returnType) return void 0;
3383
+ const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
3384
+ return unwrapped.getText(typedCls);
3385
+ }
3386
+
3270
3387
  // src/discovery/filter-for.ts
3271
3388
  function resolveMixinEntityClass(mixin, project) {
3272
3389
  const entityArg = mixin?.classArgs[0];
@@ -3275,7 +3392,7 @@ function resolveMixinEntityClass(mixin, project) {
3275
3392
  return file?.getClass(entityArg.name);
3276
3393
  }
3277
3394
  function classifyFilterForHint(typeInit) {
3278
- if (import_ts_morph6.Node.isStringLiteral(typeInit)) {
3395
+ if (import_ts_morph7.Node.isStringLiteral(typeInit)) {
3279
3396
  switch (typeInit.getLiteralValue()) {
3280
3397
  case "string":
3281
3398
  return { kind: "string" };
@@ -3289,10 +3406,10 @@ function classifyFilterForHint(typeInit) {
3289
3406
  return null;
3290
3407
  }
3291
3408
  }
3292
- if (import_ts_morph6.Node.isArrayLiteralExpression(typeInit)) {
3409
+ if (import_ts_morph7.Node.isArrayLiteralExpression(typeInit)) {
3293
3410
  const values = [];
3294
3411
  for (const el of typeInit.getElements()) {
3295
- if (!import_ts_morph6.Node.isStringLiteral(el)) return null;
3412
+ if (!import_ts_morph7.Node.isStringLiteral(el)) return null;
3296
3413
  values.push(el.getLiteralValue());
3297
3414
  }
3298
3415
  if (values.length === 0) return null;
@@ -3327,11 +3444,11 @@ function extractFilterForHints(classDecl, project) {
3327
3444
  if (!filterForDec) continue;
3328
3445
  const args = filterForDec.getArguments();
3329
3446
  const keyArg = args[0];
3330
- const inputKey = keyArg && import_ts_morph6.Node.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
3447
+ const inputKey = keyArg && import_ts_morph7.Node.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
3331
3448
  const optsArg = args[1];
3332
- if (optsArg && import_ts_morph6.Node.isObjectLiteralExpression(optsArg)) {
3449
+ if (optsArg && import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) {
3333
3450
  const typeProp = optsArg.getProperty("type");
3334
- if (typeProp && import_ts_morph6.Node.isPropertyAssignment(typeProp)) {
3451
+ if (typeProp && import_ts_morph7.Node.isPropertyAssignment(typeProp)) {
3335
3452
  const typeInit = typeProp.getInitializer();
3336
3453
  if (typeInit) {
3337
3454
  const classified = classifyFilterForHint(typeInit);
@@ -3356,21 +3473,23 @@ function extractApplyFilterInfo(method, sourceFile, project, mixin) {
3356
3473
  const args = filterDecorator.getArguments();
3357
3474
  if (args.length === 0) continue;
3358
3475
  const filterClassArg = args[0];
3359
- if (!filterClassArg || !import_ts_morph6.Node.isIdentifier(filterClassArg)) continue;
3476
+ if (!filterClassArg) continue;
3477
+ const factoryStaticClass = resolveFactoryStaticClass(filterClassArg);
3478
+ if (!factoryStaticClass && !import_ts_morph7.Node.isIdentifier(filterClassArg)) continue;
3360
3479
  let source = "query";
3361
3480
  const optionsArg = args[1];
3362
- if (optionsArg && import_ts_morph6.Node.isObjectLiteralExpression(optionsArg)) {
3481
+ if (optionsArg && import_ts_morph7.Node.isObjectLiteralExpression(optionsArg)) {
3363
3482
  const sourceProp = optionsArg.getProperty("source");
3364
- if (sourceProp && import_ts_morph6.Node.isPropertyAssignment(sourceProp)) {
3483
+ if (sourceProp && import_ts_morph7.Node.isPropertyAssignment(sourceProp)) {
3365
3484
  const init = sourceProp.getInitializer();
3366
- if (init && import_ts_morph6.Node.isStringLiteral(init) && init.getLiteralValue() === "body") {
3485
+ if (init && import_ts_morph7.Node.isStringLiteral(init) && init.getLiteralValue() === "body") {
3367
3486
  source = "body";
3368
3487
  }
3369
3488
  }
3370
3489
  }
3371
3490
  const filterClassName = filterClassArg.getText();
3372
- const resolved = findType(filterClassName, declFile, project);
3373
- const classDecl = resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg);
3491
+ const resolved = factoryStaticClass ? void 0 : findType(filterClassName, declFile, project);
3492
+ const classDecl = factoryStaticClass ?? (resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg));
3374
3493
  if (classDecl) {
3375
3494
  let fieldTypes = extractClassPropertyTypes(classDecl, project);
3376
3495
  if (fieldTypes.length === 0) {
@@ -3426,22 +3545,22 @@ function resolveRelationEntity(prop, sourceFile, project) {
3426
3545
  const args = dec.getArguments();
3427
3546
  if (args.length === 0) continue;
3428
3547
  const arg = args[0];
3429
- if (import_ts_morph6.Node.isObjectLiteralExpression(arg)) {
3548
+ if (import_ts_morph7.Node.isObjectLiteralExpression(arg)) {
3430
3549
  const entityProp = arg.getProperty("entity");
3431
- if (entityProp && import_ts_morph6.Node.isPropertyAssignment(entityProp)) {
3550
+ if (entityProp && import_ts_morph7.Node.isPropertyAssignment(entityProp)) {
3432
3551
  const init = entityProp.getInitializer();
3433
- if (init && import_ts_morph6.Node.isArrowFunction(init)) {
3552
+ if (init && import_ts_morph7.Node.isArrowFunction(init)) {
3434
3553
  const body = init.getBody();
3435
- if (import_ts_morph6.Node.isIdentifier(body)) {
3554
+ if (import_ts_morph7.Node.isIdentifier(body)) {
3436
3555
  const resolved = findType(body.getText(), prop.getSourceFile(), project);
3437
3556
  if (resolved?.kind === "class") return resolved.decl;
3438
3557
  }
3439
3558
  }
3440
3559
  }
3441
3560
  }
3442
- if (import_ts_morph6.Node.isArrowFunction(arg)) {
3561
+ if (import_ts_morph7.Node.isArrowFunction(arg)) {
3443
3562
  const body = arg.getBody();
3444
- if (import_ts_morph6.Node.isIdentifier(body)) {
3563
+ if (import_ts_morph7.Node.isIdentifier(body)) {
3445
3564
  const resolved = findType(body.getText(), prop.getSourceFile(), project);
3446
3565
  if (resolved?.kind === "class") return resolved.decl;
3447
3566
  }
@@ -3460,15 +3579,15 @@ function extractClassPropertyTypes(classDecl, project) {
3460
3579
  return fields;
3461
3580
  }
3462
3581
  function resolveLocalClassDeclaration(identifier) {
3463
- if (!import_ts_morph6.Node.isIdentifier(identifier)) return void 0;
3464
- return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && import_ts_morph6.Node.isClassDeclaration(n));
3582
+ if (!import_ts_morph7.Node.isIdentifier(identifier)) return void 0;
3583
+ return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && import_ts_morph7.Node.isClassDeclaration(n));
3465
3584
  }
3466
3585
  function resolveDeclaredEntity(optionsArg, filterClass, project) {
3467
- if (!import_ts_morph6.Node.isObjectLiteralExpression(optionsArg)) return void 0;
3586
+ if (!import_ts_morph7.Node.isObjectLiteralExpression(optionsArg)) return void 0;
3468
3587
  const entityProp = optionsArg.getProperty("entity");
3469
- if (!entityProp || !import_ts_morph6.Node.isPropertyAssignment(entityProp)) return void 0;
3588
+ if (!entityProp || !import_ts_morph7.Node.isPropertyAssignment(entityProp)) return void 0;
3470
3589
  const entityInit = entityProp.getInitializer();
3471
- if (!entityInit || !import_ts_morph6.Node.isIdentifier(entityInit)) return void 0;
3590
+ if (!entityInit || !import_ts_morph7.Node.isIdentifier(entityInit)) return void 0;
3472
3591
  const resolved = findType(entityInit.getText(), filterClass.getSourceFile(), project);
3473
3592
  if (!resolved || resolved.kind !== "class") return void 0;
3474
3593
  return resolved.decl;
@@ -3479,7 +3598,7 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
3479
3598
  const args = filterableDecorator.getArguments();
3480
3599
  if (args.length === 0) return [];
3481
3600
  const optionsArg = args[0];
3482
- if (!import_ts_morph6.Node.isObjectLiteralExpression(optionsArg)) return [];
3601
+ if (!import_ts_morph7.Node.isObjectLiteralExpression(optionsArg)) return [];
3483
3602
  const entityDecl = entityOverride ?? resolveDeclaredEntity(optionsArg, filterClass, project);
3484
3603
  if (!entityDecl) return [];
3485
3604
  const fields = collectEntityFields(
@@ -3492,17 +3611,17 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
3492
3611
  const relationsDecorator = filterClass.getDecorators().find((d) => d.getName() === "Relations");
3493
3612
  if (relationsDecorator) {
3494
3613
  const relArgs = relationsDecorator.getArguments();
3495
- if (relArgs.length > 0 && import_ts_morph6.Node.isObjectLiteralExpression(relArgs[0])) {
3614
+ if (relArgs.length > 0 && import_ts_morph7.Node.isObjectLiteralExpression(relArgs[0])) {
3496
3615
  for (const relProp of relArgs[0].getProperties()) {
3497
- if (!import_ts_morph6.Node.isPropertyAssignment(relProp)) continue;
3616
+ if (!import_ts_morph7.Node.isPropertyAssignment(relProp)) continue;
3498
3617
  const relInit = relProp.getInitializer();
3499
- if (!relInit || !import_ts_morph6.Node.isObjectLiteralExpression(relInit)) continue;
3618
+ if (!relInit || !import_ts_morph7.Node.isObjectLiteralExpression(relInit)) continue;
3500
3619
  const keysProp = relInit.getProperty("keys");
3501
- if (!keysProp || !import_ts_morph6.Node.isPropertyAssignment(keysProp)) continue;
3620
+ if (!keysProp || !import_ts_morph7.Node.isPropertyAssignment(keysProp)) continue;
3502
3621
  const keysInit = keysProp.getInitializer();
3503
- if (!keysInit || !import_ts_morph6.Node.isArrayLiteralExpression(keysInit)) continue;
3622
+ if (!keysInit || !import_ts_morph7.Node.isArrayLiteralExpression(keysInit)) continue;
3504
3623
  for (const el of keysInit.getElements()) {
3505
- if (import_ts_morph6.Node.isStringLiteral(el)) {
3624
+ if (import_ts_morph7.Node.isStringLiteral(el)) {
3506
3625
  fields.push(toFilterFieldType(el.getLiteralValue(), { kind: "unknown" }));
3507
3626
  }
3508
3627
  }
@@ -3543,22 +3662,22 @@ var PASSTHROUGH_UTILITY = /* @__PURE__ */ new Set([
3543
3662
  ]);
3544
3663
  function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /* @__PURE__ */ new Map()) {
3545
3664
  if (depth <= 0) return "unknown";
3546
- if (import_ts_morph7.Node.isArrayTypeNode(typeNode)) {
3665
+ if (import_ts_morph8.Node.isArrayTypeNode(typeNode)) {
3547
3666
  const elementType = typeNode.getElementTypeNode();
3548
3667
  return `Array<${resolveTypeNodeToString(elementType, sourceFile, project, depth, subst)}>`;
3549
3668
  }
3550
- if (import_ts_morph7.Node.isUnionTypeNode(typeNode)) {
3669
+ if (import_ts_morph8.Node.isUnionTypeNode(typeNode)) {
3551
3670
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" | ");
3552
3671
  }
3553
- if (import_ts_morph7.Node.isIntersectionTypeNode(typeNode)) {
3672
+ if (import_ts_morph8.Node.isIntersectionTypeNode(typeNode)) {
3554
3673
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" & ");
3555
3674
  }
3556
- if (import_ts_morph7.Node.isParenthesizedTypeNode(typeNode)) {
3675
+ if (import_ts_morph8.Node.isParenthesizedTypeNode(typeNode)) {
3557
3676
  return `(${resolveTypeNodeToString(typeNode.getTypeNode(), sourceFile, project, depth, subst)})`;
3558
3677
  }
3559
- if (import_ts_morph7.Node.isTypeReference(typeNode)) {
3678
+ if (import_ts_morph8.Node.isTypeReference(typeNode)) {
3560
3679
  const typeName = typeNode.getTypeName();
3561
- const name = import_ts_morph7.Node.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
3680
+ const name = import_ts_morph8.Node.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
3562
3681
  const bound = subst.get(name);
3563
3682
  if (bound !== void 0) return bound;
3564
3683
  if (name === "string" || name === "number" || name === "boolean") return name;
@@ -3581,10 +3700,10 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
3581
3700
  dbg("unresolvable type:", name, "in", sourceFile.getFilePath());
3582
3701
  return "unknown";
3583
3702
  }
3584
- if (import_ts_morph7.Node.isTypeLiteral(typeNode)) {
3703
+ if (import_ts_morph8.Node.isTypeLiteral(typeNode)) {
3585
3704
  const members = [];
3586
3705
  for (const member of typeNode.getMembers()) {
3587
- if (import_ts_morph7.Node.isPropertySignature(member)) {
3706
+ if (import_ts_morph8.Node.isPropertySignature(member)) {
3588
3707
  const memberTypeNode = member.getTypeNode();
3589
3708
  const memberType = memberTypeNode ? resolveTypeNodeToString(memberTypeNode, sourceFile, project, depth, subst) : "unknown";
3590
3709
  members.push(`${member.getName()}${member.hasQuestionToken() ? "?" : ""}: ${memberType}`);
@@ -3595,11 +3714,11 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
3595
3714
  return members.length > 0 ? `{ ${members.join("; ")} }` : "{}";
3596
3715
  }
3597
3716
  const kind = typeNode.getKind();
3598
- if (kind === import_ts_morph7.SyntaxKind.StringKeyword) return "string";
3599
- if (kind === import_ts_morph7.SyntaxKind.NumberKeyword) return "number";
3600
- if (kind === import_ts_morph7.SyntaxKind.BooleanKeyword) return "boolean";
3601
- if (kind === import_ts_morph7.SyntaxKind.UnknownKeyword) return "unknown";
3602
- if (kind === import_ts_morph7.SyntaxKind.AnyKeyword) return "unknown";
3717
+ if (kind === import_ts_morph8.SyntaxKind.StringKeyword) return "string";
3718
+ if (kind === import_ts_morph8.SyntaxKind.NumberKeyword) return "number";
3719
+ if (kind === import_ts_morph8.SyntaxKind.BooleanKeyword) return "boolean";
3720
+ if (kind === import_ts_morph8.SyntaxKind.UnknownKeyword) return "unknown";
3721
+ if (kind === import_ts_morph8.SyntaxKind.AnyKeyword) return "unknown";
3603
3722
  return typeNode.getText();
3604
3723
  }
3605
3724
  function unwrapFirstTypeArg(typeNode, sourceFile, project, depth, mode, subst = /* @__PURE__ */ new Map()) {
@@ -3684,7 +3803,7 @@ function extractQueryType(method, sourceFile, project) {
3684
3803
  if (!queryDecorator) continue;
3685
3804
  const queryArgs = queryDecorator.getArguments();
3686
3805
  const nameArg = queryArgs[0];
3687
- if (!nameArg || !import_ts_morph7.Node.isStringLiteral(nameArg)) continue;
3806
+ if (!nameArg || !import_ts_morph8.Node.isStringLiteral(nameArg)) continue;
3688
3807
  const queryName = nameArg.getLiteralValue();
3689
3808
  const typeNode = param.getTypeNode();
3690
3809
  const queryType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
@@ -3695,8 +3814,8 @@ function extractQueryType(method, sourceFile, project) {
3695
3814
  function isParamOptional(param) {
3696
3815
  if (param.hasQuestionToken() || param.hasInitializer()) return true;
3697
3816
  const typeNode = param.getTypeNode();
3698
- if (typeNode && import_ts_morph7.Node.isUnionTypeNode(typeNode)) {
3699
- return typeNode.getTypeNodes().some((t) => t.getKind() === import_ts_morph7.SyntaxKind.UndefinedKeyword);
3817
+ if (typeNode && import_ts_morph8.Node.isUnionTypeNode(typeNode)) {
3818
+ return typeNode.getTypeNodes().some((t) => t.getKind() === import_ts_morph8.SyntaxKind.UndefinedKeyword);
3700
3819
  }
3701
3820
  return false;
3702
3821
  }
@@ -3708,7 +3827,7 @@ function extractParamsType(method, sourceFile, project) {
3708
3827
  const paramArgs = paramDecorator.getArguments();
3709
3828
  if (paramArgs.length === 0) continue;
3710
3829
  const nameArg = paramArgs[0];
3711
- if (!import_ts_morph7.Node.isStringLiteral(nameArg)) continue;
3830
+ if (!import_ts_morph8.Node.isStringLiteral(nameArg)) continue;
3712
3831
  const paramName = nameArg.getLiteralValue();
3713
3832
  const typeNode = param.getTypeNode();
3714
3833
  const paramType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
@@ -3729,28 +3848,28 @@ function extractUploadedFiles(method) {
3729
3848
  for (const decorator of method.getDecorators()) {
3730
3849
  if (decorator.getName() !== "UseInterceptors") continue;
3731
3850
  for (const arg of decorator.getArguments()) {
3732
- if (!import_ts_morph7.Node.isCallExpression(arg)) continue;
3851
+ if (!import_ts_morph8.Node.isCallExpression(arg)) continue;
3733
3852
  const interceptor = arg.getExpression().getText();
3734
3853
  const callArgs = arg.getArguments();
3735
3854
  const firstArg2 = callArgs[0];
3736
3855
  if (interceptor === "FileInterceptor") {
3737
- if (firstArg2 && import_ts_morph7.Node.isStringLiteral(firstArg2)) {
3856
+ if (firstArg2 && import_ts_morph8.Node.isStringLiteral(firstArg2)) {
3738
3857
  entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
3739
3858
  multipart = true;
3740
3859
  }
3741
3860
  } else if (interceptor === "FilesInterceptor") {
3742
- if (firstArg2 && import_ts_morph7.Node.isStringLiteral(firstArg2)) {
3861
+ if (firstArg2 && import_ts_morph8.Node.isStringLiteral(firstArg2)) {
3743
3862
  entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
3744
3863
  multipart = true;
3745
3864
  }
3746
3865
  } else if (interceptor === "FileFieldsInterceptor") {
3747
- if (firstArg2 && import_ts_morph7.Node.isArrayLiteralExpression(firstArg2)) {
3866
+ if (firstArg2 && import_ts_morph8.Node.isArrayLiteralExpression(firstArg2)) {
3748
3867
  for (const el of firstArg2.getElements()) {
3749
- if (!import_ts_morph7.Node.isObjectLiteralExpression(el)) continue;
3868
+ if (!import_ts_morph8.Node.isObjectLiteralExpression(el)) continue;
3750
3869
  const nameProp = el.getProperty("name");
3751
- if (nameProp && import_ts_morph7.Node.isPropertyAssignment(nameProp)) {
3870
+ if (nameProp && import_ts_morph8.Node.isPropertyAssignment(nameProp)) {
3752
3871
  const init = nameProp.getInitializer();
3753
- if (init && import_ts_morph7.Node.isStringLiteral(init)) {
3872
+ if (init && import_ts_morph8.Node.isStringLiteral(init)) {
3754
3873
  entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
3755
3874
  }
3756
3875
  }
@@ -3770,13 +3889,13 @@ function extractResponseType(method, sourceFile, project) {
3770
3889
  if (apiResponseDecorator) {
3771
3890
  const args = apiResponseDecorator.getArguments();
3772
3891
  const optsArg = args[0];
3773
- if (optsArg && import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) {
3892
+ if (optsArg && import_ts_morph8.Node.isObjectLiteralExpression(optsArg)) {
3774
3893
  for (const prop of optsArg.getProperties()) {
3775
- if (!import_ts_morph7.Node.isPropertyAssignment(prop)) continue;
3894
+ if (!import_ts_morph8.Node.isPropertyAssignment(prop)) continue;
3776
3895
  if (prop.getName() !== "type") continue;
3777
3896
  const val = prop.getInitializer();
3778
3897
  if (!val) continue;
3779
- if (import_ts_morph7.Node.isArrayLiteralExpression(val)) {
3898
+ if (import_ts_morph8.Node.isArrayLiteralExpression(val)) {
3780
3899
  const elements = val.getElements();
3781
3900
  const firstEl = elements[0];
3782
3901
  if (elements.length > 0 && firstEl !== void 0) {
@@ -3797,24 +3916,24 @@ function extractResponseType(method, sourceFile, project) {
3797
3916
  }
3798
3917
  function apiResponseStatus(decorator) {
3799
3918
  const optsArg = decorator.getArguments()[0];
3800
- if (!optsArg || !import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) return null;
3919
+ if (!optsArg || !import_ts_morph8.Node.isObjectLiteralExpression(optsArg)) return null;
3801
3920
  for (const prop of optsArg.getProperties()) {
3802
- if (!import_ts_morph7.Node.isPropertyAssignment(prop)) continue;
3921
+ if (!import_ts_morph8.Node.isPropertyAssignment(prop)) continue;
3803
3922
  if (prop.getName() !== "status") continue;
3804
3923
  const val = prop.getInitializer();
3805
- if (val && import_ts_morph7.Node.isNumericLiteral(val)) return Number(val.getLiteralValue());
3924
+ if (val && import_ts_morph8.Node.isNumericLiteral(val)) return Number(val.getLiteralValue());
3806
3925
  }
3807
3926
  return null;
3808
3927
  }
3809
3928
  function apiResponseTypeNode(decorator) {
3810
3929
  const optsArg = decorator.getArguments()[0];
3811
- if (!optsArg || !import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) return null;
3930
+ if (!optsArg || !import_ts_morph8.Node.isObjectLiteralExpression(optsArg)) return null;
3812
3931
  for (const prop of optsArg.getProperties()) {
3813
- if (!import_ts_morph7.Node.isPropertyAssignment(prop)) continue;
3932
+ if (!import_ts_morph8.Node.isPropertyAssignment(prop)) continue;
3814
3933
  if (prop.getName() !== "type") continue;
3815
3934
  const val = prop.getInitializer();
3816
3935
  if (!val) return null;
3817
- if (import_ts_morph7.Node.isArrayLiteralExpression(val)) {
3936
+ if (import_ts_morph8.Node.isArrayLiteralExpression(val)) {
3818
3937
  const first = val.getElements()[0];
3819
3938
  return first ? { node: first, isArray: true } : null;
3820
3939
  }
@@ -3832,7 +3951,7 @@ function extractErrorType(method, sourceFile, project) {
3832
3951
  const inner = resolveIdentifierToClassType(typeInfo.node, sourceFile, project, 3);
3833
3952
  const type = typeInfo.isArray ? `Array<${inner}>` : inner;
3834
3953
  let ref = null;
3835
- if (import_ts_morph7.Node.isIdentifier(typeInfo.node)) {
3954
+ if (import_ts_morph8.Node.isIdentifier(typeInfo.node)) {
3836
3955
  const name = typeInfo.node.getText();
3837
3956
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
3838
3957
  if (localDecl?.isExported()) {
@@ -3849,7 +3968,7 @@ function extractErrorType(method, sourceFile, project) {
3849
3968
  return null;
3850
3969
  }
3851
3970
  function resolveIdentifierToClassType(node, sourceFile, project, depth) {
3852
- if (!import_ts_morph7.Node.isIdentifier(node)) return "unknown";
3971
+ if (!import_ts_morph8.Node.isIdentifier(node)) return "unknown";
3853
3972
  const name = node.getText();
3854
3973
  const resolved = findType(name, sourceFile, project);
3855
3974
  if (resolved) {
@@ -3869,9 +3988,9 @@ var STREAM_ENVELOPES = /* @__PURE__ */ new Set(["MessageEvent", "MessageEventLik
3869
3988
  var BINARY_RESPONSE_TYPES = /* @__PURE__ */ new Set(["StreamableFile", "Buffer"]);
3870
3989
  function detectBinaryResponse(method) {
3871
3990
  const node = unwrapNamedContainer(method.getReturnTypeNode(), /* @__PURE__ */ new Set(["Promise"]));
3872
- if (!node || !import_ts_morph7.Node.isTypeReference(node)) return false;
3991
+ if (!node || !import_ts_morph8.Node.isTypeReference(node)) return false;
3873
3992
  const typeName = node.getTypeName();
3874
- const name = import_ts_morph7.Node.isIdentifier(typeName) ? typeName.getText() : "";
3993
+ const name = import_ts_morph8.Node.isIdentifier(typeName) ? typeName.getText() : "";
3875
3994
  return BINARY_RESPONSE_TYPES.has(name);
3876
3995
  }
3877
3996
  function detectStreamElement(method) {
@@ -3886,9 +4005,9 @@ function detectStreamElement(method) {
3886
4005
  return null;
3887
4006
  }
3888
4007
  function streamContainerElement(node) {
3889
- if (!node || !import_ts_morph7.Node.isTypeReference(node)) return null;
4008
+ if (!node || !import_ts_morph8.Node.isTypeReference(node)) return null;
3890
4009
  const typeName = node.getTypeName();
3891
- const name = import_ts_morph7.Node.isIdentifier(typeName) ? typeName.getText() : "";
4010
+ const name = import_ts_morph8.Node.isIdentifier(typeName) ? typeName.getText() : "";
3892
4011
  if (STREAM_CONTAINERS.has(name) || STREAM_CONTAINERS_GENERATOR.has(name)) {
3893
4012
  return node.getTypeArguments()[0] ?? null;
3894
4013
  }
@@ -3898,9 +4017,9 @@ function hasAsQueryDecorator(method) {
3898
4017
  return method.getDecorators().some((d) => d.getName() === "AsQuery");
3899
4018
  }
3900
4019
  function unwrapNamedContainer(node, names) {
3901
- if (!node || !import_ts_morph7.Node.isTypeReference(node)) return node;
4020
+ if (!node || !import_ts_morph8.Node.isTypeReference(node)) return node;
3902
4021
  const typeName = node.getTypeName();
3903
- const name = import_ts_morph7.Node.isIdentifier(typeName) ? typeName.getText() : "";
4022
+ const name = import_ts_morph8.Node.isIdentifier(typeName) ? typeName.getText() : "";
3904
4023
  if (names.has(name)) {
3905
4024
  return node.getTypeArguments()[0] ?? node;
3906
4025
  }
@@ -3946,11 +4065,11 @@ function extractDtoContract(method, sourceFile, project, mixin) {
3946
4065
  if (apiResp) {
3947
4066
  const args = apiResp.getArguments();
3948
4067
  const optsArg = args[0];
3949
- if (optsArg && import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) {
4068
+ if (optsArg && import_ts_morph8.Node.isObjectLiteralExpression(optsArg)) {
3950
4069
  for (const prop of optsArg.getProperties()) {
3951
- if (import_ts_morph7.Node.isPropertyAssignment(prop) && prop.getName() === "type") {
4070
+ if (import_ts_morph8.Node.isPropertyAssignment(prop) && prop.getName() === "type") {
3952
4071
  const val = prop.getInitializer();
3953
- if (val && import_ts_morph7.Node.isIdentifier(val)) {
4072
+ if (val && import_ts_morph8.Node.isIdentifier(val)) {
3954
4073
  const name = val.getText();
3955
4074
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
3956
4075
  if (localDecl?.isExported()) {
@@ -4018,88 +4137,6 @@ function resolveParamClass(method, decoratorName, sourceFile, project) {
4018
4137
  return null;
4019
4138
  }
4020
4139
 
4021
- // src/discovery/heritage.ts
4022
- var import_ts_morph8 = require("ts-morph");
4023
- function unwrapExpression(node) {
4024
- let current = node;
4025
- while (import_ts_morph8.Node.isAsExpression(current) || import_ts_morph8.Node.isSatisfiesExpression(current) || import_ts_morph8.Node.isParenthesizedExpression(current) || import_ts_morph8.Node.isTypeAssertion(current)) {
4026
- current = current.getExpression();
4027
- }
4028
- return current;
4029
- }
4030
- function resolveReturnedClass(factoryDecl) {
4031
- const body = factoryDecl.getBody();
4032
- if (!body) return void 0;
4033
- const returns = body.getDescendants().filter((n) => import_ts_morph8.Node.isReturnStatement(n));
4034
- for (const ret of returns) {
4035
- const expr = ret.getExpression();
4036
- if (!expr) continue;
4037
- const inner = unwrapExpression(expr);
4038
- if (import_ts_morph8.Node.isClassExpression(inner)) {
4039
- return inner;
4040
- }
4041
- if (import_ts_morph8.Node.isIdentifier(inner)) {
4042
- const name = inner.getText();
4043
- const decl = body.getDescendants().find((n) => import_ts_morph8.Node.isClassDeclaration(n) && n.getName() === name);
4044
- if (decl) return decl;
4045
- }
4046
- }
4047
- return void 0;
4048
- }
4049
- function resolveInheritedMethods(cls) {
4050
- const expr = cls.getExtends()?.getExpression();
4051
- if (!expr || !import_ts_morph8.Node.isCallExpression(expr)) return void 0;
4052
- const callee = expr.getExpression();
4053
- if (!import_ts_morph8.Node.isIdentifier(callee)) return void 0;
4054
- const factoryDecl = callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => import_ts_morph8.Node.isFunctionDeclaration(n));
4055
- if (!factoryDecl) return void 0;
4056
- const returnedClass = resolveReturnedClass(factoryDecl);
4057
- if (!returnedClass) return void 0;
4058
- const classArgs = [];
4059
- for (const arg of expr.getArguments()) {
4060
- if (!import_ts_morph8.Node.isIdentifier(arg)) continue;
4061
- const decl = arg.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => import_ts_morph8.Node.isClassDeclaration(n));
4062
- if (decl) {
4063
- classArgs.push({
4064
- name: decl.getName() ?? arg.getText(),
4065
- filePath: decl.getSourceFile().getFilePath()
4066
- });
4067
- }
4068
- }
4069
- return {
4070
- methods: returnedClass.getMethods(),
4071
- factoryName: callee.getText(),
4072
- factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
4073
- classArgs
4074
- };
4075
- }
4076
- var mixinTypeProject;
4077
- function getMixinTypeProject() {
4078
- mixinTypeProject ??= new import_ts_morph8.Project({
4079
- skipAddingFilesFromTsConfig: true,
4080
- compilerOptions: { strict: true }
4081
- });
4082
- return mixinTypeProject;
4083
- }
4084
- function clearMixinTypeProject() {
4085
- mixinTypeProject = void 0;
4086
- }
4087
- function resolveInstantiatedReturnType(cls, methodName) {
4088
- const filePath = cls.getSourceFile().getFilePath();
4089
- const className = cls.getName();
4090
- if (!className) return void 0;
4091
- const project = getMixinTypeProject();
4092
- const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
4093
- const typedCls = sourceFile?.getClass(className);
4094
- if (!typedCls) return void 0;
4095
- const prop = typedCls.getType().getProperty(methodName);
4096
- if (!prop) return void 0;
4097
- const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
4098
- if (!returnType) return void 0;
4099
- const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
4100
- return unwrapped.getText(typedCls);
4101
- }
4102
-
4103
4140
  // src/discovery/zod-ast-to-ts.ts
4104
4141
  var import_ts_morph9 = require("ts-morph");
4105
4142
  function zodAstToTs(node) {
@@ -4584,9 +4621,11 @@ function extractFromSourceFile(sourceFile, project) {
4584
4621
  factoryFilePath: inherited.factoryFilePath,
4585
4622
  classArgs: inherited.classArgs
4586
4623
  } : void 0;
4624
+ const ownMethods = cls.getMethods();
4625
+ const ownNames = new Set(ownMethods.map((m) => m.getName()));
4587
4626
  const methods = [
4588
- ...cls.getMethods().map((method) => ({ method })),
4589
- ...(inherited?.methods ?? []).map((method) => ({ method, mixin: mixinBinding }))
4627
+ ...ownMethods.map((method) => ({ method, mixin: mixinBinding })),
4628
+ ...(inherited?.methods ?? []).filter((method) => !ownNames.has(method.getName())).map((method) => ({ method, mixin: mixinBinding }))
4590
4629
  ];
4591
4630
  for (const { method, mixin } of methods) {
4592
4631
  const verb = resolveVerb(method);
@@ -4812,7 +4851,7 @@ async function watch(config, onChange, options = {}) {
4812
4851
  }
4813
4852
 
4814
4853
  // src/index.ts
4815
- var VERSION = "0.17.0";
4854
+ var VERSION = "0.17.2";
4816
4855
 
4817
4856
  // src/generate-manifest.ts
4818
4857
  var MANIFEST_FILE = ".codegen-manifest.json";