@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.
package/dist/index.d.cts CHANGED
@@ -382,6 +382,6 @@ interface FastDiscoveryOptions {
382
382
  }
383
383
  declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
384
384
 
385
- declare const VERSION = "0.17.0";
385
+ declare const VERSION = "0.17.2";
386
386
 
387
387
  export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
package/dist/index.d.ts CHANGED
@@ -382,6 +382,6 @@ interface FastDiscoveryOptions {
382
382
  }
383
383
  declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
384
384
 
385
- declare const VERSION = "0.17.0";
385
+ declare const VERSION = "0.17.2";
386
386
 
387
387
  export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
package/dist/index.js CHANGED
@@ -2453,7 +2453,7 @@ import {
2453
2453
 
2454
2454
  // src/discovery/dto-type-resolver.ts
2455
2455
  import {
2456
- Node as Node6,
2456
+ Node as Node7,
2457
2457
  SyntaxKind as SyntaxKind3
2458
2458
  } from "ts-morph";
2459
2459
 
@@ -3216,7 +3216,7 @@ function inSchemaFromDecorator(decorator) {
3216
3216
 
3217
3217
  // src/discovery/filter-for.ts
3218
3218
  import {
3219
- Node as Node5
3219
+ Node as Node6
3220
3220
  } from "ts-morph";
3221
3221
 
3222
3222
  // src/discovery/filter-field-types.ts
@@ -3439,6 +3439,123 @@ function toFilterFieldType(name, r) {
3439
3439
  return ft;
3440
3440
  }
3441
3441
 
3442
+ // src/discovery/heritage.ts
3443
+ import { Node as Node5, Project as Project3 } from "ts-morph";
3444
+ function resolveHeritageCall(node) {
3445
+ if (!node) return void 0;
3446
+ const expr = unwrapExpression(node);
3447
+ if (Node5.isCallExpression(expr)) return expr;
3448
+ if (!Node5.isIdentifier(expr)) return void 0;
3449
+ const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find(
3450
+ (n) => n !== void 0 && Node5.isVariableDeclaration(n)
3451
+ );
3452
+ const init = decl?.getInitializer();
3453
+ if (!init) return void 0;
3454
+ const unwrapped = unwrapExpression(init);
3455
+ return Node5.isCallExpression(unwrapped) ? unwrapped : void 0;
3456
+ }
3457
+ function unwrapExpression(node) {
3458
+ let current = node;
3459
+ while (Node5.isAsExpression(current) || Node5.isSatisfiesExpression(current) || Node5.isParenthesizedExpression(current) || Node5.isTypeAssertion(current)) {
3460
+ current = current.getExpression();
3461
+ }
3462
+ return current;
3463
+ }
3464
+ function resolveReturnedClass(factoryDecl) {
3465
+ const body = factoryDecl.getBody();
3466
+ if (!body) return void 0;
3467
+ const returns = body.getDescendants().filter((n) => Node5.isReturnStatement(n));
3468
+ for (const ret of returns) {
3469
+ const expr = ret.getExpression();
3470
+ if (!expr) continue;
3471
+ const inner = unwrapExpression(expr);
3472
+ if (Node5.isClassExpression(inner)) {
3473
+ return inner;
3474
+ }
3475
+ if (Node5.isIdentifier(inner)) {
3476
+ const name = inner.getText();
3477
+ const decl = body.getDescendants().find((n) => Node5.isClassDeclaration(n) && n.getName() === name);
3478
+ if (decl) return decl;
3479
+ }
3480
+ }
3481
+ return void 0;
3482
+ }
3483
+ function resolveFactoryDeclaration(call) {
3484
+ const callee = call.getExpression();
3485
+ if (!Node5.isIdentifier(callee)) return void 0;
3486
+ return callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node5.isFunctionDeclaration(n));
3487
+ }
3488
+ function resolveFactoryStaticClass(node) {
3489
+ if (!Node5.isPropertyAccessExpression(node)) return void 0;
3490
+ const call = resolveHeritageCall(node.getExpression());
3491
+ if (!call) return void 0;
3492
+ const factoryDecl = resolveFactoryDeclaration(call);
3493
+ if (!factoryDecl) return void 0;
3494
+ const returnedClass = resolveReturnedClass(factoryDecl);
3495
+ if (!returnedClass) return void 0;
3496
+ const staticProp = returnedClass.getStaticProperties().find((p) => p.getName() === node.getName());
3497
+ if (!staticProp || !Node5.isPropertyDeclaration(staticProp)) return void 0;
3498
+ const init = staticProp.getInitializer();
3499
+ if (!init) return void 0;
3500
+ const inner = unwrapExpression(init);
3501
+ if (Node5.isClassExpression(inner)) return inner;
3502
+ if (!Node5.isIdentifier(inner)) return void 0;
3503
+ return inner.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && Node5.isClassDeclaration(n));
3504
+ }
3505
+ function resolveInheritedMethods(cls) {
3506
+ const expr = resolveHeritageCall(cls.getExtends()?.getExpression());
3507
+ if (!expr) return void 0;
3508
+ const callee = expr.getExpression();
3509
+ if (!Node5.isIdentifier(callee)) return void 0;
3510
+ const factoryDecl = resolveFactoryDeclaration(expr);
3511
+ if (!factoryDecl) return void 0;
3512
+ const returnedClass = resolveReturnedClass(factoryDecl);
3513
+ if (!returnedClass) return void 0;
3514
+ const classArgs = [];
3515
+ for (const arg of expr.getArguments()) {
3516
+ if (!Node5.isIdentifier(arg)) continue;
3517
+ const decl = arg.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node5.isClassDeclaration(n));
3518
+ if (decl) {
3519
+ classArgs.push({
3520
+ name: decl.getName() ?? arg.getText(),
3521
+ filePath: decl.getSourceFile().getFilePath()
3522
+ });
3523
+ }
3524
+ }
3525
+ return {
3526
+ methods: returnedClass.getMethods(),
3527
+ factoryName: callee.getText(),
3528
+ factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
3529
+ classArgs
3530
+ };
3531
+ }
3532
+ var mixinTypeProject;
3533
+ function getMixinTypeProject() {
3534
+ mixinTypeProject ??= new Project3({
3535
+ skipAddingFilesFromTsConfig: true,
3536
+ compilerOptions: { strict: true }
3537
+ });
3538
+ return mixinTypeProject;
3539
+ }
3540
+ function clearMixinTypeProject() {
3541
+ mixinTypeProject = void 0;
3542
+ }
3543
+ function resolveInstantiatedReturnType(cls, methodName) {
3544
+ const filePath = cls.getSourceFile().getFilePath();
3545
+ const className = cls.getName();
3546
+ if (!className) return void 0;
3547
+ const project = getMixinTypeProject();
3548
+ const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
3549
+ const typedCls = sourceFile?.getClass(className);
3550
+ if (!typedCls) return void 0;
3551
+ const prop = typedCls.getType().getProperty(methodName);
3552
+ if (!prop) return void 0;
3553
+ const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
3554
+ if (!returnType) return void 0;
3555
+ const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
3556
+ return unwrapped.getText(typedCls);
3557
+ }
3558
+
3442
3559
  // src/discovery/filter-for.ts
