@dudousxd/nestjs-codegen 0.17.1 → 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/cli/main.js CHANGED
@@ -2445,7 +2445,7 @@ import {
2445
2445
 
2446
2446
  // src/discovery/dto-type-resolver.ts
2447
2447
  import {
2448
- Node as Node6,
2448
+ Node as Node7,
2449
2449
  SyntaxKind as SyntaxKind3
2450
2450
  } from "ts-morph";
2451
2451
 
@@ -3208,7 +3208,7 @@ function inSchemaFromDecorator(decorator) {
3208
3208
 
3209
3209
  // src/discovery/filter-for.ts
3210
3210
  import {
3211
- Node as Node5
3211
+ Node as Node6
3212
3212
  } from "ts-morph";
3213
3213
 
3214
3214
  // src/discovery/filter-field-types.ts
@@ -3431,6 +3431,123 @@ function toFilterFieldType(name, r) {
3431
3431
  return ft;
3432
3432
  }
3433
3433
 
3434
+ // src/discovery/heritage.ts
3435
+ import { Node as Node5, Project as Project3 } from "ts-morph";
3436
+ function resolveHeritageCall(node) {
3437
+ if (!node) return void 0;
3438
+ const expr = unwrapExpression(node);
3439
+ if (Node5.isCallExpression(expr)) return expr;
3440
+ if (!Node5.isIdentifier(expr)) return void 0;
3441
+ const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find(
3442
+ (n) => n !== void 0 && Node5.isVariableDeclaration(n)
3443
+ );
3444
+ const init = decl?.getInitializer();
3445
+ if (!init) return void 0;
3446
+ const unwrapped = unwrapExpression(init);
3447
+ return Node5.isCallExpression(unwrapped) ? unwrapped : void 0;
3448
+ }
3449
+ function unwrapExpression(node) {
3450
+ let current = node;
3451
+ while (Node5.isAsExpression(current) || Node5.isSatisfiesExpression(current) || Node5.isParenthesizedExpression(current) || Node5.isTypeAssertion(current)) {
3452
+ current = current.getExpression();
3453
+ }
3454
+ return current;
3455
+ }
3456
+ function resolveReturnedClass(factoryDecl) {
3457
+ const body = factoryDecl.getBody();
3458
+ if (!body) return void 0;
3459
+ const returns = body.getDescendants().filter((n) => Node5.isReturnStatement(n));
3460
+ for (const ret of returns) {
3461
+ const expr = ret.getExpression();
3462
+ if (!expr) continue;
3463
+ const inner = unwrapExpression(expr);
3464
+ if (Node5.isClassExpression(inner)) {
3465
+ return inner;
3466
+ }
3467
+ if (Node5.isIdentifier(inner)) {
3468
+ const name = inner.getText();
3469
+ const decl = body.getDescendants().find((n) => Node5.isClassDeclaration(n) && n.getName() === name);
3470
+ if (decl) return decl;
3471
+ }
3472
+ }
3473
+ return void 0;
3474
+ }
3475
+ function resolveFactoryDeclaration(call) {
3476
+ const callee = call.getExpression();
3477
+ if (!Node5.isIdentifier(callee)) return void 0;
3478
+ return callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node5.isFunctionDeclaration(n));
3479
+ }
3480
+ function resolveFactoryStaticClass(node) {
3481
+ if (!Node5.isPropertyAccessExpression(node)) return void 0;
3482
+ const call = resolveHeritageCall(node.getExpression());
3483
+ if (!call) return void 0;
3484
+ const factoryDecl = resolveFactoryDeclaration(call);
3485
+ if (!factoryDecl) return void 0;
3486
+ const returnedClass = resolveReturnedClass(factoryDecl);
3487
+ if (!returnedClass) return void 0;
3488
+ const staticProp = returnedClass.getStaticProperties().find((p) => p.getName() === node.getName());
3489
+ if (!staticProp || !Node5.isPropertyDeclaration(staticProp)) return void 0;
3490
+ const init = staticProp.getInitializer();
3491
+ if (!init) return void 0;
3492
+ const inner = unwrapExpression(init);
3493
+ if (Node5.isClassExpression(inner)) return inner;
3494
+ if (!Node5.isIdentifier(inner)) return void 0;
3495
+ return inner.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && Node5.isClassDeclaration(n));
3496
+ }
3497
+ function resolveInheritedMethods(cls) {
3498
+ const expr = resolveHeritageCall(cls.getExtends()?.getExpression());
3499
+ if (!expr) return void 0;
3500
+ const callee = expr.getExpression();
3501
+ if (!Node5.isIdentifier(callee)) return void 0;
3502
+ const factoryDecl = resolveFactoryDeclaration(expr);
3503
+ if (!factoryDecl) return void 0;
3504
+ const returnedClass = resolveReturnedClass(factoryDecl);
3505
+ if (!returnedClass) return void 0;
3506
+ const classArgs = [];
3507
+ for (const arg of expr.getArguments()) {
3508
+ if (!Node5.isIdentifier(arg)) continue;
3509
+ const decl = arg.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node5.isClassDeclaration(n));
3510
+ if (decl) {
3511
+ classArgs.push({
3512
+ name: decl.getName() ?? arg.getText(),
3513
+ filePath: decl.getSourceFile().getFilePath()
3514
+ });
3515
+ }
3516
+ }
3517
+ return {
3518
+ methods: returnedClass.getMethods(),
3519
+ factoryName: callee.getText(),
3520
+ factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
3521
+ classArgs
3522
+ };
3523
+ }
3524
+ var mixinTypeProject;
3525
+ function getMixinTypeProject() {
3526
+ mixinTypeProject ??= new Project3({
3527
+ skipAddingFilesFromTsConfig: true,
3528
+ compilerOptions: { strict: true }
3529
+ });
3530
+ return mixinTypeProject;
3531
+ }
3532
+ function clearMixinTypeProject() {
3533
+ mixinTypeProject = void 0;
3534
+ }
3535
+ function resolveInstantiatedReturnType(cls, methodName) {
3536
+ const filePath = cls.getSourceFile().getFilePath();
3537
+ const className = cls.getName();
3538
+ if (!className) return void 0;
3539
+ const project = getMixinTypeProject();
3540
+ const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
3541
+ const typedCls = sourceFile?.getClass(className);
3542
+ if (!typedCls) return void 0;
3543
+ const prop = typedCls.getType().getProperty(methodName);
3544
+ if (!prop) return void 0;
3545
+ const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
3546
+ if (!returnType) return void 0;
3547
+ const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
3548
+ return unwrapped.getText(typedCls);
3549
+ }
3550
+
3434
3551
  // src/discovery/filter-for.ts
