@dudousxd/nestjs-codegen 0.17.2 → 0.19.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 +76 -0
- package/dist/cli/main.cjs +104 -19
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +104 -19
- 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 +104 -19
- 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 +104 -19
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +104 -19
- 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 +104 -19
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-
|
|
1
|
+
export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-Dyf4ttwU.cjs';
|
|
2
2
|
import 'ts-morph';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-
|
|
1
|
+
export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-Dyf4ttwU.js';
|
|
2
2
|
import 'ts-morph';
|
|
@@ -550,11 +550,34 @@ interface ContractDescriptor {
|
|
|
550
550
|
interface MixinBinding {
|
|
551
551
|
factoryName: string;
|
|
552
552
|
factoryFilePath: string;
|
|
553
|
-
/**
|
|
553
|
+
/**
|
|
554
|
+
* POSITIONAL call-site arguments that resolve to a class declaration, in
|
|
555
|
+
* argument order — `createTableController(Entity, { dto })` yields one entry.
|
|
556
|
+
*/
|
|
554
557
|
classArgs: Array<{
|
|
555
558
|
name: string;
|
|
556
559
|
filePath: string;
|
|
557
560
|
}>;
|
|
561
|
+
/**
|
|
562
|
+
* Class-valued properties of an OPTIONS-OBJECT call-site argument, keyed by
|
|
563
|
+
* property name — `createTableController({ entity: Entity, filter: Filter })`
|
|
564
|
+
* yields `entity` and `filter`.
|
|
565
|
+
*
|
|
566
|
+
* Keyed by name rather than flattened into {@link classArgs} because the key
|
|
567
|
+
* is what identifies the argument's role: with a single object argument there
|
|
568
|
+
* is no positional order to read a role out of, and consumers want different
|
|
569
|
+
* properties. This package resolves `entity` (to derive the filter fields of a
|
|
570
|
+
* factory-generated `@Filterable({ entity })`, whose `entity` names the
|
|
571
|
+
* factory's own parameter and resolves to nothing on its own);
|
|
572
|
+
* `@dudousxd/nestjs-filter-codegen` reads `filter` off this same binding to
|
|
573
|
+
* resolve a call-site-supplied filter class. Empty for a purely positional
|
|
574
|
+
* call; both maps are populated independently, so a factory may be called
|
|
575
|
+
* either way.
|
|
576
|
+
*/
|
|
577
|
+
namedClassArgs: Record<string, {
|
|
578
|
+
name: string;
|
|
579
|
+
filePath: string;
|
|
580
|
+
}>;
|
|
558
581
|
}
|
|
559
582
|
interface ControllerRef {
|
|
560
583
|
className: string;
|
|
@@ -550,11 +550,34 @@ interface ContractDescriptor {
|
|
|
550
550
|
interface MixinBinding {
|
|
551
551
|
factoryName: string;
|
|
552
552
|
factoryFilePath: string;
|
|
553
|
-
/**
|
|
553
|
+
/**
|
|
554
|
+
* POSITIONAL call-site arguments that resolve to a class declaration, in
|
|
555
|
+
* argument order — `createTableController(Entity, { dto })` yields one entry.
|
|
556
|
+
*/
|
|
554
557
|
classArgs: Array<{
|
|
555
558
|
name: string;
|
|
556
559
|
filePath: string;
|
|
557
560
|
}>;
|
|
561
|
+
/**
|
|
562
|
+
* Class-valued properties of an OPTIONS-OBJECT call-site argument, keyed by
|
|
563
|
+
* property name — `createTableController({ entity: Entity, filter: Filter })`
|
|
564
|
+
* yields `entity` and `filter`.
|
|
565
|
+
*
|
|
566
|
+
* Keyed by name rather than flattened into {@link classArgs} because the key
|
|
567
|
+
* is what identifies the argument's role: with a single object argument there
|
|
568
|
+
* is no positional order to read a role out of, and consumers want different
|
|
569
|
+
* properties. This package resolves `entity` (to derive the filter fields of a
|
|
570
|
+
* factory-generated `@Filterable({ entity })`, whose `entity` names the
|
|
571
|
+
* factory's own parameter and resolves to nothing on its own);
|
|
572
|
+
* `@dudousxd/nestjs-filter-codegen` reads `filter` off this same binding to
|
|
573
|
+
* resolve a call-site-supplied filter class. Empty for a purely positional
|
|
574
|
+
* call; both maps are populated independently, so a factory may be called
|
|
575
|
+
* either way.
|
|
576
|
+
*/
|
|
577
|
+
namedClassArgs: Record<string, {
|
|
578
|
+
name: string;
|
|
579
|
+
filePath: string;
|
|
580
|
+
}>;
|
|
558
581
|
}
|
|
559
582
|
interface ControllerRef {
|
|
560
583
|
className: string;
|
package/dist/index.cjs
CHANGED
|
@@ -3526,10 +3526,46 @@ function resolveReturnedClass(factoryDecl) {
|
|
|
3526
3526
|
}
|
|
3527
3527
|
return void 0;
|
|
3528
3528
|
}
|
|
3529
|
+
function factoryCalleeName(call) {
|
|
3530
|
+
const callee = unwrapExpression(call.getExpression());
|
|
3531
|
+
if (import_ts_morph6.Node.isIdentifier(callee)) return callee;
|
|
3532
|
+
if (import_ts_morph6.Node.isPropertyAccessExpression(callee)) {
|
|
3533
|
+
const name = callee.getNameNode();
|
|
3534
|
+
return import_ts_morph6.Node.isIdentifier(name) ? name : void 0;
|
|
3535
|
+
}
|
|
3536
|
+
return void 0;
|
|
3537
|
+
}
|
|
3529
3538
|
function resolveFactoryDeclaration(call) {
|
|
3530
|
-
const
|
|
3531
|
-
|
|
3532
|
-
|
|
3539
|
+
const name = factoryCalleeName(call);
|
|
3540
|
+
return name ? resolveFactoryFromName(name, /* @__PURE__ */ new Set()) : void 0;
|
|
3541
|
+
}
|
|
3542
|
+
function resolveFactoryFromName(name, seen) {
|
|
3543
|
+
if (seen.has(name)) return void 0;
|
|
3544
|
+
seen.add(name);
|
|
3545
|
+
const decls = name.getDefinitions().map((d) => d.getDeclarationNode()).filter((n) => n !== void 0);
|
|
3546
|
+
for (const decl of decls) {
|
|
3547
|
+
if (import_ts_morph6.Node.isFunctionDeclaration(decl) || import_ts_morph6.Node.isMethodDeclaration(decl)) return decl;
|
|
3548
|
+
if (import_ts_morph6.Node.isPropertyAssignment(decl)) {
|
|
3549
|
+
const init = decl.getInitializer();
|
|
3550
|
+
const inner = init ? unwrapExpression(init) : void 0;
|
|
3551
|
+
if (inner && import_ts_morph6.Node.isIdentifier(inner)) {
|
|
3552
|
+
const resolved = resolveFactoryFromName(inner, seen);
|
|
3553
|
+
if (resolved) return resolved;
|
|
3554
|
+
}
|
|
3555
|
+
continue;
|
|
3556
|
+
}
|
|
3557
|
+
if (import_ts_morph6.Node.isShorthandPropertyAssignment(decl)) {
|
|
3558
|
+
const nameNode = decl.getNameNode();
|
|
3559
|
+
const resolved = import_ts_morph6.Node.isIdentifier(nameNode) ? resolveFactoryFromName(nameNode, seen) : void 0;
|
|
3560
|
+
if (resolved) return resolved;
|
|
3561
|
+
}
|
|
3562
|
+
}
|
|
3563
|
+
return void 0;
|
|
3564
|
+
}
|
|
3565
|
+
function warnUnresolvedFactory(cls, calleeText, reason) {
|
|
3566
|
+
console.warn(
|
|
3567
|
+
`[nestjs-codegen/fast] ${cls.getName() ?? "<anonymous class>"} in ${cls.getSourceFile().getFilePath()} extends ${calleeText}(...) but ${reason} \u2014 it contributes NO routes to the generated client. Resolvable factory callees: a name (\`factory(...)\`), a namespace or object property (\`ns.factory(...)\`), or a static method (\`Factory.create(...)\`), each resolving to a function or method declaration that returns a class.`
|
|
3568
|
+
);
|
|
3533
3569
|
}
|
|
3534
3570
|
function resolveFactoryStaticClass(node) {
|
|
3535
3571
|
if (!import_ts_morph6.Node.isPropertyAccessExpression(node)) return void 0;
|
|
@@ -3551,30 +3587,78 @@ function resolveFactoryStaticClass(node) {
|
|
|
3551
3587
|
function resolveInheritedMethods(cls) {
|
|
3552
3588
|
const expr = resolveHeritageCall(cls.getExtends()?.getExpression());
|
|
3553
3589
|
if (!expr) return void 0;
|
|
3554
|
-
const
|
|
3555
|
-
|
|
3590
|
+
const isController = cls.getDecorator("Controller") !== void 0;
|
|
3591
|
+
const calleeText = expr.getExpression().getText();
|
|
3556
3592
|
const factoryDecl = resolveFactoryDeclaration(expr);
|
|
3557
|
-
if (!factoryDecl)
|
|
3593
|
+
if (!factoryDecl) {
|
|
3594
|
+
if (isController) {
|
|
3595
|
+
warnUnresolvedFactory(
|
|
3596
|
+
cls,
|
|
3597
|
+
calleeText,
|
|
3598
|
+
factoryCalleeName(expr) ? "its callee does not resolve to a function or method declaration" : "its callee is not a name that can be resolved statically"
|
|
3599
|
+
);
|
|
3600
|
+
}
|
|
3601
|
+
return void 0;
|
|
3602
|
+
}
|
|
3558
3603
|
const returnedClass = resolveReturnedClass(factoryDecl);
|
|
3559
|
-
if (!returnedClass)
|
|
3604
|
+
if (!returnedClass) {
|
|
3605
|
+
if (isController) {
|
|
3606
|
+
warnUnresolvedFactory(cls, calleeText, "that factory does not return a class declaration");
|
|
3607
|
+
}
|
|
3608
|
+
return void 0;
|
|
3609
|
+
}
|
|
3560
3610
|
const classArgs = [];
|
|
3611
|
+
const namedClassArgs = {};
|
|
3561
3612
|
for (const arg of expr.getArguments()) {
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3613
|
+
const positional = resolveClassReference(arg);
|
|
3614
|
+
if (positional) {
|
|
3615
|
+
classArgs.push(positional);
|
|
3616
|
+
continue;
|
|
3617
|
+
}
|
|
3618
|
+
if (!import_ts_morph6.Node.isObjectLiteralExpression(arg)) continue;
|
|
3619
|
+
for (const prop of arg.getProperties()) {
|
|
3620
|
+
const named = resolvePropertyClassReference(prop);
|
|
3621
|
+
if (!named) continue;
|
|
3622
|
+
namedClassArgs[named.key] ??= named.ref;
|
|
3569
3623
|
}
|
|
3570
3624
|
}
|
|
3571
3625
|
return {
|
|
3572
3626
|
methods: returnedClass.getMethods(),
|
|
3573
|
-
|
|
3627
|
+
// The DECLARATION's name, not the call-site text: consumers look the factory
|
|
3628
|
+
// back up by name inside `factoryFilePath`, which a qualified
|
|
3629
|
+
// `tables.createTableController` would never match. For a bare identifier
|
|
3630
|
+
// the two coincide (bar an import alias, where the declaration name is the
|
|
3631
|
+
// one that resolves anyway).
|
|
3632
|
+
factoryName: factoryDecl.getName() ?? calleeText,
|
|
3574
3633
|
factoryFilePath: factoryDecl.getSourceFile().getFilePath(),
|
|
3575
|
-
classArgs
|
|
3634
|
+
classArgs,
|
|
3635
|
+
namedClassArgs
|
|
3576
3636
|
};
|
|
3577
3637
|
}
|
|
3638
|
+
function resolveClassReference(node) {
|
|
3639
|
+
const expr = unwrapExpression(node);
|
|
3640
|
+
if (!import_ts_morph6.Node.isIdentifier(expr)) return void 0;
|
|
3641
|
+
const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => n !== void 0 && import_ts_morph6.Node.isClassDeclaration(n));
|
|
3642
|
+
if (!decl) return void 0;
|
|
3643
|
+
return {
|
|
3644
|
+
name: decl.getName() ?? expr.getText(),
|
|
3645
|
+
filePath: decl.getSourceFile().getFilePath()
|
|
3646
|
+
};
|
|
3647
|
+
}
|
|
3648
|
+
function resolvePropertyClassReference(prop) {
|
|
3649
|
+
if (import_ts_morph6.Node.isShorthandPropertyAssignment(prop)) {
|
|
3650
|
+
const ref2 = resolveClassReference(prop.getNameNode());
|
|
3651
|
+
return ref2 ? { key: prop.getName(), ref: ref2 } : void 0;
|
|
3652
|
+
}
|
|
3653
|
+
if (!import_ts_morph6.Node.isPropertyAssignment(prop)) return void 0;
|
|
3654
|
+
const init = prop.getInitializer();
|
|
3655
|
+
if (!init) return void 0;
|
|
3656
|
+
const ref = resolveClassReference(init);
|
|
3657
|
+
if (!ref) return void 0;
|
|
3658
|
+
const nameNode = prop.getNameNode();
|
|
3659
|
+
const key = import_ts_morph6.Node.isStringLiteral(nameNode) ? nameNode.getLiteralValue() : prop.getName();
|
|
3660
|
+
return { key, ref };
|
|
3661
|
+
}
|
|
3578
3662
|
var mixinTypeProject;
|
|
3579
3663
|
function getMixinTypeProject() {
|
|
3580
3664
|
mixinTypeProject ??= new import_ts_morph6.Project({
|
|
@@ -3604,7 +3688,7 @@ function resolveInstantiatedReturnType(cls, methodName) {
|
|
|
3604
3688
|
|
|
3605
3689
|
// src/discovery/filter-for.ts
|
|
3606
3690
|
function resolveMixinEntityClass(mixin, project) {
|
|
3607
|
-
const entityArg = mixin?.classArgs[0];
|
|
3691
|
+
const entityArg = mixin?.namedClassArgs?.entity ?? mixin?.classArgs[0];
|
|
3608
3692
|
if (!entityArg) return void 0;
|
|
3609
3693
|
const file = project.getSourceFile(entityArg.filePath) ?? project.addSourceFileAtPathIfExists(entityArg.filePath);
|
|
3610
3694
|
return file?.getClass(entityArg.name);
|
|
@@ -4856,7 +4940,8 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4856
4940
|
const mixinBinding = inherited ? {
|
|
4857
4941
|
factoryName: inherited.factoryName,
|
|
4858
4942
|
factoryFilePath: inherited.factoryFilePath,
|
|
4859
|
-
classArgs: inherited.classArgs
|
|
4943
|
+
classArgs: inherited.classArgs,
|
|
4944
|
+
namedClassArgs: inherited.namedClassArgs
|
|
4860
4945
|
} : void 0;
|
|
4861
4946
|
const ownMethods = cls.getMethods();
|
|
4862
4947
|
const ownNames = new Set(ownMethods.map((m) => m.getName()));
|
|
@@ -5171,7 +5256,7 @@ function createChainModuleRenderer(opts) {
|
|
|
5171
5256
|
}
|
|
5172
5257
|
|
|
5173
5258
|
// src/index.ts
|
|
5174
|
-
var VERSION = "0.
|
|
5259
|
+
var VERSION = "0.19.0";
|
|
5175
5260
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5176
5261
|
0 && (module.exports = {
|
|
5177
5262
|
CodegenError,
|