3443
3560
  function resolveMixinEntityClass(mixin, project) {
3444
3561
  const entityArg = mixin?.classArgs[0];
@@ -3447,7 +3564,7 @@ function resolveMixinEntityClass(mixin, project) {
3447
3564
  return file?.getClass(entityArg.name);
3448
3565
  }
3449
3566
  function classifyFilterForHint(typeInit) {
3450
- if (Node5.isStringLiteral(typeInit)) {
3567
+ if (Node6.isStringLiteral(typeInit)) {
3451
3568
  switch (typeInit.getLiteralValue()) {
3452
3569
  case "string":
3453
3570
  return { kind: "string" };
@@ -3461,10 +3578,10 @@ function classifyFilterForHint(typeInit) {
3461
3578
  return null;
3462
3579
  }
3463
3580
  }
3464
- if (Node5.isArrayLiteralExpression(typeInit)) {
3581
+ if (Node6.isArrayLiteralExpression(typeInit)) {
3465
3582
  const values = [];
3466
3583
  for (const el of typeInit.getElements()) {
3467
- if (!Node5.isStringLiteral(el)) return null;
3584
+ if (!Node6.isStringLiteral(el)) return null;
3468
3585
  values.push(el.getLiteralValue());
3469
3586
  }
3470
3587
  if (values.length === 0) return null;
@@ -3499,11 +3616,11 @@ function extractFilterForHints(classDecl, project) {
3499
3616
  if (!filterForDec) continue;
3500
3617
  const args = filterForDec.getArguments();
3501
3618
  const keyArg = args[0];
3502
- const inputKey = keyArg && Node5.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
3619
+ const inputKey = keyArg && Node6.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
3503
3620
  const optsArg = args[1];
3504
- if (optsArg && Node5.isObjectLiteralExpression(optsArg)) {
3621
+ if (optsArg && Node6.isObjectLiteralExpression(optsArg)) {
3505
3622
  const typeProp = optsArg.getProperty("type");
3506
- if (typeProp && Node5.isPropertyAssignment(typeProp)) {
3623
+ if (typeProp && Node6.isPropertyAssignment(typeProp)) {
3507
3624
  const typeInit = typeProp.getInitializer();
3508
3625
  if (typeInit) {
3509
3626
  const classified = classifyFilterForHint(typeInit);
@@ -3528,21 +3645,23 @@ function extractApplyFilterInfo(method, sourceFile, project, mixin) {
3528
3645
  const args = filterDecorator.getArguments();
3529
3646
  if (args.length === 0) continue;
3530
3647
  const filterClassArg = args[0];
3531
- if (!filterClassArg || !Node5.isIdentifier(filterClassArg)) continue;
3648
+ if (!filterClassArg) continue;
3649
+ const factoryStaticClass = resolveFactoryStaticClass(filterClassArg);
3650
+ if (!factoryStaticClass && !Node6.isIdentifier(filterClassArg)) continue;
3532
3651
  let source = "query";
3533
3652
  const optionsArg = args[1];
3534
- if (optionsArg && Node5.isObjectLiteralExpression(optionsArg)) {
3653
+ if (optionsArg && Node6.isObjectLiteralExpression(optionsArg)) {
3535
3654
  const sourceProp = optionsArg.getProperty("source");
3536
- if (sourceProp && Node5.isPropertyAssignment(sourceProp)) {
3655
+ if (sourceProp && Node6.isPropertyAssignment(sourceProp)) {
3537
3656
  const init = sourceProp.getInitializer();
3538
- if (init && Node5.isStringLiteral(init) && init.getLiteralValue() === "body") {
3657
+ if (init && Node6.isStringLiteral(init) && init.getLiteralValue() === "body") {
3539
3658
  source = "body";
3540
3659
  }
3541
3660
  }
3542
3661
  }
3543
3662
  const filterClassName = filterClassArg.getText();
3544
- const resolved = findType(filterClassName, declFile, project);
3545
- const classDecl = resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg);
3663
+ const resolved = factoryStaticClass ? void 0 : findType(filterClassName, declFile, project);
3664
+ const classDecl = factoryStaticClass ?? (resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg));
3546
3665
  if (classDecl) {
3547
3666
  let fieldTypes = extractClassPropertyTypes(classDecl, project);
3548
3667
  if (fieldTypes.length === 0) {
@@ -3598,22 +3717,22 @@ function resolveRelationEntity(prop, sourceFile, project) {
3598
3717
  const args = dec.getArguments();
3599
3718
  if (args.length === 0) continue;
3600
3719
  const arg = args[0];
3601
- if (Node5.isObjectLiteralExpression(arg)) {
3720
+ if (Node6.isObjectLiteralExpression(arg)) {
3602
3721
  const entityProp = arg.getProperty("entity");
3603
- if (entityProp && Node5.isPropertyAssignment(entityProp)) {
3722
+ if (entityProp && Node6.isPropertyAssignment(entityProp)) {
3604
3723
  const init = entityProp.getInitializer();
3605
- if (init && Node5.isArrowFunction(init)) {
3724
+ if (init && Node6.isArrowFunction(init)) {
3606
3725
  const body = init.getBody();
3607
- if (Node5.isIdentifier(body)) {
3726
+ if (Node6.isIdentifier(body)) {
3608
3727
  const resolved = findType(body.getText(), prop.getSourceFile(), project);
3609
3728
  if (resolved?.kind === "class") return resolved.decl;
3610
3729
  }
3611
3730
  }
3612
3731
  }
3613
3732
  }
3614
- if (Node5.isArrowFunction(arg)) {
3733
+ if (Node6.isArrowFunction(arg)) {
3615
3734
  const body = arg.getBody();
3616
- if (Node5.isIdentifier(body)) {
3735
+ if (Node6.isIdentifier(body)) {
3617
3736
  const resolved = findType(body.getText(), prop.getSourceFile(), project);
3618
3737
  if (resolved?.kind === "class") return resolved.decl;
3619
3738
  }
@@ -3632,15 +3751,15 @@ function extractClassPropertyTypes(classDecl, project) {
3632
3751
  return fields;
3633
3752
  }
3634
3753
  function resolveLocalClassDeclaration(identifier) {
3635
- if (!Node5.isIdentifier(identifier)) return void 0;
3636
- return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && Node5.isClassDeclaration(n));
3754
+ if (!Node6.isIdentifier(identifier)) return void 0;
3755
+ return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && Node6.isClassDeclaration(n));
3637
3756
  }
3638
3757
  function resolveDeclaredEntity(optionsArg, filterClass, project) {
3639
- if (!Node5.isObjectLiteralExpression(optionsArg)) return void 0;
3758
+ if (!Node6.isObjectLiteralExpression(optionsArg)) return void 0;
3640
3759
  const entityProp = optionsArg.getProperty("entity");
3641
- if (!entityProp || !Node5.isPropertyAssignment(entityProp)) return void 0;
3760
+ if (!entityProp || !Node6.isPropertyAssignment(entityProp)) return void 0;
3642
3761
  const entityInit = entityProp.getInitializer();
3643
- if (!entityInit || !Node5.isIdentifier(entityInit)) return void 0;
3762
+ if (!entityInit || !Node6.isIdentifier(entityInit)) return void 0;
3644
3763
  const resolved = findType(entityInit.getText(), filterClass.getSourceFile(), project);
3645
3764
  if (!resolved || resolved.kind !== "class") return void 0;
3646
3765
  return resolved.decl;
@@ -3651,7 +3770,7 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
3651
3770
  const args = filterableDecorator.getArguments();
3652
3771
  if (args.length === 0) return [];
3653
3772
  const optionsArg = args[0];
3654
- if (!Node5.isObjectLiteralExpression(optionsArg)) return [];
3773
+ if (!Node6.isObjectLiteralExpression(optionsArg)) return [];
3655
3774
  const entityDecl = entityOverride ?? resolveDeclaredEntity(optionsArg, filterClass, project);
3656
3775
  if (!entityDecl) return [];
3657
3776
  const fields = collectEntityFields(
@@ -3664,17 +3783,17 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
3664
3783
  const relationsDecorator = filterClass.getDecorators().find((d) => d.getName() === "Relations");
3665
3784
  if (relationsDecorator) {
3666
3785
  const relArgs = relationsDecorator.getArguments();
3667
- if (relArgs.length > 0 && Node5.isObjectLiteralExpression(relArgs[0])) {
3786
+ if (relArgs.length > 0 && Node6.isObjectLiteralExpression(relArgs[0])) {
3668
3787
  for (const relProp of relArgs[0].getProperties()) {
3669
- if (!Node5.isPropertyAssignment(relProp)) continue;
3788
+ if (!Node6.isPropertyAssignment(relProp)) continue;
3670
3789
  const relInit = relProp.getInitializer();
3671
- if (!relInit || !Node5.isObjectLiteralExpression(relInit)) continue;
3790
+ if (!relInit || !Node6.isObjectLiteralExpression(relInit)) continue;
3672
3791
  const keysProp = relInit.getProperty("keys");
3673
- if (!keysProp || !Node5.isPropertyAssignment(keysProp)) continue;
3792
+ if (!keysProp || !Node6.isPropertyAssignment(keysProp)) continue;
3674
3793
  const keysInit = keysProp.getInitializer();
3675
- if (!keysInit || !Node5.isArrayLiteralExpression(keysInit)) continue;
3794
+ if (!keysInit || !Node6.isArrayLiteralExpression(keysInit)) continue;
3676
3795
  for (const el of keysInit.getElements()) {
3677
- if (Node5.isStringLiteral(el)) {
3796
+ if (Node6.isStringLiteral(el)) {
3678
3797
  fields.push(toFilterFieldType(el.getLiteralValue(), { kind: "unknown" }));
3679
3798
  }
3680
3799
  }
@@ -3715,22 +3834,22 @@ var PASSTHROUGH_UTILITY = /* @__PURE__ */ new Set([
3715
3834
  ]);
3716
3835
  function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /* @__PURE__ */ new Map()) {
3717
3836
  if (depth <= 0) return "unknown";
3718
- if (Node6.isArrayTypeNode(typeNode)) {
3837
+ if (Node7.isArrayTypeNode(typeNode)) {
3719
3838
  const elementType = typeNode.getElementTypeNode();
3720
3839
  return `Array<${resolveTypeNodeToString(elementType, sourceFile, project, depth, subst)}>`;
3721
3840
  }
3722
- if (Node6.isUnionTypeNode(typeNode)) {
3841
+ if (Node7.isUnionTypeNode(typeNode)) {
3723
3842
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" | ");
3724
3843
  }
3725
- if (Node6.isIntersectionTypeNode(typeNode)) {
3844
+ if (Node7.isIntersectionTypeNode(typeNode)) {
3726
3845
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" & ");
3727
3846
  }
3728
- if (Node6.isParenthesizedTypeNode(typeNode)) {
3847
+ if (Node7.isParenthesizedTypeNode(typeNode)) {
3729
3848
  return `(${resolveTypeNodeToString(typeNode.getTypeNode(), sourceFile, project, depth, subst)})`;
3730
3849
  }
3731
- if (Node6.isTypeReference(typeNode)) {
3850
+ if (Node7.isTypeReference(typeNode)) {
3732
3851
  const typeName = typeNode.getTypeName();
3733
- const name = Node6.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
3852
+ const name = Node7.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
3734
3853
  const bound = subst.get(name);
3735
3854
  if (bound !== void 0) return bound;
3736
3855
  if (name === "string" || name === "number" || name === "boolean") return name;
@@ -3753,10 +3872,10 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
3753
3872
  dbg("unresolvable type:", name, "in", sourceFile.getFilePath());
3754
3873
  return "unknown";
3755
3874
  }
3756
- if (Node6.isTypeLiteral(typeNode)) {
3875
+ if (Node7.isTypeLiteral(typeNode)) {
3757
3876
  const members = [];
3758
3877
  for (const member of typeNode.getMembers()) {
3759
- if (Node6.isPropertySignature(member)) {
3878
+ if (Node7.isPropertySignature(member)) {
3760
3879
  const memberTypeNode = member.getTypeNode();
3761
3880
  const memberType = memberTypeNode ? resolveTypeNodeToString(memberTypeNode, sourceFile, project, depth, subst) : "unknown";
3762
3881
  members.push(`${member.getName()}${member.hasQuestionToken() ? "?" : ""}: ${memberType}`);
@@ -3856,7 +3975,7 @@ function extractQueryType(method, sourceFile, project) {
3856
3975
  if (!queryDecorator) continue;
3857
3976
  const queryArgs = queryDecorator.getArguments();
3858
3977
  const nameArg = queryArgs[0];
3859
- if (!nameArg || !Node6.isStringLiteral(nameArg)) continue;
3978
+ if (!nameArg || !Node7.isStringLiteral(nameArg)) continue;
3860
3979
  const queryName = nameArg.getLiteralValue();
3861
3980
  const typeNode = param.getTypeNode();
3862
3981
  const queryType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
@@ -3867,7 +3986,7 @@ function extractQueryType(method, sourceFile, project) {
3867
3986
  function isParamOptional(param) {
3868
3987
  if (param.hasQuestionToken() || param.hasInitializer()) return true;
3869
3988
  const typeNode = param.getTypeNode();
3870
- if (typeNode && Node6.isUnionTypeNode(typeNode)) {
3989
+ if (typeNode && Node7.isUnionTypeNode(typeNode)) {
3871
3990
  return typeNode.getTypeNodes().some((t) => t.getKind() === SyntaxKind3.UndefinedKeyword);
3872
3991
  }
3873
3992
  return false;
@@ -3880,7 +3999,7 @@ function extractParamsType(method, sourceFile, project) {
3880
3999
  const paramArgs = paramDecorator.getArguments();
3881
4000
  if (paramArgs.length === 0) continue;
3882
4001
  const nameArg = paramArgs[0];
3883
- if (!Node6.isStringLiteral(nameArg)) continue;
4002
+ if (!Node7.isStringLiteral(nameArg)) continue;
3884
4003
  const paramName = nameArg.getLiteralValue();
3885
4004
  const typeNode = param.getTypeNode();
3886
4005
  const paramType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
@@ -3901,28 +4020,28 @@ function extractUploadedFiles(method) {
3901
4020
  for (const decorator of method.getDecorators()) {
3902
4021
  if (decorator.getName() !== "UseInterceptors") continue;
3903
4022
  for (const arg of decorator.getArguments()) {
3904
- if (!Node6.isCallExpression(arg)) continue;
4023
+ if (!Node7.isCallExpression(arg)) continue;
3905
4024
  const interceptor = arg.getExpression().getText();
3906
4025
  const callArgs = arg.getArguments();
3907
4026
  const firstArg2 = callArgs[0];
3908
4027
  if (interceptor === "FileInterceptor") {
3909
- if (firstArg2 && Node6.isStringLiteral(firstArg2)) {
4028
+ if (firstArg2 && Node7.isStringLiteral(firstArg2)) {
3910
4029
  entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
3911
4030
  multipart = true;
3912
4031
  }
3913
4032
  } else if (interceptor === "FilesInterceptor") {
3914
- if (firstArg2 && Node6.isStringLiteral(firstArg2)) {
4033
+ if (firstArg2 && Node7.isStringLiteral(firstArg2)) {
3915
4034
  entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
3916
4035
  multipart = true;
3917
4036
  }
3918
4037
  } else if (interceptor === "FileFieldsInterceptor") {
3919
- if (firstArg2 && Node6.isArrayLiteralExpression(firstArg2)) {
4038
+ if (firstArg2 && Node7.isArrayLiteralExpression(firstArg2)) {
3920
4039
  for (const el of firstArg2.getElements()) {
3921
- if (!Node6.isObjectLiteralExpression(el)) continue;
4040
+ if (!Node7.isObjectLiteralExpression(el)) continue;
3922
4041
  const nameProp = el.getProperty("name");
3923
- if (nameProp && Node6.isPropertyAssignment(nameProp)) {
4042
+ if (nameProp && Node7.isPropertyAssignment(nameProp)) {
3924
4043
  const init = nameProp.getInitializer();
3925
- if (init && Node6.isStringLiteral(init)) {
4044
+ if (init && Node7.isStringLiteral(init)) {
3926
4045
  entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
3927
4046
  }
3928
4047
  }
@@ -3942,13 +4061,13 @@ function extractResponseType(method, sourceFile, project) {
3942
4061
  if (apiResponseDecorator) {
3943
4062
  const args = apiResponseDecorator.getArguments();
3944
4063
  const optsArg = args[0];
3945
- if (optsArg && Node6.isObjectLiteralExpression(optsArg)) {
4064
+ if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
3946
4065
  for (const prop of optsArg.getProperties()) {
3947
- if (!Node6.isPropertyAssignment(prop)) continue;
4066
+ if (!Node7.isPropertyAssignment(prop)) continue;
3948
4067
  if (prop.getName() !== "type") continue;
3949
4068
  const val = prop.getInitializer();
3950
4069
  if (!val) continue;
3951
- if (Node6.isArrayLiteralExpression(val)) {
4070
+ if (Node7.isArrayLiteralExpression(val)) {
3952
4071
  const elements = val.getElements();
3953
4072
  const firstEl = elements[0];
3954
4073
  if (elements.length > 0 && firstEl !== void 0) {
@@ -3969,24 +4088,24 @@ function extractResponseType(method, sourceFile, project) {
3969
4088
  }
3970
4089
  function apiResponseStatus(decorator) {
3971
4090
  const optsArg = decorator.getArguments()[0];
3972
- if (!optsArg || !Node6.isObjectLiteralExpression(optsArg)) return null;
4091
+ if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
3973
4092
  for (const prop of optsArg.getProperties()) {
3974
- if (!Node6.isPropertyAssignment(prop)) continue;
4093
+ if (!Node7.isPropertyAssignment(prop)) continue;
3975
4094
  if (prop.getName() !== "status") continue;
3976
4095
  const val = prop.getInitializer();
3977
- if (val && Node6.isNumericLiteral(val)) return Number(val.getLiteralValue());
4096
+ if (val && Node7.isNumericLiteral(val)) return Number(val.getLiteralValue());
3978
4097
  }
3979
4098
  return null;
3980
4099
  }
3981
4100
  function apiResponseTypeNode(decorator) {
3982
4101
  const optsArg = decorator.getArguments()[0];
3983
- if (!optsArg || !Node6.isObjectLiteralExpression(optsArg)) return null;
4102
+ if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
3984
4103
  for (const prop of optsArg.getProperties()) {
3985
- if (!Node6.isPropertyAssignment(prop)) continue;
4104
+ if (!Node7.isPropertyAssignment(prop)) continue;
3986
4105
  if (prop.getName() !== "type") continue;
3987
4106
  const val = prop.getInitializer();
3988
4107
  if (!val) return null;
3989
- if (Node6.isArrayLiteralExpression(val)) {
4108
+ if (Node7.isArrayLiteralExpression(val)) {
3990
4109
  const first = val.getElements()[0];
3991
4110
  return first ? { node: first, isArray: true } : null;
3992
4111
  }
@@ -4004,7 +4123,7 @@ function extractErrorType(method, sourceFile, project) {
4004
4123
  const inner = resolveIdentifierToClassType(typeInfo.node, sourceFile, project, 3);
4005
4124
  const type = typeInfo.isArray ? `Array<${inner}>` : inner;
4006
4125
  let ref = null;
4007
- if (Node6.isIdentifier(typeInfo.node)) {
4126
+ if (Node7.isIdentifier(typeInfo.node)) {
4008
4127
  const name = typeInfo.node.getText();
4009
4128
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
4010
4129
  if (localDecl?.isExported()) {
@@ -4021,7 +4140,7 @@ function extractErrorType(method, sourceFile, project) {
4021
4140
  return null;
4022
4141
  }
4023
4142
  function resolveIdentifierToClassType(node, sourceFile, project, depth) {
4024
- if (!Node6.isIdentifier(node)) return "unknown";
4143
+ if (!Node7.isIdentifier(node)) return "unknown";
4025
4144
  const name = node.getText();
4026
4145
  const resolved = findType(name, sourceFile, project);
4027
4146
  if (resolved) {
@@ -4041,9 +4160,9 @@ var STREAM_ENVELOPES = /* @__PURE__ */ new Set(["MessageEvent", "MessageEventLik
4041
4160
  var BINARY_RESPONSE_TYPES = /* @__PURE__ */ new Set(["StreamableFile", "Buffer"]);
4042
4161
  function detectBinaryResponse(method) {
4043
4162
  const node = unwrapNamedContainer(method.getReturnTypeNode(), /* @__PURE__ */ new Set(["Promise"]));
4044
- if (!node || !Node6.isTypeReference(node)) return false;
4163
+ if (!node || !Node7.isTypeReference(node)) return false;
4045
4164
  const typeName = node.getTypeName();
4046
- const name = Node6.isIdentifier(typeName) ? typeName.getText() : "";
4165
+ const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
4047
4166
  return BINARY_RESPONSE_TYPES.has(name);
4048
4167
  }
4049
4168
  function detectStreamElement(method) {
@@ -4058,9 +4177,9 @@ function detectStreamElement(method) {
4058
4177
  return null;
4059
4178
  }
4060
4179
  function streamContainerElement(node) {
4061
- if (!node || !Node6.isTypeReference(node)) return null;
4180
+ if (!node || !Node7.isTypeReference(node)) return null;
4062
4181
  const typeName = node.getTypeName();
4063
- const name = Node6.isIdentifier(typeName) ? typeName.getText() : "";
4182
+ const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
4064
4183
  if (STREAM_CONTAINERS.has(name) || STREAM_CONTAINERS_GENERATOR.has(name)) {
4065
4184
  return node.getTypeArguments()[0] ?? null;
4066
4185
  }
@@ -4070,9 +4189,9 @@ function hasAsQueryDecorator(method) {
4070
4189
  return method.getDecorators().some((d) => d.getName() === "AsQuery");
4071
4190
  }
4072
4191
  function unwrapNamedContainer(node, names) {
4073
- if (!node || !Node6.isTypeReference(node)) return node;
4192
+ if (!node || !Node7.isTypeReference(node)) return node;
4074
4193
  const typeName = node.getTypeName();
4075
- const name = Node6.isIdentifier(typeName) ? typeName.getText() : "";
4194
+ const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
4076
4195
  if (names.has(name)) {
4077
4196
  return node.getTypeArguments()[0] ?? node;
4078
4197
  }
@@ -4118,11 +4237,11 @@ function extractDtoContract(method, sourceFile, project, mixin) {
4118
4237
  if (apiResp) {
4119
4238
  const args = apiResp.getArguments();
4120
4239
  const optsArg = args[0];
4121
- if (optsArg && Node6.isObjectLiteralExpression(optsArg)) {
4240
+ if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
4122
4241
  for (const prop of optsArg.getProperties()) {
4123
- if (Node6.isPropertyAssignment(prop) && prop.getName() === "type") {
4242
+ if (Node7.isPropertyAssignment(prop) && prop.getName() === "type") {
4124
4243
  const val = prop.getInitializer();
4125
- if (val && Node6.isIdentifier(val)) {
4244
+ if (val && Node7.isIdentifier(val)) {
4126
4245
  const name = val.getText();
4127
4246
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
4128
4247
  if (localDecl?.isExported()) {
@@ -4190,88 +4309,6 @@ function resolveParamClass(method, decoratorName, sourceFile, project) {
4190
4309
  return null;
4191
4310
  }
4192
4311
 
4193
- // src/discovery/heritage.ts
4194
- import { Node as Node7, Project as Project3 } from "ts-morph";
4195
- function unwrapExpression(node) {
4196
- let current = node;
4197
- while (Node7.isAsExpression(current) || Node7.isSatisfiesExpression(current) || Node7.isParenthesizedExpression(current) || Node7.isTypeAssertion(current)) {
4198
- current = current.getExpression();
4199
- }
4200
- return current;
4201
- }
4202
- function resolveReturnedClass(factoryDecl) {
4203
- const body = factoryDecl.getBody();
4204
- if (!body) return void 0;
4205
- const returns = body.getDescendants().filter((n) => Node7.isReturnStatement(n));
4206
- for (const ret of returns) {
4207
- const expr = ret.getExpression();
4208
- if (!expr) continue;
4209
- const inner = unwrapExpression(expr);
4210
- if (Node7.isClassExpression(inner)) {
4211
- return inner;
4212
- }
4213
- if (Node7.isIdentifier(inner)) {
4214
- const name = inner.getText();
4215
- const decl = body.getDescendants().find((n) => Node7.isClassDeclaration(n) && n.getName() === name);
4216
- if (decl) return decl;
4217
- }
4218
- }
4219
- return void 0;
4220
- }
4221
- function resolveInheritedMethods(cls) {
4222
- const expr = cls.getExtends()?.getExpression();
4223
- if (!expr || !Node7.isCallExpression(expr)) return void 0;
4224
- const callee = expr.getExpression();
4225
- if (!Node7.isIdentifier(callee)) return void 0;
4226
- const factoryDecl = callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node7.isFunctionDeclaration(n));
4227
- if (!factoryDecl) return void 0;
4228
- const returnedClass = resolveReturnedClass(factoryDecl);
4229
- if (!returnedClass) return void 0;
4230
- const classArgs = [];
4231
- for (const arg of expr.getArguments()) {
4232
- if (!Node7.isIdentifier(arg)) continue;
4233
- const decl = arg.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node7.isClassDeclaration(n));
4234
- if (decl) {
4235
- classArgs.push({
4236
- name: decl.getName() ?? arg.getText(),
4237
- filePath: decl.getSourceFile().getFilePath()
4238
- });
4239
- }
4240
- }
4241
- return {
4242
- methods: returnedClass.getMethods(),
4243
- factoryName: callee.getText(),
4244
- factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
4245
- classArgs
4246
- };
4247
- }
4248
- var mixinTypeProject;
4249
- function getMixinTypeProject() {
4250
- mixinTypeProject ??= new Project3({
4251
- skipAddingFilesFromTsConfig: true,
4252
- compilerOptions: { strict: true }
4253
- });
4254
- return mixinTypeProject;
4255
- }
4256
- function clearMixinTypeProject() {
4257
- mixinTypeProject = void 0;
4258
- }
4259
- function resolveInstantiatedReturnType(cls, methodName) {
4260
- const filePath = cls.getSourceFile().getFilePath();
4261
- const className = cls.getName();
4262
- if (!className) return void 0;
4263
- const project = getMixinTypeProject();
4264
- const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
4265
- const typedCls = sourceFile?.getClass(className);
4266
- if (!typedCls) return void 0;
4267
- const prop = typedCls.getType().getProperty(methodName);
4268
- if (!prop) return void 0;
4269
- const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
4270
- if (!returnType) return void 0;
4271
- const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
4272
- return unwrapped.getText(typedCls);
4273
- }
4274
-
4275
4312
  // src/discovery/zod-ast-to-ts.ts
4276
4313
  import { Node as Node8, SyntaxKind as SyntaxKind4 } from "ts-morph";
4277
4314
  function zodAstToTs(node) {
@@ -4775,9 +4812,11 @@ function extractFromSourceFile(sourceFile, project) {
4775
4812
  factoryFilePath: inherited.factoryFilePath,
4776
4813
  classArgs: inherited.classArgs
4777
4814
  } : void 0;
4815
+ const ownMethods = cls.getMethods();
4816
+ const ownNames = new Set(ownMethods.map((m) => m.getName()));
4778
4817
  const methods = [
4779
- ...cls.getMethods().map((method) => ({ method })),
4780
- ...(inherited?.methods ?? []).map((method) => ({ method, mixin: mixinBinding }))
4818
+ ...ownMethods.map((method) => ({ method, mixin: mixinBinding })),
4819
+ ...(inherited?.methods ?? []).filter((method) => !ownNames.has(method.getName())).map((method) => ({ method, mixin: mixinBinding }))
4781
4820
  ];
4782
4821
  for (const { method, mixin } of methods) {
4783
4822
  const verb = resolveVerb(method);
@@ -5086,7 +5125,7 @@ function createChainModuleRenderer(opts) {
5086
5125
  }
5087
5126
 
5088
5127
  // src/index.ts
5089
- var VERSION = "0.17.0";
5128
+ var VERSION = "0.17.2";
5090
5129
  export {
5091
5130
  CodegenError,
5092
5131
  ConfigError,