@dudousxd/nestjs-codegen 0.17.1 → 0.18.0

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.cjs CHANGED
@@ -2475,7 +2475,7 @@ var import_fast_glob3 = __toESM(require("fast-glob"), 1);
2475
2475
  var import_ts_morph10 = require("ts-morph");
2476
2476
 
2477
2477
  // src/discovery/dto-type-resolver.ts
2478
- var import_ts_morph7 = require("ts-morph");
2478
+ var import_ts_morph8 = require("ts-morph");
2479
2479
 
2480
2480
  // src/discovery/dto-to-ir.ts
2481
2481
  var import_ts_morph4 = require("ts-morph");
@@ -3231,7 +3231,7 @@ function inSchemaFromDecorator(decorator) {
3231
3231
  }
3232
3232
 
3233
3233
  // src/discovery/filter-for.ts
3234
- var import_ts_morph6 = require("ts-morph");
3234
+ var import_ts_morph7 = require("ts-morph");
3235
3235
 
3236
3236
  // src/discovery/filter-field-types.ts
3237
3237
  var import_ts_morph5 = require("ts-morph");
@@ -3450,15 +3450,161 @@ function toFilterFieldType(name, r) {
3450
3450
  return ft;
3451
3451
  }
3452
3452
 
3453
+ // src/discovery/heritage.ts
3454
+ var import_ts_morph6 = require("ts-morph");
3455
+ function resolveHeritageCall(node) {
3456
+ if (!node) return void 0;
3457
+ const expr = unwrapExpression(node);
3458
+ if (import_ts_morph6.Node.isCallExpression(expr)) return expr;
3459
+ if (!import_ts_morph6.Node.isIdentifier(expr)) return void 0;
3460
+ const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find(
3461
+ (n) => n !== void 0 && import_ts_morph6.Node.isVariableDeclaration(n)
3462
+ );
3463
+ const init = decl?.getInitializer();
3464
+ if (!init) return void 0;
3465
+ const unwrapped = unwrapExpression(init);
3466
+ return import_ts_morph6.Node.isCallExpression(unwrapped) ? unwrapped : void 0;
3467
+ }
3468
+ function unwrapExpression(node) {
3469
+ let current = node;
3470
+ 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)) {
3471
+ current = current.getExpression();
3472
+ }
3473
+ return current;
3474
+ }
3475
+ function resolveReturnedClass(factoryDecl) {
3476
+ const body = factoryDecl.getBody();
3477
+ if (!body) return void 0;
3478
+ const returns = body.getDescendants().filter((n) => import_ts_morph6.Node.isReturnStatement(n));
3479
+ for (const ret of returns) {
3480
+ const expr = ret.getExpression();
3481
+ if (!expr) continue;
3482
+ const inner = unwrapExpression(expr);
3483
+ if (import_ts_morph6.Node.isClassExpression(inner)) {
3484
+ return inner;
3485
+ }
3486
+ if (import_ts_morph6.Node.isIdentifier(inner)) {
3487
+ const name = inner.getText();
3488
+ const decl = body.getDescendants().find((n) => import_ts_morph6.Node.isClassDeclaration(n) && n.getName() === name);
3489
+ if (decl) return decl;
3490
+ }
3491
+ }
3492
+ return void 0;
3493
+ }
3494
+ function resolveFactoryDeclaration(call) {
3495
+ const callee = call.getExpression();
3496
+ if (!import_ts_morph6.Node.isIdentifier(callee)) return void 0;
3497
+ return callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => import_ts_morph6.Node.isFunctionDeclaration(n));
3498
+ }
3499
+ function resolveFactoryStaticClass(node) {
3500
+ if (!import_ts_morph6.Node.isPropertyAccessExpression(node)) return void 0;
3501
+ const call = resolveHeritageCall(node.getExpression());
3502
+ if (!call) return void 0;
3503
+ const factoryDecl = resolveFactoryDeclaration(call);
3504
+ if (!factoryDecl) return void 0;
3505
+ const returnedClass = resolveReturnedClass(factoryDecl);
3506
+ if (!returnedClass) return void 0;
3507
+ const staticProp = returnedClass.getStaticProperties().find((p) => p.getName() === node.getName());
3508
+ if (!staticProp || !import_ts_morph6.Node.isPropertyDeclaration(staticProp)) return void 0;
3509
+ const init = staticProp.getInitializer();
3510
+ if (!init) return void 0;
3511
+ const inner = unwrapExpression(init);
3512
+ if (import_ts_morph6.Node.isClassExpression(inner)) return inner;
3513
+ if (!import_ts_morph6.Node.isIdentifier(inner)) return void 0;
3514
+ return inner.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && import_ts_morph6.Node.isClassDeclaration(n));
3515
+ }
3516
+ function resolveInheritedMethods(cls) {
3517
+ const expr = resolveHeritageCall(cls.getExtends()?.getExpression());
3518
+ if (!expr) return void 0;
3519
+ const callee = expr.getExpression();
3520
+ if (!import_ts_morph6.Node.isIdentifier(callee)) return void 0;
3521
+ const factoryDecl = resolveFactoryDeclaration(expr);
3522
+ if (!factoryDecl) return void 0;
3523
+ const returnedClass = resolveReturnedClass(factoryDecl);
3524
+ if (!returnedClass) return void 0;
3525
+ const classArgs = [];
3526
+ const namedClassArgs = {};
3527
+ for (const arg of expr.getArguments()) {
3528
+ const positional = resolveClassReference(arg);
3529
+ if (positional) {
3530
+ classArgs.push(positional);
3531
+ continue;
3532
+ }
3533
+ if (!import_ts_morph6.Node.isObjectLiteralExpression(arg)) continue;
3534
+ for (const prop of arg.getProperties()) {
3535
+ const named = resolvePropertyClassReference(prop);
3536
+ if (!named) continue;
3537
+ namedClassArgs[named.key] ??= named.ref;
3538
+ }
3539
+ }
3540
+ return {
3541
+ methods: returnedClass.getMethods(),
3542
+ factoryName: callee.getText(),
3543
+ factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
3544
+ classArgs,
3545
+ namedClassArgs
3546
+ };
3547
+ }
3548
+ function resolveClassReference(node) {
3549
+ const expr = unwrapExpression(node);
3550
+ if (!import_ts_morph6.Node.isIdentifier(expr)) return void 0;
3551
+ const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && import_ts_morph6.Node.isClassDeclaration(n));
3552
+ if (!decl) return void 0;
3553
+ return {
3554
+ name: decl.getName() ?? expr.getText(),
3555
+ filePath: decl.getSourceFile().getFilePath()
3556
+ };
3557
+ }
3558
+ function resolvePropertyClassReference(prop) {
3559
+ if (import_ts_morph6.Node.isShorthandPropertyAssignment(prop)) {
3560
+ const ref2 = resolveClassReference(prop.getNameNode());
3561
+ return ref2 ? { key: prop.getName(), ref: ref2 } : void 0;
3562
+ }
3563
+ if (!import_ts_morph6.Node.isPropertyAssignment(prop)) return void 0;
3564
+ const init = prop.getInitializer();
3565
+ if (!init) return void 0;
3566
+ const ref = resolveClassReference(init);
3567
+ if (!ref) return void 0;
3568
+ const nameNode = prop.getNameNode();
3569
+ const key = import_ts_morph6.Node.isStringLiteral(nameNode) ? nameNode.getLiteralValue() : prop.getName();
3570
+ return { key, ref };
3571
+ }
3572
+ var mixinTypeProject;
3573
+ function getMixinTypeProject() {
3574
+ mixinTypeProject ??= new import_ts_morph6.Project({
3575
+ skipAddingFilesFromTsConfig: true,
3576
+ compilerOptions: { strict: true }
3577
+ });
3578
+ return mixinTypeProject;
3579
+ }
3580
+ function clearMixinTypeProject() {
3581
+ mixinTypeProject = void 0;
3582
+ }
3583
+ function resolveInstantiatedReturnType(cls, methodName) {
3584
+ const filePath = cls.getSourceFile().getFilePath();
3585
+ const className = cls.getName();
3586
+ if (!className) return void 0;
3587
+ const project = getMixinTypeProject();
3588
+ const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
3589
+ const typedCls = sourceFile?.getClass(className);
3590
+ if (!typedCls) return void 0;
3591
+ const prop = typedCls.getType().getProperty(methodName);
3592
+ if (!prop) return void 0;
3593
+ const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
3594
+ if (!returnType) return void 0;
3595
+ const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
3596
+ return unwrapped.getText(typedCls);
3597
+ }
3598
+
3453
3599
  // src/discovery/filter-for.ts
