@nestia/migrate 0.9.6 → 0.10.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/lib/MigrateApplication.js +367 -197
- package/lib/MigrateApplication.js.map +1 -1
- package/lib/analyzers/MigrateControllerAnalyzer.js +5 -0
- package/lib/analyzers/MigrateControllerAnalyzer.js.map +1 -1
- package/lib/analyzers/MigrateMethodAnalyzer.js +121 -36
- package/lib/analyzers/MigrateMethodAnalyzer.js.map +1 -1
- package/lib/bundles/NEST_TEMPLATE.js +2 -2
- package/lib/bundles/SDK_TEMPLATE.js +1 -1
- package/lib/programmers/MigrateSchemaProgrammer.js +15 -13
- package/lib/programmers/MigrateSchemaProgrammer.js.map +1 -1
- package/lib/structures/ISwagger.d.ts +1 -1
- package/lib/structures/ISwaggerComponents.d.ts +7 -1
- package/lib/structures/ISwaggerRoute.d.ts +6 -41
- package/lib/structures/ISwaggerRouteBodyContent.d.ts +14 -0
- package/lib/structures/ISwaggerRouteBodyContent.js +3 -0
- package/lib/structures/ISwaggerRouteBodyContent.js.map +1 -0
- package/lib/structures/ISwaggerRouteHeader.d.ts +0 -0
- package/lib/structures/ISwaggerRouteHeader.js +2 -0
- package/lib/structures/ISwaggerRouteHeader.js.map +1 -0
- package/lib/structures/ISwaggerRouteParameter.d.ts +13 -0
- package/lib/structures/ISwaggerRouteParameter.js +3 -0
- package/lib/structures/ISwaggerRouteParameter.js.map +1 -0
- package/lib/structures/ISwaggerRouteRequestBody.d.ts +11 -0
- package/lib/structures/ISwaggerRouteRequestBody.js +3 -0
- package/lib/structures/ISwaggerRouteRequestBody.js.map +1 -0
- package/lib/structures/ISwaggerRouteResponse.d.ts +10 -0
- package/lib/structures/ISwaggerRouteResponse.js +3 -0
- package/lib/structures/ISwaggerRouteResponse.js.map +1 -0
- package/lib/utils/SwaggerComponentsExplorer.d.ts +9 -0
- package/lib/utils/SwaggerComponentsExplorer.js +29 -0
- package/lib/utils/SwaggerComponentsExplorer.js.map +1 -0
- package/lib/utils/SwaggerExplorer.d.ts +0 -0
- package/lib/utils/SwaggerExplorer.js +2 -0
- package/lib/utils/SwaggerExplorer.js.map +1 -0
- package/lib/utils/SwaggerTypeChecker.d.ts +2 -2
- package/lib/utils/SwaggerTypeChecker.js +25 -25
- package/lib/utils/SwaggerTypeChecker.js.map +1 -1
- package/package.json +2 -2
- package/src/analyzers/MigrateControllerAnalyzer.ts +7 -0
- package/src/analyzers/MigrateMethodAnalyzer.ts +147 -71
- package/src/bundles/NEST_TEMPLATE.ts +2 -2
- package/src/bundles/SDK_TEMPLATE.ts +1 -1
- package/src/programmers/MigrateSchemaProgrammer.ts +19 -16
- package/src/structures/ISwagger.ts +4 -1
- package/src/structures/ISwaggerComponents.ts +7 -1
- package/src/structures/ISwaggerRoute.ts +9 -44
- package/src/structures/ISwaggerRouteBodyContent.ts +15 -0
- package/src/structures/ISwaggerRouteHeader.ts +0 -0
- package/src/structures/ISwaggerRouteParameter.ts +14 -0
- package/src/structures/ISwaggerRouteRequestBody.ts +12 -0
- package/src/structures/ISwaggerRouteResponse.ts +11 -0
- package/src/utils/SwaggerComponentsExplorer.ts +43 -0
- package/src/utils/SwaggerTypeChecker.ts +5 -5
@@ -1,12 +1,17 @@
|
|
1
|
+
import typia from "typia";
|
1
2
|
import { Escaper } from "typia/lib/utils/Escaper";
|
2
3
|
|
3
4
|
import { IMigrateProgram } from "../structures/IMigrateProgram";
|
4
5
|
import { IMigrateRoute } from "../structures/IMigrateRoute";
|
5
6
|
import { ISwagger } from "../structures/ISwagger";
|
6
7
|
import { ISwaggerRoute } from "../structures/ISwaggerRoute";
|
8
|
+
import { ISwaggerRouteBodyContent } from "../structures/ISwaggerRouteBodyContent";
|
9
|
+
import { ISwaggerRouteParameter } from "../structures/ISwaggerRouteParameter";
|
10
|
+
import { ISwaggerRouteResponse } from "../structures/ISwaggerRouteResponse";
|
7
11
|
import { ISwaggerSchema } from "../structures/ISwaggerSchema";
|
8
12
|
import { StringUtil } from "../utils/StringUtil";
|
9
|
-
import {
|
13
|
+
import { SwaggerComponentsExplorer } from "../utils/SwaggerComponentsExplorer";
|
14
|
+
import { SwaggerTypeChecker } from "../utils/SwaggerTypeChecker";
|
10
15
|
|
11
16
|
export namespace MigrateMethodAnalzyer {
|
12
17
|
export const analyze =
|
@@ -19,12 +24,46 @@ export namespace MigrateMethodAnalzyer {
|
|
19
24
|
const success = emplaceBodySchema("response")(
|
20
25
|
emplaceReference(props.swagger)("response"),
|
21
26
|
)(
|
22
|
-
|
23
|
-
|
24
|
-
|
27
|
+
(() => {
|
28
|
+
const response =
|
29
|
+
route.responses?.["201"] ??
|
30
|
+
route.responses?.["200"] ??
|
31
|
+
route.responses?.default;
|
32
|
+
if (response === undefined) return undefined;
|
33
|
+
SwaggerComponentsExplorer.getResponse(props.swagger.components)(
|
34
|
+
response,
|
35
|
+
) ?? undefined;
|
36
|
+
})(),
|
25
37
|
);
|
26
38
|
|
27
39
|
const failures: string[] = [];
|
40
|
+
for (const p of route.parameters ?? [])
|
41
|
+
if (
|
42
|
+
SwaggerComponentsExplorer.getParameter(props.swagger.components)(
|
43
|
+
p,
|
44
|
+
) === null
|
45
|
+
)
|
46
|
+
failures.push(
|
47
|
+
`parameter "${(p as ISwaggerRouteParameter.IReference).$ref}" is not defined in "components.parameters".`,
|
48
|
+
);
|
49
|
+
for (const value of Object.values(route.responses ?? {}))
|
50
|
+
if (
|
51
|
+
SwaggerComponentsExplorer.getResponse(props.swagger.components)(
|
52
|
+
value,
|
53
|
+
) === null
|
54
|
+
)
|
55
|
+
failures.push(
|
56
|
+
`response "${(value as ISwaggerRouteResponse.IReference).$ref}" is not defined in "components.responses".`,
|
57
|
+
);
|
58
|
+
if (
|
59
|
+
route.requestBody &&
|
60
|
+
SwaggerComponentsExplorer.getRequestBody(props.swagger.components)(
|
61
|
+
route.requestBody,
|
62
|
+
) === null
|
63
|
+
)
|
64
|
+
failures.push(
|
65
|
+
`requestBody "${(route.requestBody as ISwaggerRouteParameter.IReference).$ref}" is not defined in "components.requestBodies".`,
|
66
|
+
);
|
28
67
|
if (body === false)
|
29
68
|
failures.push(
|
30
69
|
`supports only "application/json", "application/x-www-form-urlencoded", "multipart/form-data" and "text/plain" content type in the request body.`,
|
@@ -39,17 +78,27 @@ export namespace MigrateMethodAnalzyer {
|
|
39
78
|
);
|
40
79
|
|
41
80
|
const [headers, query] = ["header", "query"].map((type) => {
|
42
|
-
const parameters = (route.parameters ?? [])
|
43
|
-
(
|
44
|
-
|
81
|
+
const parameters: ISwaggerRouteParameter[] = (route.parameters ?? [])
|
82
|
+
.filter(
|
83
|
+
(p) =>
|
84
|
+
SwaggerComponentsExplorer.getParameter(props.swagger.components)(
|
85
|
+
p,
|
86
|
+
)?.in === type,
|
87
|
+
)
|
88
|
+
.map(
|
89
|
+
(p) =>
|
90
|
+
SwaggerComponentsExplorer.getParameter(props.swagger.components)(
|
91
|
+
p,
|
92
|
+
)!,
|
93
|
+
);
|
45
94
|
if (parameters.length === 0) return null;
|
46
95
|
|
47
96
|
const objects = parameters
|
48
97
|
.map((p) =>
|
49
|
-
|
98
|
+
SwaggerTypeChecker.isObject(p.schema)
|
50
99
|
? p.schema
|
51
|
-
:
|
52
|
-
|
100
|
+
: SwaggerTypeChecker.isReference(p.schema) &&
|
101
|
+
SwaggerTypeChecker.isObject(
|
53
102
|
(props.swagger.components.schemas ?? {})[
|
54
103
|
p.schema.$ref.replace(`#/components/schemas/`, ``)
|
55
104
|
] ?? {},
|
@@ -60,11 +109,11 @@ export namespace MigrateMethodAnalzyer {
|
|
60
109
|
.filter((s) => !!s);
|
61
110
|
const primitives = parameters.filter(
|
62
111
|
(p) =>
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
112
|
+
SwaggerTypeChecker.isBoolean(p.schema) ||
|
113
|
+
SwaggerTypeChecker.isNumber(p.schema) ||
|
114
|
+
SwaggerTypeChecker.isInteger(p.schema) ||
|
115
|
+
SwaggerTypeChecker.isString(p.schema) ||
|
116
|
+
SwaggerTypeChecker.isArray(p.schema),
|
68
117
|
);
|
69
118
|
if (objects.length === 1 && primitives.length === 0) return objects[0];
|
70
119
|
else if (objects.length > 1) {
|
@@ -75,7 +124,7 @@ export namespace MigrateMethodAnalzyer {
|
|
75
124
|
}
|
76
125
|
|
77
126
|
const dto: ISwaggerSchema.IObject | null = objects[0]
|
78
|
-
?
|
127
|
+
? SwaggerTypeChecker.isObject(objects[0])
|
79
128
|
? objects[0]
|
80
129
|
: ((props.swagger.components.schemas ?? {})[
|
81
130
|
(objects[0] as ISwaggerSchema.IReference).$ref.replace(
|
@@ -86,7 +135,7 @@ export namespace MigrateMethodAnalzyer {
|
|
86
135
|
: null;
|
87
136
|
const entire: ISwaggerSchema.IObject[] = [
|
88
137
|
...objects.map((o) =>
|
89
|
-
|
138
|
+
SwaggerTypeChecker.isObject(o)
|
90
139
|
? o
|
91
140
|
: (props.swagger.components.schemas?.[
|
92
141
|
o.$ref.replace(`#/components/schemas/`, ``)
|
@@ -152,7 +201,11 @@ export namespace MigrateMethodAnalzyer {
|
|
152
201
|
);
|
153
202
|
if (
|
154
203
|
parameterNames.length !==
|
155
|
-
(route.parameters ?? []).filter(
|
204
|
+
(route.parameters ?? []).filter(
|
205
|
+
(p) =>
|
206
|
+
SwaggerComponentsExplorer.getParameter(props.swagger.components)(p)
|
207
|
+
?.in === "path",
|
208
|
+
).length
|
156
209
|
)
|
157
210
|
failures.push(
|
158
211
|
"number of path parameters are not matched with its full path.",
|
@@ -179,7 +232,10 @@ export namespace MigrateMethodAnalzyer {
|
|
179
232
|
}
|
180
233
|
: null,
|
181
234
|
parameters: (route.parameters ?? [])
|
182
|
-
.
|
235
|
+
.map((p) =>
|
236
|
+
SwaggerComponentsExplorer.getParameter(props.swagger.components)(p),
|
237
|
+
)
|
238
|
+
.filter((p) => p !== null && p.in === "path")
|
183
239
|
.map((p, i) => ({
|
184
240
|
name: parameterNames[i],
|
185
241
|
key: (() => {
|
@@ -191,8 +247,8 @@ export namespace MigrateMethodAnalzyer {
|
|
191
247
|
}
|
192
248
|
})(),
|
193
249
|
schema: {
|
194
|
-
...p
|
195
|
-
description: p
|
250
|
+
...p!.schema,
|
251
|
+
description: p!.schema.description ?? p!.description,
|
196
252
|
},
|
197
253
|
})),
|
198
254
|
query: query
|
@@ -211,74 +267,94 @@ export namespace MigrateMethodAnalzyer {
|
|
211
267
|
key !== "200" &&
|
212
268
|
key !== "201" &&
|
213
269
|
key !== "default" &&
|
214
|
-
!!
|
270
|
+
!!SwaggerComponentsExplorer.getResponse(
|
271
|
+
props.swagger.components,
|
272
|
+
)(value)?.content?.["application/json"],
|
215
273
|
)
|
216
|
-
.map(([key, value]) =>
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
274
|
+
.map(([key, value]) => {
|
275
|
+
const r = SwaggerComponentsExplorer.getResponse(
|
276
|
+
props.swagger.components,
|
277
|
+
)(value)!;
|
278
|
+
return [
|
279
|
+
key,
|
280
|
+
{
|
281
|
+
description: r.description,
|
282
|
+
schema: r.content?.["application/json"]?.schema ?? {},
|
283
|
+
},
|
284
|
+
];
|
285
|
+
}),
|
223
286
|
),
|
224
287
|
deprecated: route.deprecated ?? false,
|
225
|
-
comment: () => describe(route),
|
288
|
+
comment: () => describe(props.swagger)(route),
|
226
289
|
tags: route.tags ?? [],
|
227
290
|
};
|
228
291
|
};
|
229
292
|
|
230
|
-
const describe =
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
293
|
+
const describe =
|
294
|
+
(swagger: ISwagger) =>
|
295
|
+
(route: ISwaggerRoute): string => {
|
296
|
+
const commentTags: string[] = [];
|
297
|
+
const add = (text: string) => {
|
298
|
+
if (commentTags.every((line) => line !== text)) commentTags.push(text);
|
299
|
+
};
|
235
300
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
301
|
+
let description: string = route.description ?? "";
|
302
|
+
if (route.summary) {
|
303
|
+
const emended: string = route.summary.endsWith(".")
|
304
|
+
? route.summary
|
305
|
+
: route.summary + ".";
|
306
|
+
if (
|
307
|
+
!!description.length &&
|
308
|
+
!description.startsWith(route.summary) &&
|
309
|
+
!route["x-nestia-jsDocTags"]?.some((t) => t.name === "summary")
|
310
|
+
)
|
311
|
+
description = `${emended}\n${description}`;
|
312
|
+
}
|
313
|
+
for (const p of route.parameters ?? []) {
|
314
|
+
const param: ISwaggerRouteParameter | null = (() => {
|
315
|
+
if (!typia.is<ISwaggerRouteParameter.IReference>(p))
|
316
|
+
return typia.is<ISwaggerRouteParameter>(p) ? p : null;
|
317
|
+
return (
|
318
|
+
swagger.components.parameters?.[
|
319
|
+
p.$ref.replace(`#/components/parameters/`, ``)
|
320
|
+
] ?? null
|
321
|
+
);
|
322
|
+
})();
|
323
|
+
if (param !== null && param.description)
|
324
|
+
add(`@param ${param.name} ${param.description}`);
|
325
|
+
}
|
326
|
+
if (route.requestBody?.description)
|
327
|
+
add(`@param body ${route.requestBody.description}`);
|
328
|
+
for (const security of route.security ?? [])
|
329
|
+
for (const [name, scopes] of Object.entries(security))
|
330
|
+
add(`@security ${[name, ...scopes].join("")}`);
|
331
|
+
if (route.tags) route.tags.forEach((name) => add(`@tag ${name}`));
|
332
|
+
if (route.deprecated) add("@deprecated");
|
333
|
+
return description.length
|
334
|
+
? commentTags.length
|
335
|
+
? `${description}\n\n${commentTags.join("\n")}`
|
336
|
+
: description
|
337
|
+
: commentTags.join("\n");
|
338
|
+
};
|
263
339
|
|
264
340
|
const isNotObjectLiteral = (schema: ISwaggerSchema): boolean =>
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
(
|
341
|
+
SwaggerTypeChecker.isReference(schema) ||
|
342
|
+
SwaggerTypeChecker.isBoolean(schema) ||
|
343
|
+
SwaggerTypeChecker.isNumber(schema) ||
|
344
|
+
SwaggerTypeChecker.isString(schema) ||
|
345
|
+
SwaggerTypeChecker.isUnknown(schema) ||
|
346
|
+
(SwaggerTypeChecker.isAnyOf(schema) &&
|
271
347
|
schema.anyOf.every(isNotObjectLiteral)) ||
|
272
|
-
(
|
348
|
+
(SwaggerTypeChecker.isOneOf(schema) &&
|
273
349
|
schema.oneOf.every(isNotObjectLiteral)) ||
|
274
|
-
(
|
350
|
+
(SwaggerTypeChecker.isArray(schema) && isNotObjectLiteral(schema.items));
|
275
351
|
|
276
352
|
const emplaceBodySchema =
|
277
353
|
(from: "request" | "response") =>
|
278
354
|
(emplacer: (schema: ISwaggerSchema) => ISwaggerSchema.IReference) =>
|
279
355
|
(meta?: {
|
280
356
|
description?: string;
|
281
|
-
content?:
|
357
|
+
content?: ISwaggerRouteBodyContent;
|
282
358
|
"x-nestia-encrypted"?: boolean;
|
283
359
|
}): false | null | IMigrateRoute.IBody => {
|
284
360
|
if (!meta?.content) return null;
|
@@ -47,7 +47,7 @@ export const NEST_TEMPLATE = [
|
|
47
47
|
{
|
48
48
|
"location": "",
|
49
49
|
"file": "package.json",
|
50
|
-
"content": "{\r\n \"private\": true,\r\n \"name\": \"@ORGANIZATION/PROJECT\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"Starter kit of Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"scripts\": {\r\n \"test\": \"node bin/test\",\r\n \"test:webpack\": \"npm run webpack && node bin/test/webpack.js\",\r\n \"------------------------BUILDS------------------------\": \"\",\r\n \"build\": \"npm run build:sdk && npm run build:main && npm run build:test\",\r\n \"build:api\": \"rimraf packages/api/lib && npm run build:sdk && tsc -p packages/api/tsconfig.json\",\r\n \"build:main\": \"rimraf lib && tsc\",\r\n \"build:sdk\": \"rimraf src/api/functional && nestia sdk\",\r\n \"build:swagger\": \"npx nestia swagger\",\r\n \"build:test\": \"rimraf bin && tsc -p test/tsconfig.json\",\r\n \"dev\": \"npm run build:test -- --watch\",\r\n \"eslint\": \"eslint src && eslint test\",\r\n \"eslint:fix\": \"eslint --fix src && eslint --fix test\",\r\n \"prepare\": \"ts-patch install && typia patch\",\r\n \"prettier\": \"prettier src --write && prettier test --write\",\r\n \"------------------------WEBPACK------------------------\": \"\",\r\n \"webpack\": \"rimraf dist && webpack\",\r\n \"webpack:start\": \"cd dist && node dist/server\",\r\n \"------------------------DEPLOYS------------------------\": \"\",\r\n \"package:api\": \"npm run build:swagger && npm run build:api && cd packages/api && npm publish\",\r\n \"start\": \"node lib/executable/server\",\r\n \"start:swagger\": \"ts-node src/executable/swagger.ts\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia-start\"\r\n },\r\n \"keywords\": [\r\n \"nestia\",\r\n \"template\",\r\n \"boilerplate\"\r\n ],\r\n \"author\": \"AUTHOR\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia-start/issues\"\r\n },\r\n \"homepage\": \"https://github.com/samchon/nestia-start#readme\",\r\n \"devDependencies\": {\r\n \"@nestia/e2e\": \"^0.4.
|
50
|
+
"content": "{\r\n \"private\": true,\r\n \"name\": \"@ORGANIZATION/PROJECT\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"Starter kit of Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"scripts\": {\r\n \"test\": \"node bin/test\",\r\n \"test:webpack\": \"npm run webpack && node bin/test/webpack.js\",\r\n \"------------------------BUILDS------------------------\": \"\",\r\n \"build\": \"npm run build:sdk && npm run build:main && npm run build:test\",\r\n \"build:api\": \"rimraf packages/api/lib && npm run build:sdk && tsc -p packages/api/tsconfig.json\",\r\n \"build:main\": \"rimraf lib && tsc\",\r\n \"build:sdk\": \"rimraf src/api/functional && nestia sdk\",\r\n \"build:swagger\": \"npx nestia swagger\",\r\n \"build:test\": \"rimraf bin && tsc -p test/tsconfig.json\",\r\n \"dev\": \"npm run build:test -- --watch\",\r\n \"eslint\": \"eslint src && eslint test\",\r\n \"eslint:fix\": \"eslint --fix src && eslint --fix test\",\r\n \"prepare\": \"ts-patch install && typia patch\",\r\n \"prettier\": \"prettier src --write && prettier test --write\",\r\n \"------------------------WEBPACK------------------------\": \"\",\r\n \"webpack\": \"rimraf dist && webpack\",\r\n \"webpack:start\": \"cd dist && node dist/server\",\r\n \"------------------------DEPLOYS------------------------\": \"\",\r\n \"package:api\": \"npm run build:swagger && npm run build:api && cd packages/api && npm publish\",\r\n \"start\": \"node lib/executable/server\",\r\n \"start:swagger\": \"ts-node src/executable/swagger.ts\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia-start\"\r\n },\r\n \"keywords\": [\r\n \"nestia\",\r\n \"template\",\r\n \"boilerplate\"\r\n ],\r\n \"author\": \"AUTHOR\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia-start/issues\"\r\n },\r\n \"homepage\": \"https://github.com/samchon/nestia-start#readme\",\r\n \"devDependencies\": {\r\n \"@nestia/e2e\": \"^0.4.2\",\r\n \"@nestia/sdk\": \"^2.5.16\",\r\n \"@trivago/prettier-plugin-sort-imports\": \"^4.3.0\",\r\n \"@types/cli\": \"^0.11.21\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"@types/inquirer\": \"^8.2.5\",\r\n \"@types/node\": \"^18.11.0\",\r\n \"@types/uuid\": \"^8.3.4\",\r\n \"@typescript-eslint/eslint-plugin\": \"^6.19.1\",\r\n \"@typescript-eslint/parser\": \"^6.19.1\",\r\n \"chalk\": \"^4.1.0\",\r\n \"cli\": \"^1.0.1\",\r\n \"copy-webpack-plugin\": \"^11.0.0\",\r\n \"eslint-plugin-deprecation\": \"^2.0.0\",\r\n \"express\": \"^4.18.2\",\r\n \"nestia\": \"^5.3.0\",\r\n \"prettier\": \"^3.2.4\",\r\n \"prettier-plugin-prisma\": \"^5.0.0\",\r\n \"rimraf\": \"^3.0.2\",\r\n \"source-map-support\": \"^0.5.21\",\r\n \"swagger-ui-express\": \"^5.0.0\",\r\n \"ts-loader\": \"^9.5.1\",\r\n \"ts-node\": \"^10.9.1\",\r\n \"ts-patch\": \"^3.0.2\",\r\n \"typescript\": \"^5.3.2\",\r\n \"typescript-transform-paths\": \"^3.4.6\",\r\n \"webpack\": \"^5.89.0\",\r\n \"webpack-cli\": \"^5.1.4\",\r\n \"write-file-webpack-plugin\": \"^4.5.1\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/core\": \"^2.5.16\",\r\n \"@nestia/fetcher\": \"^2.5.16\",\r\n \"@nestjs/common\": \"^10.3.5\",\r\n \"@nestjs/core\": \"^10.3.5\",\r\n \"@nestjs/platform-express\": \"^10.3.5\",\r\n \"commander\": \"10.0.0\",\r\n \"dotenv\": \"^16.3.1\",\r\n \"dotenv-expand\": \"^10.0.0\",\r\n \"inquirer\": \"8.2.5\",\r\n \"serialize-error\": \"^4.1.0\",\r\n \"tstl\": \"^2.5.13\",\r\n \"typia\": \"^5.5.7\",\r\n \"uuid\": \"^9.0.0\"\r\n },\r\n \"stackblitz\": {\r\n \"startCommand\": \"npm run prepare && npm run build:test && npm run test\"\r\n }\r\n}"
|
51
51
|
},
|
52
52
|
{
|
53
53
|
"location": "packages/api",
|
@@ -62,7 +62,7 @@ export const NEST_TEMPLATE = [
|
|
62
62
|
{
|
63
63
|
"location": "packages/api",
|
64
64
|
"file": "package.json",
|
65
|
-
"content": "{\r\n \"name\": \"@ORGANIZATION/PROJECT-api\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"SDK library generated by Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"npm run build:sdk && npm run compile\",\r\n \"build:sdk\": \"rimraf ../../src/api/functional && cd ../.. && npx nestia sdk && cd packages/api\",\r\n \"compile\": \"rimraf lib && tsc\",\r\n \"deploy\": \"npm run build && npm publish\",\r\n \"prepare\": \"ts-patch install && typia patch\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia\"\r\n },\r\n \"author\": \"Jeongho Nam\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia/issues\"\r\n },\r\n \"homepage\": \"https://nestia.io\",\r\n \"files\": [\r\n \"lib\",\r\n \"swagger.json\",\r\n \"package.json\",\r\n \"README.md\"\r\n ],\r\n \"devDependencies\": {\r\n \"rimraf\": \"^5.0.5\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.1.2\",\r\n \"typescript\": \"^5.3.3\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^2.5.
|
65
|
+
"content": "{\r\n \"name\": \"@ORGANIZATION/PROJECT-api\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"SDK library generated by Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"npm run build:sdk && npm run compile\",\r\n \"build:sdk\": \"rimraf ../../src/api/functional && cd ../.. && npx nestia sdk && cd packages/api\",\r\n \"compile\": \"rimraf lib && tsc\",\r\n \"deploy\": \"npm run build && npm publish\",\r\n \"prepare\": \"ts-patch install && typia patch\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia\"\r\n },\r\n \"author\": \"Jeongho Nam\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia/issues\"\r\n },\r\n \"homepage\": \"https://nestia.io\",\r\n \"files\": [\r\n \"lib\",\r\n \"swagger.json\",\r\n \"package.json\",\r\n \"README.md\"\r\n ],\r\n \"devDependencies\": {\r\n \"rimraf\": \"^5.0.5\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.1.2\",\r\n \"typescript\": \"^5.3.3\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^2.5.16\",\r\n \"typia\": \"^5.5.7\"\r\n }\r\n}"
|
66
66
|
},
|
67
67
|
{
|
68
68
|
"location": "packages/api",
|
@@ -22,7 +22,7 @@ export const SDK_TEMPLATE = [
|
|
22
22
|
{
|
23
23
|
"location": "",
|
24
24
|
"file": "package.json",
|
25
|
-
"content": "{\r\n \"name\": \"@ORGANIZATION/PROJECT-api\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"SDK library generated by Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"rimraf lib && tsc\",\r\n \"build:test\": \"rimraf bin && tsc --project test/tsconfig.json\",\r\n \"deploy\": \"npm run build && npm publish\",\r\n \"dev\": \"npm run build:test -- --watch\",\r\n \"prepare\": \"ts-patch install && typia patch\",\r\n \"start\": \"npx ts-node test/start.ts\",\r\n \"test\": \"npx ts-node test/index.ts\",\r\n \"test:simulate\": \"npx ts-node test/index.ts --simulate true\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia\"\r\n },\r\n \"author\": \"Jeongho Nam\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia/issues\"\r\n },\r\n \"homepage\": \"https://nestia.io\",\r\n \"files\": [\r\n \"lib\",\r\n \"swagger.json\",\r\n \"package.json\",\r\n \"README.md\"\r\n ],\r\n \"devDependencies\": {\r\n \"@nestia/e2e\": \"^0.4.1\",\r\n \"@types/inquirer\": \"8.2.5\",\r\n \"commander\": \"^10.0.0\",\r\n \"inquirer\": \"8.2.5\",\r\n \"prettier\": \"^3.2.5\",\r\n \"rimraf\": \"^5.0.5\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.1.2\",\r\n \"typescript\": \"^5.3.3\",\r\n \"typescript-transform-paths\": \"^3.4.6\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^2.5.
|
25
|
+
"content": "{\r\n \"name\": \"@ORGANIZATION/PROJECT-api\",\r\n \"version\": \"0.1.0\",\r\n \"description\": \"SDK library generated by Nestia\",\r\n \"main\": \"lib/index.js\",\r\n \"typings\": \"lib/index.d.ts\",\r\n \"scripts\": {\r\n \"build\": \"rimraf lib && tsc\",\r\n \"build:test\": \"rimraf bin && tsc --project test/tsconfig.json\",\r\n \"deploy\": \"npm run build && npm publish\",\r\n \"dev\": \"npm run build:test -- --watch\",\r\n \"prepare\": \"ts-patch install && typia patch\",\r\n \"start\": \"npx ts-node test/start.ts\",\r\n \"test\": \"npx ts-node test/index.ts\",\r\n \"test:simulate\": \"npx ts-node test/index.ts --simulate true\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"https://github.com/samchon/nestia\"\r\n },\r\n \"author\": \"Jeongho Nam\",\r\n \"license\": \"MIT\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/samchon/nestia/issues\"\r\n },\r\n \"homepage\": \"https://nestia.io\",\r\n \"files\": [\r\n \"lib\",\r\n \"swagger.json\",\r\n \"package.json\",\r\n \"README.md\"\r\n ],\r\n \"devDependencies\": {\r\n \"@nestia/e2e\": \"^0.4.1\",\r\n \"@types/inquirer\": \"8.2.5\",\r\n \"commander\": \"^10.0.0\",\r\n \"inquirer\": \"8.2.5\",\r\n \"prettier\": \"^3.2.5\",\r\n \"rimraf\": \"^5.0.5\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"ts-patch\": \"^3.1.2\",\r\n \"typescript\": \"^5.3.3\",\r\n \"typescript-transform-paths\": \"^3.4.6\"\r\n },\r\n \"dependencies\": {\r\n \"@nestia/fetcher\": \"^2.5.16\",\r\n \"typia\": \"^5.5.7\"\r\n }\r\n}"
|
26
26
|
},
|
27
27
|
{
|
28
28
|
"location": "",
|
@@ -7,7 +7,7 @@ import { Escaper } from "typia/lib/utils/Escaper";
|
|
7
7
|
import { ISwaggerComponents } from "../structures/ISwaggerComponents";
|
8
8
|
import { ISwaggerSchema } from "../structures/ISwaggerSchema";
|
9
9
|
import { FilePrinter } from "../utils/FilePrinter";
|
10
|
-
import {
|
10
|
+
import { SwaggerTypeChecker } from "../utils/SwaggerTypeChecker";
|
11
11
|
import { MigrateImportProgrammer } from "./MigrateImportProgrammer";
|
12
12
|
|
13
13
|
export namespace MigrateSchemaProgrammer {
|
@@ -19,34 +19,32 @@ export namespace MigrateSchemaProgrammer {
|
|
19
19
|
(importer: MigrateImportProgrammer) =>
|
20
20
|
(schema: ISwaggerSchema): ts.TypeNode => {
|
21
21
|
const union: ts.TypeNode[] = [];
|
22
|
-
if (
|
22
|
+
if (SwaggerTypeChecker.isUnknown(schema))
|
23
23
|
return TypeFactory.keyword("any");
|
24
|
-
else if (
|
25
|
-
|
26
|
-
else if (SwaggerSwaggerChecker.isNullable(components)(schema))
|
24
|
+
else if (SwaggerTypeChecker.isNullOnly(schema)) return createNode("null");
|
25
|
+
else if (SwaggerTypeChecker.isNullable(components)(schema))
|
27
26
|
union.push(createNode("null"));
|
28
27
|
|
29
28
|
const type: ts.TypeNode = (() => {
|
30
29
|
// ATOMIC
|
31
|
-
if (
|
32
|
-
|
33
|
-
else if (SwaggerSwaggerChecker.isInteger(schema))
|
30
|
+
if (SwaggerTypeChecker.isBoolean(schema)) return writeBoolean(schema);
|
31
|
+
else if (SwaggerTypeChecker.isInteger(schema))
|
34
32
|
return writeInteger(importer)(schema);
|
35
|
-
else if (
|
33
|
+
else if (SwaggerTypeChecker.isNumber(schema))
|
36
34
|
return writeNumber(importer)(schema);
|
37
35
|
// INSTANCES
|
38
|
-
else if (
|
36
|
+
else if (SwaggerTypeChecker.isString(schema))
|
39
37
|
return writeString(importer)(schema);
|
40
|
-
else if (
|
38
|
+
else if (SwaggerTypeChecker.isArray(schema))
|
41
39
|
return writeArray(components)(importer)(schema);
|
42
|
-
else if (
|
40
|
+
else if (SwaggerTypeChecker.isObject(schema))
|
43
41
|
return writeObject(components)(importer)(schema);
|
44
|
-
else if (
|
42
|
+
else if (SwaggerTypeChecker.isReference(schema))
|
45
43
|
return writeReference(components)(importer)(schema);
|
46
44
|
// NESTED UNION
|
47
|
-
else if (
|
45
|
+
else if (SwaggerTypeChecker.isAnyOf(schema))
|
48
46
|
return writeUnion(components)(importer)(schema.anyOf);
|
49
|
-
else if (
|
47
|
+
else if (SwaggerTypeChecker.isOneOf(schema))
|
50
48
|
return writeUnion(components)(importer)(schema.oneOf);
|
51
49
|
else return TypeFactory.keyword("any");
|
52
50
|
})();
|
@@ -236,10 +234,15 @@ export namespace MigrateSchemaProgrammer {
|
|
236
234
|
(
|
237
235
|
schema: ISwaggerSchema.IReference,
|
238
236
|
): ts.TypeReferenceNode | ts.KeywordTypeNode => {
|
237
|
+
if (schema.$ref.startsWith("#/components/schemas") === false)
|
238
|
+
return TypeFactory.keyword("any");
|
239
239
|
const name: string = schema.$ref.split("/").at(-1)!;
|
240
240
|
return name === ""
|
241
241
|
? TypeFactory.keyword("any")
|
242
|
-
: importer.dto(
|
242
|
+
: importer.dto(
|
243
|
+
schema.$ref.split("/").at(-1)!,
|
244
|
+
components["x-nestia-namespace"],
|
245
|
+
);
|
243
246
|
};
|
244
247
|
|
245
248
|
/* -----------------------------------------------------------
|
@@ -1,8 +1,14 @@
|
|
1
|
+
import { ISwaggerRouteParameter } from "./ISwaggerRouteParameter";
|
2
|
+
import { ISwaggerRouteRequestBody } from "./ISwaggerRouteRequestBody";
|
3
|
+
import { ISwaggerRouteResponse } from "./ISwaggerRouteResponse";
|
1
4
|
import { ISwaggerSchema } from "./ISwaggerSchema";
|
2
5
|
import { ISwaggerSecurityScheme } from "./ISwaggerSecurityScheme";
|
3
6
|
|
4
7
|
export interface ISwaggerComponents {
|
8
|
+
parameters?: Record<string, ISwaggerRouteParameter>;
|
9
|
+
requestBodies?: Record<string, ISwaggerRouteRequestBody>;
|
10
|
+
responses?: Record<string, ISwaggerRouteResponse>;
|
5
11
|
schemas?: Record<string, ISwaggerSchema>;
|
6
12
|
securitySchemes?: Record<string, ISwaggerSecurityScheme>;
|
7
|
-
namespace?: string;
|
13
|
+
"x-nestia-namespace"?: string;
|
8
14
|
}
|
@@ -1,11 +1,16 @@
|
|
1
1
|
import { IJsDocTagInfo } from "typia/lib/schemas/metadata/IJsDocTagInfo";
|
2
2
|
|
3
|
-
import {
|
3
|
+
import { ISwaggerRouteParameter } from "./ISwaggerRouteParameter";
|
4
|
+
import { ISwaggerRouteRequestBody } from "./ISwaggerRouteRequestBody";
|
5
|
+
import { ISwaggerRouteResponse } from "./ISwaggerRouteResponse";
|
4
6
|
|
5
7
|
export interface ISwaggerRoute {
|
6
|
-
parameters?:
|
7
|
-
requestBody?:
|
8
|
-
responses?:
|
8
|
+
parameters?: (ISwaggerRouteParameter | ISwaggerRouteParameter.IReference)[];
|
9
|
+
requestBody?: ISwaggerRouteRequestBody;
|
10
|
+
responses?: Record<
|
11
|
+
string,
|
12
|
+
ISwaggerRouteResponse | ISwaggerRouteResponse.IReference
|
13
|
+
>;
|
9
14
|
summary?: string;
|
10
15
|
description?: string;
|
11
16
|
deprecated?: boolean;
|
@@ -13,43 +18,3 @@ export interface ISwaggerRoute {
|
|
13
18
|
tags?: string[];
|
14
19
|
"x-nestia-jsDocTags"?: IJsDocTagInfo[];
|
15
20
|
}
|
16
|
-
export namespace ISwaggerRoute {
|
17
|
-
export interface IParameter {
|
18
|
-
name?: string;
|
19
|
-
in: "path" | "query" | "header" | "cookie";
|
20
|
-
schema: ISwaggerSchema;
|
21
|
-
required?: boolean;
|
22
|
-
description?: string;
|
23
|
-
}
|
24
|
-
export interface IRequestBody {
|
25
|
-
description?: string;
|
26
|
-
content: IContent;
|
27
|
-
required?: boolean;
|
28
|
-
"x-nestia-encrypted"?: boolean;
|
29
|
-
}
|
30
|
-
export type IResponseBody = Record<
|
31
|
-
string,
|
32
|
-
{
|
33
|
-
description?: string;
|
34
|
-
content?: IContent;
|
35
|
-
"x-nestia-encrypted"?: boolean;
|
36
|
-
}
|
37
|
-
>;
|
38
|
-
export interface IContent {
|
39
|
-
"text/plain"?: {
|
40
|
-
schema: ISwaggerSchema;
|
41
|
-
};
|
42
|
-
"application/json"?: {
|
43
|
-
schema: ISwaggerSchema;
|
44
|
-
};
|
45
|
-
"application/x-www-form-urlencoded"?: {
|
46
|
-
schema: ISwaggerSchema;
|
47
|
-
};
|
48
|
-
"multipart/form-data"?: {
|
49
|
-
schema: ISwaggerSchema;
|
50
|
-
};
|
51
|
-
"*/*"?: {
|
52
|
-
schema: ISwaggerSchema;
|
53
|
-
};
|
54
|
-
}
|
55
|
-
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { ISwaggerSchema } from "./ISwaggerSchema";
|
2
|
+
|
3
|
+
export interface ISwaggerRouteBodyContent {
|
4
|
+
"text/plain"?: ISwaggerRouteBodyContent.IMediaType;
|
5
|
+
"application/json"?: ISwaggerRouteBodyContent.IMediaType;
|
6
|
+
"application/x-www-form-urlencoded"?: ISwaggerRouteBodyContent.IMediaType;
|
7
|
+
"multipart/form-data"?: ISwaggerRouteBodyContent.IMediaType;
|
8
|
+
"*/*"?: ISwaggerRouteBodyContent.IMediaType;
|
9
|
+
}
|
10
|
+
export namespace ISwaggerRouteBodyContent {
|
11
|
+
export interface IMediaType {
|
12
|
+
schema?: ISwaggerSchema;
|
13
|
+
"x-nestia-encrypted"?: boolean;
|
14
|
+
}
|
15
|
+
}
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { ISwaggerSchema } from "./ISwaggerSchema";
|
2
|
+
|
3
|
+
export interface ISwaggerRouteParameter {
|
4
|
+
name?: string;
|
5
|
+
in: "path" | "query" | "header" | "cookie";
|
6
|
+
schema: ISwaggerSchema;
|
7
|
+
required?: boolean;
|
8
|
+
description?: string;
|
9
|
+
}
|
10
|
+
export namespace ISwaggerRouteParameter {
|
11
|
+
export interface IReference {
|
12
|
+
$ref: `#/components/parameters/${string}`;
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { ISwaggerRouteBodyContent } from "./ISwaggerRouteBodyContent";
|
2
|
+
|
3
|
+
export interface ISwaggerRouteRequestBody {
|
4
|
+
description?: string;
|
5
|
+
required?: boolean;
|
6
|
+
content?: ISwaggerRouteBodyContent;
|
7
|
+
}
|
8
|
+
export namespace ISwaggerRouteRequestBody {
|
9
|
+
export interface IReference {
|
10
|
+
$ref: `#/components/requestBodies/${string}`;
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { ISwaggerRouteBodyContent } from "./ISwaggerRouteBodyContent";
|
2
|
+
|
3
|
+
export interface ISwaggerRouteResponse {
|
4
|
+
description?: string;
|
5
|
+
content?: ISwaggerRouteBodyContent;
|
6
|
+
}
|
7
|
+
export namespace ISwaggerRouteResponse {
|
8
|
+
export interface IReference {
|
9
|
+
$ref: `#/components/responses/${string}`;
|
10
|
+
}
|
11
|
+
}
|