@nestia/sdk 1.0.1 → 1.0.2
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/assets/config/nestia.config.ts +16 -25
- package/lib/INestiaConfig.d.ts +36 -21
- package/lib/analyses/ControllerAnalyzer.js +21 -1
- package/lib/analyses/ControllerAnalyzer.js.map +1 -1
- package/lib/executable/internal/NestiaSdkConfig.js +168 -14
- package/lib/executable/internal/NestiaSdkConfig.js.map +1 -1
- package/lib/generates/FunctionGenerator.js +29 -9
- package/lib/generates/FunctionGenerator.js.map +1 -1
- package/lib/generates/SwaggerGenerator.d.ts +1 -1
- package/lib/generates/SwaggerGenerator.js +27 -7
- package/lib/generates/SwaggerGenerator.js.map +1 -1
- package/lib/structures/IRoute.d.ts +8 -0
- package/lib/structures/ISwaggerDocument.d.ts +95 -0
- package/lib/structures/{ISwagger.js → ISwaggerDocument.js} +1 -1
- package/lib/structures/ISwaggerDocument.js.map +1 -0
- package/package.json +3 -3
- package/src/INestiaConfig.ts +44 -21
- package/src/analyses/ControllerAnalyzer.ts +21 -1
- package/src/generates/FunctionGenerator.ts +49 -11
- package/src/generates/SwaggerGenerator.ts +47 -18
- package/src/structures/IRoute.ts +4 -0
- package/src/structures/ISwaggerDocument.ts +117 -0
- package/lib/structures/ISwagger.d.ts +0 -48
- package/lib/structures/ISwagger.js.map +0 -1
- package/src/structures/ISwagger.ts +0 -55
|
@@ -12,13 +12,13 @@ import { ApplicationProgrammer } from "typia/lib/programmers/ApplicationProgramm
|
|
|
12
12
|
|
|
13
13
|
import { INestiaConfig } from "../INestiaConfig";
|
|
14
14
|
import { IRoute } from "../structures/IRoute";
|
|
15
|
-
import {
|
|
15
|
+
import { ISwaggerDocument } from "../structures/ISwaggerDocument";
|
|
16
16
|
import { MapUtil } from "../utils/MapUtil";
|
|
17
17
|
|
|
18
18
|
export namespace SwaggerGenerator {
|
|
19
19
|
export async function generate(
|
|
20
20
|
checker: ts.TypeChecker,
|
|
21
|
-
config: INestiaConfig.
|
|
21
|
+
config: INestiaConfig.ISwaggerConfig,
|
|
22
22
|
routeList: IRoute[],
|
|
23
23
|
): Promise<void> {
|
|
24
24
|
// PREPARE ASSETS
|
|
@@ -33,11 +33,11 @@ export namespace SwaggerGenerator {
|
|
|
33
33
|
|
|
34
34
|
// CONSTRUCT SWAGGER DOCUMENTS
|
|
35
35
|
const tupleList: Array<ISchemaTuple> = [];
|
|
36
|
-
const swagger:
|
|
37
|
-
const pathDict: Map<string,
|
|
36
|
+
const swagger: ISwaggerDocument = await initialize(location);
|
|
37
|
+
const pathDict: Map<string, ISwaggerDocument.IPath> = new Map();
|
|
38
38
|
|
|
39
39
|
for (const route of routeList) {
|
|
40
|
-
const path:
|
|
40
|
+
const path: ISwaggerDocument.IPath = MapUtil.take(
|
|
41
41
|
pathDict,
|
|
42
42
|
get_path(route.path, route.parameters),
|
|
43
43
|
() => ({}),
|
|
@@ -62,13 +62,16 @@ export namespace SwaggerGenerator {
|
|
|
62
62
|
},
|
|
63
63
|
);
|
|
64
64
|
swagger.components = {
|
|
65
|
-
...(swagger.components
|
|
65
|
+
...(swagger.components ?? {}),
|
|
66
66
|
schemas: application.components.schemas,
|
|
67
67
|
};
|
|
68
68
|
tupleList.forEach(({ schema }, index) => {
|
|
69
69
|
Object.assign(schema, application.schemas[index]!);
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
+
// CONFIGURE SECURITY
|
|
73
|
+
if (config.security) fill_security(config.security, swagger);
|
|
74
|
+
|
|
72
75
|
// ERASE IJsonComponents.IObject.$id
|
|
73
76
|
for (const obj of Object.values(swagger.components.schemas))
|
|
74
77
|
if (obj.$id) delete obj.$id;
|
|
@@ -84,9 +87,9 @@ export namespace SwaggerGenerator {
|
|
|
84
87
|
/* ---------------------------------------------------------
|
|
85
88
|
INITIALIZERS
|
|
86
89
|
--------------------------------------------------------- */
|
|
87
|
-
async function initialize(path: string): Promise<
|
|
90
|
+
async function initialize(path: string): Promise<ISwaggerDocument> {
|
|
88
91
|
// LOAD OR CREATE NEW SWAGGER DATA
|
|
89
|
-
const swagger:
|
|
92
|
+
const swagger: ISwaggerDocument = fs.existsSync(path)
|
|
90
93
|
? JSON.parse(await fs.promises.readFile(path, "utf8"))
|
|
91
94
|
: {
|
|
92
95
|
openapi: "3.0.1",
|
|
@@ -122,7 +125,7 @@ export namespace SwaggerGenerator {
|
|
|
122
125
|
collection: MetadataCollection,
|
|
123
126
|
tupleList: Array<ISchemaTuple>,
|
|
124
127
|
route: IRoute,
|
|
125
|
-
):
|
|
128
|
+
): ISwaggerDocument.IRoute {
|
|
126
129
|
const bodyParam = route.parameters.find(
|
|
127
130
|
(param) => param.category === "body",
|
|
128
131
|
);
|
|
@@ -170,9 +173,35 @@ export namespace SwaggerGenerator {
|
|
|
170
173
|
route,
|
|
171
174
|
),
|
|
172
175
|
description: CommentFactory.generate(route.comments),
|
|
176
|
+
"x-nestia-jsDocTags": route.tags,
|
|
173
177
|
};
|
|
174
178
|
}
|
|
175
179
|
|
|
180
|
+
function fill_security(
|
|
181
|
+
security: Required<INestiaConfig.ISwaggerConfig>["security"],
|
|
182
|
+
swagger: ISwaggerDocument,
|
|
183
|
+
): void {
|
|
184
|
+
swagger.security ??= [];
|
|
185
|
+
swagger.components.securitySchemes = {};
|
|
186
|
+
|
|
187
|
+
for (const [key, value] of Object.entries(security)) {
|
|
188
|
+
swagger.security.push(key);
|
|
189
|
+
swagger.components.securitySchemes[key] = emend_security(value);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function emend_security(
|
|
194
|
+
input: INestiaConfig.ISwaggerConfig.ISecurityScheme,
|
|
195
|
+
): ISwaggerDocument.ISecurityScheme {
|
|
196
|
+
if (input.type === "apiKey")
|
|
197
|
+
return {
|
|
198
|
+
...input,
|
|
199
|
+
in: input.in ?? "header",
|
|
200
|
+
name: input.name ?? "Authorization",
|
|
201
|
+
};
|
|
202
|
+
return input;
|
|
203
|
+
}
|
|
204
|
+
|
|
176
205
|
/* ---------------------------------------------------------
|
|
177
206
|
REQUEST & RESPONSE
|
|
178
207
|
--------------------------------------------------------- */
|
|
@@ -182,7 +211,7 @@ export namespace SwaggerGenerator {
|
|
|
182
211
|
tupleList: Array<ISchemaTuple>,
|
|
183
212
|
route: IRoute,
|
|
184
213
|
parameter: IRoute.IParameter,
|
|
185
|
-
):
|
|
214
|
+
): ISwaggerDocument.IParameter {
|
|
186
215
|
const schema: IJsonSchema | null = generate_schema(
|
|
187
216
|
checker,
|
|
188
217
|
collection,
|
|
@@ -195,7 +224,7 @@ export namespace SwaggerGenerator {
|
|
|
195
224
|
);
|
|
196
225
|
|
|
197
226
|
return {
|
|
198
|
-
name: parameter.field
|
|
227
|
+
name: parameter.field ?? parameter.name,
|
|
199
228
|
in: parameter.category === "param" ? "path" : parameter.category,
|
|
200
229
|
description:
|
|
201
230
|
get_parametric_description(route, "param", parameter.name) ||
|
|
@@ -211,7 +240,7 @@ export namespace SwaggerGenerator {
|
|
|
211
240
|
tupleList: Array<ISchemaTuple>,
|
|
212
241
|
route: IRoute,
|
|
213
242
|
parameter: IRoute.IParameter,
|
|
214
|
-
):
|
|
243
|
+
): ISwaggerDocument.IRequestBody {
|
|
215
244
|
const schema: IJsonSchema | null = generate_schema(
|
|
216
245
|
checker,
|
|
217
246
|
collection,
|
|
@@ -226,7 +255,7 @@ export namespace SwaggerGenerator {
|
|
|
226
255
|
return {
|
|
227
256
|
description:
|
|
228
257
|
warning.get(parameter.encrypted).get("request") +
|
|
229
|
-
(get_parametric_description(route, "param", parameter.name)
|
|
258
|
+
(get_parametric_description(route, "param", parameter.name) ??
|
|
230
259
|
""),
|
|
231
260
|
content: {
|
|
232
261
|
"application/json": {
|
|
@@ -242,7 +271,7 @@ export namespace SwaggerGenerator {
|
|
|
242
271
|
collection: MetadataCollection,
|
|
243
272
|
tupleList: Array<ISchemaTuple>,
|
|
244
273
|
route: IRoute,
|
|
245
|
-
):
|
|
274
|
+
): ISwaggerDocument.IResponseBody {
|
|
246
275
|
// OUTPUT WITH SUCCESS STATUS
|
|
247
276
|
const status: string =
|
|
248
277
|
route.method === "GET" || route.method === "DELETE" ? "200" : "201";
|
|
@@ -252,12 +281,12 @@ export namespace SwaggerGenerator {
|
|
|
252
281
|
tupleList,
|
|
253
282
|
route.output.type,
|
|
254
283
|
);
|
|
255
|
-
const success:
|
|
284
|
+
const success: ISwaggerDocument.IResponseBody = {
|
|
256
285
|
[status]: {
|
|
257
286
|
description:
|
|
258
287
|
warning.get(route.encrypted).get("response", route.method) +
|
|
259
|
-
(get_parametric_description(route, "return")
|
|
260
|
-
get_parametric_description(route, "returns")
|
|
288
|
+
(get_parametric_description(route, "return") ??
|
|
289
|
+
get_parametric_description(route, "returns") ??
|
|
261
290
|
""),
|
|
262
291
|
content:
|
|
263
292
|
schema === null || route.output.name === "void"
|
|
@@ -271,7 +300,7 @@ export namespace SwaggerGenerator {
|
|
|
271
300
|
};
|
|
272
301
|
|
|
273
302
|
// EXCEPTION STATUSES
|
|
274
|
-
const exceptions:
|
|
303
|
+
const exceptions: ISwaggerDocument.IResponseBody = Object.fromEntries(
|
|
275
304
|
route.tags
|
|
276
305
|
.filter(
|
|
277
306
|
(tag) =>
|
package/src/structures/IRoute.ts
CHANGED
|
@@ -16,6 +16,10 @@ export interface IRoute {
|
|
|
16
16
|
symbol: string;
|
|
17
17
|
comments: ts.SymbolDisplayPart[];
|
|
18
18
|
tags: ts.JSDocTagInfo[];
|
|
19
|
+
setHeaders: Array<
|
|
20
|
+
| { type: "setter"; source: string; target?: string }
|
|
21
|
+
| { type: "assigner"; source: string }
|
|
22
|
+
>;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
export namespace IRoute {
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { IJsonComponents, IJsonSchema } from "typia";
|
|
2
|
+
import { IJsDocTagInfo } from "typia/lib/metadata/IJsDocTagInfo";
|
|
3
|
+
|
|
4
|
+
export interface ISwaggerDocument {
|
|
5
|
+
openapi: "3.0";
|
|
6
|
+
servers: ISwaggerDocument.IServer[];
|
|
7
|
+
info: ISwaggerDocument.IInfo;
|
|
8
|
+
components: ISwaggerDocument.IComponents;
|
|
9
|
+
security?: string[];
|
|
10
|
+
paths: Record<string, ISwaggerDocument.IPath>;
|
|
11
|
+
}
|
|
12
|
+
export namespace ISwaggerDocument {
|
|
13
|
+
export interface IServer {
|
|
14
|
+
url: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface IInfo {
|
|
19
|
+
version: string;
|
|
20
|
+
title: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface IComponents extends IJsonComponents {
|
|
24
|
+
securitySchemes?: Record<string, ISecurityScheme>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* ---------------------------------------------------------
|
|
28
|
+
SECURITY SCHEMES
|
|
29
|
+
--------------------------------------------------------- */
|
|
30
|
+
export type ISecurityScheme =
|
|
31
|
+
| ISecurityScheme.IHttpBasic
|
|
32
|
+
| ISecurityScheme.IHttpBearer
|
|
33
|
+
| ISecurityScheme.IApiKey
|
|
34
|
+
| ISecurityScheme.IOpenId
|
|
35
|
+
| ISecurityScheme.IOAuth2;
|
|
36
|
+
export namespace ISecurityScheme {
|
|
37
|
+
export interface IHttpBasic {
|
|
38
|
+
type: "http";
|
|
39
|
+
schema: "basic";
|
|
40
|
+
}
|
|
41
|
+
export interface IHttpBearer {
|
|
42
|
+
type: "http";
|
|
43
|
+
scheme: "bearer";
|
|
44
|
+
bearerFormat?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface IApiKey {
|
|
47
|
+
type: "apiKey";
|
|
48
|
+
in: "header" | "query" | "cookie";
|
|
49
|
+
name: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface IOpenId {
|
|
53
|
+
type: "openIdConnect";
|
|
54
|
+
openIdConnectUrl: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface IOAuth2 {
|
|
58
|
+
type: "oauth2";
|
|
59
|
+
flows: IOAuth2.IFlowSet;
|
|
60
|
+
description?: string;
|
|
61
|
+
}
|
|
62
|
+
export namespace IOAuth2 {
|
|
63
|
+
export interface IFlowSet {
|
|
64
|
+
authorizationCode?: IFlow;
|
|
65
|
+
implicit?: Omit<IFlow, "tokenUrl">;
|
|
66
|
+
password?: Omit<IFlow, "authorizationUrl">;
|
|
67
|
+
clientCredentials?: Omit<IFlow, "authorizationUrl">;
|
|
68
|
+
}
|
|
69
|
+
export interface IFlow {
|
|
70
|
+
authorizationUrl: string;
|
|
71
|
+
tokenUrl: string;
|
|
72
|
+
refreshUrl: string;
|
|
73
|
+
scopes?: Record<string, string>;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* ---------------------------------------------------------
|
|
79
|
+
ROUTE FUNCTIONS
|
|
80
|
+
--------------------------------------------------------- */
|
|
81
|
+
export type IPath = Record<string, IRoute>;
|
|
82
|
+
export interface IRoute {
|
|
83
|
+
tags: string[];
|
|
84
|
+
parameters: IParameter[];
|
|
85
|
+
requestBody?: IRequestBody;
|
|
86
|
+
responses: IResponseBody;
|
|
87
|
+
summary?: string;
|
|
88
|
+
description: string;
|
|
89
|
+
security?: string[];
|
|
90
|
+
"x-nestia-jsDocTags": IJsDocTagInfo[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface IParameter {
|
|
94
|
+
name: string;
|
|
95
|
+
in: string;
|
|
96
|
+
schema: IJsonSchema;
|
|
97
|
+
required: true;
|
|
98
|
+
description: string;
|
|
99
|
+
}
|
|
100
|
+
export interface IRequestBody {
|
|
101
|
+
description: string;
|
|
102
|
+
content: IJsonContent;
|
|
103
|
+
required: true;
|
|
104
|
+
}
|
|
105
|
+
export type IResponseBody = Record<
|
|
106
|
+
string,
|
|
107
|
+
{
|
|
108
|
+
description: string;
|
|
109
|
+
content?: IJsonContent;
|
|
110
|
+
}
|
|
111
|
+
>;
|
|
112
|
+
export interface IJsonContent {
|
|
113
|
+
"application/json": {
|
|
114
|
+
schema: IJsonSchema;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { IJsonComponents, IJsonSchema } from "typia";
|
|
2
|
-
export interface ISwagger {
|
|
3
|
-
openapi: "3.0";
|
|
4
|
-
servers: ISwagger.IServer[];
|
|
5
|
-
info: ISwagger.IInfo;
|
|
6
|
-
paths: Record<string, ISwagger.IPath>;
|
|
7
|
-
components: IJsonComponents;
|
|
8
|
-
}
|
|
9
|
-
export declare namespace ISwagger {
|
|
10
|
-
type IPath = Record<string, IRoute>;
|
|
11
|
-
interface IRoute {
|
|
12
|
-
description: string;
|
|
13
|
-
tags: string[];
|
|
14
|
-
parameters: IParameter[];
|
|
15
|
-
responses: IResponseBody;
|
|
16
|
-
requestBody?: IRequestBody;
|
|
17
|
-
summary?: string;
|
|
18
|
-
}
|
|
19
|
-
interface IInfo {
|
|
20
|
-
version: string;
|
|
21
|
-
title: string;
|
|
22
|
-
}
|
|
23
|
-
interface IParameter {
|
|
24
|
-
name: string;
|
|
25
|
-
in: string;
|
|
26
|
-
schema: IJsonSchema;
|
|
27
|
-
required: true;
|
|
28
|
-
description: string;
|
|
29
|
-
}
|
|
30
|
-
interface IRequestBody {
|
|
31
|
-
description: string;
|
|
32
|
-
content: IJsonContent;
|
|
33
|
-
required: true;
|
|
34
|
-
}
|
|
35
|
-
type IResponseBody = Record<string, {
|
|
36
|
-
description: string;
|
|
37
|
-
content?: IJsonContent;
|
|
38
|
-
}>;
|
|
39
|
-
interface IServer {
|
|
40
|
-
url: string;
|
|
41
|
-
description?: string;
|
|
42
|
-
}
|
|
43
|
-
interface IJsonContent {
|
|
44
|
-
"application/json": {
|
|
45
|
-
schema: IJsonSchema;
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ISwagger.js","sourceRoot":"","sources":["../../src/structures/ISwagger.ts"],"names":[],"mappings":""}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { IJsonComponents, IJsonSchema } from "typia";
|
|
2
|
-
|
|
3
|
-
export interface ISwagger {
|
|
4
|
-
openapi: "3.0";
|
|
5
|
-
servers: ISwagger.IServer[];
|
|
6
|
-
info: ISwagger.IInfo;
|
|
7
|
-
paths: Record<string, ISwagger.IPath>;
|
|
8
|
-
components: IJsonComponents;
|
|
9
|
-
}
|
|
10
|
-
export namespace ISwagger {
|
|
11
|
-
export type IPath = Record<string, IRoute>;
|
|
12
|
-
export interface IRoute {
|
|
13
|
-
description: string;
|
|
14
|
-
tags: string[];
|
|
15
|
-
parameters: IParameter[];
|
|
16
|
-
responses: IResponseBody;
|
|
17
|
-
requestBody?: IRequestBody;
|
|
18
|
-
summary?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface IInfo {
|
|
22
|
-
version: string;
|
|
23
|
-
title: string;
|
|
24
|
-
}
|
|
25
|
-
export interface IParameter {
|
|
26
|
-
name: string;
|
|
27
|
-
in: string;
|
|
28
|
-
schema: IJsonSchema;
|
|
29
|
-
required: true;
|
|
30
|
-
description: string;
|
|
31
|
-
}
|
|
32
|
-
export interface IRequestBody {
|
|
33
|
-
description: string;
|
|
34
|
-
content: IJsonContent;
|
|
35
|
-
required: true;
|
|
36
|
-
}
|
|
37
|
-
export type IResponseBody = Record<
|
|
38
|
-
string,
|
|
39
|
-
{
|
|
40
|
-
description: string;
|
|
41
|
-
content?: IJsonContent;
|
|
42
|
-
}
|
|
43
|
-
>;
|
|
44
|
-
|
|
45
|
-
export interface IServer {
|
|
46
|
-
url: string;
|
|
47
|
-
description?: string;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface IJsonContent {
|
|
51
|
-
"application/json": {
|
|
52
|
-
schema: IJsonSchema;
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
}
|