3435
3552
  function resolveMixinEntityClass(mixin, project) {
3436
3553
  const entityArg = mixin?.classArgs[0];
@@ -3439,7 +3556,7 @@ function resolveMixinEntityClass(mixin, project) {
3439
3556
  return file?.getClass(entityArg.name);
3440
3557
  }
3441
3558
  function classifyFilterForHint(typeInit) {
3442
- if (Node5.isStringLiteral(typeInit)) {
3559
+ if (Node6.isStringLiteral(typeInit)) {
3443
3560
  switch (typeInit.getLiteralValue()) {
3444
3561
  case "string":
3445
3562
  return { kind: "string" };
@@ -3453,10 +3570,10 @@ function classifyFilterForHint(typeInit) {
3453
3570
  return null;
3454
3571
  }
3455
3572
  }
3456
- if (Node5.isArrayLiteralExpression(typeInit)) {
3573
+ if (Node6.isArrayLiteralExpression(typeInit)) {
3457
3574
  const values = [];
3458
3575
  for (const el of typeInit.getElements()) {
3459
- if (!Node5.isStringLiteral(el)) return null;
3576
+ if (!Node6.isStringLiteral(el)) return null;
3460
3577
  values.push(el.getLiteralValue());
3461
3578
  }
3462
3579
  if (values.length === 0) return null;
@@ -3491,11 +3608,11 @@ function extractFilterForHints(classDecl, project) {
3491
3608
  if (!filterForDec) continue;
3492
3609
  const args = filterForDec.getArguments();
3493
3610
  const keyArg = args[0];
3494
- const inputKey = keyArg && Node5.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
3611
+ const inputKey = keyArg && Node6.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
3495
3612
  const optsArg = args[1];
3496
- if (optsArg && Node5.isObjectLiteralExpression(optsArg)) {
3613
+ if (optsArg && Node6.isObjectLiteralExpression(optsArg)) {
3497
3614
  const typeProp = optsArg.getProperty("type");
3498
- if (typeProp && Node5.isPropertyAssignment(typeProp)) {
3615
+ if (typeProp && Node6.isPropertyAssignment(typeProp)) {
3499
3616
  const typeInit = typeProp.getInitializer();
3500
3617
  if (typeInit) {
3501
3618
  const classified = classifyFilterForHint(typeInit);
@@ -3520,21 +3637,23 @@ function extractApplyFilterInfo(method, sourceFile, project, mixin) {
3520
3637
  const args = filterDecorator.getArguments();
3521
3638
  if (args.length === 0) continue;
3522
3639
  const filterClassArg = args[0];
3523
- if (!filterClassArg || !Node5.isIdentifier(filterClassArg)) continue;
3640
+ if (!filterClassArg) continue;
3641
+ const factoryStaticClass = resolveFactoryStaticClass(filterClassArg);
3642
+ if (!factoryStaticClass && !Node6.isIdentifier(filterClassArg)) continue;
3524
3643
  let source = "query";
3525
3644
  const optionsArg = args[1];
3526
- if (optionsArg && Node5.isObjectLiteralExpression(optionsArg)) {
3645
+ if (optionsArg && Node6.isObjectLiteralExpression(optionsArg)) {
3527
3646
  const sourceProp = optionsArg.getProperty("source");
3528
- if (sourceProp && Node5.isPropertyAssignment(sourceProp)) {
3647
+ if (sourceProp && Node6.isPropertyAssignment(sourceProp)) {
3529
3648
  const init = sourceProp.getInitializer();
3530
- if (init && Node5.isStringLiteral(init) && init.getLiteralValue() === "body") {
3649
+ if (init && Node6.isStringLiteral(init) && init.getLiteralValue() === "body") {
3531
3650
  source = "body";
3532
3651
  }
3533
3652
  }
3534
3653
  }
3535
3654
  const filterClassName = filterClassArg.getText();
3536
- const resolved = findType(filterClassName, declFile, project);
3537
- const classDecl = resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg);
3655
+ const resolved = factoryStaticClass ? void 0 : findType(filterClassName, declFile, project);
3656
+ const classDecl = factoryStaticClass ?? (resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg));
3538
3657
  if (classDecl) {
3539
3658
  let fieldTypes = extractClassPropertyTypes(classDecl, project);
3540
3659
  if (fieldTypes.length === 0) {
@@ -3590,22 +3709,22 @@ function resolveRelationEntity(prop, sourceFile, project) {
3590
3709
  const args = dec.getArguments();
3591
3710
  if (args.length === 0) continue;
3592
3711
  const arg = args[0];
3593
- if (Node5.isObjectLiteralExpression(arg)) {
3712
+ if (Node6.isObjectLiteralExpression(arg)) {
3594
3713
  const entityProp = arg.getProperty("entity");
3595
- if (entityProp && Node5.isPropertyAssignment(entityProp)) {
3714
+ if (entityProp && Node6.isPropertyAssignment(entityProp)) {
3596
3715
  const init = entityProp.getInitializer();
3597
- if (init && Node5.isArrowFunction(init)) {
3716
+ if (init && Node6.isArrowFunction(init)) {
3598
3717
  const body = init.getBody();
3599
- if (Node5.isIdentifier(body)) {
3718
+ if (Node6.isIdentifier(body)) {
3600
3719
  const resolved = findType(body.getText(), prop.getSourceFile(), project);
3601
3720
  if (resolved?.kind === "class") return resolved.decl;
3602
3721
  }
3603
3722
  }
3604
3723
  }
3605
3724
  }
3606
- if (Node5.isArrowFunction(arg)) {
3725
+ if (Node6.isArrowFunction(arg)) {
3607
3726
  const body = arg.getBody();
3608
- if (Node5.isIdentifier(body)) {
3727
+ if (Node6.isIdentifier(body)) {
3609
3728
  const resolved = findType(body.getText(), prop.getSourceFile(), project);
3610
3729
  if (resolved?.kind === "class") return resolved.decl;
3611
3730
  }
@@ -3624,15 +3743,15 @@ function extractClassPropertyTypes(classDecl, project) {
3624
3743
  return fields;
3625
3744
  }
3626
3745
  function resolveLocalClassDeclaration(identifier) {
3627
- if (!Node5.isIdentifier(identifier)) return void 0;
3628
- return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && Node5.isClassDeclaration(n));
3746
+ if (!Node6.isIdentifier(identifier)) return void 0;
3747
+ return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && Node6.isClassDeclaration(n));
3629
3748
  }
3630
3749
  function resolveDeclaredEntity(optionsArg, filterClass, project) {
3631
- if (!Node5.isObjectLiteralExpression(optionsArg)) return void 0;
3750
+ if (!Node6.isObjectLiteralExpression(optionsArg)) return void 0;
3632
3751
  const entityProp = optionsArg.getProperty("entity");
3633
- if (!entityProp || !Node5.isPropertyAssignment(entityProp)) return void 0;
3752
+ if (!entityProp || !Node6.isPropertyAssignment(entityProp)) return void 0;
3634
3753
  const entityInit = entityProp.getInitializer();
3635
- if (!entityInit || !Node5.isIdentifier(entityInit)) return void 0;
3754
+ if (!entityInit || !Node6.isIdentifier(entityInit)) return void 0;
3636
3755
  const resolved = findType(entityInit.getText(), filterClass.getSourceFile(), project);
3637
3756
  if (!resolved || resolved.kind !== "class") return void 0;
3638
3757
  return resolved.decl;
@@ -3643,7 +3762,7 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
3643
3762
  const args = filterableDecorator.getArguments();
3644
3763
  if (args.length === 0) return [];
3645
3764
  const optionsArg = args[0];
3646
- if (!Node5.isObjectLiteralExpression(optionsArg)) return [];
3765
+ if (!Node6.isObjectLiteralExpression(optionsArg)) return [];
3647
3766
  const entityDecl = entityOverride ?? resolveDeclaredEntity(optionsArg, filterClass, project);
3648
3767
  if (!entityDecl) return [];
3649
3768
  const fields = collectEntityFields(
@@ -3656,17 +3775,17 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
3656
3775
  const relationsDecorator = filterClass.getDecorators().find((d) => d.getName() === "Relations");
3657
3776
  if (relationsDecorator) {
3658
3777
  const relArgs = relationsDecorator.getArguments();
3659
- if (relArgs.length > 0 && Node5.isObjectLiteralExpression(relArgs[0])) {
3778
+ if (relArgs.length > 0 && Node6.isObjectLiteralExpression(relArgs[0])) {
3660
3779
  for (const relProp of relArgs[0].getProperties()) {
3661
- if (!Node5.isPropertyAssignment(relProp)) continue;
3780
+ if (!Node6.isPropertyAssignment(relProp)) continue;
3662
3781
  const relInit = relProp.getInitializer();
3663
- if (!relInit || !Node5.isObjectLiteralExpression(relInit)) continue;
3782
+ if (!relInit || !Node6.isObjectLiteralExpression(relInit)) continue;
3664
3783
  const keysProp = relInit.getProperty("keys");
3665
- if (!keysProp || !Node5.isPropertyAssignment(keysProp)) continue;
3784
+ if (!keysProp || !Node6.isPropertyAssignment(keysProp)) continue;
3666
3785
  const keysInit = keysProp.getInitializer();
3667
- if (!keysInit || !Node5.isArrayLiteralExpression(keysInit)) continue;
3786
+ if (!keysInit || !Node6.isArrayLiteralExpression(keysInit)) continue;
3668
3787
  for (const el of keysInit.getElements()) {
3669
- if (Node5.isStringLiteral(el)) {
3788
+ if (Node6.isStringLiteral(el)) {
3670
3789
  fields.push(toFilterFieldType(el.getLiteralValue(), { kind: "unknown" }));
3671
3790
  }
3672
3791
  }
@@ -3707,22 +3826,22 @@ var PASSTHROUGH_UTILITY = /* @__PURE__ */ new Set([
3707
3826
  ]);
3708
3827
  function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /* @__PURE__ */ new Map()) {
3709
3828
  if (depth <= 0) return "unknown";
3710
- if (Node6.isArrayTypeNode(typeNode)) {
3829
+ if (Node7.isArrayTypeNode(typeNode)) {
3711
3830
  const elementType = typeNode.getElementTypeNode();
3712
3831
  return `Array<${resolveTypeNodeToString(elementType, sourceFile, project, depth, subst)}>`;
3713
3832
  }
3714
- if (Node6.isUnionTypeNode(typeNode)) {
3833
+ if (Node7.isUnionTypeNode(typeNode)) {
3715
3834
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" | ");
3716
3835
  }
3717
- if (Node6.isIntersectionTypeNode(typeNode)) {
3836
+ if (Node7.isIntersectionTypeNode(typeNode)) {
3718
3837
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" & ");
3719
3838
  }
3720
- if (Node6.isParenthesizedTypeNode(typeNode)) {
3839
+ if (Node7.isParenthesizedTypeNode(typeNode)) {
3721
3840
  return `(${resolveTypeNodeToString(typeNode.getTypeNode(), sourceFile, project, depth, subst)})`;
3722
3841
  }
3723
- if (Node6.isTypeReference(typeNode)) {
3842
+ if (Node7.isTypeReference(typeNode)) {
3724
3843
  const typeName = typeNode.getTypeName();
3725
- const name = Node6.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
3844
+ const name = Node7.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
3726
3845
  const bound = subst.get(name);
3727
3846
  if (bound !== void 0) return bound;
3728
3847
  if (name === "string" || name === "number" || name === "boolean") return name;
@@ -3745,10 +3864,10 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
3745
3864
  dbg("unresolvable type:", name, "in", sourceFile.getFilePath());
3746
3865
  return "unknown";
3747
3866
  }
3748
- if (Node6.isTypeLiteral(typeNode)) {
3867
+ if (Node7.isTypeLiteral(typeNode)) {
3749
3868
  const members = [];
3750
3869
  for (const member of typeNode.getMembers()) {
3751
- if (Node6.isPropertySignature(member)) {
3870
+ if (Node7.isPropertySignature(member)) {
3752
3871
  const memberTypeNode = member.getTypeNode();
3753
3872
  const memberType = memberTypeNode ? resolveTypeNodeToString(memberTypeNode, sourceFile, project, depth, subst) : "unknown";
3754
3873
  members.push(`${member.getName()}${member.hasQuestionToken() ? "?" : ""}: ${memberType}`);
@@ -3848,7 +3967,7 @@ function extractQueryType(method, sourceFile, project) {
3848
3967
  if (!queryDecorator) continue;
3849
3968
  const queryArgs = queryDecorator.getArguments();
3850
3969
  const nameArg = queryArgs[0];
3851
- if (!nameArg || !Node6.isStringLiteral(nameArg)) continue;
3970
+ if (!nameArg || !Node7.isStringLiteral(nameArg)) continue;
3852
3971
  const queryName = nameArg.getLiteralValue();
3853
3972
  const typeNode = param.getTypeNode();
3854
3973
  const queryType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
@@ -3859,7 +3978,7 @@ function extractQueryType(method, sourceFile, project) {
3859
3978
  function isParamOptional(param) {
3860
3979
  if (param.hasQuestionToken() || param.hasInitializer()) return true;
3861
3980
  const typeNode = param.getTypeNode();
3862
- if (typeNode && Node6.isUnionTypeNode(typeNode)) {
3981
+ if (typeNode && Node7.isUnionTypeNode(typeNode)) {
3863
3982
  return typeNode.getTypeNodes().some((t) => t.getKind() === SyntaxKind3.UndefinedKeyword);
3864
3983
  }
3865
3984
  return false;
@@ -3872,7 +3991,7 @@ function extractParamsType(method, sourceFile, project) {
3872
3991
  const paramArgs = paramDecorator.getArguments();
3873
3992
  if (paramArgs.length === 0) continue;
3874
3993
  const nameArg = paramArgs[0];
3875
- if (!Node6.isStringLiteral(nameArg)) continue;
3994
+ if (!Node7.isStringLiteral(nameArg)) continue;
3876
3995
  const paramName = nameArg.getLiteralValue();
3877
3996
  const typeNode = param.getTypeNode();
3878
3997
  const paramType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
@@ -3893,28 +4012,28 @@ function extractUploadedFiles(method) {
3893
4012
  for (const decorator of method.getDecorators()) {
3894
4013
  if (decorator.getName() !== "UseInterceptors") continue;
3895
4014
  for (const arg of decorator.getArguments()) {
3896
- if (!Node6.isCallExpression(arg)) continue;
4015
+ if (!Node7.isCallExpression(arg)) continue;
3897
4016
  const interceptor = arg.getExpression().getText();
3898
4017
  const callArgs = arg.getArguments();
3899
4018
  const firstArg2 = callArgs[0];
3900
4019
  if (interceptor === "FileInterceptor") {
3901
- if (firstArg2 && Node6.isStringLiteral(firstArg2)) {
4020
+ if (firstArg2 && Node7.isStringLiteral(firstArg2)) {
3902
4021
  entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
3903
4022
  multipart = true;
3904
4023
  }
3905
4024
  } else if (interceptor === "FilesInterceptor") {
3906
- if (firstArg2 && Node6.isStringLiteral(firstArg2)) {
4025
+ if (firstArg2 && Node7.isStringLiteral(firstArg2)) {
3907
4026
  entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
3908
4027
  multipart = true;
3909
4028
  }
3910
4029
  } else if (interceptor === "FileFieldsInterceptor") {
3911
- if (firstArg2 && Node6.isArrayLiteralExpression(firstArg2)) {
4030
+ if (firstArg2 && Node7.isArrayLiteralExpression(firstArg2)) {
3912
4031
  for (const el of firstArg2.getElements()) {
3913
- if (!Node6.isObjectLiteralExpression(el)) continue;
4032
+ if (!Node7.isObjectLiteralExpression(el)) continue;
3914
4033
  const nameProp = el.getProperty("name");
3915
- if (nameProp && Node6.isPropertyAssignment(nameProp)) {
4034
+ if (nameProp && Node7.isPropertyAssignment(nameProp)) {
3916
4035
  const init = nameProp.getInitializer();
3917
- if (init && Node6.isStringLiteral(init)) {
4036
+ if (init && Node7.isStringLiteral(init)) {
3918
4037
  entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
3919
4038
  }
3920
4039
  }
@@ -3934,13 +4053,13 @@ function extractResponseType(method, sourceFile, project) {
3934
4053
  if (apiResponseDecorator) {
3935
4054
  const args = apiResponseDecorator.getArguments();
3936
4055
  const optsArg = args[0];
3937
- if (optsArg && Node6.isObjectLiteralExpression(optsArg)) {
4056
+ if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
3938
4057
  for (const prop of optsArg.getProperties()) {
3939
- if (!Node6.isPropertyAssignment(prop)) continue;
4058
+ if (!Node7.isPropertyAssignment(prop)) continue;
3940
4059
  if (prop.getName() !== "type") continue;
3941
4060
  const val = prop.getInitializer();
3942
4061
  if (!val) continue;
3943
- if (Node6.isArrayLiteralExpression(val)) {
4062
+ if (Node7.isArrayLiteralExpression(val)) {
3944
4063
  const elements = val.getElements();
3945
4064
  const firstEl = elements[0];
3946
4065
  if (elements.length > 0 && firstEl !== void 0) {
@@ -3961,24 +4080,24 @@ function extractResponseType(method, sourceFile, project) {
3961
4080
  }
3962
4081
  function apiResponseStatus(decorator) {
3963
4082
  const optsArg = decorator.getArguments()[0];
3964
- if (!optsArg || !Node6.isObjectLiteralExpression(optsArg)) return null;
4083
+ if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
3965
4084
  for (const prop of optsArg.getProperties()) {
3966
- if (!Node6.isPropertyAssignment(prop)) continue;
4085
+ if (!Node7.isPropertyAssignment(prop)) continue;
3967
4086
  if (prop.getName() !== "status") continue;
3968
4087
  const val = prop.getInitializer();
3969
- if (val && Node6.isNumericLiteral(val)) return Number(val.getLiteralValue());
4088
+ if (val && Node7.isNumericLiteral(val)) return Number(val.getLiteralValue());
3970
4089
  }
3971
4090
  return null;
3972
4091
  }
3973
4092
  function apiResponseTypeNode(decorator) {
3974
4093
  const optsArg = decorator.getArguments()[0];
3975
- if (!optsArg || !Node6.isObjectLiteralExpression(optsArg)) return null;
4094
+ if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
3976
4095
  for (const prop of optsArg.getProperties()) {
3977
- if (!Node6.isPropertyAssignment(prop)) continue;
4096
+ if (!Node7.isPropertyAssignment(prop)) continue;
3978
4097
  if (prop.getName() !== "type") continue;
3979
4098
  const val = prop.getInitializer();
3980
4099
  if (!val) return null;
3981
- if (Node6.isArrayLiteralExpression(val)) {
4100
+ if (Node7.isArrayLiteralExpression(val)) {
3982
4101
  const first = val.getElements()[0];
3983
4102
  return first ? { node: first, isArray: true } : null;
3984
4103
  }
@@ -3996,7 +4115,7 @@ function extractErrorType(method, sourceFile, project) {
3996
4115
  const inner = resolveIdentifierToClassType(typeInfo.node, sourceFile, project, 3);
3997
4116
  const type = typeInfo.isArray ? `Array<${inner}>` : inner;
3998
4117
  let ref = null;
3999
- if (Node6.isIdentifier(typeInfo.node)) {
4118
+ if (Node7.isIdentifier(typeInfo.node)) {
4000
4119
  const name = typeInfo.node.getText();
4001
4120
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
4002
4121
  if (localDecl?.isExported()) {
@@ -4013,7 +4132,7 @@ function extractErrorType(method, sourceFile, project) {
4013
4132
  return null;
4014
4133
  }
4015
4134
  function resolveIdentifierToClassType(node, sourceFile, project, depth) {
4016
- if (!Node6.isIdentifier(node)) return "unknown";
4135
+ if (!Node7.isIdentifier(node)) return "unknown";
4017
4136
  const name = node.getText();
4018
4137
  const resolved = findType(name, sourceFile, project);
4019
4138
  if (resolved) {
@@ -4033,9 +4152,9 @@ var STREAM_ENVELOPES = /* @__PURE__ */ new Set(["MessageEvent", "MessageEventLik
4033
4152
  var BINARY_RESPONSE_TYPES = /* @__PURE__ */ new Set(["StreamableFile", "Buffer"]);
4034
4153
  function detectBinaryResponse(method) {
4035
4154
  const node = unwrapNamedContainer(method.getReturnTypeNode(), /* @__PURE__ */ new Set(["Promise"]));
4036
- if (!node || !Node6.isTypeReference(node)) return false;
4155
+ if (!node || !Node7.isTypeReference(node)) return false;
4037
4156
  const typeName = node.getTypeName();
4038
- const name = Node6.isIdentifier(typeName) ? typeName.getText() : "";
4157
+ const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
4039
4158
  return BINARY_RESPONSE_TYPES.has(name);
4040
4159
  }
4041
4160
  function detectStreamElement(method) {
@@ -4050,9 +4169,9 @@ function detectStreamElement(method) {
4050
4169
  return null;
4051
4170
  }
4052
4171
  function streamContainerElement(node) {
4053
- if (!node || !Node6.isTypeReference(node)) return null;
4172
+ if (!node || !Node7.isTypeReference(node)) return null;
4054
4173
  const typeName = node.getTypeName();
4055
- const name = Node6.isIdentifier(typeName) ? typeName.getText() : "";
4174
+ const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
4056
4175
  if (STREAM_CONTAINERS.has(name) || STREAM_CONTAINERS_GENERATOR.has(name)) {
4057
4176
  return node.getTypeArguments()[0] ?? null;
4058
4177
  }
@@ -4062,9 +4181,9 @@ function hasAsQueryDecorator(method) {
4062
4181
  return method.getDecorators().some((d) => d.getName() === "AsQuery");
4063
4182
  }
4064
4183
  function unwrapNamedContainer(node, names) {
4065
- if (!node || !Node6.isTypeReference(node)) return node;
4184
+ if (!node || !Node7.isTypeReference(node)) return node;
4066
4185
  const typeName = node.getTypeName();
4067
- const name = Node6.isIdentifier(typeName) ? typeName.getText() : "";
4186
+ const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
4068
4187
  if (names.has(name)) {
4069
4188
  return node.getTypeArguments()[0] ?? node;
4070
4189
  }
@@ -4110,11 +4229,11 @@ function extractDtoContract(method, sourceFile, project, mixin) {
4110
4229
  if (apiResp) {
4111
4230
  const args = apiResp.getArguments();
4112
4231
  const optsArg = args[0];
4113
- if (optsArg && Node6.isObjectLiteralExpression(optsArg)) {
4232
+ if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
4114
4233
  for (const prop of optsArg.getProperties()) {
4115
- if (Node6.isPropertyAssignment(prop) && prop.getName() === "type") {
4234
+ if (Node7.isPropertyAssignment(prop) && prop.getName() === "type") {
4116
4235
  const val = prop.getInitializer();
4117
- if (val && Node6.isIdentifier(val)) {
4236
+ if (val && Node7.isIdentifier(val)) {
4118
4237
  const name = val.getText();
4119
4238
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
4120
4239
  if (localDecl?.isExported()) {
@@ -4182,101 +4301,6 @@ function resolveParamClass(method, decoratorName, sourceFile, project) {
4182
4301
  return null;
4183
4302
  }
4184
4303
 
4185
- // src/discovery/heritage.ts
4186
- import { Node as Node7, Project as Project3 } from "ts-morph";
4187
- function resolveHeritageCall(node) {
4188
- if (!node) return void 0;
4189
- const expr = unwrapExpression(node);
4190
- if (Node7.isCallExpression(expr)) return expr;
4191
- if (!Node7.isIdentifier(expr)) return void 0;
4192
- const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find(
4193
- (n) => n !== void 0 && Node7.isVariableDeclaration(n)
4194
- );
4195
- const init = decl?.getInitializer();
4196
- if (!init) return void 0;
4197
- const unwrapped = unwrapExpression(init);
4198
- return Node7.isCallExpression(unwrapped) ? unwrapped : void 0;
4199
- }
4200
- function unwrapExpression(node) {
4201
- let current = node;
4202
- while (Node7.isAsExpression(current) || Node7.isSatisfiesExpression(current) || Node7.isParenthesizedExpression(current) || Node7.isTypeAssertion(current)) {
4203
- current = current.getExpression();
4204
- }
4205
- return current;
4206
- }
4207
- function resolveReturnedClass(factoryDecl) {
4208
- const body = factoryDecl.getBody();
4209
- if (!body) return void 0;
4210
- const returns = body.getDescendants().filter((n) => Node7.isReturnStatement(n));
4211
- for (const ret of returns) {
4212
- const expr = ret.getExpression();
4213
- if (!expr) continue;
4214
- const inner = unwrapExpression(expr);
4215
- if (Node7.isClassExpression(inner)) {
4216
- return inner;
4217
- }
4218
- if (Node7.isIdentifier(inner)) {
4219
- const name = inner.getText();
4220
- const decl = body.getDescendants().find((n) => Node7.isClassDeclaration(n) && n.getName() === name);
4221
- if (decl) return decl;
4222
- }
4223
- }
4224
- return void 0;
4225
- }
4226
- function resolveInheritedMethods(cls) {
4227
- const expr = resolveHeritageCall(cls.getExtends()?.getExpression());
4228
- if (!expr) return void 0;
4229
- const callee = expr.getExpression();
4230
- if (!Node7.isIdentifier(callee)) return void 0;
4231
- const factoryDecl = callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node7.isFunctionDeclaration(n));
4232
- if (!factoryDecl) return void 0;
4233
- const returnedClass = resolveReturnedClass(factoryDecl);
4234
- if (!returnedClass) return void 0;
4235
- const classArgs = [];
4236
- for (const arg of expr.getArguments()) {
4237
- if (!Node7.isIdentifier(arg)) continue;
4238
- const decl = arg.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node7.isClassDeclaration(n));
4239
- if (decl) {
4240
- classArgs.push({
4241
- name: decl.getName() ?? arg.getText(),
4242
- filePath: decl.getSourceFile().getFilePath()
4243
- });
4244
- }
4245
- }
4246
- return {
4247
- methods: returnedClass.getMethods(),
4248
- factoryName: callee.getText(),
4249
- factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
4250
- classArgs
4251
- };
4252
- }
4253
- var mixinTypeProject;
4254
- function getMixinTypeProject() {
4255
- mixinTypeProject ??= new Project3({
4256
- skipAddingFilesFromTsConfig: true,
4257
- compilerOptions: { strict: true }
4258
- });
4259
- return mixinTypeProject;
4260
- }
4261
- function clearMixinTypeProject() {
4262
- mixinTypeProject = void 0;
4263
- }
4264
- function resolveInstantiatedReturnType(cls, methodName) {
4265
- const filePath = cls.getSourceFile().getFilePath();
4266
- const className = cls.getName();
4267
- if (!className) return void 0;
4268
- const project = getMixinTypeProject();
4269
- const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
4270
- const typedCls = sourceFile?.getClass(className);
4271
- if (!typedCls) return void 0;
4272
- const prop = typedCls.getType().getProperty(methodName);
4273
- if (!prop) return void 0;
4274
- const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
4275
- if (!returnType) return void 0;
4276
- const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
4277
- return unwrapped.getText(typedCls);
4278
- }
4279
-
4280
4304
  // src/discovery/zod-ast-to-ts.ts
4281
4305
  import { Node as Node8, SyntaxKind as SyntaxKind4 } from "ts-morph";
4282
4306
  function zodAstToTs(node) {
@@ -5010,7 +5034,7 @@ async function watch(config, onChange, options = {}) {
5010
5034
  }
5011
5035
 
5012
5036
  // src/index.ts
5013
- var VERSION = "0.17.1";
5037
+ var VERSION = "0.17.2";
5014
5038
 
5015
5039
  // src/cli/codegen.ts
5016
5040
  async function runCodegen(opts = {}) {