@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/CHANGELOG.md +48 -0
- package/dist/cli/main.cjs +228 -174
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +222 -168
- package/dist/cli/main.js.map +1 -1
- package/dist/extension/index.d.cts +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/{index-DCF9QSPY.d.cts → index-Dyf4ttwU.d.cts} +24 -1
- package/dist/{index-DCF9QSPY.d.ts → index-Dyf4ttwU.d.ts} +24 -1
- package/dist/index.cjs +228 -174
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +222 -168
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +228 -174
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +1 -1
- package/dist/nest/index.d.ts +1 -1
- package/dist/nest/index.js +222 -168
- 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,15 +3431,161 @@ 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
|
+
const namedClassArgs = {};
|
|
3508
|
+
for (const arg of expr.getArguments()) {
|
|
3509
|
+
const positional = resolveClassReference(arg);
|
|
3510
|
+
if (positional) {
|
|
3511
|
+
classArgs.push(positional);
|
|
3512
|
+
continue;
|
|
3513
|
+
}
|
|
3514
|
+
if (!Node5.isObjectLiteralExpression(arg)) continue;
|
|
3515
|
+
for (const prop of arg.getProperties()) {
|
|
3516
|
+
const named = resolvePropertyClassReference(prop);
|
|
3517
|
+
if (!named) continue;
|
|
3518
|
+
namedClassArgs[named.key] ??= named.ref;
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
return {
|
|
3522
|
+
methods: returnedClass.getMethods(),
|
|
3523
|
+
factoryName: callee.getText(),
|
|
3524
|
+
factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
|
|
3525
|
+
classArgs,
|
|
3526
|
+
namedClassArgs
|
|
3527
|
+
};
|
|
3528
|
+
}
|
|
3529
|
+
function resolveClassReference(node) {
|
|
3530
|
+
const expr = unwrapExpression(node);
|
|
3531
|
+
if (!Node5.isIdentifier(expr)) return void 0;
|
|
3532
|
+
const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && Node5.isClassDeclaration(n));
|
|
3533
|
+
if (!decl) return void 0;
|
|
3534
|
+
return {
|
|
3535
|
+
name: decl.getName() ?? expr.getText(),
|
|
3536
|
+
filePath: decl.getSourceFile().getFilePath()
|
|
3537
|
+
};
|
|
3538
|
+
}
|
|
3539
|
+
function resolvePropertyClassReference(prop) {
|
|
3540
|
+
if (Node5.isShorthandPropertyAssignment(prop)) {
|
|
3541
|
+
const ref2 = resolveClassReference(prop.getNameNode());
|
|
3542
|
+
return ref2 ? { key: prop.getName(), ref: ref2 } : void 0;
|
|
3543
|
+
}
|
|
3544
|
+
if (!Node5.isPropertyAssignment(prop)) return void 0;
|
|
3545
|
+
const init = prop.getInitializer();
|
|
3546
|
+
if (!init) return void 0;
|
|
3547
|
+
const ref = resolveClassReference(init);
|
|
3548
|
+
if (!ref) return void 0;
|
|
3549
|
+
const nameNode = prop.getNameNode();
|
|
3550
|
+
const key = Node5.isStringLiteral(nameNode) ? nameNode.getLiteralValue() : prop.getName();
|
|
3551
|
+
return { key, ref };
|
|
3552
|
+
}
|
|
3553
|
+
var mixinTypeProject;
|
|
3554
|
+
function getMixinTypeProject() {
|
|
3555
|
+
mixinTypeProject ??= new Project3({
|
|
3556
|
+
skipAddingFilesFromTsConfig: true,
|
|
3557
|
+
compilerOptions: { strict: true }
|
|
3558
|
+
});
|
|
3559
|
+
return mixinTypeProject;
|
|
3560
|
+
}
|
|
3561
|
+
function clearMixinTypeProject() {
|
|
3562
|
+
mixinTypeProject = void 0;
|
|
3563
|
+
}
|
|
3564
|
+
function resolveInstantiatedReturnType(cls, methodName) {
|
|
3565
|
+
const filePath = cls.getSourceFile().getFilePath();
|
|
3566
|
+
const className = cls.getName();
|
|
3567
|
+
if (!className) return void 0;
|
|
3568
|
+
const project = getMixinTypeProject();
|
|
3569
|
+
const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPathIfExists(filePath);
|
|
3570
|
+
const typedCls = sourceFile?.getClass(className);
|
|
3571
|
+
if (!typedCls) return void 0;
|
|
3572
|
+
const prop = typedCls.getType().getProperty(methodName);
|
|
3573
|
+
if (!prop) return void 0;
|
|
3574
|
+
const returnType = prop.getTypeAtLocation(typedCls).getCallSignatures()[0]?.getReturnType();
|
|
3575
|
+
if (!returnType) return void 0;
|
|
3576
|
+
const unwrapped = returnType.getSymbol()?.getName() === "Promise" ? returnType.getTypeArguments()[0] ?? returnType : returnType;
|
|
3577
|
+
return unwrapped.getText(typedCls);
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3434
3580
|
// src/discovery/filter-for.ts
|
|
3435
3581
|
function resolveMixinEntityClass(mixin, project) {
|
|
3436
|
-
const entityArg = mixin?.classArgs[0];
|
|
3582
|
+
const entityArg = mixin?.namedClassArgs?.entity ?? mixin?.classArgs[0];
|
|
3437
3583
|
if (!entityArg) return void 0;
|
|
3438
3584
|
const file = project.getSourceFile(entityArg.filePath) ?? project.addSourceFileAtPathIfExists(entityArg.filePath);
|
|
3439
3585
|
return file?.getClass(entityArg.name);
|
|
3440
3586
|
}
|
|
3441
3587
|
function classifyFilterForHint(typeInit) {
|
|
3442
|
-
if (
|
|
3588
|
+
if (Node6.isStringLiteral(typeInit)) {
|
|
3443
3589
|
switch (typeInit.getLiteralValue()) {
|
|
3444
3590
|
case "string":
|
|
3445
3591
|
return { kind: "string" };
|
|
@@ -3453,10 +3599,10 @@ function classifyFilterForHint(typeInit) {
|
|
|
3453
3599
|
return null;
|
|
3454
3600
|
}
|
|
3455
3601
|
}
|
|
3456
|
-
if (
|
|
3602
|
+
if (Node6.isArrayLiteralExpression(typeInit)) {
|
|
3457
3603
|
const values = [];
|
|
3458
3604
|
for (const el of typeInit.getElements()) {
|
|
3459
|
-
if (!
|
|
3605
|
+
if (!Node6.isStringLiteral(el)) return null;
|
|
3460
3606
|
values.push(el.getLiteralValue());
|
|
3461
3607
|
}
|
|
3462
3608
|
if (values.length === 0) return null;
|
|
@@ -3491,11 +3637,11 @@ function extractFilterForHints(classDecl, project) {
|
|
|
3491
3637
|
if (!filterForDec) continue;
|
|
3492
3638
|
const args = filterForDec.getArguments();
|
|
3493
3639
|
const keyArg = args[0];
|
|
3494
|
-
const inputKey = keyArg &&
|
|
3640
|
+
const inputKey = keyArg && Node6.isStringLiteral(keyArg) ? keyArg.getLiteralValue() : method.getName();
|
|
3495
3641
|
const optsArg = args[1];
|
|
3496
|
-
if (optsArg &&
|
|
3642
|
+
if (optsArg && Node6.isObjectLiteralExpression(optsArg)) {
|
|
3497
3643
|
const typeProp = optsArg.getProperty("type");
|
|
3498
|
-
if (typeProp &&
|
|
3644
|
+
if (typeProp && Node6.isPropertyAssignment(typeProp)) {
|
|
3499
3645
|
const typeInit = typeProp.getInitializer();
|
|
3500
3646
|
if (typeInit) {
|
|
3501
3647
|
const classified = classifyFilterForHint(typeInit);
|
|
@@ -3520,21 +3666,23 @@ function extractApplyFilterInfo(method, sourceFile, project, mixin) {
|
|
|
3520
3666
|
const args = filterDecorator.getArguments();
|
|
3521
3667
|
if (args.length === 0) continue;
|
|
3522
3668
|
const filterClassArg = args[0];
|
|
3523
|
-
if (!filterClassArg
|
|
3669
|
+
if (!filterClassArg) continue;
|
|
3670
|
+
const factoryStaticClass = resolveFactoryStaticClass(filterClassArg);
|
|
3671
|
+
if (!factoryStaticClass && !Node6.isIdentifier(filterClassArg)) continue;
|
|
3524
3672
|
let source = "query";
|
|
3525
3673
|
const optionsArg = args[1];
|
|
3526
|
-
if (optionsArg &&
|
|
3674
|
+
if (optionsArg && Node6.isObjectLiteralExpression(optionsArg)) {
|
|
3527
3675
|
const sourceProp = optionsArg.getProperty("source");
|
|
3528
|
-
if (sourceProp &&
|
|
3676
|
+
if (sourceProp && Node6.isPropertyAssignment(sourceProp)) {
|
|
3529
3677
|
const init = sourceProp.getInitializer();
|
|
3530
|
-
if (init &&
|
|
3678
|
+
if (init && Node6.isStringLiteral(init) && init.getLiteralValue() === "body") {
|
|
3531
3679
|
source = "body";
|
|
3532
3680
|
}
|
|
3533
3681
|
}
|
|
3534
3682
|
}
|
|
3535
3683
|
const filterClassName = filterClassArg.getText();
|
|
3536
|
-
const resolved = findType(filterClassName, declFile, project);
|
|
3537
|
-
const classDecl = resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg);
|
|
3684
|
+
const resolved = factoryStaticClass ? void 0 : findType(filterClassName, declFile, project);
|
|
3685
|
+
const classDecl = factoryStaticClass ?? (resolved?.kind === "class" ? resolved.decl : resolveLocalClassDeclaration(filterClassArg));
|
|
3538
3686
|
if (classDecl) {
|
|
3539
3687
|
let fieldTypes = extractClassPropertyTypes(classDecl, project);
|
|
3540
3688
|
if (fieldTypes.length === 0) {
|
|
@@ -3590,22 +3738,22 @@ function resolveRelationEntity(prop, sourceFile, project) {
|
|
|
3590
3738
|
const args = dec.getArguments();
|
|
3591
3739
|
if (args.length === 0) continue;
|
|
3592
3740
|
const arg = args[0];
|
|
3593
|
-
if (
|
|
3741
|
+
if (Node6.isObjectLiteralExpression(arg)) {
|
|
3594
3742
|
const entityProp = arg.getProperty("entity");
|
|
3595
|
-
if (entityProp &&
|
|
3743
|
+
if (entityProp && Node6.isPropertyAssignment(entityProp)) {
|
|
3596
3744
|
const init = entityProp.getInitializer();
|
|
3597
|
-
if (init &&
|
|
3745
|
+
if (init && Node6.isArrowFunction(init)) {
|
|
3598
3746
|
const body = init.getBody();
|
|
3599
|
-
if (
|
|
3747
|
+
if (Node6.isIdentifier(body)) {
|
|
3600
3748
|
const resolved = findType(body.getText(), prop.getSourceFile(), project);
|
|
3601
3749
|
if (resolved?.kind === "class") return resolved.decl;
|
|
3602
3750
|
}
|
|
3603
3751
|
}
|
|
3604
3752
|
}
|
|
3605
3753
|
}
|
|
3606
|
-
if (
|
|
3754
|
+
if (Node6.isArrowFunction(arg)) {
|
|
3607
3755
|
const body = arg.getBody();
|
|
3608
|
-
if (
|
|
3756
|
+
if (Node6.isIdentifier(body)) {
|
|
3609
3757
|
const resolved = findType(body.getText(), prop.getSourceFile(), project);
|
|
3610
3758
|
if (resolved?.kind === "class") return resolved.decl;
|
|
3611
3759
|
}
|
|
@@ -3624,15 +3772,15 @@ function extractClassPropertyTypes(classDecl, project) {
|
|
|
3624
3772
|
return fields;
|
|
3625
3773
|
}
|
|
3626
3774
|
function resolveLocalClassDeclaration(identifier) {
|
|
3627
|
-
if (!
|
|
3628
|
-
return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 &&
|
|
3775
|
+
if (!Node6.isIdentifier(identifier)) return void 0;
|
|
3776
|
+
return identifier.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && Node6.isClassDeclaration(n));
|
|
3629
3777
|
}
|
|
3630
3778
|
function resolveDeclaredEntity(optionsArg, filterClass, project) {
|
|
3631
|
-
if (!
|
|
3779
|
+
if (!Node6.isObjectLiteralExpression(optionsArg)) return void 0;
|
|
3632
3780
|
const entityProp = optionsArg.getProperty("entity");
|
|
3633
|
-
if (!entityProp || !
|
|
3781
|
+
if (!entityProp || !Node6.isPropertyAssignment(entityProp)) return void 0;
|
|
3634
3782
|
const entityInit = entityProp.getInitializer();
|
|
3635
|
-
if (!entityInit || !
|
|
3783
|
+
if (!entityInit || !Node6.isIdentifier(entityInit)) return void 0;
|
|
3636
3784
|
const resolved = findType(entityInit.getText(), filterClass.getSourceFile(), project);
|
|
3637
3785
|
if (!resolved || resolved.kind !== "class") return void 0;
|
|
3638
3786
|
return resolved.decl;
|
|
@@ -3643,7 +3791,7 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
|
|
|
3643
3791
|
const args = filterableDecorator.getArguments();
|
|
3644
3792
|
if (args.length === 0) return [];
|
|
3645
3793
|
const optionsArg = args[0];
|
|
3646
|
-
if (!
|
|
3794
|
+
if (!Node6.isObjectLiteralExpression(optionsArg)) return [];
|
|
3647
3795
|
const entityDecl = entityOverride ?? resolveDeclaredEntity(optionsArg, filterClass, project);
|
|
3648
3796
|
if (!entityDecl) return [];
|
|
3649
3797
|
const fields = collectEntityFields(
|
|
@@ -3656,17 +3804,17 @@ function extractFilterableEntityFields(filterClass, project, entityOverride) {
|
|
|
3656
3804
|
const relationsDecorator = filterClass.getDecorators().find((d) => d.getName() === "Relations");
|
|
3657
3805
|
if (relationsDecorator) {
|
|
3658
3806
|
const relArgs = relationsDecorator.getArguments();
|
|
3659
|
-
if (relArgs.length > 0 &&
|
|
3807
|
+
if (relArgs.length > 0 && Node6.isObjectLiteralExpression(relArgs[0])) {
|
|
3660
3808
|
for (const relProp of relArgs[0].getProperties()) {
|
|
3661
|
-
if (!
|
|
3809
|
+
if (!Node6.isPropertyAssignment(relProp)) continue;
|
|
3662
3810
|
const relInit = relProp.getInitializer();
|
|
3663
|
-
if (!relInit || !
|
|
3811
|
+
if (!relInit || !Node6.isObjectLiteralExpression(relInit)) continue;
|
|
3664
3812
|
const keysProp = relInit.getProperty("keys");
|
|
3665
|
-
if (!keysProp || !
|
|
3813
|
+
if (!keysProp || !Node6.isPropertyAssignment(keysProp)) continue;
|
|
3666
3814
|
const keysInit = keysProp.getInitializer();
|
|
3667
|
-
if (!keysInit || !
|
|
3815
|
+
if (!keysInit || !Node6.isArrayLiteralExpression(keysInit)) continue;
|
|
3668
3816
|
for (const el of keysInit.getElements()) {
|
|
3669
|
-
if (
|
|
3817
|
+
if (Node6.isStringLiteral(el)) {
|
|
3670
3818
|
fields.push(toFilterFieldType(el.getLiteralValue(), { kind: "unknown" }));
|
|
3671
3819
|
}
|
|
3672
3820
|
}
|
|
@@ -3707,22 +3855,22 @@ var PASSTHROUGH_UTILITY = /* @__PURE__ */ new Set([
|
|
|
3707
3855
|
]);
|
|
3708
3856
|
function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /* @__PURE__ */ new Map()) {
|
|
3709
3857
|
if (depth <= 0) return "unknown";
|
|
3710
|
-
if (
|
|
3858
|
+
if (Node7.isArrayTypeNode(typeNode)) {
|
|
3711
3859
|
const elementType = typeNode.getElementTypeNode();
|
|
3712
3860
|
return `Array<${resolveTypeNodeToString(elementType, sourceFile, project, depth, subst)}>`;
|
|
3713
3861
|
}
|
|
3714
|
-
if (
|
|
3862
|
+
if (Node7.isUnionTypeNode(typeNode)) {
|
|
3715
3863
|
return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" | ");
|
|
3716
3864
|
}
|
|
3717
|
-
if (
|
|
3865
|
+
if (Node7.isIntersectionTypeNode(typeNode)) {
|
|
3718
3866
|
return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" & ");
|
|
3719
3867
|
}
|
|
3720
|
-
if (
|
|
3868
|
+
if (Node7.isParenthesizedTypeNode(typeNode)) {
|
|
3721
3869
|
return `(${resolveTypeNodeToString(typeNode.getTypeNode(), sourceFile, project, depth, subst)})`;
|
|
3722
3870
|
}
|
|
3723
|
-
if (
|
|
3871
|
+
if (Node7.isTypeReference(typeNode)) {
|
|
3724
3872
|
const typeName = typeNode.getTypeName();
|
|
3725
|
-
const name =
|
|
3873
|
+
const name = Node7.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
|
|
3726
3874
|
const bound = subst.get(name);
|
|
3727
3875
|
if (bound !== void 0) return bound;
|
|
3728
3876
|
if (name === "string" || name === "number" || name === "boolean") return name;
|
|
@@ -3745,10 +3893,10 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
|
|
|
3745
3893
|
dbg("unresolvable type:", name, "in", sourceFile.getFilePath());
|
|
3746
3894
|
return "unknown";
|
|
3747
3895
|
}
|
|
3748
|
-
if (
|
|
3896
|
+
if (Node7.isTypeLiteral(typeNode)) {
|
|
3749
3897
|
const members = [];
|
|
3750
3898
|
for (const member of typeNode.getMembers()) {
|
|
3751
|
-
if (
|
|
3899
|
+
if (Node7.isPropertySignature(member)) {
|
|
3752
3900
|
const memberTypeNode = member.getTypeNode();
|
|
3753
3901
|
const memberType = memberTypeNode ? resolveTypeNodeToString(memberTypeNode, sourceFile, project, depth, subst) : "unknown";
|
|
3754
3902
|
members.push(`${member.getName()}${member.hasQuestionToken() ? "?" : ""}: ${memberType}`);
|
|
@@ -3848,7 +3996,7 @@ function extractQueryType(method, sourceFile, project) {
|
|
|
3848
3996
|
if (!queryDecorator) continue;
|
|
3849
3997
|
const queryArgs = queryDecorator.getArguments();
|
|
3850
3998
|
const nameArg = queryArgs[0];
|
|
3851
|
-
if (!nameArg || !
|
|
3999
|
+
if (!nameArg || !Node7.isStringLiteral(nameArg)) continue;
|
|
3852
4000
|
const queryName = nameArg.getLiteralValue();
|
|
3853
4001
|
const typeNode = param.getTypeNode();
|
|
3854
4002
|
const queryType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
|
|
@@ -3859,7 +4007,7 @@ function extractQueryType(method, sourceFile, project) {
|
|
|
3859
4007
|
function isParamOptional(param) {
|
|
3860
4008
|
if (param.hasQuestionToken() || param.hasInitializer()) return true;
|
|
3861
4009
|
const typeNode = param.getTypeNode();
|
|
3862
|
-
if (typeNode &&
|
|
4010
|
+
if (typeNode && Node7.isUnionTypeNode(typeNode)) {
|
|
3863
4011
|
return typeNode.getTypeNodes().some((t) => t.getKind() === SyntaxKind3.UndefinedKeyword);
|
|
3864
4012
|
}
|
|
3865
4013
|
return false;
|
|
@@ -3872,7 +4020,7 @@ function extractParamsType(method, sourceFile, project) {
|
|
|
3872
4020
|
const paramArgs = paramDecorator.getArguments();
|
|
3873
4021
|
if (paramArgs.length === 0) continue;
|
|
3874
4022
|
const nameArg = paramArgs[0];
|
|
3875
|
-
if (!
|
|
4023
|
+
if (!Node7.isStringLiteral(nameArg)) continue;
|
|
3876
4024
|
const paramName = nameArg.getLiteralValue();
|
|
3877
4025
|
const typeNode = param.getTypeNode();
|
|
3878
4026
|
const paramType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
|
|
@@ -3893,28 +4041,28 @@ function extractUploadedFiles(method) {
|
|
|
3893
4041
|
for (const decorator of method.getDecorators()) {
|
|
3894
4042
|
if (decorator.getName() !== "UseInterceptors") continue;
|
|
3895
4043
|
for (const arg of decorator.getArguments()) {
|
|
3896
|
-
if (!
|
|
4044
|
+
if (!Node7.isCallExpression(arg)) continue;
|
|
3897
4045
|
const interceptor = arg.getExpression().getText();
|
|
3898
4046
|
const callArgs = arg.getArguments();
|
|
3899
4047
|
const firstArg2 = callArgs[0];
|
|
3900
4048
|
if (interceptor === "FileInterceptor") {
|
|
3901
|
-
if (firstArg2 &&
|
|
4049
|
+
if (firstArg2 && Node7.isStringLiteral(firstArg2)) {
|
|
3902
4050
|
entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
|
|
3903
4051
|
multipart = true;
|
|
3904
4052
|
}
|
|
3905
4053
|
} else if (interceptor === "FilesInterceptor") {
|
|
3906
|
-
if (firstArg2 &&
|
|
4054
|
+
if (firstArg2 && Node7.isStringLiteral(firstArg2)) {
|
|
3907
4055
|
entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
|
|
3908
4056
|
multipart = true;
|
|
3909
4057
|
}
|
|
3910
4058
|
} else if (interceptor === "FileFieldsInterceptor") {
|
|
3911
|
-
if (firstArg2 &&
|
|
4059
|
+
if (firstArg2 && Node7.isArrayLiteralExpression(firstArg2)) {
|
|
3912
4060
|
for (const el of firstArg2.getElements()) {
|
|
3913
|
-
if (!
|
|
4061
|
+
if (!Node7.isObjectLiteralExpression(el)) continue;
|
|
3914
4062
|
const nameProp = el.getProperty("name");
|
|
3915
|
-
if (nameProp &&
|
|
4063
|
+
if (nameProp && Node7.isPropertyAssignment(nameProp)) {
|
|
3916
4064
|
const init = nameProp.getInitializer();
|
|
3917
|
-
if (init &&
|
|
4065
|
+
if (init && Node7.isStringLiteral(init)) {
|
|
3918
4066
|
entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
|
|
3919
4067
|
}
|
|
3920
4068
|
}
|
|
@@ -3934,13 +4082,13 @@ function extractResponseType(method, sourceFile, project) {
|
|
|
3934
4082
|
if (apiResponseDecorator) {
|
|
3935
4083
|
const args = apiResponseDecorator.getArguments();
|
|
3936
4084
|
const optsArg = args[0];
|
|
3937
|
-
if (optsArg &&
|
|
4085
|
+
if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
|
|
3938
4086
|
for (const prop of optsArg.getProperties()) {
|
|
3939
|
-
if (!
|
|
4087
|
+
if (!Node7.isPropertyAssignment(prop)) continue;
|
|
3940
4088
|
if (prop.getName() !== "type") continue;
|
|
3941
4089
|
const val = prop.getInitializer();
|
|
3942
4090
|
if (!val) continue;
|
|
3943
|
-
if (
|
|
4091
|
+
if (Node7.isArrayLiteralExpression(val)) {
|
|
3944
4092
|
const elements = val.getElements();
|
|
3945
4093
|
const firstEl = elements[0];
|
|
3946
4094
|
if (elements.length > 0 && firstEl !== void 0) {
|
|
@@ -3961,24 +4109,24 @@ function extractResponseType(method, sourceFile, project) {
|
|
|
3961
4109
|
}
|
|
3962
4110
|
function apiResponseStatus(decorator) {
|
|
3963
4111
|
const optsArg = decorator.getArguments()[0];
|
|
3964
|
-
if (!optsArg || !
|
|
4112
|
+
if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
|
|
3965
4113
|
for (const prop of optsArg.getProperties()) {
|
|
3966
|
-
if (!
|
|
4114
|
+
if (!Node7.isPropertyAssignment(prop)) continue;
|
|
3967
4115
|
if (prop.getName() !== "status") continue;
|
|
3968
4116
|
const val = prop.getInitializer();
|
|
3969
|
-
if (val &&
|
|
4117
|
+
if (val && Node7.isNumericLiteral(val)) return Number(val.getLiteralValue());
|
|
3970
4118
|
}
|
|
3971
4119
|
return null;
|
|
3972
4120
|
}
|
|
3973
4121
|
function apiResponseTypeNode(decorator) {
|
|
3974
4122
|
const optsArg = decorator.getArguments()[0];
|
|
3975
|
-
if (!optsArg || !
|
|
4123
|
+
if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
|
|
3976
4124
|
for (const prop of optsArg.getProperties()) {
|
|
3977
|
-
if (!
|
|
4125
|
+
if (!Node7.isPropertyAssignment(prop)) continue;
|
|
3978
4126
|
if (prop.getName() !== "type") continue;
|
|
3979
4127
|
const val = prop.getInitializer();
|
|
3980
4128
|
if (!val) return null;
|
|
3981
|
-
if (
|
|
4129
|
+
if (Node7.isArrayLiteralExpression(val)) {
|
|
3982
4130
|
const first = val.getElements()[0];
|
|
3983
4131
|
return first ? { node: first, isArray: true } : null;
|
|
3984
4132
|
}
|
|
@@ -3996,7 +4144,7 @@ function extractErrorType(method, sourceFile, project) {
|
|
|
3996
4144
|
const inner = resolveIdentifierToClassType(typeInfo.node, sourceFile, project, 3);
|
|
3997
4145
|
const type = typeInfo.isArray ? `Array<${inner}>` : inner;
|
|
3998
4146
|
let ref = null;
|
|
3999
|
-
if (
|
|
4147
|
+
if (Node7.isIdentifier(typeInfo.node)) {
|
|
4000
4148
|
const name = typeInfo.node.getText();
|
|
4001
4149
|
const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
|
|
4002
4150
|
if (localDecl?.isExported()) {
|
|
@@ -4013,7 +4161,7 @@ function extractErrorType(method, sourceFile, project) {
|
|
|
4013
4161
|
return null;
|
|
4014
4162
|
}
|
|
4015
4163
|
function resolveIdentifierToClassType(node, sourceFile, project, depth) {
|
|
4016
|
-
if (!
|
|
4164
|
+
if (!Node7.isIdentifier(node)) return "unknown";
|
|
4017
4165
|
const name = node.getText();
|
|
4018
4166
|
const resolved = findType(name, sourceFile, project);
|
|
4019
4167
|
if (resolved) {
|
|
@@ -4033,9 +4181,9 @@ var STREAM_ENVELOPES = /* @__PURE__ */ new Set(["MessageEvent", "MessageEventLik
|
|
|
4033
4181
|
var BINARY_RESPONSE_TYPES = /* @__PURE__ */ new Set(["StreamableFile", "Buffer"]);
|
|
4034
4182
|
function detectBinaryResponse(method) {
|
|
4035
4183
|
const node = unwrapNamedContainer(method.getReturnTypeNode(), /* @__PURE__ */ new Set(["Promise"]));
|
|
4036
|
-
if (!node || !
|
|
4184
|
+
if (!node || !Node7.isTypeReference(node)) return false;
|
|
4037
4185
|
const typeName = node.getTypeName();
|
|
4038
|
-
const name =
|
|
4186
|
+
const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
|
|
4039
4187
|
return BINARY_RESPONSE_TYPES.has(name);
|
|
4040
4188
|
}
|
|
4041
4189
|
function detectStreamElement(method) {
|
|
@@ -4050,9 +4198,9 @@ function detectStreamElement(method) {
|
|
|
4050
4198
|
return null;
|
|
4051
4199
|
}
|
|
4052
4200
|
function streamContainerElement(node) {
|
|
4053
|
-
if (!node || !
|
|
4201
|
+
if (!node || !Node7.isTypeReference(node)) return null;
|
|
4054
4202
|
const typeName = node.getTypeName();
|
|
4055
|
-
const name =
|
|
4203
|
+
const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
|
|
4056
4204
|
if (STREAM_CONTAINERS.has(name) || STREAM_CONTAINERS_GENERATOR.has(name)) {
|
|
4057
4205
|
return node.getTypeArguments()[0] ?? null;
|
|
4058
4206
|
}
|
|
@@ -4062,9 +4210,9 @@ function hasAsQueryDecorator(method) {
|
|
|
4062
4210
|
return method.getDecorators().some((d) => d.getName() === "AsQuery");
|
|
4063
4211
|
}
|
|
4064
4212
|
function unwrapNamedContainer(node, names) {
|
|
4065
|
-
if (!node || !
|
|
4213
|
+
if (!node || !Node7.isTypeReference(node)) return node;
|
|
4066
4214
|
const typeName = node.getTypeName();
|
|
4067
|
-
const name =
|
|
4215
|
+
const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
|
|
4068
4216
|
if (names.has(name)) {
|
|
4069
4217
|
return node.getTypeArguments()[0] ?? node;
|
|
4070
4218
|
}
|
|
@@ -4110,11 +4258,11 @@ function extractDtoContract(method, sourceFile, project, mixin) {
|
|
|
4110
4258
|
if (apiResp) {
|
|
4111
4259
|
const args = apiResp.getArguments();
|
|
4112
4260
|
const optsArg = args[0];
|
|
4113
|
-
if (optsArg &&
|
|
4261
|
+
if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
|
|
4114
4262
|
for (const prop of optsArg.getProperties()) {
|
|
4115
|
-
if (
|
|
4263
|
+
if (Node7.isPropertyAssignment(prop) && prop.getName() === "type") {
|
|
4116
4264
|
const val = prop.getInitializer();
|
|
4117
|
-
if (val &&
|
|
4265
|
+
if (val && Node7.isIdentifier(val)) {
|
|
4118
4266
|
const name = val.getText();
|
|
4119
4267
|
const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
|
|
4120
4268
|
if (localDecl?.isExported()) {
|
|
@@ -4182,101 +4330,6 @@ function resolveParamClass(method, decoratorName, sourceFile, project) {
|
|
|
4182
4330
|
return null;
|
|
4183
4331
|
}
|
|
4184
4332
|
|
|
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
4333
|
// src/discovery/zod-ast-to-ts.ts
|
|
4281
4334
|
import { Node as Node8, SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
4282
4335
|
function zodAstToTs(node) {
|
|
@@ -4778,7 +4831,8 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4778
4831
|
const mixinBinding = inherited ? {
|
|
4779
4832
|
factoryName: inherited.factoryName,
|
|
4780
4833
|
factoryFilePath: inherited.factoryFilePath,
|
|
4781
|
-
classArgs: inherited.classArgs
|
|
4834
|
+
classArgs: inherited.classArgs,
|
|
4835
|
+
namedClassArgs: inherited.namedClassArgs
|
|
4782
4836
|
} : void 0;
|
|
4783
4837
|
const ownMethods = cls.getMethods();
|
|
4784
4838
|
const ownNames = new Set(ownMethods.map((m) => m.getName()));
|
|
@@ -5010,7 +5064,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5010
5064
|
}
|
|
5011
5065
|
|
|
5012
5066
|
// src/index.ts
|
|
5013
|
-
var VERSION = "0.
|
|
5067
|
+
var VERSION = "0.18.0";
|
|
5014
5068
|
|
|
5015
5069
|
// src/cli/codegen.ts
|
|
5016
5070
|
async function runCodegen(opts = {}) {
|