@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/CHANGELOG.md +45 -0
- package/dist/cli/main.cjs +200 -161
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +194 -155
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +200 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +194 -155
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +200 -161
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.js +194 -155
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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 (
|
|
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 (
|
|
3573
|
+
if (Node6.isArrayLiteralExpression(typeInit)) {
|
|
3457
3574
|
const values = [];
|
|
3458
3575
|
for (const el of typeInit.getElements()) {
|
|
3459
|
-
if (!
|
|
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 &&
|
|
3611
|
+
const inputKey = keyArg && Node6.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
|
|
3495
3612
|
const optsArg = args[1];
|
|
3496
|
-
if (optsArg &&
|
|
3613
|
+
if (optsArg && Node6.isObjectLiteralExpression(optsArg)) {
|
|
3497
3614
|
const typeProp = optsArg.getProperty("type");
|
|
3498
|
-
if (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
|
|
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 &&
|
|
3645
|
+
if (optionsArg && Node6.isObjectLiteralExpression(optionsArg)) {
|
|
3527
3646
|
const sourceProp = optionsArg.getProperty("source");
|
|
3528
|
-
if (sourceProp &&
|
|
3647
|
+
if (sourceProp && Node6.isPropertyAssignment(sourceProp)) {
|
|
3529
3648
|
const init = sourceProp.getInitializer();
|
|
3530
|
-
if (init &&
|
|
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 (
|
|
3712
|
+
if (Node6.isObjectLiteralExpression(arg)) {
|
|
3594
3713
|
const entityProp = arg.getProperty("entity");
|
|
3595
|
-
if (entityProp &&
|
|
3714
|
+
if (entityProp && Node6.isPropertyAssignment(entityProp)) {
|
|
3596
3715
|
const init = entityProp.getInitializer();
|
|
3597
|
-
if (init &&
|
|
3716
|
+
if (init && Node6.isArrowFunction(init)) {
|
|
3598
3717
|
const body = init.getBody();
|
|
3599
|
-
if (
|
|
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 (
|
|
3725
|
+
if (Node6.isArrowFunction(arg)) {
|
|
3607
3726
|
const body = arg.getBody();
|
|
3608
|
-
if (
|
|
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 (!
|
|
3628
|
-
return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 &&
|
|
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 (!
|
|
3750
|
+
if (!Node6.isObjectLiteralExpression(optionsArg)) return void 0;
|
|
3632
3751
|
const entityProp = optionsArg.getProperty("entity");
|
|
3633
|
-
if (!entityProp || !
|
|
3752
|
+
if (!entityProp || !Node6.isPropertyAssignment(entityProp)) return void 0;
|
|
3634
3753
|
const entityInit = entityProp.getInitializer();
|
|
3635
|
-
if (!entityInit || !
|
|
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 (!
|
|
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 &&
|
|
3778
|
+
if (relArgs.length > 0 && Node6.isObjectLiteralExpression(relArgs[0])) {
|
|
3660
3779
|
for (const relProp of relArgs[0].getProperties()) {
|
|
3661
|
-
if (!
|
|
3780
|
+
if (!Node6.isPropertyAssignment(relProp)) continue;
|
|
3662
3781
|
const relInit = relProp.getInitializer();
|
|
3663
|
-
if (!relInit || !
|
|
3782
|
+
if (!relInit || !Node6.isObjectLiteralExpression(relInit)) continue;
|
|
3664
3783
|
const keysProp = relInit.getProperty("keys");
|
|
3665
|
-
if (!keysProp || !
|
|
3784
|
+
if (!keysProp || !Node6.isPropertyAssignment(keysProp)) continue;
|
|
3666
3785
|
const keysInit = keysProp.getInitializer();
|
|
3667
|
-
if (!keysInit || !
|
|
3786
|
+
if (!keysInit || !Node6.isArrayLiteralExpression(keysInit)) continue;
|
|
3668
3787
|
for (const el of keysInit.getElements()) {
|
|
3669
|
-
if (
|
|
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 (
|
|
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 (
|
|
3833
|
+
if (Node7.isUnionTypeNode(typeNode)) {
|
|
3715
3834
|
return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" | ");
|
|
3716
3835
|
}
|
|
3717
|
-
if (
|
|
3836
|
+
if (Node7.isIntersectionTypeNode(typeNode)) {
|
|
3718
3837
|
return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" & ");
|
|
3719
3838
|
}
|
|
3720
|
-
if (
|
|
3839
|
+
if (Node7.isParenthesizedTypeNode(typeNode)) {
|
|
3721
3840
|
return `(${resolveTypeNodeToString(typeNode.getTypeNode(), sourceFile, project, depth, subst)})`;
|
|
3722
3841
|
}
|
|
3723
|
-
if (
|
|
3842
|
+
if (Node7.isTypeReference(typeNode)) {
|
|
3724
3843
|
const typeName = typeNode.getTypeName();
|
|
3725
|
-
const name =
|
|
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 (
|
|
3867
|
+
if (Node7.isTypeLiteral(typeNode)) {
|
|
3749
3868
|
const members = [];
|
|
3750
3869
|
for (const member of typeNode.getMembers()) {
|
|
3751
|
-
if (
|
|
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 || !
|
|
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 &&
|
|
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 (!
|
|
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 (!
|
|
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 &&
|
|
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 &&
|
|
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 &&
|
|
4030
|
+
if (firstArg2 && Node7.isArrayLiteralExpression(firstArg2)) {
|
|
3912
4031
|
for (const el of firstArg2.getElements()) {
|
|
3913
|
-
if (!
|
|
4032
|
+
if (!Node7.isObjectLiteralExpression(el)) continue;
|
|
3914
4033
|
const nameProp = el.getProperty("name");
|
|
3915
|
-
if (nameProp &&
|
|
4034
|
+
if (nameProp && Node7.isPropertyAssignment(nameProp)) {
|
|
3916
4035
|
const init = nameProp.getInitializer();
|
|
3917
|
-
if (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 &&
|
|
4056
|
+
if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
|
|
3938
4057
|
for (const prop of optsArg.getProperties()) {
|
|
3939
|
-
if (!
|
|
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 (
|
|
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 || !
|
|
4083
|
+
if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
|
|
3965
4084
|
for (const prop of optsArg.getProperties()) {
|
|
3966
|
-
if (!
|
|
4085
|
+
if (!Node7.isPropertyAssignment(prop)) continue;
|
|
3967
4086
|
if (prop.getName() !== "status") continue;
|
|
3968
4087
|
const val = prop.getInitializer();
|
|
3969
|
-
if (val &&
|
|
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 || !
|
|
4094
|
+
if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
|
|
3976
4095
|
for (const prop of optsArg.getProperties()) {
|
|
3977
|
-
if (!
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
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 || !
|
|
4155
|
+
if (!node || !Node7.isTypeReference(node)) return false;
|
|
4037
4156
|
const typeName = node.getTypeName();
|
|
4038
|
-
const name =
|
|
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 || !
|
|
4172
|
+
if (!node || !Node7.isTypeReference(node)) return null;
|
|
4054
4173
|
const typeName = node.getTypeName();
|
|
4055
|
-
const name =
|
|
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 || !
|
|
4184
|
+
if (!node || !Node7.isTypeReference(node)) return node;
|
|
4066
4185
|
const typeName = node.getTypeName();
|
|
4067
|
-
const name =
|
|
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 &&
|
|
4232
|
+
if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
|
|
4114
4233
|
for (const prop of optsArg.getProperties()) {
|
|
4115
|
-
if (
|
|
4234
|
+
if (Node7.isPropertyAssignment(prop) && prop.getName() === "type") {
|
|
4116
4235
|
const val = prop.getInitializer();
|
|
4117
|
-
if (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,88 +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 unwrapExpression(node) {
|
|
4188
|
-
let current = node;
|
|
4189
|
-
while (Node7.isAsExpression(current) || Node7.isSatisfiesExpression(current) || Node7.isParenthesizedExpression(current) || Node7.isTypeAssertion(current)) {
|
|
4190
|
-
current = current.getExpression();
|
|
4191
|
-
}
|
|
4192
|
-
return current;
|
|
4193
|
-
}
|
|
4194
|
-
function resolveReturnedClass(factoryDecl) {
|
|
4195
|
-
const body = factoryDecl.getBody();
|
|
4196
|
-
if (!body) return void 0;
|
|
4197
|
-
const returns = body.getDescendants().filter((n) => Node7.isReturnStatement(n));
|
|
4198
|
-
for (const ret of returns) {
|
|
4199
|
-
const expr = ret.getExpression();
|
|
4200
|
-
if (!expr) continue;
|
|
4201
|
-
const inner = unwrapExpression(expr);
|
|
4202
|
-
if (Node7.isClassExpression(inner)) {
|
|
4203
|
-
return inner;
|
|
4204
|
-
}
|
|
4205
|
-
if (Node7.isIdentifier(inner)) {
|
|
4206
|
-
const name = inner.getText();
|
|
4207
|
-
const decl = body.getDescendants().find((n) => Node7.isClassDeclaration(n) && n.getName() === name);
|
|
4208
|
-
if (decl) return decl;
|
|
4209
|
-
}
|
|
4210
|
-
}
|
|
4211
|
-
return void 0;
|
|
4212
|
-
}
|
|
4213
|
-
function resolveInheritedMethods(cls) {
|
|
4214
|
-
const expr = cls.getExtends()?.getExpression();
|
|
4215
|
-
if (!expr || !Node7.isCallExpression(expr)) return void 0;
|
|
4216
|
-
const callee = expr.getExpression();
|
|
4217
|
-
if (!Node7.isIdentifier(callee)) return void 0;
|
|
4218
|
-
const factoryDecl = callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node7.isFunctionDeclaration(n));
|
|
4219
|
-
if (!factoryDecl) return void 0;
|
|
4220
|
-
const returnedClass = resolveReturnedClass(factoryDecl);
|
|
4221
|
-
if (!returnedClass) return void 0;
|
|
4222
|
-
const classArgs = [];
|
|
4223
|
-
for (const arg of expr.getArguments()) {
|
|
4224
|
-
if (!Node7.isIdentifier(arg)) continue;
|
|
4225
|
-
const decl = arg.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node7.isClassDeclaration(n));
|
|
4226
|
-
if (decl) {
|
|
4227
|
-
classArgs.push({
|
|
4228
|
-
name: decl.getName() ?? arg.getText(),
|
|
4229
|
-
filePath: decl.getSourceFile().getFilePath()
|
|
4230
|
-
});
|
|
4231
|
-
}
|
|
4232
|
-
}
|
|
4233
|
-
return {
|
|
4234
|
-
methods: returnedClass.getMethods(),
|
|
4235
|
-
factoryName: callee.getText(),
|
|
4236
|
-
factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
|
|
4237
|
-
classArgs
|
|
4238
|
-
};
|
|
4239
|
-
}
|
|
4240
|
-
var mixinTypeProject;
|
|
4241
|
-
function getMixinTypeProject() {
|
|
4242
|
-
mixinTypeProject ??= new Project3({
|
|
4243
|
-
skipAddingFilesFromTsConfig: true,
|
|
4244
|
-
compilerOptions: { strict: true }
|
|
4245
|
-
});
|
|
4246
|
-
return mixinTypeProject;
|
|
4247
|
-
}
|
|
4248
|
-
function clearMixinTypeProject() {
|
|
4249
|
-
mixinTypeProject = void 0;
|
|
4250
|
-
}
|
|
4251
|
-
function resolveInstantiatedReturnType(cls, methodName) {
|
|
4252
|
-
const filePath = cls.getSourceFile().getFilePath();
|
|
4253
|
-
const className = cls.getName();
|
|
4254
|
-
if (!className) return void 0;
|
|
4255
|
-
const project = getMixinTypeProject();
|
|
4256
|
-
const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
|
|
4257
|
-
const typedCls = sourceFile?.getClass(className);
|
|
4258
|
-
if (!typedCls) return void 0;
|
|
4259
|
-
const prop = typedCls.getType().getProperty(methodName);
|
|
4260
|
-
if (!prop) return void 0;
|
|
4261
|
-
const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
|
|
4262
|
-
if (!returnType) return void 0;
|
|
4263
|
-
const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
|
|
4264
|
-
return unwrapped.getText(typedCls);
|
|
4265
|
-
}
|
|
4266
|
-
|
|
4267
4304
|
// src/discovery/zod-ast-to-ts.ts
|
|
4268
4305
|
import { Node as Node8, SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
4269
4306
|
function zodAstToTs(node) {
|
|
@@ -4767,9 +4804,11 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4767
4804
|
factoryFilePath: inherited.factoryFilePath,
|
|
4768
4805
|
classArgs: inherited.classArgs
|
|
4769
4806
|
} : void 0;
|
|
4807
|
+
const ownMethods = cls.getMethods();
|
|
4808
|
+
const ownNames = new Set(ownMethods.map((m) => m.getName()));
|
|
4770
4809
|
const methods = [
|
|
4771
|
-
...
|
|
4772
|
-
...(inherited?.methods ?? []).map((method) => ({ method, mixin: mixinBinding }))
|
|
4810
|
+
...ownMethods.map((method) => ({ method, mixin: mixinBinding })),
|
|
4811
|
+
...(inherited?.methods ?? []).filter((method) => !ownNames.has(method.getName())).map((method) => ({ method, mixin: mixinBinding }))
|
|
4773
4812
|
];
|
|
4774
4813
|
for (const { method, mixin } of methods) {
|
|
4775
4814
|
const verb = resolveVerb(method);
|
|
@@ -4995,7 +5034,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
4995
5034
|
}
|
|
4996
5035
|
|
|
4997
5036
|
// src/index.ts
|
|
4998
|
-
var VERSION = "0.17.
|
|
5037
|
+
var VERSION = "0.17.2";
|
|
4999
5038
|
|
|
5000
5039
|
// src/cli/codegen.ts
|
|
5001
5040
|
async function runCodegen(opts = {}) {
|