nestjs-trpc 1.3.1 → 1.3.3
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/generators/decorator.generator.d.ts +1 -2
- package/dist/generators/decorator.generator.d.ts.map +1 -1
- package/dist/generators/decorator.generator.js +3 -32
- package/dist/utils/file.util.d.ts +2 -3
- package/dist/utils/file.util.d.ts.map +1 -1
- package/dist/utils/file.util.js +2 -2
- package/dist/utils/type.util.d.ts +3 -3
- package/dist/utils/type.util.d.ts.map +1 -1
- package/dist/utils/type.util.js +82 -10
- package/lib/generators/decorator.generator.ts +5 -52
- package/lib/utils/file.util.ts +23 -8
- package/lib/utils/type.util.ts +100 -10
- package/package.json +3 -3
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Decorator,
|
|
1
|
+
import { Decorator, Project, SourceFile } from 'ts-morph';
|
|
2
2
|
import { DecoratorGeneratorMetadata } from '../interfaces/generator.interface';
|
|
3
3
|
export declare class DecoratorGenerator {
|
|
4
4
|
private readonly consoleLogger;
|
|
5
5
|
serializeProcedureDecorators(decorators: Decorator[], sourceFile: SourceFile, project: Project): Array<DecoratorGeneratorMetadata>;
|
|
6
|
-
private buildSourceFileImportsMap;
|
|
7
6
|
}
|
|
8
7
|
//# sourceMappingURL=decorator.generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorator.generator.d.ts","sourceRoot":"","sources":["../../lib/generators/decorator.generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"decorator.generator.d.ts","sourceRoot":"","sources":["../../lib/generators/decorator.generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAI/E,qBACa,kBAAkB;IAE7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAExC,4BAA4B,CACjC,UAAU,EAAE,SAAS,EAAE,EACvB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,OAAO,GACf,KAAK,CAAC,0BAA0B,CAAC;CAqCrC"}
|
|
@@ -4,15 +4,13 @@ exports.DecoratorGenerator = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const file_util_1 = require("../utils/file.util");
|
|
6
6
|
const common_1 = require("@nestjs/common");
|
|
7
|
-
const path = require("node:path");
|
|
8
7
|
let DecoratorGenerator = class DecoratorGenerator {
|
|
9
8
|
serializeProcedureDecorators(decorators, sourceFile, project) {
|
|
10
|
-
|
|
11
|
-
const decoratorsArray = decorators.reduce((array, decorator) => {
|
|
9
|
+
return decorators.reduce((array, decorator) => {
|
|
12
10
|
const decoratorName = decorator.getName();
|
|
13
11
|
if (decoratorName === 'Query' || decoratorName === 'Mutation') {
|
|
14
|
-
const input = (0, file_util_1.getDecoratorPropertyValue)(decorator, 'input', sourceFile,
|
|
15
|
-
const output = (0, file_util_1.getDecoratorPropertyValue)(decorator, 'output', sourceFile,
|
|
12
|
+
const input = (0, file_util_1.getDecoratorPropertyValue)(decorator, 'input', sourceFile, project);
|
|
13
|
+
const output = (0, file_util_1.getDecoratorPropertyValue)(decorator, 'output', sourceFile, project);
|
|
16
14
|
array.push({
|
|
17
15
|
name: decoratorName,
|
|
18
16
|
arguments: {
|
|
@@ -29,33 +27,6 @@ let DecoratorGenerator = class DecoratorGenerator {
|
|
|
29
27
|
}
|
|
30
28
|
return array;
|
|
31
29
|
}, []);
|
|
32
|
-
return decoratorsArray;
|
|
33
|
-
}
|
|
34
|
-
buildSourceFileImportsMap(sourceFile, project) {
|
|
35
|
-
const sourceFileImportsMap = new Map();
|
|
36
|
-
const importDeclarations = sourceFile.getImportDeclarations();
|
|
37
|
-
for (const importDeclaration of importDeclarations) {
|
|
38
|
-
const namedImports = importDeclaration.getNamedImports();
|
|
39
|
-
for (const namedImport of namedImports) {
|
|
40
|
-
const name = namedImport.getName();
|
|
41
|
-
const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
|
|
42
|
-
const resolvedPath = path.resolve(path.dirname(sourceFile.getFilePath()), moduleSpecifier + '.ts');
|
|
43
|
-
const importedSourceFile = project.addSourceFileAtPathIfExists(resolvedPath);
|
|
44
|
-
if (!importedSourceFile)
|
|
45
|
-
continue;
|
|
46
|
-
const schemaVariable = importedSourceFile.getVariableDeclaration(name);
|
|
47
|
-
if (schemaVariable) {
|
|
48
|
-
const initializer = schemaVariable.getInitializer();
|
|
49
|
-
if (initializer) {
|
|
50
|
-
sourceFileImportsMap.set(name, {
|
|
51
|
-
initializer,
|
|
52
|
-
sourceFile: importedSourceFile,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return sourceFileImportsMap;
|
|
59
30
|
}
|
|
60
31
|
};
|
|
61
32
|
exports.DecoratorGenerator = DecoratorGenerator;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { SourceFile, Decorator } from 'ts-morph';
|
|
2
|
-
import { SourceFileImportsMap } from '../interfaces/generator.interface';
|
|
1
|
+
import { SourceFile, Decorator, Project } from 'ts-morph';
|
|
3
2
|
export declare function generateStaticDeclaration(sourceFile: SourceFile): void;
|
|
4
3
|
export declare function saveOrOverrideFile(sourceFile: SourceFile): Promise<void>;
|
|
5
|
-
export declare function getDecoratorPropertyValue(decorator: Decorator, propertyName: string, sourceFile: SourceFile,
|
|
4
|
+
export declare function getDecoratorPropertyValue(decorator: Decorator, propertyName: string, sourceFile: SourceFile, project: Project): string | null;
|
|
6
5
|
//# sourceMappingURL=file.util.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.util.d.ts","sourceRoot":"","sources":["../../lib/utils/file.util.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"file.util.d.ts","sourceRoot":"","sources":["../../lib/utils/file.util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAKV,SAAS,EACT,OAAO,EACR,MAAM,UAAU,CAAC;AAGlB,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAsBtE;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,OAAO,GACf,MAAM,GAAG,IAAI,CAyBf"}
|
package/dist/utils/file.util.js
CHANGED
|
@@ -31,7 +31,7 @@ async function saveOrOverrideFile(sourceFile) {
|
|
|
31
31
|
sourceFile.formatText({ indentSize: 2 });
|
|
32
32
|
await sourceFile.save();
|
|
33
33
|
}
|
|
34
|
-
function getDecoratorPropertyValue(decorator, propertyName, sourceFile,
|
|
34
|
+
function getDecoratorPropertyValue(decorator, propertyName, sourceFile, project) {
|
|
35
35
|
const args = decorator.getArguments();
|
|
36
36
|
for (const arg of args) {
|
|
37
37
|
if (arg.getKind() === ts_morph_1.SyntaxKind.ObjectLiteralExpression) {
|
|
@@ -41,7 +41,7 @@ function getDecoratorPropertyValue(decorator, propertyName, sourceFile, importsM
|
|
|
41
41
|
return null;
|
|
42
42
|
}
|
|
43
43
|
const propertyInitializer = property.getInitializer();
|
|
44
|
-
return (0, type_util_1.flattenZodSchema)(propertyInitializer,
|
|
44
|
+
return (0, type_util_1.flattenZodSchema)(propertyInitializer, sourceFile, project, propertyInitializer.getText());
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
return null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Node, SourceFile, Type } from 'ts-morph';
|
|
2
|
-
import { ProcedureGeneratorMetadata
|
|
1
|
+
import { Node, Project, SourceFile, Type } from 'ts-morph';
|
|
2
|
+
import { ProcedureGeneratorMetadata } from '../interfaces/generator.interface';
|
|
3
3
|
export declare function findCtxOutProperty(type: Type): string | undefined;
|
|
4
4
|
export declare function generateProcedureString(procedure: ProcedureGeneratorMetadata): string;
|
|
5
|
-
export declare function flattenZodSchema(node: Node,
|
|
5
|
+
export declare function flattenZodSchema(node: Node, sourceFile: SourceFile, project: Project, schema: string): string;
|
|
6
6
|
//# sourceMappingURL=type.util.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type.util.d.ts","sourceRoot":"","sources":["../../lib/utils/type.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"type.util.d.ts","sourceRoot":"","sources":["../../lib/utils/type.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EACL,0BAA0B,EAE3B,MAAM,mCAAmC,CAAC;AAE3C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAKjE;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,0BAA0B,GACpC,MAAM,CAeR;AA2FD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,GACb,MAAM,CAiGR"}
|
package/dist/utils/type.util.js
CHANGED
|
@@ -11,7 +11,7 @@ function findCtxOutProperty(type) {
|
|
|
11
11
|
}
|
|
12
12
|
function generateProcedureString(procedure) {
|
|
13
13
|
const { name, decorators } = procedure;
|
|
14
|
-
const decorator = decorators.find(
|
|
14
|
+
const decorator = decorators.find((decorator) => decorator.name === 'Mutation' || decorator.name === 'Query');
|
|
15
15
|
if (!decorator) {
|
|
16
16
|
return '';
|
|
17
17
|
}
|
|
@@ -20,14 +20,85 @@ function generateProcedureString(procedure) {
|
|
|
20
20
|
.join('');
|
|
21
21
|
return `${name}: publicProcedure${decoratorArgumentsArray}.${decorator.name.toLowerCase()}(async () => "PLACEHOLDER_DO_NOT_REMOVE" as any )`;
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* https://github.com/dsherret/ts-morph/issues/327
|
|
25
|
+
* Note that if the module resolution of the compiler is Classic then it won't resolve those implicit index.ts module specifiers.
|
|
26
|
+
* So for example, if the moduleResolution compiler option isn't explicitly set then setting the module
|
|
27
|
+
* compiler option to anything but ModuleKind.CommonJS will cause the module resolution kind to resolve to Classic.
|
|
28
|
+
* Additionally, if moduleResolution and the module compiler option isn't set,
|
|
29
|
+
* then a script target of ES2015 and above will also use Classic module resolution.
|
|
30
|
+
*/
|
|
31
|
+
function resolveBarrelFileImport(barrelSourceFile, name, project) {
|
|
32
|
+
// Traverse through export declarations to find the actual source of the named import
|
|
33
|
+
for (const exportDeclaration of barrelSourceFile.getExportDeclarations()) {
|
|
34
|
+
const exportedSourceFile = exportDeclaration.getModuleSpecifierSourceFile();
|
|
35
|
+
if (exportedSourceFile == null)
|
|
36
|
+
continue;
|
|
37
|
+
// Check if the named export is explicitly re-exported
|
|
38
|
+
const namedExports = exportDeclaration.getNamedExports();
|
|
39
|
+
if (namedExports.length > 0) {
|
|
40
|
+
const matchingExport = namedExports.find((e) => e.getName() === name);
|
|
41
|
+
if (matchingExport) {
|
|
42
|
+
return exportedSourceFile;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Handle `export * from ...` case: recursively resolve the export
|
|
47
|
+
const schemaVariable = exportedSourceFile.getVariableDeclaration(name);
|
|
48
|
+
if (schemaVariable) {
|
|
49
|
+
return exportedSourceFile;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Continue resolving if it's another barrel file
|
|
53
|
+
const baseSourceFile = resolveBarrelFileImport(exportedSourceFile, name, project);
|
|
54
|
+
if (baseSourceFile)
|
|
55
|
+
return baseSourceFile;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
function buildSourceFileImportsMap(sourceFile, project) {
|
|
62
|
+
const sourceFileImportsMap = new Map();
|
|
63
|
+
const importDeclarations = sourceFile.getImportDeclarations();
|
|
64
|
+
for (const importDeclaration of importDeclarations) {
|
|
65
|
+
const namedImports = importDeclaration.getNamedImports();
|
|
66
|
+
for (const namedImport of namedImports) {
|
|
67
|
+
const name = namedImport.getName();
|
|
68
|
+
const importedSourceFile = importDeclaration.getModuleSpecifierSourceFile();
|
|
69
|
+
if (importedSourceFile == null) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const resolvedSourceFile = importedSourceFile.getFilePath().endsWith('index.ts') &&
|
|
73
|
+
importedSourceFile.getVariableDeclaration(name) == null
|
|
74
|
+
? resolveBarrelFileImport(importedSourceFile, name, project)
|
|
75
|
+
: importedSourceFile;
|
|
76
|
+
if (resolvedSourceFile == null) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const schemaVariable = resolvedSourceFile.getVariableDeclaration(name);
|
|
80
|
+
if (schemaVariable != null) {
|
|
81
|
+
const initializer = schemaVariable.getInitializer();
|
|
82
|
+
if (initializer) {
|
|
83
|
+
sourceFileImportsMap.set(name, {
|
|
84
|
+
initializer,
|
|
85
|
+
sourceFile: resolvedSourceFile,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return sourceFileImportsMap;
|
|
92
|
+
}
|
|
93
|
+
function flattenZodSchema(node, sourceFile, project, schema) {
|
|
94
|
+
const importsMap = buildSourceFileImportsMap(sourceFile, project);
|
|
24
95
|
if (ts_morph_1.Node.isIdentifier(node)) {
|
|
25
96
|
const identifierName = node.getText();
|
|
26
97
|
const identifierDeclaration = sourceFile.getVariableDeclaration(identifierName);
|
|
27
98
|
if (identifierDeclaration != null) {
|
|
28
99
|
const identifierInitializer = identifierDeclaration.getInitializer();
|
|
29
100
|
if (identifierInitializer != null) {
|
|
30
|
-
const identifierSchema = flattenZodSchema(identifierInitializer,
|
|
101
|
+
const identifierSchema = flattenZodSchema(identifierInitializer, sourceFile, project, identifierInitializer.getText());
|
|
31
102
|
schema = schema.replace(identifierName, identifierSchema);
|
|
32
103
|
}
|
|
33
104
|
}
|
|
@@ -35,7 +106,7 @@ function flattenZodSchema(node, importsMap, sourceFile, schema) {
|
|
|
35
106
|
const importedIdentifier = importsMap.get(identifierName);
|
|
36
107
|
if (importedIdentifier != null) {
|
|
37
108
|
const { initializer } = importedIdentifier;
|
|
38
|
-
const identifierSchema = flattenZodSchema(initializer,
|
|
109
|
+
const identifierSchema = flattenZodSchema(initializer, importedIdentifier.sourceFile, project, initializer.getText());
|
|
39
110
|
schema = schema.replace(identifierName, identifierSchema);
|
|
40
111
|
}
|
|
41
112
|
}
|
|
@@ -46,7 +117,7 @@ function flattenZodSchema(node, importsMap, sourceFile, schema) {
|
|
|
46
117
|
const propertyText = property.getText();
|
|
47
118
|
const propertyInitializer = property.getInitializer();
|
|
48
119
|
if (propertyInitializer != null) {
|
|
49
|
-
schema = schema.replace(propertyText, flattenZodSchema(propertyInitializer,
|
|
120
|
+
schema = schema.replace(propertyText, flattenZodSchema(propertyInitializer, sourceFile, project, propertyText));
|
|
50
121
|
}
|
|
51
122
|
}
|
|
52
123
|
}
|
|
@@ -54,23 +125,24 @@ function flattenZodSchema(node, importsMap, sourceFile, schema) {
|
|
|
54
125
|
else if (ts_morph_1.Node.isArrayLiteralExpression(node)) {
|
|
55
126
|
for (const element of node.getElements()) {
|
|
56
127
|
const elementText = element.getText();
|
|
57
|
-
schema = schema.replace(elementText, flattenZodSchema(element,
|
|
128
|
+
schema = schema.replace(elementText, flattenZodSchema(element, sourceFile, project, elementText));
|
|
58
129
|
}
|
|
59
130
|
}
|
|
60
131
|
else if (ts_morph_1.Node.isCallExpression(node)) {
|
|
61
132
|
const expression = node.getExpression();
|
|
62
|
-
if (ts_morph_1.Node.isPropertyAccessExpression(expression) &&
|
|
63
|
-
|
|
133
|
+
if (ts_morph_1.Node.isPropertyAccessExpression(expression) &&
|
|
134
|
+
!expression.getText().startsWith('z')) {
|
|
135
|
+
const baseSchema = flattenZodSchema(expression, sourceFile, project, expression.getText());
|
|
64
136
|
const propertyName = expression.getName();
|
|
65
137
|
schema = schema.replace(expression.getText(), `${baseSchema}.${propertyName}`);
|
|
66
138
|
}
|
|
67
139
|
for (const arg of node.getArguments()) {
|
|
68
140
|
const argText = arg.getText();
|
|
69
|
-
schema = schema.replace(argText, flattenZodSchema(arg,
|
|
141
|
+
schema = schema.replace(argText, flattenZodSchema(arg, sourceFile, project, argText));
|
|
70
142
|
}
|
|
71
143
|
}
|
|
72
144
|
else if (ts_morph_1.Node.isPropertyAccessExpression(node)) {
|
|
73
|
-
schema = flattenZodSchema(node.getExpression(),
|
|
145
|
+
schema = flattenZodSchema(node.getExpression(), sourceFile, project, node.getExpression().getText());
|
|
74
146
|
}
|
|
75
147
|
return schema;
|
|
76
148
|
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import { Decorator,
|
|
2
|
-
import {
|
|
3
|
-
DecoratorGeneratorMetadata,
|
|
4
|
-
SourceFileImportsMap,
|
|
5
|
-
} from '../interfaces/generator.interface';
|
|
1
|
+
import { Decorator, Project, SourceFile } from 'ts-morph';
|
|
2
|
+
import { DecoratorGeneratorMetadata } from '../interfaces/generator.interface';
|
|
6
3
|
import { getDecoratorPropertyValue } from '../utils/file.util';
|
|
7
4
|
import { ConsoleLogger, Inject, Injectable } from '@nestjs/common';
|
|
8
|
-
import * as path from 'node:path';
|
|
9
5
|
|
|
10
6
|
@Injectable()
|
|
11
7
|
export class DecoratorGenerator {
|
|
@@ -17,12 +13,7 @@ export class DecoratorGenerator {
|
|
|
17
13
|
sourceFile: SourceFile,
|
|
18
14
|
project: Project,
|
|
19
15
|
): Array<DecoratorGeneratorMetadata> {
|
|
20
|
-
|
|
21
|
-
sourceFile,
|
|
22
|
-
project,
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
const decoratorsArray = decorators.reduce<DecoratorGeneratorMetadata[]>(
|
|
16
|
+
return decorators.reduce<DecoratorGeneratorMetadata[]>(
|
|
26
17
|
(array, decorator) => {
|
|
27
18
|
const decoratorName = decorator.getName();
|
|
28
19
|
|
|
@@ -31,13 +22,13 @@ export class DecoratorGenerator {
|
|
|
31
22
|
decorator,
|
|
32
23
|
'input',
|
|
33
24
|
sourceFile,
|
|
34
|
-
|
|
25
|
+
project,
|
|
35
26
|
);
|
|
36
27
|
const output = getDecoratorPropertyValue(
|
|
37
28
|
decorator,
|
|
38
29
|
'output',
|
|
39
30
|
sourceFile,
|
|
40
|
-
|
|
31
|
+
project,
|
|
41
32
|
);
|
|
42
33
|
|
|
43
34
|
array.push({
|
|
@@ -57,43 +48,5 @@ export class DecoratorGenerator {
|
|
|
57
48
|
},
|
|
58
49
|
[],
|
|
59
50
|
);
|
|
60
|
-
|
|
61
|
-
return decoratorsArray;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
private buildSourceFileImportsMap(
|
|
65
|
-
sourceFile: SourceFile,
|
|
66
|
-
project: Project,
|
|
67
|
-
): Map<string, SourceFileImportsMap> {
|
|
68
|
-
const sourceFileImportsMap = new Map<string, SourceFileImportsMap>();
|
|
69
|
-
const importDeclarations = sourceFile.getImportDeclarations();
|
|
70
|
-
|
|
71
|
-
for (const importDeclaration of importDeclarations) {
|
|
72
|
-
const namedImports = importDeclaration.getNamedImports();
|
|
73
|
-
for (const namedImport of namedImports) {
|
|
74
|
-
const name = namedImport.getName();
|
|
75
|
-
const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
|
|
76
|
-
const resolvedPath = path.resolve(
|
|
77
|
-
path.dirname(sourceFile.getFilePath()),
|
|
78
|
-
moduleSpecifier + '.ts',
|
|
79
|
-
);
|
|
80
|
-
const importedSourceFile =
|
|
81
|
-
project.addSourceFileAtPathIfExists(resolvedPath);
|
|
82
|
-
if (!importedSourceFile) continue;
|
|
83
|
-
|
|
84
|
-
const schemaVariable = importedSourceFile.getVariableDeclaration(name);
|
|
85
|
-
if (schemaVariable) {
|
|
86
|
-
const initializer = schemaVariable.getInitializer();
|
|
87
|
-
if (initializer) {
|
|
88
|
-
sourceFileImportsMap.set(name, {
|
|
89
|
-
initializer,
|
|
90
|
-
sourceFile: importedSourceFile,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return sourceFileImportsMap;
|
|
98
51
|
}
|
|
99
52
|
}
|
package/lib/utils/file.util.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
SourceFile,
|
|
3
|
+
StructureKind,
|
|
4
|
+
VariableDeclarationKind,
|
|
5
|
+
Expression,
|
|
6
|
+
SyntaxKind,
|
|
7
|
+
Decorator,
|
|
8
|
+
Project,
|
|
9
|
+
} from 'ts-morph';
|
|
4
10
|
import { flattenZodSchema } from './type.util';
|
|
5
11
|
|
|
6
12
|
export function generateStaticDeclaration(sourceFile: SourceFile): void {
|
|
@@ -27,7 +33,9 @@ export function generateStaticDeclaration(sourceFile: SourceFile): void {
|
|
|
27
33
|
]);
|
|
28
34
|
}
|
|
29
35
|
|
|
30
|
-
export async function saveOrOverrideFile(
|
|
36
|
+
export async function saveOrOverrideFile(
|
|
37
|
+
sourceFile: SourceFile,
|
|
38
|
+
): Promise<void> {
|
|
31
39
|
sourceFile.formatText({ indentSize: 2 });
|
|
32
40
|
await sourceFile.save();
|
|
33
41
|
}
|
|
@@ -36,23 +44,30 @@ export function getDecoratorPropertyValue(
|
|
|
36
44
|
decorator: Decorator,
|
|
37
45
|
propertyName: string,
|
|
38
46
|
sourceFile: SourceFile,
|
|
39
|
-
|
|
47
|
+
project: Project,
|
|
40
48
|
): string | null {
|
|
41
49
|
const args = decorator.getArguments();
|
|
42
50
|
|
|
43
51
|
for (const arg of args) {
|
|
44
52
|
if (arg.getKind() === SyntaxKind.ObjectLiteralExpression) {
|
|
45
53
|
const properties = (arg as any).getProperties();
|
|
46
|
-
const property = properties.find(
|
|
54
|
+
const property = properties.find(
|
|
55
|
+
(p: any) => p.getName() === propertyName,
|
|
56
|
+
);
|
|
47
57
|
|
|
48
58
|
if (!property) {
|
|
49
59
|
return null;
|
|
50
60
|
}
|
|
51
61
|
|
|
52
62
|
const propertyInitializer: Expression = property.getInitializer();
|
|
53
|
-
return flattenZodSchema(
|
|
63
|
+
return flattenZodSchema(
|
|
64
|
+
propertyInitializer,
|
|
65
|
+
sourceFile,
|
|
66
|
+
project,
|
|
67
|
+
propertyInitializer.getText(),
|
|
68
|
+
);
|
|
54
69
|
}
|
|
55
70
|
}
|
|
56
71
|
|
|
57
72
|
return null;
|
|
58
|
-
}
|
|
73
|
+
}
|
package/lib/utils/type.util.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Node, SourceFile, Type } from 'ts-morph';
|
|
1
|
+
import { Node, Project, SourceFile, Type } from 'ts-morph';
|
|
2
2
|
import {
|
|
3
3
|
ProcedureGeneratorMetadata,
|
|
4
4
|
SourceFileImportsMap,
|
|
@@ -16,7 +16,7 @@ export function generateProcedureString(
|
|
|
16
16
|
): string {
|
|
17
17
|
const { name, decorators } = procedure;
|
|
18
18
|
const decorator = decorators.find(
|
|
19
|
-
(
|
|
19
|
+
(decorator) => decorator.name === 'Mutation' || decorator.name === 'Query',
|
|
20
20
|
);
|
|
21
21
|
|
|
22
22
|
if (!decorator) {
|
|
@@ -30,12 +30,102 @@ export function generateProcedureString(
|
|
|
30
30
|
return `${name}: publicProcedure${decoratorArgumentsArray}.${decorator.name.toLowerCase()}(async () => "PLACEHOLDER_DO_NOT_REMOVE" as any )`;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* https://github.com/dsherret/ts-morph/issues/327
|
|
35
|
+
* Note that if the module resolution of the compiler is Classic then it won't resolve those implicit index.ts module specifiers.
|
|
36
|
+
* So for example, if the moduleResolution compiler option isn't explicitly set then setting the module
|
|
37
|
+
* compiler option to anything but ModuleKind.CommonJS will cause the module resolution kind to resolve to Classic.
|
|
38
|
+
* Additionally, if moduleResolution and the module compiler option isn't set,
|
|
39
|
+
* then a script target of ES2015 and above will also use Classic module resolution.
|
|
40
|
+
*/
|
|
41
|
+
function resolveBarrelFileImport(
|
|
42
|
+
barrelSourceFile: SourceFile,
|
|
43
|
+
name: string,
|
|
44
|
+
project: Project,
|
|
45
|
+
): SourceFile | undefined {
|
|
46
|
+
// Traverse through export declarations to find the actual source of the named import
|
|
47
|
+
for (const exportDeclaration of barrelSourceFile.getExportDeclarations()) {
|
|
48
|
+
const exportedSourceFile = exportDeclaration.getModuleSpecifierSourceFile();
|
|
49
|
+
if (exportedSourceFile == null) continue;
|
|
50
|
+
|
|
51
|
+
// Check if the named export is explicitly re-exported
|
|
52
|
+
const namedExports = exportDeclaration.getNamedExports();
|
|
53
|
+
if (namedExports.length > 0) {
|
|
54
|
+
const matchingExport = namedExports.find((e) => e.getName() === name);
|
|
55
|
+
if (matchingExport) {
|
|
56
|
+
return exportedSourceFile;
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
// Handle `export * from ...` case: recursively resolve the export
|
|
60
|
+
const schemaVariable = exportedSourceFile.getVariableDeclaration(name);
|
|
61
|
+
if (schemaVariable) {
|
|
62
|
+
return exportedSourceFile;
|
|
63
|
+
} else {
|
|
64
|
+
// Continue resolving if it's another barrel file
|
|
65
|
+
const baseSourceFile = resolveBarrelFileImport(
|
|
66
|
+
exportedSourceFile,
|
|
67
|
+
name,
|
|
68
|
+
project,
|
|
69
|
+
);
|
|
70
|
+
if (baseSourceFile) return baseSourceFile;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function buildSourceFileImportsMap(
|
|
79
|
+
sourceFile: SourceFile,
|
|
80
|
+
project: Project,
|
|
81
|
+
): Map<string, SourceFileImportsMap> {
|
|
82
|
+
const sourceFileImportsMap = new Map<string, SourceFileImportsMap>();
|
|
83
|
+
const importDeclarations = sourceFile.getImportDeclarations();
|
|
84
|
+
|
|
85
|
+
for (const importDeclaration of importDeclarations) {
|
|
86
|
+
const namedImports = importDeclaration.getNamedImports();
|
|
87
|
+
for (const namedImport of namedImports) {
|
|
88
|
+
const name = namedImport.getName();
|
|
89
|
+
const importedSourceFile =
|
|
90
|
+
importDeclaration.getModuleSpecifierSourceFile();
|
|
91
|
+
|
|
92
|
+
if (importedSourceFile == null) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const resolvedSourceFile =
|
|
97
|
+
importedSourceFile.getFilePath().endsWith('index.ts') &&
|
|
98
|
+
importedSourceFile.getVariableDeclaration(name) == null
|
|
99
|
+
? resolveBarrelFileImport(importedSourceFile, name, project)
|
|
100
|
+
: importedSourceFile;
|
|
101
|
+
|
|
102
|
+
if (resolvedSourceFile == null) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const schemaVariable = resolvedSourceFile.getVariableDeclaration(name);
|
|
107
|
+
if (schemaVariable != null) {
|
|
108
|
+
const initializer = schemaVariable.getInitializer();
|
|
109
|
+
if (initializer) {
|
|
110
|
+
sourceFileImportsMap.set(name, {
|
|
111
|
+
initializer,
|
|
112
|
+
sourceFile: resolvedSourceFile,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return sourceFileImportsMap;
|
|
120
|
+
}
|
|
121
|
+
|
|
33
122
|
export function flattenZodSchema(
|
|
34
123
|
node: Node,
|
|
35
|
-
importsMap: Map<string, SourceFileImportsMap>,
|
|
36
124
|
sourceFile: SourceFile,
|
|
125
|
+
project: Project,
|
|
37
126
|
schema: string,
|
|
38
127
|
): string {
|
|
128
|
+
const importsMap = buildSourceFileImportsMap(sourceFile, project);
|
|
39
129
|
if (Node.isIdentifier(node)) {
|
|
40
130
|
const identifierName = node.getText();
|
|
41
131
|
const identifierDeclaration =
|
|
@@ -47,8 +137,8 @@ export function flattenZodSchema(
|
|
|
47
137
|
if (identifierInitializer != null) {
|
|
48
138
|
const identifierSchema = flattenZodSchema(
|
|
49
139
|
identifierInitializer,
|
|
50
|
-
importsMap,
|
|
51
140
|
sourceFile,
|
|
141
|
+
project,
|
|
52
142
|
identifierInitializer.getText(),
|
|
53
143
|
);
|
|
54
144
|
|
|
@@ -61,8 +151,8 @@ export function flattenZodSchema(
|
|
|
61
151
|
const { initializer } = importedIdentifier;
|
|
62
152
|
const identifierSchema = flattenZodSchema(
|
|
63
153
|
initializer,
|
|
64
|
-
importsMap,
|
|
65
154
|
importedIdentifier.sourceFile,
|
|
155
|
+
project,
|
|
66
156
|
initializer.getText(),
|
|
67
157
|
);
|
|
68
158
|
|
|
@@ -80,8 +170,8 @@ export function flattenZodSchema(
|
|
|
80
170
|
propertyText,
|
|
81
171
|
flattenZodSchema(
|
|
82
172
|
propertyInitializer,
|
|
83
|
-
importsMap,
|
|
84
173
|
sourceFile,
|
|
174
|
+
project,
|
|
85
175
|
propertyText,
|
|
86
176
|
),
|
|
87
177
|
);
|
|
@@ -93,7 +183,7 @@ export function flattenZodSchema(
|
|
|
93
183
|
const elementText = element.getText();
|
|
94
184
|
schema = schema.replace(
|
|
95
185
|
elementText,
|
|
96
|
-
flattenZodSchema(element,
|
|
186
|
+
flattenZodSchema(element, sourceFile, project, elementText),
|
|
97
187
|
);
|
|
98
188
|
}
|
|
99
189
|
} else if (Node.isCallExpression(node)) {
|
|
@@ -104,8 +194,8 @@ export function flattenZodSchema(
|
|
|
104
194
|
) {
|
|
105
195
|
const baseSchema = flattenZodSchema(
|
|
106
196
|
expression,
|
|
107
|
-
importsMap,
|
|
108
197
|
sourceFile,
|
|
198
|
+
project,
|
|
109
199
|
expression.getText(),
|
|
110
200
|
);
|
|
111
201
|
const propertyName = expression.getName();
|
|
@@ -118,14 +208,14 @@ export function flattenZodSchema(
|
|
|
118
208
|
const argText = arg.getText();
|
|
119
209
|
schema = schema.replace(
|
|
120
210
|
argText,
|
|
121
|
-
flattenZodSchema(arg,
|
|
211
|
+
flattenZodSchema(arg, sourceFile, project, argText),
|
|
122
212
|
);
|
|
123
213
|
}
|
|
124
214
|
} else if (Node.isPropertyAccessExpression(node)) {
|
|
125
215
|
schema = flattenZodSchema(
|
|
126
216
|
node.getExpression(),
|
|
127
|
-
importsMap,
|
|
128
217
|
sourceFile,
|
|
218
|
+
project,
|
|
129
219
|
node.getExpression().getText(),
|
|
130
220
|
);
|
|
131
221
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nestjs-trpc",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"homepage": "https://nestjs-trpc.io",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./lib/index.ts",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@nestjs/common": "^9.3.8 || ^10.0.0",
|
|
44
44
|
"@nestjs/core": "^9.3.8 || ^10.0.0",
|
|
45
|
-
"@trpc/server": "^10.
|
|
45
|
+
"@trpc/server": "^10.0.0",
|
|
46
46
|
"reflect-metadata": "^0.1.13 || ^0.2.0",
|
|
47
47
|
"rxjs": "7.8.1",
|
|
48
48
|
"zod": "^3.14.0"
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"tsconfig-paths": "^4.2.0",
|
|
65
65
|
"type-fest": "^4.21.0",
|
|
66
66
|
"typescript": "5.5.3",
|
|
67
|
-
"zod": "^3.14.
|
|
67
|
+
"zod": "^3.14.4"
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"func-loc": "^0.1.16",
|