3454
3600
  function resolveMixinEntityClass(mixin, project) {
3455
- const entityArg = mixin?.classArgs[0];
3601
+ const entityArg = mixin?.namedClassArgs?.entity ?? mixin?.classArgs[0];
3456
3602
  if (!entityArg) return void 0;
3457
3603
  const file = project.getSourceFile(entityArg.filePath) ?? project.addSourceFileAtPathIfExists(entityArg.filePath);
3458
3604
  return file?.getClass(entityArg.name);
3459
3605
  }
3460
3606
  function classifyFilterForHint(typeInit) {
3461
- if (import_ts_morph6.Node.isStringLiteral(typeInit)) {
3607
+ if (import_ts_morph7.Node.isStringLiteral(typeInit)) {
3462
3608
  switch (typeInit.getLiteralValue()) {
3463
3609
  case "string":
3464
3610
  return { kind: "string" };
@@ -3472,10 +3618,10 @@ function classifyFilterForHint(typeInit) {
3472
3618
  return null;
3473
3619
  }
3474
3620
  }
3475
- if (import_ts_morph6.Node.isArrayLiteralExpression(typeInit)) {
3621
+ if (import_ts_morph7.Node.isArrayLiteralExpression(typeInit)) {
3476
3622
  const values = [];
3477
3623
  for (const el of typeInit.getElements()) {
3478
- if (!import_ts_morph6.Node.isStringLiteral(el)) return null;
3624
+ if (!import_ts_morph7.Node.isStringLiteral(el)) return null;
3479
3625
  values.push(el.getLiteralValue());
3480
3626
  }
3481
3627
  if (values.length === 0) return null;
@@ -3510,11 +3656,11 @@ function extractFilterForHints(classDecl, project) {
3510
3656
  if (!filterForDec) continue;
3511
3657
  const args = filterForDec.getArguments();
3512
3658
  const keyArg = args[0];
3513
- const inputKey = keyArg && import_ts_morph6.Node.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
3659
+ const inputKey = keyArg && import_ts_morph7.Node.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
3514
3660
  const optsArg = args[1];
3515
- if (optsArg && import_ts_morph6.Node.isObjectLiteralExpression(optsArg)) {
3661
+ if (optsArg && import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) {
3516
3662
  const typeProp = optsArg.getProperty("type");
3517
- if (typeProp && import_ts_morph6.Node.isPropertyAssignment(typeProp)) {
3663
+ if (typeProp && import_ts_morph7.Node.isPropertyAssignment(typeProp)) {
3518
3664
  const typeInit = typeProp.getInitializer();
3519
3665
  if (typeInit) {
3520
3666
  const classified = classifyFilterForHint(typeInit);
@@ -3539,21 +3685,23 @@ function extractApplyFilterInfo(method, sourceFile, project, mixin) {
3539
3685
  const args = filterDecorator.getArguments();
3540
3686
  if (args.length === 0) continue;
3541
3687
  const filterClassArg = args[0];
3542
- if (!filterClassArg || !import_ts_morph6.Node.isIdentifier(filterClassArg)) continue;
3688
+ if (!filterClassArg) continue;
3689
+ const factoryStaticClass = resolveFactoryStaticClass(filterClassArg);
3690
+ if (!factoryStaticClass && !import_ts_morph7.Node.isIdentifier(filterClassArg)) continue;
3543
3691
  let source = "query";
3544
3692
  const optionsArg = args[1];
3545
- if (optionsArg && import_ts_morph6.Node.isObjectLiteralExpression(optionsArg)) {
3693
+ if (optionsArg && import_ts_morph7.Node.isObjectLiteralExpression(optionsArg)) {
3546
3694
  const sourceProp = optionsArg.getProperty("source");
3547
- if (sourceProp && import_ts_morph6.Node.isPropertyAssignment(sourceProp)) {
3695
+ if (sourceProp && import_ts_morph7.Node.isPropertyAssignment(sourceProp)) {
3548
3696
  const init = sourceProp.getInitializer();
3549
- if (init && import_ts_morph6.Node.isStringLiteral(init) && init.getLiteralValue() === "body") {
3697
+ if (init && import_ts_morph7.Node.isStringLiteral(init) && init.getLiteralValue() === "body") {
3550
3698
  source = "body";
3551
3699
  }
3552
3700
  }
3553
3701
  }
3554
3702
  const filterClassName = filterClassArg.getText();
3555
- const resolved = findType(filterClassName, declFile, project);
3556
- const classDecl = resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg);
3703
+ const resolved = factoryStaticClass ? void 0 : findType(filterClassName, declFile, project);
3704
+ const classDecl = factoryStaticClass ?? (resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg));
3557
3705
  if (classDecl) {
3558
3706
  let fieldTypes = extractClassPropertyTypes(classDecl, project);
3559
3707
  if (fieldTypes.length === 0) {
@@ -3609,22 +3757,22 @@ function resolveRelationEntity(prop, sourceFile, project) {
3609
3757
  const args = dec.getArguments();
3610
3758
  if (args.length === 0) continue;
3611
3759
  const arg = args[0];
3612
- if (import_ts_morph6.Node.isObjectLiteralExpression(arg)) {
3760
+ if (import_ts_morph7.Node.isObjectLiteralExpression(arg)) {
3613
3761
  const entityProp = arg.getProperty("entity");
3614
- if (entityProp && import_ts_morph6.Node.isPropertyAssignment(entityProp)) {
3762
+ if (entityProp && import_ts_morph7.Node.isPropertyAssignment(entityProp)) {
3615
3763
  const init = entityProp.getInitializer();
3616
- if (init && import_ts_morph6.Node.isArrowFunction(init)) {
3764
+ if (init && import_ts_morph7.Node.isArrowFunction(init)) {
3617
3765
  const body = init.getBody();
3618
- if (import_ts_morph6.Node.isIdentifier(body)) {
3766
+ if (import_ts_morph7.Node.isIdentifier(body)) {
3619
3767
  const resolved = findType(body.getText(), prop.getSourceFile(), project);
3620
3768
  if (resolved?.kind === "class") return resolved.decl;
3621
3769
  }
3622
3770
  }
3623
3771
  }
3624
3772
  }
3625
- if (import_ts_morph6.Node.isArrowFunction(arg)) {
3773
+ if (import_ts_morph7.Node.isArrowFunction(arg)) {
3626
3774
  const body = arg.getBody();
3627
- if (import_ts_morph6.Node.isIdentifier(body)) {
3775
+ if (import_ts_morph7.Node.isIdentifier(body)) {
3628
3776
  const resolved = findType(body.getText(), prop.getSourceFile(), project);
3629
3777
  if (resolved?.kind === "class") return resolved.decl;
3630
3778
  }
@@ -3643,15 +3791,15 @@ function extractClassPropertyTypes(classDecl, project) {
3643
3791
  return fields;
3644
3792
  }
3645
3793
  function resolveLocalClassDeclaration(identifier) {
3646
- if (!import_ts_morph6.Node.isIdentifier(identifier)) return void 0;
3647
- return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && import_ts_morph6.Node.isClassDeclaration(n));
3794
+ if (!import_ts_morph7.Node.isIdentifier(identifier)) return void 0;
3795
+ return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && import_ts_morph7.Node.isClassDeclaration(n));
3648
3796
  }
3649
3797
  function resolveDeclaredEntity(optionsArg, filterClass, project) {
3650
- if (!import_ts_morph6.Node.isObjectLiteralExpression(optionsArg)) return void 0;
3798
+ if (!import_ts_morph7.Node.isObjectLiteralExpression(optionsArg)) return void 0;
3651
3799
  const entityProp = optionsArg.getProperty("entity");
3652
- if (!entityProp || !import_ts_morph6.Node.isPropertyAssignment(entityProp)) return void 0;
3800
+ if (!entityProp || !import_ts_morph7.Node.isPropertyAssignment(entityProp)) return void 0;
3653
3801
  const entityInit = entityProp.getInitializer();
3654
- if (!entityInit || !import_ts_morph6.Node.isIdentifier(entityInit)) return void 0;
3802
+ if (!entityInit || !import_ts_morph7.Node.isIdentifier(entityInit)) return void 0;
3655
3803
  const resolved = findType(entityInit.getText(), filterClass.getSourceFile(), project);
3656
3804
  if (!resolved || resolved.kind !== "class") return void 0;
3657
3805
  return resolved.decl;
@@ -3662,7 +3810,7 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
3662
3810
  const args = filterableDecorator.getArguments();
3663
3811
  if (args.length === 0) return [];
3664
3812
  const optionsArg = args[0];
3665
- if (!import_ts_morph6.Node.isObjectLiteralExpression(optionsArg)) return [];
3813
+ if (!import_ts_morph7.Node.isObjectLiteralExpression(optionsArg)) return [];
3666
3814
  const entityDecl = entityOverride ?? resolveDeclaredEntity(optionsArg, filterClass, project);
3667
3815
  if (!entityDecl) return [];
3668
3816
  const fields = collectEntityFields(
@@ -3675,17 +3823,17 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
3675
3823
  const relationsDecorator = filterClass.getDecorators().find((d) => d.getName() === "Relations");
3676
3824
  if (relationsDecorator) {
3677
3825
  const relArgs = relationsDecorator.getArguments();
3678
- if (relArgs.length > 0 && import_ts_morph6.Node.isObjectLiteralExpression(relArgs[0])) {
3826
+ if (relArgs.length > 0 && import_ts_morph7.Node.isObjectLiteralExpression(relArgs[0])) {
3679
3827
  for (const relProp of relArgs[0].getProperties()) {
3680
- if (!import_ts_morph6.Node.isPropertyAssignment(relProp)) continue;
3828
+ if (!import_ts_morph7.Node.isPropertyAssignment(relProp)) continue;
3681
3829
  const relInit = relProp.getInitializer();
3682
- if (!relInit || !import_ts_morph6.Node.isObjectLiteralExpression(relInit)) continue;
3830
+ if (!relInit || !import_ts_morph7.Node.isObjectLiteralExpression(relInit)) continue;
3683
3831
  const keysProp = relInit.getProperty("keys");
3684
- if (!keysProp || !import_ts_morph6.Node.isPropertyAssignment(keysProp)) continue;
3832
+ if (!keysProp || !import_ts_morph7.Node.isPropertyAssignment(keysProp)) continue;
3685
3833
  const keysInit = keysProp.getInitializer();
3686
- if (!keysInit || !import_ts_morph6.Node.isArrayLiteralExpression(keysInit)) continue;
3834
+ if (!keysInit || !import_ts_morph7.Node.isArrayLiteralExpression(keysInit)) continue;
3687
3835
  for (const el of keysInit.getElements()) {
3688
- if (import_ts_morph6.Node.isStringLiteral(el)) {
3836
+ if (import_ts_morph7.Node.isStringLiteral(el)) {
3689
3837
  fields.push(toFilterFieldType(el.getLiteralValue(), { kind: "unknown" }));
3690
3838
  }
3691
3839
  }
@@ -3726,22 +3874,22 @@ var PASSTHROUGH_UTILITY = /* @__PURE__ */ new Set([
3726
3874
  ]);
3727
3875
  function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /* @__PURE__ */ new Map()) {
3728
3876
  if (depth <= 0) return "unknown";
3729
- if (import_ts_morph7.Node.isArrayTypeNode(typeNode)) {
3877
+ if (import_ts_morph8.Node.isArrayTypeNode(typeNode)) {
3730
3878
  const elementType = typeNode.getElementTypeNode();
3731
3879
  return `Array<${resolveTypeNodeToString(elementType, sourceFile, project, depth, subst)}>`;
3732
3880
  }
3733
- if (import_ts_morph7.Node.isUnionTypeNode(typeNode)) {
3881
+ if (import_ts_morph8.Node.isUnionTypeNode(typeNode)) {
3734
3882
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" | ");
3735
3883
  }
3736
- if (import_ts_morph7.Node.isIntersectionTypeNode(typeNode)) {
3884
+ if (import_ts_morph8.Node.isIntersectionTypeNode(typeNode)) {
3737
3885
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" & ");
3738
3886
  }
3739
- if (import_ts_morph7.Node.isParenthesizedTypeNode(typeNode)) {
3887
+ if (import_ts_morph8.Node.isParenthesizedTypeNode(typeNode)) {
3740
3888
  return `(${resolveTypeNodeToString(typeNode.getTypeNode(), sourceFile, project, depth, subst)})`;
3741
3889
  }
3742
- if (import_ts_morph7.Node.isTypeReference(typeNode)) {
3890
+ if (import_ts_morph8.Node.isTypeReference(typeNode)) {
3743
3891
  const typeName = typeNode.getTypeName();
3744
- const name = import_ts_morph7.Node.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
3892
+ const name = import_ts_morph8.Node.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
3745
3893
  const bound = subst.get(name);
3746
3894
  if (bound !== void 0) return bound;
3747
3895
  if (name === "string" || name === "number" || name === "boolean") return name;
@@ -3764,10 +3912,10 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
3764
3912
  dbg("unresolvable type:", name, "in", sourceFile.getFilePath());
3765
3913
  return "unknown";
3766
3914
  }
3767
- if (import_ts_morph7.Node.isTypeLiteral(typeNode)) {
3915
+ if (import_ts_morph8.Node.isTypeLiteral(typeNode)) {
3768
3916
  const members = [];
3769
3917
  for (const member of typeNode.getMembers()) {
3770
- if (import_ts_morph7.Node.isPropertySignature(member)) {
3918
+ if (import_ts_morph8.Node.isPropertySignature(member)) {
3771
3919
  const memberTypeNode = member.getTypeNode();
3772
3920
  const memberType = memberTypeNode ? resolveTypeNodeToString(memberTypeNode, sourceFile, project, depth, subst) : "unknown";
3773
3921
  members.push(`${member.getName()}${member.hasQuestionToken() ? "?" : ""}: ${memberType}`);
@@ -3778,11 +3926,11 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
3778
3926
  return members.length > 0 ? `{ ${members.join("; ")} }` : "{}";
3779
3927
  }
3780
3928
  const kind = typeNode.getKind();
3781
- if (kind === import_ts_morph7.SyntaxKind.StringKeyword) return "string";
3782
- if (kind === import_ts_morph7.SyntaxKind.NumberKeyword) return "number";
3783
- if (kind === import_ts_morph7.SyntaxKind.BooleanKeyword) return "boolean";
3784
- if (kind === import_ts_morph7.SyntaxKind.UnknownKeyword) return "unknown";
3785
- if (kind === import_ts_morph7.SyntaxKind.AnyKeyword) return "unknown";
3929
+ if (kind === import_ts_morph8.SyntaxKind.StringKeyword) return "string";
3930
+ if (kind === import_ts_morph8.SyntaxKind.NumberKeyword) return "number";
3931
+ if (kind === import_ts_morph8.SyntaxKind.BooleanKeyword) return "boolean";
3932
+ if (kind === import_ts_morph8.SyntaxKind.UnknownKeyword) return "unknown";
3933
+ if (kind === import_ts_morph8.SyntaxKind.AnyKeyword) return "unknown";
3786
3934
  return typeNode.getText();
3787
3935
  }
3788
3936
  function unwrapFirstTypeArg(typeNode, sourceFile, project, depth, mode, subst = /* @__PURE__ */ new Map()) {
@@ -3867,7 +4015,7 @@ function extractQueryType(method, sourceFile, project) {
3867
4015
  if (!queryDecorator) continue;
3868
4016
  const queryArgs = queryDecorator.getArguments();
3869
4017
  const nameArg = queryArgs[0];
3870
- if (!nameArg || !import_ts_morph7.Node.isStringLiteral(nameArg)) continue;
4018
+ if (!nameArg || !import_ts_morph8.Node.isStringLiteral(nameArg)) continue;
3871
4019
  const queryName = nameArg.getLiteralValue();
3872
4020
  const typeNode = param.getTypeNode();
3873
4021
  const queryType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
@@ -3878,8 +4026,8 @@ function extractQueryType(method, sourceFile, project) {
3878
4026
  function isParamOptional(param) {
3879
4027
  if (param.hasQuestionToken() || param.hasInitializer()) return true;
3880
4028
  const typeNode = param.getTypeNode();
3881
- if (typeNode && import_ts_morph7.Node.isUnionTypeNode(typeNode)) {
3882
- return typeNode.getTypeNodes().some((t) => t.getKind() === import_ts_morph7.SyntaxKind.UndefinedKeyword);
4029
+ if (typeNode && import_ts_morph8.Node.isUnionTypeNode(typeNode)) {
4030
+ return typeNode.getTypeNodes().some((t) => t.getKind() === import_ts_morph8.SyntaxKind.UndefinedKeyword);
3883
4031
  }
3884
4032
  return false;
3885
4033
  }
@@ -3891,7 +4039,7 @@ function extractParamsType(method, sourceFile, project) {
3891
4039
  const paramArgs = paramDecorator.getArguments();
3892
4040
  if (paramArgs.length === 0) continue;
3893
4041
  const nameArg = paramArgs[0];
3894
- if (!import_ts_morph7.Node.isStringLiteral(nameArg)) continue;
4042
+ if (!import_ts_morph8.Node.isStringLiteral(nameArg)) continue;
3895
4043
  const paramName = nameArg.getLiteralValue();
3896
4044
  const typeNode = param.getTypeNode();
3897
4045
  const paramType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
@@ -3912,28 +4060,28 @@ function extractUploadedFiles(method) {
3912
4060
  for (const decorator of method.getDecorators()) {
3913
4061
  if (decorator.getName() !== "UseInterceptors") continue;
3914
4062
  for (const arg of decorator.getArguments()) {
3915
- if (!import_ts_morph7.Node.isCallExpression(arg)) continue;
4063
+ if (!import_ts_morph8.Node.isCallExpression(arg)) continue;
3916
4064
  const interceptor = arg.getExpression().getText();
3917
4065
  const callArgs = arg.getArguments();
3918
4066
  const firstArg2 = callArgs[0];
3919
4067
  if (interceptor === "FileInterceptor") {
3920
- if (firstArg2 && import_ts_morph7.Node.isStringLiteral(firstArg2)) {
4068
+ if (firstArg2 && import_ts_morph8.Node.isStringLiteral(firstArg2)) {
3921
4069
  entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
3922
4070
  multipart = true;
3923
4071
  }
3924
4072
  } else if (interceptor === "FilesInterceptor") {
3925
- if (firstArg2 && import_ts_morph7.Node.isStringLiteral(firstArg2)) {
4073
+ if (firstArg2 && import_ts_morph8.Node.isStringLiteral(firstArg2)) {
3926
4074
  entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
3927
4075
  multipart = true;
3928
4076
  }
3929
4077
  } else if (interceptor === "FileFieldsInterceptor") {
3930
- if (firstArg2 && import_ts_morph7.Node.isArrayLiteralExpression(firstArg2)) {
4078
+ if (firstArg2 && import_ts_morph8.Node.isArrayLiteralExpression(firstArg2)) {
3931
4079
  for (const el of firstArg2.getElements()) {
3932
- if (!import_ts_morph7.Node.isObjectLiteralExpression(el)) continue;
4080
+ if (!import_ts_morph8.Node.isObjectLiteralExpression(el)) continue;
3933
4081
  const nameProp = el.getProperty("name");
3934
- if (nameProp && import_ts_morph7.Node.isPropertyAssignment(nameProp)) {
4082
+ if (nameProp && import_ts_morph8.Node.isPropertyAssignment(nameProp)) {
3935
4083
  const init = nameProp.getInitializer();
3936
- if (init && import_ts_morph7.Node.isStringLiteral(init)) {
4084
+ if (init && import_ts_morph8.Node.isStringLiteral(init)) {
3937
4085
  entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
3938
4086
  }
3939
4087
  }
@@ -3953,13 +4101,13 @@ function extractResponseType(method, sourceFile, project) {
3953
4101
  if (apiResponseDecorator) {
3954
4102
  const args = apiResponseDecorator.getArguments();
3955
4103
  const optsArg = args[0];
3956
- if (optsArg && import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) {
4104
+ if (optsArg && import_ts_morph8.Node.isObjectLiteralExpression(optsArg)) {
3957
4105
  for (const prop of optsArg.getProperties()) {
3958
- if (!import_ts_morph7.Node.isPropertyAssignment(prop)) continue;
4106
+ if (!import_ts_morph8.Node.isPropertyAssignment(prop)) continue;
3959
4107
  if (prop.getName() !== "type") continue;
3960
4108
  const val = prop.getInitializer();
3961
4109
  if (!val) continue;
3962
- if (import_ts_morph7.Node.isArrayLiteralExpression(val)) {
4110
+ if (import_ts_morph8.Node.isArrayLiteralExpression(val)) {
3963
4111
  const elements = val.getElements();
3964
4112
  const firstEl = elements[0];
3965
4113
  if (elements.length > 0 && firstEl !== void 0) {
@@ -3980,24 +4128,24 @@ function extractResponseType(method, sourceFile, project) {
3980
4128
  }
3981
4129
  function apiResponseStatus(decorator) {
3982
4130
  const optsArg = decorator.getArguments()[0];
3983
- if (!optsArg || !import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) return null;
4131
+ if (!optsArg || !import_ts_morph8.Node.isObjectLiteralExpression(optsArg)) return null;
3984
4132
  for (const prop of optsArg.getProperties()) {
3985
- if (!import_ts_morph7.Node.isPropertyAssignment(prop)) continue;
4133
+ if (!import_ts_morph8.Node.isPropertyAssignment(prop)) continue;
3986
4134
  if (prop.getName() !== "status") continue;
3987
4135
  const val = prop.getInitializer();
3988
- if (val && import_ts_morph7.Node.isNumericLiteral(val)) return Number(val.getLiteralValue());
4136
+ if (val && import_ts_morph8.Node.isNumericLiteral(val)) return Number(val.getLiteralValue());
3989
4137
  }
3990
4138
  return null;
3991
4139
  }
3992
4140
  function apiResponseTypeNode(decorator) {
3993
4141
  const optsArg = decorator.getArguments()[0];
3994
- if (!optsArg || !import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) return null;
4142
+ if (!optsArg || !import_ts_morph8.Node.isObjectLiteralExpression(optsArg)) return null;
3995
4143
  for (const prop of optsArg.getProperties()) {
3996
- if (!import_ts_morph7.Node.isPropertyAssignment(prop)) continue;
4144
+ if (!import_ts_morph8.Node.isPropertyAssignment(prop)) continue;
3997
4145
  if (prop.getName() !== "type") continue;
3998
4146
  const val = prop.getInitializer();
3999
4147
  if (!val) return null;
4000
- if (import_ts_morph7.Node.isArrayLiteralExpression(val)) {
4148
+ if (import_ts_morph8.Node.isArrayLiteralExpression(val)) {
4001
4149
  const first = val.getElements()[0];
4002
4150
  return first ? { node: first, isArray: true } : null;
4003
4151
  }
@@ -4015,7 +4163,7 @@ function extractErrorType(method, sourceFile, project) {
4015
4163
  const inner = resolveIdentifierToClassType(typeInfo.node, sourceFile, project, 3);
4016
4164
  const type = typeInfo.isArray ? `Array<${inner}>` : inner;
4017
4165
  let ref = null;
4018
- if (import_ts_morph7.Node.isIdentifier(typeInfo.node)) {
4166
+ if (import_ts_morph8.Node.isIdentifier(typeInfo.node)) {
4019
4167
  const name = typeInfo.node.getText();
4020
4168
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
4021
4169
  if (localDecl?.isExported()) {
@@ -4032,7 +4180,7 @@ function extractErrorType(method, sourceFile, project) {
4032
4180
  return null;
4033
4181
  }
4034
4182
  function resolveIdentifierToClassType(node, sourceFile, project, depth) {
4035
- if (!import_ts_morph7.Node.isIdentifier(node)) return "unknown";
4183
+ if (!import_ts_morph8.Node.isIdentifier(node)) return "unknown";
4036
4184
  const name = node.getText();
4037
4185
  const resolved = findType(name, sourceFile, project);
4038
4186
  if (resolved) {
@@ -4052,9 +4200,9 @@ var STREAM_ENVELOPES = /* @__PURE__ */ new Set(["MessageEvent", "MessageEventLik
4052
4200
  var BINARY_RESPONSE_TYPES = /* @__PURE__ */ new Set(["StreamableFile", "Buffer"]);
4053
4201
  function detectBinaryResponse(method) {
4054
4202
  const node = unwrapNamedContainer(method.getReturnTypeNode(), /* @__PURE__ */ new Set(["Promise"]));
4055
- if (!node || !import_ts_morph7.Node.isTypeReference(node)) return false;
4203
+ if (!node || !import_ts_morph8.Node.isTypeReference(node)) return false;
4056
4204
  const typeName = node.getTypeName();
4057
- const name = import_ts_morph7.Node.isIdentifier(typeName) ? typeName.getText() : "";
4205
+ const name = import_ts_morph8.Node.isIdentifier(typeName) ? typeName.getText() : "";
4058
4206
  return BINARY_RESPONSE_TYPES.has(name);
4059
4207
  }
4060
4208
  function detectStreamElement(method) {
@@ -4069,9 +4217,9 @@ function detectStreamElement(method) {
4069
4217
  return null;
4070
4218
  }
4071
4219
  function streamContainerElement(node) {
4072
- if (!node || !import_ts_morph7.Node.isTypeReference(node)) return null;
4220
+ if (!node || !import_ts_morph8.Node.isTypeReference(node)) return null;
4073
4221
  const typeName = node.getTypeName();
4074
- const name = import_ts_morph7.Node.isIdentifier(typeName) ? typeName.getText() : "";
4222
+ const name = import_ts_morph8.Node.isIdentifier(typeName) ? typeName.getText() : "";
4075
4223
  if (STREAM_CONTAINERS.has(name) || STREAM_CONTAINERS_GENERATOR.has(name)) {
4076
4224
  return node.getTypeArguments()[0] ?? null;
4077
4225
  }
@@ -4081,9 +4229,9 @@ function hasAsQueryDecorator(method) {
4081
4229
  return method.getDecorators().some((d) => d.getName() === "AsQuery");
4082
4230
  }
4083
4231
  function unwrapNamedContainer(node, names) {
4084
- if (!node || !import_ts_morph7.Node.isTypeReference(node)) return node;
4232
+ if (!node || !import_ts_morph8.Node.isTypeReference(node)) return node;
4085
4233
  const typeName = node.getTypeName();
4086
- const name = import_ts_morph7.Node.isIdentifier(typeName) ? typeName.getText() : "";
4234
+ const name = import_ts_morph8.Node.isIdentifier(typeName) ? typeName.getText() : "";
4087
4235
  if (names.has(name)) {
4088
4236
  return node.getTypeArguments()[0] ?? node;
4089
4237
  }
@@ -4129,11 +4277,11 @@ function extractDtoContract(method, sourceFile, project, mixin) {
4129
4277
  if (apiResp) {
4130
4278
  const args = apiResp.getArguments();
4131
4279
  const optsArg = args[0];
4132
- if (optsArg && import_ts_morph7.Node.isObjectLiteralExpression(optsArg)) {
4280
+ if (optsArg && import_ts_morph8.Node.isObjectLiteralExpression(optsArg)) {
4133
4281
  for (const prop of optsArg.getProperties()) {
4134
- if (import_ts_morph7.Node.isPropertyAssignment(prop) && prop.getName() === "type") {
4282
+ if (import_ts_morph8.Node.isPropertyAssignment(prop) && prop.getName() === "type") {
4135
4283
  const val = prop.getInitializer();
4136
- if (val && import_ts_morph7.Node.isIdentifier(val)) {
4284
+ if (val && import_ts_morph8.Node.isIdentifier(val)) {
4137
4285
  const name = val.getText();
4138
4286
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
4139
4287
  if (localDecl?.isExported()) {
@@ -4201,101 +4349,6 @@ function resolveParamClass(method, decoratorName, sourceFile, project) {
4201
4349
  return null;
4202
4350
  }
4203
4351
 
4204
- // src/discovery/heritage.ts
4205
- var import_ts_morph8 = require("ts-morph");
4206
- function resolveHeritageCall(node) {
4207
- if (!node) return void 0;
4208
- const expr = unwrapExpression(node);
4209
- if (import_ts_morph8.Node.isCallExpression(expr)) return expr;
4210
- if (!import_ts_morph8.Node.isIdentifier(expr)) return void 0;
4211
- const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find(
4212
- (n) => n !== void 0 && import_ts_morph8.Node.isVariableDeclaration(n)
4213
- );
4214
- const init = decl?.getInitializer();
4215
- if (!init) return void 0;
4216
- const unwrapped = unwrapExpression(init);
4217
- return import_ts_morph8.Node.isCallExpression(unwrapped) ? unwrapped : void 0;
4218
- }
4219
- function unwrapExpression(node) {
4220
- let current = node;
4221
- 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)) {
4222
- current = current.getExpression();
4223
- }
4224
- return current;
4225
- }
4226
- function resolveReturnedClass(factoryDecl) {
4227
- const body = factoryDecl.getBody();
4228
- if (!body) return void 0;
4229
- const returns = body.getDescendants().filter((n) => import_ts_morph8.Node.isReturnStatement(n));
4230
- for (const ret of returns) {
4231
- const expr = ret.getExpression();
4232
- if (!expr) continue;
4233
- const inner = unwrapExpression(expr);
4234
- if (import_ts_morph8.Node.isClassExpression(inner)) {
4235
- return inner;
4236
- }
4237
- if (import_ts_morph8.Node.isIdentifier(inner)) {
4238
- const name = inner.getText();
4239
- const decl = body.getDescendants().find((n) => import_ts_morph8.Node.isClassDeclaration(n) && n.getName() === name);
4240
- if (decl) return decl;
4241
- }
4242
- }
4243
- return void 0;
4244
- }
4245
- function resolveInheritedMethods(cls) {
4246
- const expr = resolveHeritageCall(cls.getExtends()?.getExpression());
4247
- if (!expr) return void 0;
4248
- const callee = expr.getExpression();
4249
- if (!import_ts_morph8.Node.isIdentifier(callee)) return void 0;
4250
- const factoryDecl = callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => import_ts_morph8.Node.isFunctionDeclaration(n));
4251
- if (!factoryDecl) return void 0;
4252
- const returnedClass = resolveReturnedClass(factoryDecl);
4253
- if (!returnedClass) return void 0;
4254
- const classArgs = [];
4255
- for (const arg of expr.getArguments()) {
4256
- if (!import_ts_morph8.Node.isIdentifier(arg)) continue;
4257
- const decl = arg.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => import_ts_morph8.Node.isClassDeclaration(n));
4258
- if (decl) {
4259
- classArgs.push({
4260
- name: decl.getName() ?? arg.getText(),
4261
- filePath: decl.getSourceFile().getFilePath()
4262
- });
4263
- }
4264
- }
4265
- return {
4266
- methods: returnedClass.getMethods(),
4267
- factoryName: callee.getText(),
4268
- factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
4269
- classArgs
4270
- };
4271
- }
4272
- var mixinTypeProject;
4273
- function getMixinTypeProject() {
4274
- mixinTypeProject ??= new import_ts_morph8.Project({
4275
- skipAddingFilesFromTsConfig: true,
4276
- compilerOptions: { strict: true }
4277
- });
4278
- return mixinTypeProject;
4279
- }
4280
- function clearMixinTypeProject() {
4281
- mixinTypeProject = void 0;
4282
- }
4283
- function resolveInstantiatedReturnType(cls, methodName) {
4284
- const filePath = cls.getSourceFile().getFilePath();
4285
- const className = cls.getName();
4286
- if (!className) return void 0;
4287
- const project = getMixinTypeProject();
4288
- const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
4289
- const typedCls = sourceFile?.getClass(className);
4290
- if (!typedCls) return void 0;
4291
- const prop = typedCls.getType().getProperty(methodName);
4292
- if (!prop) return void 0;
4293
- const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
4294
- if (!returnType) return void 0;
4295
- const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
4296
- return unwrapped.getText(typedCls);
4297
- }
4298
-
4299
4352
  // src/discovery/zod-ast-to-ts.ts
4300
4353
  var import_ts_morph9 = require("ts-morph");
4301
4354
  function zodAstToTs(node) {
@@ -4797,7 +4850,8 @@ function extractFromSourceFile(sourceFile, project) {
4797
4850
  const mixinBinding = inherited ? {
4798
4851
  factoryName: inherited.factoryName,
4799
4852
  factoryFilePath: inherited.factoryFilePath,
4800
- classArgs: inherited.classArgs
4853
+ classArgs: inherited.classArgs,
4854
+ namedClassArgs: inherited.namedClassArgs
4801
4855
  } : void 0;
4802
4856
  const ownMethods = cls.getMethods();
4803
4857
  const ownNames = new Set(ownMethods.map((m) => m.getName()));
@@ -5029,7 +5083,7 @@ async function watch(config, onChange, options = {}) {
5029
5083
  }
5030
5084
 
5031
5085
  // src/index.ts
5032
- var VERSION = "0.17.1";
5086
+ var VERSION = "0.18.0";
5033
5087
 
5034
5088
  // src/cli/codegen.ts
5035
5089
  async function runCodegen(opts = {}) {