@nestia/sdk 7.1.1 → 7.2.1
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/lib/analyses/DtoAnalyzer.d.ts +21 -0
- package/lib/analyses/DtoAnalyzer.js +203 -0
- package/lib/analyses/DtoAnalyzer.js.map +1 -0
- package/lib/analyses/ImportAnalyzer.d.ts +3 -8
- package/lib/analyses/ImportAnalyzer.js +84 -102
- package/lib/analyses/ImportAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.js +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js +1 -1
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -1
- package/lib/generates/internal/E2eFileProgrammer.js +3 -9
- package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
- package/lib/generates/internal/ImportDictionary.d.ts +9 -11
- package/lib/generates/internal/ImportDictionary.js +55 -48
- package/lib/generates/internal/ImportDictionary.js.map +1 -1
- package/lib/generates/internal/SdkAliasCollection.js +24 -18
- package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
- package/lib/generates/internal/SdkFileProgrammer.js +1 -7
- package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpCloneReferencer.js +3 -1
- package/lib/generates/internal/SdkHttpCloneReferencer.js.map +1 -1
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js +4 -3
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkImportWizard.js +28 -21
- package/lib/generates/internal/SdkImportWizard.js.map +1 -1
- package/lib/generates/internal/SdkTypeProgrammer.js +3 -2
- package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkTypeTagProgrammer.js +10 -8
- package/lib/generates/internal/SdkTypeTagProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +8 -6
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +12 -9
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
- package/lib/structures/IReflectHttpOperation.d.ts +2 -2
- package/lib/structures/IReflectImport.d.ts +6 -0
- package/lib/structures/{IReflectTypeImport.js → IReflectImport.js} +1 -1
- package/lib/structures/IReflectImport.js.map +1 -0
- package/lib/structures/IReflectWebSocketOperation.d.ts +2 -2
- package/lib/structures/IReflectWebSocketOperationParameter.d.ts +2 -2
- package/lib/structures/ITypedHttpRoute.d.ts +2 -2
- package/lib/structures/ITypedWebSocketRoute.d.ts +2 -2
- package/lib/transformers/IOperationMetadata.d.ts +3 -3
- package/lib/transformers/SdkOperationProgrammer.d.ts +3 -1
- package/lib/transformers/SdkOperationProgrammer.js +57 -26
- package/lib/transformers/SdkOperationProgrammer.js.map +1 -1
- package/lib/transformers/SdkOperationTransformer.js +3 -3
- package/lib/transformers/SdkOperationTransformer.js.map +1 -1
- package/package.json +4 -4
- package/src/analyses/DtoAnalyzer.ts +246 -0
- package/src/analyses/ImportAnalyzer.ts +110 -155
- package/src/analyses/ReflectHttpOperationAnalyzer.ts +1 -1
- package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +3 -3
- package/src/generates/internal/E2eFileProgrammer.ts +3 -11
- package/src/generates/internal/ImportDictionary.ts +111 -84
- package/src/generates/internal/SdkAliasCollection.ts +24 -18
- package/src/generates/internal/SdkFileProgrammer.ts +1 -7
- package/src/generates/internal/SdkHttpCloneReferencer.ts +3 -1
- package/src/generates/internal/SdkHttpSimulationProgrammer.ts +4 -3
- package/src/generates/internal/SdkImportWizard.ts +28 -21
- package/src/generates/internal/SdkTypeProgrammer.ts +3 -2
- package/src/generates/internal/SdkTypeTagProgrammer.ts +10 -8
- package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +8 -6
- package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +12 -9
- package/src/structures/IReflectHttpOperation.ts +2 -2
- package/src/structures/IReflectHttpOperationParameter.ts +2 -6
- package/src/structures/IReflectImport.ts +6 -0
- package/src/structures/IReflectWebSocketOperation.ts +2 -2
- package/src/structures/IReflectWebSocketOperationParameter.ts +3 -5
- package/src/structures/ITypedHttpRoute.ts +2 -2
- package/src/structures/ITypedWebSocketRoute.ts +2 -2
- package/src/transformers/IOperationMetadata.ts +3 -3
- package/src/transformers/SdkOperationProgrammer.ts +60 -31
- package/src/transformers/SdkOperationTransformer.ts +7 -8
- package/lib/structures/IReflectTypeImport.d.ts +0 -4
- package/lib/structures/IReflectTypeImport.js.map +0 -1
- package/src/structures/IReflectTypeImport.ts +0 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestia/sdk",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.2.1",
|
|
4
4
|
"description": "Nestia SDK and Swagger generator",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://nestia.io",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@nestia/core": "^7.
|
|
36
|
-
"@nestia/fetcher": "^7.
|
|
35
|
+
"@nestia/core": "^7.2.1",
|
|
36
|
+
"@nestia/fetcher": "^7.2.1",
|
|
37
37
|
"@samchon/openapi": "^4.5.0",
|
|
38
38
|
"cli": "^1.0.1",
|
|
39
39
|
"get-function-location": "^2.0.0",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"typia": "^9.5.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@nestia/core": ">=7.
|
|
50
|
+
"@nestia/core": ">=7.2.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@nestjs/common": "^11.0.13",
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
|
|
3
|
+
import { IReflectImport } from "../structures/IReflectImport";
|
|
4
|
+
import { IReflectType } from "../structures/IReflectType";
|
|
5
|
+
import { ImportAnalyzer } from "./ImportAnalyzer";
|
|
6
|
+
|
|
7
|
+
export namespace DtoAnalyzer {
|
|
8
|
+
export interface INodeProps {
|
|
9
|
+
checker: ts.TypeChecker;
|
|
10
|
+
imports: IReflectImport[];
|
|
11
|
+
typeNode: ts.TypeNode;
|
|
12
|
+
}
|
|
13
|
+
export interface ITypeProps {
|
|
14
|
+
checker: ts.TypeChecker;
|
|
15
|
+
imports: IReflectImport[];
|
|
16
|
+
type: ts.Type;
|
|
17
|
+
}
|
|
18
|
+
export interface IOutput {
|
|
19
|
+
imports: IReflectImport[];
|
|
20
|
+
type: IReflectType;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const analyzeNode = (props: INodeProps): IOutput | null => {
|
|
24
|
+
try {
|
|
25
|
+
const container: IReflectImport[] = [];
|
|
26
|
+
const type: IReflectType = exploreNode(
|
|
27
|
+
{
|
|
28
|
+
checker: props.checker,
|
|
29
|
+
imports: props.imports,
|
|
30
|
+
container,
|
|
31
|
+
},
|
|
32
|
+
props.typeNode,
|
|
33
|
+
);
|
|
34
|
+
return {
|
|
35
|
+
type,
|
|
36
|
+
imports: ImportAnalyzer.merge(container),
|
|
37
|
+
};
|
|
38
|
+
} catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const analyzeType = (props: ITypeProps): IOutput | null => {
|
|
44
|
+
try {
|
|
45
|
+
const container: IReflectImport[] = [];
|
|
46
|
+
const type: IReflectType = exploreType(
|
|
47
|
+
{
|
|
48
|
+
checker: props.checker,
|
|
49
|
+
imports: props.imports,
|
|
50
|
+
container,
|
|
51
|
+
},
|
|
52
|
+
props.type,
|
|
53
|
+
);
|
|
54
|
+
return {
|
|
55
|
+
type,
|
|
56
|
+
imports: ImportAnalyzer.merge(container),
|
|
57
|
+
};
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
type IContext = Omit<INodeProps, "typeNode"> & {
|
|
64
|
+
container: IReflectImport[];
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const exploreNode = (ctx: IContext, typeNode: ts.TypeNode): IReflectType => {
|
|
68
|
+
// Analyze symbol, and take special cares
|
|
69
|
+
if (ts.isIntersectionTypeNode(typeNode))
|
|
70
|
+
return {
|
|
71
|
+
name: typeNode.types
|
|
72
|
+
.map((child) => exploreNode(ctx, child))
|
|
73
|
+
.map(getEscapedText)
|
|
74
|
+
.join(" & "),
|
|
75
|
+
};
|
|
76
|
+
else if (ts.isUnionTypeNode(typeNode))
|
|
77
|
+
return {
|
|
78
|
+
name: typeNode.types
|
|
79
|
+
.map((child) => exploreNode(ctx, child))
|
|
80
|
+
.map(getEscapedText)
|
|
81
|
+
.join(" | "),
|
|
82
|
+
};
|
|
83
|
+
else if (ts.isParenthesizedTypeNode(typeNode))
|
|
84
|
+
return {
|
|
85
|
+
name: `(${exploreNode(ctx, typeNode.type).name})`,
|
|
86
|
+
};
|
|
87
|
+
else if (ts.isTypeOperatorNode(typeNode)) {
|
|
88
|
+
const prefix: string | null =
|
|
89
|
+
typeNode.operator === ts.SyntaxKind.KeyOfKeyword
|
|
90
|
+
? "keyof"
|
|
91
|
+
: typeNode.operator === ts.SyntaxKind.UniqueKeyword
|
|
92
|
+
? "unique"
|
|
93
|
+
: typeNode.operator === ts.SyntaxKind.ReadonlyKeyword
|
|
94
|
+
? "readonly"
|
|
95
|
+
: null;
|
|
96
|
+
if (prefix === null)
|
|
97
|
+
return exploreType(ctx, ctx.checker.getTypeFromTypeNode(typeNode));
|
|
98
|
+
return {
|
|
99
|
+
name: `${prefix} ${exploreNode(ctx, typeNode.type).name}`,
|
|
100
|
+
};
|
|
101
|
+
} else if (ts.isTypePredicateNode(typeNode) || ts.isTypeQueryNode(typeNode))
|
|
102
|
+
return exploreType(ctx, ctx.checker.getTypeFromTypeNode(typeNode));
|
|
103
|
+
else if (ts.isTypeReferenceNode(typeNode) === false)
|
|
104
|
+
return {
|
|
105
|
+
name: typeNode.getText(),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// Find matched import statement
|
|
109
|
+
const name: string = typeNode.typeName.getText();
|
|
110
|
+
const prefix: string = name.split(".")[0];
|
|
111
|
+
|
|
112
|
+
let matched: boolean = false;
|
|
113
|
+
const insert = (imp: IReflectImport): void => {
|
|
114
|
+
matched ||= true;
|
|
115
|
+
ctx.container.push(imp);
|
|
116
|
+
};
|
|
117
|
+
for (const imp of ctx.imports)
|
|
118
|
+
if (prefix === imp.default)
|
|
119
|
+
insert({
|
|
120
|
+
file: imp.file,
|
|
121
|
+
asterisk: null,
|
|
122
|
+
default: prefix,
|
|
123
|
+
elements: [],
|
|
124
|
+
});
|
|
125
|
+
else if (prefix === imp.asterisk)
|
|
126
|
+
insert({
|
|
127
|
+
file: imp.file,
|
|
128
|
+
asterisk: prefix,
|
|
129
|
+
default: null,
|
|
130
|
+
elements: [],
|
|
131
|
+
});
|
|
132
|
+
else if (imp.elements.includes(prefix))
|
|
133
|
+
insert({
|
|
134
|
+
file: imp.file,
|
|
135
|
+
asterisk: null,
|
|
136
|
+
default: null,
|
|
137
|
+
elements: [prefix],
|
|
138
|
+
});
|
|
139
|
+
if (prefix !== "Promise" && matched === false)
|
|
140
|
+
return exploreType(ctx, ctx.checker.getTypeFromTypeNode(typeNode));
|
|
141
|
+
|
|
142
|
+
// Finalize with generic arguments
|
|
143
|
+
if (!!typeNode.typeArguments?.length) {
|
|
144
|
+
const top: ts.TypeNode = typeNode.typeArguments[0];
|
|
145
|
+
if (name === "Promise") return exploreNode(ctx, top);
|
|
146
|
+
return {
|
|
147
|
+
name,
|
|
148
|
+
typeArguments: typeNode.typeArguments.map((child) =>
|
|
149
|
+
exploreNode(ctx, child),
|
|
150
|
+
),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return { name };
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const exploreType = (ctx: IContext, type: ts.Type): IReflectType => {
|
|
157
|
+
// Analyze symbol, and take special cares
|
|
158
|
+
const symbol: ts.Symbol | undefined = type.aliasSymbol ?? type.symbol;
|
|
159
|
+
if (type.aliasSymbol === undefined && type.isUnionOrIntersection()) {
|
|
160
|
+
const joiner: string = type.isIntersection() ? " & " : " | ";
|
|
161
|
+
return {
|
|
162
|
+
name: type.types
|
|
163
|
+
.map((child) => exploreType(ctx, child))
|
|
164
|
+
.map(getEscapedText)
|
|
165
|
+
.join(joiner),
|
|
166
|
+
};
|
|
167
|
+
} else if (symbol === undefined)
|
|
168
|
+
return {
|
|
169
|
+
name: ctx.checker.typeToString(
|
|
170
|
+
type,
|
|
171
|
+
undefined,
|
|
172
|
+
ts.TypeFormatFlags.NoTruncation,
|
|
173
|
+
),
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// Find matched import statement
|
|
177
|
+
const name: string = getNameOfSymbol(symbol);
|
|
178
|
+
const prefix: string = name.split(".")[0];
|
|
179
|
+
|
|
180
|
+
let matched: boolean = false;
|
|
181
|
+
const insert = (imp: IReflectImport): void => {
|
|
182
|
+
matched ||= true;
|
|
183
|
+
ctx.container.push(imp);
|
|
184
|
+
};
|
|
185
|
+
for (const imp of ctx.imports)
|
|
186
|
+
if (imp.elements.includes(prefix))
|
|
187
|
+
insert({
|
|
188
|
+
file: imp.file,
|
|
189
|
+
asterisk: null,
|
|
190
|
+
default: null,
|
|
191
|
+
elements: [prefix],
|
|
192
|
+
});
|
|
193
|
+
if (prefix !== "Promise" && matched === false)
|
|
194
|
+
emplaceSymbol(ctx, symbol, prefix);
|
|
195
|
+
|
|
196
|
+
// Finalize with generic arguments
|
|
197
|
+
const generic: readonly ts.Type[] = type.aliasSymbol
|
|
198
|
+
? (type.aliasTypeArguments ?? [])
|
|
199
|
+
: ctx.checker.getTypeArguments(type as ts.TypeReference);
|
|
200
|
+
return generic.length
|
|
201
|
+
? name === "Promise"
|
|
202
|
+
? exploreType(ctx, generic[0])
|
|
203
|
+
: {
|
|
204
|
+
name,
|
|
205
|
+
typeArguments: generic.map((child) => exploreType(ctx, child)),
|
|
206
|
+
}
|
|
207
|
+
: { name };
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const emplaceSymbol = (
|
|
211
|
+
ctx: IContext,
|
|
212
|
+
symbol: ts.Symbol,
|
|
213
|
+
prefix: string,
|
|
214
|
+
): void => {
|
|
215
|
+
// GET SOURCE FILE
|
|
216
|
+
const sourceFile: ts.SourceFile | undefined =
|
|
217
|
+
symbol.declarations?.[0]?.getSourceFile();
|
|
218
|
+
if (sourceFile === undefined) return;
|
|
219
|
+
if (sourceFile.fileName.indexOf("/typescript/lib") === -1)
|
|
220
|
+
ctx.container.push({
|
|
221
|
+
file: sourceFile.fileName,
|
|
222
|
+
asterisk: null,
|
|
223
|
+
default: null,
|
|
224
|
+
elements: [prefix],
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const getEscapedText = (type: IReflectType): string =>
|
|
230
|
+
type.typeArguments
|
|
231
|
+
? `${type.name}<${type.typeArguments.map(getEscapedText).join(", ")}>`
|
|
232
|
+
: type.name;
|
|
233
|
+
|
|
234
|
+
const getNameOfSymbol = (symbol: ts.Symbol): string =>
|
|
235
|
+
exploreName(
|
|
236
|
+
symbol.escapedName.toString(),
|
|
237
|
+
symbol.getDeclarations()?.[0]?.parent,
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
const exploreName = (name: string, decl?: ts.Node): string =>
|
|
241
|
+
decl && ts.isModuleBlock(decl)
|
|
242
|
+
? exploreName(
|
|
243
|
+
`${decl.parent.name.getFullText().trim()}.${name}`,
|
|
244
|
+
decl.parent.parent,
|
|
245
|
+
)
|
|
246
|
+
: name;
|
|
@@ -1,171 +1,126 @@
|
|
|
1
|
+
import path from "path";
|
|
1
2
|
import ts from "typescript";
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
import { IReflectTypeImport } from "../structures/IReflectTypeImport";
|
|
4
|
+
import { IReflectImport } from "../structures/IReflectImport";
|
|
5
5
|
import { MapUtil } from "../utils/MapUtil";
|
|
6
6
|
|
|
7
7
|
export namespace ImportAnalyzer {
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
type: explore({
|
|
22
|
-
checker,
|
|
23
|
-
generics,
|
|
24
|
-
imports,
|
|
25
|
-
type,
|
|
26
|
-
}),
|
|
27
|
-
imports: [...imports].map(([file, instances]) => ({
|
|
28
|
-
file,
|
|
29
|
-
instances: Array.from(instances),
|
|
30
|
-
})),
|
|
31
|
-
};
|
|
32
|
-
} catch {
|
|
33
|
-
return {
|
|
34
|
-
imports: [],
|
|
35
|
-
type: null,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
};
|
|
8
|
+
export const analyze = (file: ts.SourceFile): IReflectImport[] =>
|
|
9
|
+
file.statements
|
|
10
|
+
.filter(ts.isImportDeclaration)
|
|
11
|
+
.map((imp) => {
|
|
12
|
+
const clause: ts.ImportClause | undefined = imp.importClause;
|
|
13
|
+
if (clause === undefined) return null;
|
|
14
|
+
try {
|
|
15
|
+
// no real position
|
|
16
|
+
// import statement generated by transformer like typia
|
|
17
|
+
imp.moduleSpecifier.getText();
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
39
21
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
22
|
+
const reflect: IReflectImport = {
|
|
23
|
+
file: normalizePath(
|
|
24
|
+
path.dirname(file.fileName),
|
|
25
|
+
ts.isStringLiteral(imp.moduleSpecifier)
|
|
26
|
+
? imp.moduleSpecifier.text
|
|
27
|
+
: escapeQuotes(imp.moduleSpecifier.getText()),
|
|
28
|
+
),
|
|
29
|
+
elements: [],
|
|
30
|
+
default: null,
|
|
31
|
+
asterisk: null,
|
|
32
|
+
};
|
|
33
|
+
if (clause.name) reflect.default = clause.name.getText();
|
|
34
|
+
if (clause.namedBindings === undefined) return reflect;
|
|
35
|
+
else if (ts.isNamedImports(clause.namedBindings))
|
|
36
|
+
reflect.elements = clause.namedBindings.elements.map((e) =>
|
|
37
|
+
e.name.getText(),
|
|
38
|
+
);
|
|
39
|
+
else if (ts.isNamespaceImport(clause.namedBindings))
|
|
40
|
+
reflect.asterisk = clause.namedBindings.name.getText();
|
|
41
|
+
return reflect;
|
|
42
|
+
})
|
|
43
|
+
.filter((r) => r !== null);
|
|
53
44
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
45
|
+
export const merge = (imports: IReflectImport[]): IReflectImport[] => {
|
|
46
|
+
// group by files
|
|
47
|
+
const fileGroups: Map<string, IReflectImport[]> = new Map();
|
|
48
|
+
for (const imp of imports) {
|
|
49
|
+
const array: IReflectImport[] = MapUtil.take(
|
|
50
|
+
fileGroups,
|
|
51
|
+
imp.file,
|
|
52
|
+
() => [],
|
|
61
53
|
);
|
|
62
|
-
|
|
63
|
-
throw new Error(
|
|
64
|
-
"Error on ImportAnalyzer.analyze(): invalid promise type.",
|
|
65
|
-
);
|
|
66
|
-
type = generic[0];
|
|
54
|
+
array.push(imp);
|
|
67
55
|
}
|
|
68
|
-
return
|
|
56
|
+
return Array.from(fileGroups.entries())
|
|
57
|
+
.map(([key, value]) => mergeGroup(key, value))
|
|
58
|
+
.flat();
|
|
69
59
|
};
|
|
70
60
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
.join(joiner),
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
// NO SYMBOL
|
|
112
|
-
else if (symbol === undefined)
|
|
113
|
-
return {
|
|
114
|
-
name: props.checker.typeToString(
|
|
115
|
-
type,
|
|
116
|
-
undefined,
|
|
117
|
-
ts.TypeFormatFlags.NoTruncation,
|
|
118
|
-
),
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
//----
|
|
122
|
-
// SPECIALIZATION
|
|
123
|
-
//----
|
|
124
|
-
const name: string = getNameOfSymbol(symbol);
|
|
125
|
-
const sourceFile: ts.SourceFile | undefined =
|
|
126
|
-
symbol.declarations?.[0]?.getSourceFile();
|
|
127
|
-
if (sourceFile === undefined) return { name };
|
|
128
|
-
else if (sourceFile.fileName.indexOf("typescript/lib") === -1) {
|
|
129
|
-
const set: Set<string> = MapUtil.take(
|
|
130
|
-
props.imports,
|
|
131
|
-
sourceFile.fileName,
|
|
132
|
-
() => new Set(),
|
|
61
|
+
function mergeGroup(
|
|
62
|
+
file: string,
|
|
63
|
+
imports: IReflectImport[],
|
|
64
|
+
): IReflectImport[] {
|
|
65
|
+
const allStarImports: IReflectImport[] = Array.from(
|
|
66
|
+
new Set(
|
|
67
|
+
imports
|
|
68
|
+
.filter((imp) => imp.asterisk !== null)
|
|
69
|
+
.map((imp) => imp.asterisk!),
|
|
70
|
+
),
|
|
71
|
+
)
|
|
72
|
+
.sort()
|
|
73
|
+
.map(
|
|
74
|
+
(allStarImport) =>
|
|
75
|
+
({
|
|
76
|
+
file,
|
|
77
|
+
elements: [],
|
|
78
|
+
default: null,
|
|
79
|
+
asterisk: allStarImport,
|
|
80
|
+
}) satisfies IReflectImport,
|
|
81
|
+
);
|
|
82
|
+
const defaultImports: IReflectImport[] = Array.from(
|
|
83
|
+
new Set(
|
|
84
|
+
imports
|
|
85
|
+
.filter((imp) => imp.default !== null)
|
|
86
|
+
.map((imp) => imp.default!),
|
|
87
|
+
),
|
|
88
|
+
)
|
|
89
|
+
.sort()
|
|
90
|
+
.map(
|
|
91
|
+
(defaultImport) =>
|
|
92
|
+
({
|
|
93
|
+
file,
|
|
94
|
+
elements: [],
|
|
95
|
+
default: defaultImport,
|
|
96
|
+
asterisk: null,
|
|
97
|
+
}) satisfies IReflectImport,
|
|
133
98
|
);
|
|
134
|
-
|
|
99
|
+
const instances: Set<string> = new Set(
|
|
100
|
+
imports.map((imp) => imp.elements).flat(),
|
|
101
|
+
);
|
|
102
|
+
if (instances.size !== 0) {
|
|
103
|
+
if (defaultImports.length !== 0)
|
|
104
|
+
defaultImports[0].elements = Array.from(instances).sort();
|
|
105
|
+
else
|
|
106
|
+
defaultImports.push({
|
|
107
|
+
file,
|
|
108
|
+
elements: Array.from(instances).sort(),
|
|
109
|
+
default: null,
|
|
110
|
+
asterisk: null,
|
|
111
|
+
});
|
|
135
112
|
}
|
|
113
|
+
return [...allStarImports, ...defaultImports];
|
|
114
|
+
}
|
|
136
115
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
? name === "Promise"
|
|
143
|
-
? explore({
|
|
144
|
-
...props,
|
|
145
|
-
type: generic[0],
|
|
146
|
-
})
|
|
147
|
-
: {
|
|
148
|
-
name,
|
|
149
|
-
typeArguments: generic.map((child) =>
|
|
150
|
-
explore({
|
|
151
|
-
...props,
|
|
152
|
-
type: child,
|
|
153
|
-
}),
|
|
154
|
-
),
|
|
155
|
-
}
|
|
156
|
-
: { name };
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
const exploreName = (name: string, decl?: ts.Node): string =>
|
|
160
|
-
decl && ts.isModuleBlock(decl)
|
|
161
|
-
? exploreName(
|
|
162
|
-
`${decl.parent.name.getFullText().trim()}.${name}`,
|
|
163
|
-
decl.parent.parent,
|
|
164
|
-
)
|
|
165
|
-
: name;
|
|
116
|
+
function escapeQuotes(str: string): string {
|
|
117
|
+
if (str.startsWith("'") && str.endsWith("'")) return str.slice(1, -1);
|
|
118
|
+
else if (str.startsWith('"') && str.endsWith('"')) return str.slice(1, -1);
|
|
119
|
+
return str;
|
|
120
|
+
}
|
|
166
121
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
122
|
+
function normalizePath(root: string, str: string): string {
|
|
123
|
+
if (str.startsWith(".")) return path.resolve(root, str);
|
|
124
|
+
return `node_modules/${str}`;
|
|
125
|
+
}
|
|
171
126
|
}
|
|
@@ -101,7 +101,7 @@ export namespace ReflectHttpOperationAnalyzer {
|
|
|
101
101
|
errors,
|
|
102
102
|
}),
|
|
103
103
|
tags: Reflect.getMetadata("swagger/apiUseTags", props.function) ?? [],
|
|
104
|
-
imports: ImportAnalyzer.
|
|
104
|
+
imports: ImportAnalyzer.merge(
|
|
105
105
|
[
|
|
106
106
|
...props.metadata.parameters
|
|
107
107
|
.filter((x) => parameters.some((y) => x.index === y.index))
|
|
@@ -2,7 +2,7 @@ import { ranges } from "tstl";
|
|
|
2
2
|
|
|
3
3
|
import { INestiaProject } from "../structures/INestiaProject";
|
|
4
4
|
import { IReflectController } from "../structures/IReflectController";
|
|
5
|
-
import {
|
|
5
|
+
import { IReflectImport } from "../structures/IReflectImport";
|
|
6
6
|
import { IReflectWebSocketOperation } from "../structures/IReflectWebSocketOperation";
|
|
7
7
|
import { IReflectWebSocketOperationParameter } from "../structures/IReflectWebSocketOperationParameter";
|
|
8
8
|
import { IOperationMetadata } from "../transformers/IOperationMetadata";
|
|
@@ -50,7 +50,7 @@ export namespace ReflectWebSocketOperationAnalyzer {
|
|
|
50
50
|
].join("\n"),
|
|
51
51
|
);
|
|
52
52
|
|
|
53
|
-
const imports:
|
|
53
|
+
const imports: IReflectImport[] = [];
|
|
54
54
|
const parameters: IReflectWebSocketOperationParameter[] = preconfigured
|
|
55
55
|
.map((p) => {
|
|
56
56
|
// METADATA INFO
|
|
@@ -164,7 +164,7 @@ export namespace ReflectWebSocketOperationAnalyzer {
|
|
|
164
164
|
function: ctx.function,
|
|
165
165
|
versions: ReflectMetadataAnalyzer.versions(ctx.function),
|
|
166
166
|
parameters,
|
|
167
|
-
imports: ImportAnalyzer.
|
|
167
|
+
imports: ImportAnalyzer.merge(imports),
|
|
168
168
|
description: ctx.metadata.description ?? null,
|
|
169
169
|
jsDocTags: ctx.metadata.jsDocTags,
|
|
170
170
|
};
|
|
@@ -18,21 +18,13 @@ export namespace E2eFileProgrammer {
|
|
|
18
18
|
const importer: ImportDictionary = new ImportDictionary(
|
|
19
19
|
`${props.current}/${getFunctionName(route)}.ts`,
|
|
20
20
|
);
|
|
21
|
-
if (project.config.clone !== true)
|
|
22
|
-
for (const tuple of route.imports)
|
|
23
|
-
for (const instance of tuple.instances)
|
|
24
|
-
importer.internal({
|
|
25
|
-
file: tuple.file,
|
|
26
|
-
type: true,
|
|
27
|
-
instance,
|
|
28
|
-
});
|
|
21
|
+
if (project.config.clone !== true) importer.declarations(route.imports);
|
|
29
22
|
importer.internal({
|
|
30
|
-
type: false,
|
|
31
23
|
file: props.api,
|
|
32
|
-
|
|
24
|
+
declaration: false,
|
|
25
|
+
type: "default",
|
|
33
26
|
name: "api",
|
|
34
27
|
});
|
|
35
|
-
|
|
36
28
|
const functor: ts.Statement = generateFunctor(project)(importer)(route);
|
|
37
29
|
await FilePrinter.write({
|
|
38
30
|
location: importer.file,
|