nestia 2.1.3 → 2.1.6
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/README.md +255 -137
- package/lib/analyses/ControllerAnalyzer.d.ts.map +1 -1
- package/lib/analyses/ControllerAnalyzer.js +34 -7
- package/lib/analyses/ReflectAnalyzer.d.ts.map +1 -1
- package/lib/analyses/ReflectAnalyzer.js +51 -18
- package/lib/generates/SwaggerGenerator.d.ts.map +1 -1
- package/lib/generates/SwaggerGenerator.js +4 -4
- package/lib/structures/IController.d.ts +2 -2
- package/lib/structures/IController.d.ts.map +1 -1
- package/lib/structures/ISwagger.d.ts +5 -3
- package/lib/structures/ISwagger.d.ts.map +1 -1
- package/package.json +3 -3
- package/lib/factories/CommentFactory.d.ts +0 -5
- package/lib/factories/CommentFactory.d.ts.map +0 -1
- package/lib/factories/CommentFactory.js +0 -14
- package/lib/factories/MetadataCollection.d.ts +0 -14
- package/lib/factories/MetadataCollection.d.ts.map +0 -1
- package/lib/factories/MetadataCollection.js +0 -83
- package/lib/factories/MetadataFactory.d.ts +0 -8
- package/lib/factories/MetadataFactory.d.ts.map +0 -1
- package/lib/factories/MetadataFactory.js +0 -251
- package/lib/factories/SchemaFactory.d.ts +0 -9
- package/lib/factories/SchemaFactory.d.ts.map +0 -1
- package/lib/factories/SchemaFactory.js +0 -179
package/README.md
CHANGED
|
@@ -1,60 +1,36 @@
|
|
|
1
1
|
# Nestia
|
|
2
|
-
Automatic `SDK` and `Swagger` generator for the `NestJS
|
|
2
|
+
Automatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.
|
|
3
3
|
|
|
4
4
|
[](https://github.com/samchon/nestia/blob/master/LICENSE)
|
|
5
5
|
[](https://www.npmjs.com/package/nestia)
|
|
6
6
|
[](https://www.npmjs.com/package/nestia)
|
|
7
7
|
[](https://github.com/samchon/nestia/actions?query=workflow%3Abuild)
|
|
8
|
-
[](https://github.com/samchon/nestia/wiki)
|
|
8
|
+
[](https://github.com/samchon/nestia/wiki)
|
|
9
9
|
|
|
10
10
|
- Github: https://github.com/samchon/nestia
|
|
11
|
-
- NPM: https://www.npmjs.com/
|
|
11
|
+
- NPM: https://www.npmjs.com/package/nestia
|
|
12
12
|
- Guide Documents: https://github.com/samchon/nestia/wiki
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
# INSTALL NESTIA
|
|
16
|
-
npm install --save-dev nestia
|
|
17
|
-
|
|
18
|
-
# BUILDING SDK LIBRARY
|
|
19
|
-
npx nestia sdk "src/controller" --out "src/api"
|
|
20
|
-
npx nestia sdk "src/**/*.controller.ts" --out "src/api"
|
|
21
|
-
npx nestia sdk "src/controller" \
|
|
22
|
-
--exclude "src/controller/test" \
|
|
23
|
-
--out "src/api"
|
|
24
|
-
|
|
25
|
-
# BUILDING SWAGGER.JSON IS ALSO POSSIBLE
|
|
26
|
-
npx nestia swagger "src/controller" -- out "swagger.json"
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Don't write any swagger comment and DTO decorator. Just run the `nestia` up.
|
|
30
|
-
|
|
31
|
-
- No swagger comment/decorator
|
|
32
|
-
- No DTO comment/decorator
|
|
33
|
-
- Only pure `interface`s and NestJS code are required
|
|
34
|
-
- Suppors generic typed `interface`s and `controller`s
|
|
35
|
-
- Support union/intersection types
|
|
36
|
-
- Support conditional types
|
|
14
|
+
`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators. All you need to do is use the `nestia` CLI as shown below.
|
|
37
15
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Therefore, don't write any swagger comment and don't use any DTO related decorator function. Just use the pure interface type with the pure `NestJS` code. Reading below sections and looking at example codes of the `nestia`, feel how the `nestia` is much stronger than the legacy `@nestjs/swagger`.
|
|
16
|
+
Reading below contents, feel how the "compilation level" makes `nestia` stronger.
|
|
41
17
|
|
|
42
18
|
Components | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`
|
|
43
19
|
-----------|---|---|---
|
|
44
|
-
DTO
|
|
45
|
-
|
|
20
|
+
Pure DTO interface | ✔ | ✔ | ❌
|
|
21
|
+
Description comments | ✔ | ✔ | ❌
|
|
46
22
|
Simple structure | ✔ | ✔ | ✔
|
|
47
|
-
Generic
|
|
48
|
-
Union
|
|
49
|
-
Intersection
|
|
50
|
-
Conditional
|
|
23
|
+
Generic type | ✔ | ✔ | ❌
|
|
24
|
+
Union type | ✔ | ✔ | ▲
|
|
25
|
+
Intersection type | ✔ | ✔ | ▲
|
|
26
|
+
Conditional type | ✔ | ▲ | ❌
|
|
51
27
|
Auto completion | ✔ | ❌ | ❌
|
|
52
28
|
Type hints | ✔ | ❌ | ❌
|
|
53
29
|
2x faster `JSON.stringify()` | ✔ | ❌ | ❌
|
|
54
|
-
Ensure type safety |
|
|
30
|
+
Ensure type safety | ✅ | ❌ | ❌
|
|
55
31
|
|
|
56
32
|
```typescript
|
|
57
|
-
// IMPORT SDK LIBRARY
|
|
33
|
+
// IMPORT SDK LIBRARY GENERATED BY NESTIA
|
|
58
34
|
import api from "@samchon/shopping-api";
|
|
59
35
|
import { IPage } from "@samchon/shopping-api/lib/structures/IPage";
|
|
60
36
|
import { ISale } from "@samchon/shopping-api/lib/structures/ISale";
|
|
@@ -112,14 +88,44 @@ export async function trace_sale_question_and_comment
|
|
|
112
88
|
|
|
113
89
|
|
|
114
90
|
|
|
91
|
+
## Setup
|
|
92
|
+
Just like any other package, you've got to install it before you can use it.
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
npm install --save-dev nestia
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
After the installation, you can generate the `SDK` or `Swagger`, directly.
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
npx nestia sdk "src/**/*.controller" --out "src/api"
|
|
102
|
+
npx nestia swagger "src/**/*.controller" --out "swagger.json"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
> If all of your controller files are gathered into one directory:
|
|
106
|
+
>
|
|
107
|
+
> ```sh
|
|
108
|
+
> npx nestia sdk "src/controllers" --out "src/api"
|
|
109
|
+
> npx nestia swagger "src/controllers" --out "swagger.json"
|
|
110
|
+
> ```
|
|
111
|
+
>
|
|
112
|
+
> You can omit all of the parameters if you've configured the [nestia.config.ts](#configuration) file.
|
|
113
|
+
>
|
|
114
|
+
> ```sh
|
|
115
|
+
> npx nestia sdk
|
|
116
|
+
> npx nestia swagger
|
|
117
|
+
> ```
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
115
121
|
|
|
116
122
|
## Demonstrations
|
|
117
123
|
### Pure DTO Interface
|
|
118
|
-
|
|
124
|
+
`nestia` can utilize pure interface type as DTO.
|
|
119
125
|
|
|
120
|
-
Unlike
|
|
126
|
+
Unlike `@nestjs/swagger` which requires the DTO class with decorators, `nestia` can use the pure interface type directly. Also, `nestia` can utilize the pure descriptive comments, instead of using the `description` property of the decorators. Furthermore, `nestia` can even support generic types, union/intersection types and even conditional types.
|
|
121
127
|
|
|
122
|
-
|
|
128
|
+
Look at the code below, you may see the difference between `nestia` and `@nestjs/swagger`, and thereby catch the meaning of the pure DTO interface.
|
|
123
129
|
|
|
124
130
|
- Simple [`ISaleArticleComment`](https://github.com/samchon/nestia/tree/master/demo/simple/src/api/structures/ISaleArticleComment.ts)
|
|
125
131
|
- Generic interfaces
|
|
@@ -127,15 +133,77 @@ Furthermore, as the `nestia` can use the pure interface type directly, it's poss
|
|
|
127
133
|
- parent interface, [`ISaleInquiry<Content>`](https://github.com/samchon/nestia/tree/master/demo/generic/src/api/structures/ISaleInquiry.ts)
|
|
128
134
|
- 1st sub-type interface, [`ISaleQuestion`](https://github.com/samchon/nestia/tree/master/demo/generic/src/api/structures/ISaleQuestion.ts)
|
|
129
135
|
- 2nd sub-type interface, [`ISaleReview`](https://github.com/samchon/nestia/tree/master/demo/generic/src/api/structures/ISaleReview.ts)
|
|
130
|
-
- Union alias type [`ISaleEntireArticle`](https://github.com/samchon/nestia/tree/master/demo/
|
|
131
|
-
|
|
132
|
-
Looking at the below example code, then you may understand which differences between the `nestia` and `@nestjs/swagger` and what the pure interface DTO type means. Writing the legacy DTO class of the `@nestjs/swagger` after a very long time, I felt the feeling again, "this is insane".
|
|
136
|
+
- Union alias type [`ISaleEntireArticle`](https://github.com/samchon/nestia/tree/master/demo/union/src/api/structures/ISaleEntireArticle.ts)
|
|
133
137
|
|
|
134
138
|
> The below example code would be shown by clicking the arrow button or text.
|
|
135
139
|
|
|
136
140
|
<details>
|
|
137
141
|
<summary>
|
|
138
|
-
|
|
142
|
+
Traditional DTO class using <code>@nestjs/swagger</code>
|
|
143
|
+
</summary>
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
export class SaleArticleComment
|
|
147
|
+
{
|
|
148
|
+
@ApiProperty({
|
|
149
|
+
description:
|
|
150
|
+
`Comment wrote on a sale related article.
|
|
151
|
+
|
|
152
|
+
When an article of a sale has been enrolled, all of the participants like consumers and sellers can write a comment on that article. However, when the writer is a consumer, the consumer can hide its name through the annoymous option.
|
|
153
|
+
|
|
154
|
+
Also, writing a reply comment for a specific comment is possible and in that case, the ISaleArticleComment.parent_id property would be activated.`
|
|
155
|
+
})
|
|
156
|
+
id: number;
|
|
157
|
+
|
|
158
|
+
@ApiProperty({
|
|
159
|
+
type: "number",
|
|
160
|
+
nullable: true,
|
|
161
|
+
description:
|
|
162
|
+
`Parent comment ID.
|
|
163
|
+
|
|
164
|
+
Only When this comment has been written as a reply.`
|
|
165
|
+
})
|
|
166
|
+
parent_id: number | null;
|
|
167
|
+
|
|
168
|
+
@ApiProperty({
|
|
169
|
+
type: "string",
|
|
170
|
+
description: "Type of the writer."
|
|
171
|
+
})
|
|
172
|
+
writer_type: "seller" | "consumer";
|
|
173
|
+
|
|
174
|
+
@ApiProperty({
|
|
175
|
+
type: "string",
|
|
176
|
+
nullable: true,
|
|
177
|
+
description:
|
|
178
|
+
`Name of the writer.
|
|
179
|
+
|
|
180
|
+
When this is a type of anonymous comment, writer name would be hidden.`
|
|
181
|
+
})
|
|
182
|
+
writer_name: string | null;
|
|
183
|
+
|
|
184
|
+
@ApiProperty({
|
|
185
|
+
type: "array",
|
|
186
|
+
items: {
|
|
187
|
+
schema: { $ref: getSchemaPath(SaleArticleComment.Content) }
|
|
188
|
+
},
|
|
189
|
+
description:
|
|
190
|
+
`Contents of the comments.
|
|
191
|
+
|
|
192
|
+
When the comment writer tries to modify content, it would not modify the comment content but would be accumulated Therefore, all of the people can read how the content has been changed.`
|
|
193
|
+
})
|
|
194
|
+
contents: SaleArticleComment.Content[];
|
|
195
|
+
|
|
196
|
+
@ApiProperty({
|
|
197
|
+
description: "Creation time."
|
|
198
|
+
})
|
|
199
|
+
created_at: string;
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
</details>
|
|
203
|
+
|
|
204
|
+
<details>
|
|
205
|
+
<summary>
|
|
206
|
+
Pure DTO interface using <code>nestia</code>
|
|
139
207
|
</summary>
|
|
140
208
|
|
|
141
209
|
```typescript
|
|
@@ -235,79 +303,116 @@ export namespace ISaleArticleComment
|
|
|
235
303
|
|
|
236
304
|
<details>
|
|
237
305
|
<summary>
|
|
238
|
-
|
|
306
|
+
Generic typed DTO using <code>nestia</code>
|
|
239
307
|
</summary>
|
|
240
308
|
|
|
241
309
|
```typescript
|
|
242
|
-
|
|
310
|
+
/**
|
|
311
|
+
* Inquiry article.
|
|
312
|
+
*
|
|
313
|
+
* Sub-type of article and super-type of question and answer.
|
|
314
|
+
*
|
|
315
|
+
* - List of the sub-types
|
|
316
|
+
* - {@link ISaleQuestion}
|
|
317
|
+
* - {@link ISaleReview}
|
|
318
|
+
*
|
|
319
|
+
* @template Content Content type
|
|
320
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
321
|
+
*/
|
|
322
|
+
export interface ISaleInquiry<Content extends ISaleInquiry.IContent>
|
|
323
|
+
extends ISaleArticle<Content>
|
|
243
324
|
{
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
When an article of a sale has been enrolled, all of the participants like consumers and sellers can write a comment on that article. However, when the writer is a consumer, the consumer can hide its name through the annoymous option.
|
|
249
|
-
|
|
250
|
-
Also, writing a reply comment for a specific comment is possible and in that case, the ISaleArticleComment.parent_id property would be activated.`
|
|
251
|
-
})
|
|
325
|
+
/**
|
|
326
|
+
* Primary Key.
|
|
327
|
+
*/
|
|
252
328
|
id: number;
|
|
253
329
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
`Parent comment ID.
|
|
259
|
-
|
|
260
|
-
Only When this comment has been written as a reply.`
|
|
261
|
-
})
|
|
262
|
-
parent_id: number | null;
|
|
330
|
+
/**
|
|
331
|
+
* Name of the writer.
|
|
332
|
+
*/
|
|
333
|
+
writer: string;
|
|
263
334
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
335
|
+
/**
|
|
336
|
+
* List of contents.
|
|
337
|
+
*
|
|
338
|
+
* When the article writer tries to modify content, it would not modify the article
|
|
339
|
+
* content but would be accumulated. Therefore, all the people can read how
|
|
340
|
+
* the content has been changed.
|
|
341
|
+
*/
|
|
342
|
+
contents: Content[];
|
|
269
343
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
344
|
+
/**
|
|
345
|
+
* Creation time.
|
|
346
|
+
*/
|
|
347
|
+
createdAat: string;
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Formal answer from the seller.
|
|
351
|
+
*/
|
|
352
|
+
answer: ISaleInquiryAnswer | null;
|
|
353
|
+
}
|
|
354
|
+
export namespace ISaleInquiry
|
|
355
|
+
{
|
|
356
|
+
/**
|
|
357
|
+
* Content info.
|
|
358
|
+
*/
|
|
359
|
+
export interface IContent
|
|
360
|
+
{
|
|
361
|
+
/**
|
|
362
|
+
* Primary Key
|
|
363
|
+
*/
|
|
364
|
+
id: string;
|
|
275
365
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
366
|
+
/**
|
|
367
|
+
* Title of the content.
|
|
368
|
+
*/
|
|
369
|
+
title: string;
|
|
279
370
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
},
|
|
285
|
-
description:
|
|
286
|
-
`Contents of the comments.
|
|
371
|
+
/**
|
|
372
|
+
* Body of the content.
|
|
373
|
+
*/
|
|
374
|
+
body: string;
|
|
287
375
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
376
|
+
/**
|
|
377
|
+
* Attached files.
|
|
378
|
+
*/
|
|
379
|
+
files: IAttachmentFile[];
|
|
291
380
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
381
|
+
/**
|
|
382
|
+
* Creation time.
|
|
383
|
+
*/
|
|
384
|
+
createdAt: string;
|
|
385
|
+
}
|
|
296
386
|
}
|
|
297
387
|
```
|
|
298
388
|
</details>
|
|
299
389
|
|
|
390
|
+
<details>
|
|
391
|
+
<summary>
|
|
392
|
+
Union typed DTO using <code>nestia</code>
|
|
393
|
+
</summary>
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
/**
|
|
397
|
+
* Union type of the entire sub-type articles.
|
|
398
|
+
*
|
|
399
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
400
|
+
*/
|
|
401
|
+
export type ISaleEntireArtcle = ISaleQuestion | ISaleReview;
|
|
402
|
+
```
|
|
403
|
+
</details>
|
|
404
|
+
|
|
300
405
|
|
|
301
406
|
|
|
302
407
|
|
|
303
408
|
### Advanced Controller Class
|
|
304
409
|
Controller also can use the generic arguments.
|
|
305
410
|
|
|
306
|
-
In the previous [Pure DTO Interface](#pure-dto-interface) corner, we've learned that
|
|
411
|
+
In the previous [Pure DTO Interface](#pure-dto-interface) corner, we've learned that `nestia` can use the pure interface type as DTO. Also, we've learned that utilizing generic, union/intersection and even conditional typed interfaces are also possible.
|
|
307
412
|
|
|
308
|
-
In the Controller case, it's
|
|
413
|
+
In the Controller case, it's same with the upper DTO story. With `nestia`, defining a generic typed controller class is also possible, too. By defining a generic typed controller class as a super-type class, you can reduce both duplicated code and description comments.
|
|
309
414
|
|
|
310
|
-
Look at the below code and feel how
|
|
415
|
+
Look at the below code and feel how powerful `nestia` is. It should be stated that, `@nestjs/swagger` cannot construct such generic or union typed controller class.
|
|
311
416
|
|
|
312
417
|
- Simple [`CustomerSaleArticleCommentsController`](https://github.com/samchon/nestia/blob/master/demo/simple/src/controllers/ConsumerSaleArticleCommentsController.ts)
|
|
313
418
|
- Generic controllers
|
|
@@ -316,6 +421,26 @@ Look at the below code and feel how the `nestia` is powerful. I repeat that, `@n
|
|
|
316
421
|
- 2nd sub-type controller, [`ConsumerSaleQuestionsController`](https://github.com/samchon/nestia/tree/master/demo/generic/src/controllers/ConsumerSaleQuestionsController.ts)
|
|
317
422
|
- Union controller, [`ConsumerSaleEntireArticlesController`](https://github.com/samchon/nestia/tree/master/demo/union/src/controllers/ConsumerSaleEntireArticlesController.ts)
|
|
318
423
|
|
|
424
|
+
> [typescript-is](https://github.com/woutervh-/typescript-is) can replace the class-validator with only one line.
|
|
425
|
+
>
|
|
426
|
+
> ```typescript
|
|
427
|
+
> import * as nest from "@nestjs/common";
|
|
428
|
+
> import { assertType } from "typescript-is";
|
|
429
|
+
>
|
|
430
|
+
> @nest.Controller("consumers/:section/sales/:saleId/questions")
|
|
431
|
+
> export class SaleQuestionsController
|
|
432
|
+
> extends SaleInquiriesController<
|
|
433
|
+
> ISaleQuestion,
|
|
434
|
+
> ISaleQuestion.IContent,
|
|
435
|
+
> ISaleQuestion.IStore>
|
|
436
|
+
> {
|
|
437
|
+
> public constructor()
|
|
438
|
+
> {
|
|
439
|
+
> super(input => assertType<ISaleQuestion.IStore>(input));
|
|
440
|
+
> }
|
|
441
|
+
> }
|
|
442
|
+
> ```
|
|
443
|
+
|
|
319
444
|
```typescript
|
|
320
445
|
import * as express from "express";
|
|
321
446
|
import * as nest from "@nestjs/common";
|
|
@@ -328,6 +453,11 @@ export abstract class SaleInquiriesController<
|
|
|
328
453
|
Store extends ISaleInquiry.IStore,
|
|
329
454
|
Json extends ISaleInquiry<Content>>
|
|
330
455
|
{
|
|
456
|
+
/**
|
|
457
|
+
* Constructor with type assert function.
|
|
458
|
+
*/
|
|
459
|
+
protected constructor(private readonly assert: (input: Store) => void);
|
|
460
|
+
|
|
331
461
|
/**
|
|
332
462
|
* Store a new inquiry.
|
|
333
463
|
*
|
|
@@ -385,19 +515,19 @@ export abstract class SaleInquiriesController<
|
|
|
385
515
|
|
|
386
516
|
|
|
387
517
|
### Software Development Kit
|
|
388
|
-
> `Swagger` is torturing
|
|
518
|
+
> `Swagger` is torturing client developers.
|
|
389
519
|
>
|
|
390
|
-
> If you're a backend developer and you deliver a `Swagger` to your companion client developers,
|
|
520
|
+
> If you're a backend developer and you deliver a `Swagger` to your companion client developers, they should analyze the `Swagger` and implement duplicated router functions with DTO interfaces by themselves. During those jobs, if a client developer takes a mistake by mis-reading the `Swagger`, it becomes a critical runtime error directly.
|
|
391
521
|
>
|
|
392
|
-
> Why
|
|
522
|
+
> Why are you torturing the client developers such like that? If you deliver an SDK (Software Development Kit) instead of the `Swagger`, the client developers don't need to read the `Swagger` file. They never need to implement the duplicated DTO interfaces with router functions, either.
|
|
393
523
|
>
|
|
394
|
-
> Therefore, just build the SDK through this `nestia` and
|
|
524
|
+
> Therefore, just build the SDK through this `nestia` and deliver the SDK. Your client developers would be anticipated from the long time torturing and become happy. Your solution would be much more reliable and efficient, too.
|
|
395
525
|
|
|
396
|
-
Looking at the SDK library file, generated by
|
|
526
|
+
Looking at the SDK library file, generated by `nestia`, it is perfect.
|
|
397
527
|
|
|
398
|
-
|
|
528
|
+
Route method, path and parameters are well-formed and DTO structures are correctly imported. Also, descriptive comments are fully revived in the SDK library, regardless of where they are written.
|
|
399
529
|
|
|
400
|
-
Furthermore, there's not any problem even when
|
|
530
|
+
Furthermore, there's not any problem even when a generic typed controller class comes. `nestia` will specialize the generic arguments exactly, by analyzing your `NestJS` server code, in the compilation level.
|
|
401
531
|
|
|
402
532
|
- [simple/.../comments/index.ts](https://github.com/samchon/nestia/blob/master/demo/simple/src/api/functional/consumers/sales/articles/comments/index.ts)
|
|
403
533
|
- [generic/.../questions/index.ts](https://github.com/samchon/nestia/tree/master/demo/generic/src/api/functional/consumers/sales/questions/index.ts)
|
|
@@ -540,11 +670,9 @@ export namespace update
|
|
|
540
670
|
### Swagger
|
|
541
671
|
Building `Swagger` is also possible and even much powerful.
|
|
542
672
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
Looking at the [simple/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Fsimple%2Fswagger.json) file, generated by the `nestia`, it seems perfect. Exact route method, path and parameters are constructed and DTO structures are exactly same with the pure interace type `ISaleArticleComment`. Also, comments written on the controller class method, DTO interface `ISaleArticleComment` and its properties are exactly revied on the `description` fields in the `swagger.json`.
|
|
673
|
+
Looking at the [simple/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Fsimple%2Fswagger.json) file, generated by `nestia`, everything is perfect. Route method, path and parameters are well-formed. Also, schema definitions are exactly matched with the pure interface type `ISaleArticleComment`. Of course, descriptive comments are perfectly resurrected in the `description` properties of the `swagger.json` file.
|
|
546
674
|
|
|
547
|
-
Looking at the another file [generic/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Fgeneric%2Fswagger.json), you can find that there isn't any problem even when
|
|
675
|
+
Looking at the another file [generic/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Fgeneric%2Fswagger.json), you can find that there isn't any problem even when a generic typed DTO and controller come. The last file [union/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Funion%2Fswagger.json), there's no problem on the union type, either.
|
|
548
676
|
|
|
549
677
|
- View in the `Swagger Editor`
|
|
550
678
|
- [simple/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Fsimple%2Fswagger.json)
|
|
@@ -565,29 +693,34 @@ SDK Generation | ✔ | ✔ | ❌
|
|
|
565
693
|
Type check in runtime | ✔ | ❌ | ❌
|
|
566
694
|
Custom compiler options | ✔ | ❌ | ❌
|
|
567
695
|
|
|
568
|
-
|
|
696
|
+
`nestia` can configure generator options by two ways: CLI and configuration file.
|
|
569
697
|
|
|
570
|
-
|
|
698
|
+
At first, the CLI (Command Line Interface) is convenient, but does not support detailed options.
|
|
571
699
|
|
|
572
|
-
```
|
|
700
|
+
```sh
|
|
573
701
|
# BASIC COMMAND
|
|
574
|
-
npx nestia <
|
|
702
|
+
npx nestia <sdk|swagger> <source_directories_or_patterns> \
|
|
575
703
|
--exclude <exclude_directory_or_pattern> \
|
|
576
704
|
--out <output_directory_or_file>
|
|
577
705
|
|
|
578
706
|
# EXAMPLES
|
|
579
|
-
npx nestia
|
|
580
|
-
npx nestia swagger "src/**/*.controller.ts" --
|
|
707
|
+
npx nestia sdk "src/controllers" --out "src/api"
|
|
708
|
+
npx nestia swagger "src/**/*.controller.ts" --out "swagger.json"
|
|
581
709
|
npx nestia swagger "src/main/controllers" "src/sub/controllers" \
|
|
582
710
|
--exclude "src/main/test" \
|
|
583
711
|
--out "composite.swagger.json"
|
|
584
712
|
|
|
585
713
|
# ONLY WHEN NESTIA.CONFIG.TS EXISTS
|
|
586
|
-
npx nestia
|
|
714
|
+
npx nestia sdk
|
|
587
715
|
npx nestia swagger
|
|
588
716
|
```
|
|
589
717
|
|
|
590
|
-
|
|
718
|
+
Besides, the configuration file `nestia.config.ts` supports much detailed options.
|
|
719
|
+
|
|
720
|
+
The detailed options are listed up to the `IConfiguration` interface. You can utilize the `IConfiguration` type like below. If you want to know more about those options, please check the [Guide Documents](https://github.com/samchon/nestia/wiki/Configuration).
|
|
721
|
+
|
|
722
|
+
<details>
|
|
723
|
+
<summary> Read <code>IConfiguration</code> </summary>
|
|
591
724
|
|
|
592
725
|
```typescript
|
|
593
726
|
/**
|
|
@@ -595,10 +728,9 @@ Otherwise, configuration file `nestia.config.ts` may hard to construct and the c
|
|
|
595
728
|
*
|
|
596
729
|
* @author Jeongho Nam - https://github.com/samchon
|
|
597
730
|
*/
|
|
598
|
-
export interface IConfiguration
|
|
599
|
-
{
|
|
731
|
+
export interface IConfiguration {
|
|
600
732
|
/**
|
|
601
|
-
* List of files or directories containing the NestJS controller classes.
|
|
733
|
+
* List of files or directories containing the `NestJS` controller classes.
|
|
602
734
|
*/
|
|
603
735
|
input: string | string[] | IConfiguration.IInput;
|
|
604
736
|
|
|
@@ -660,13 +792,12 @@ export interface IConfiguration
|
|
|
660
792
|
export namespace IConfiguration
|
|
661
793
|
{
|
|
662
794
|
/**
|
|
663
|
-
* List of files or directories to include or exclude to specifying the NestJS
|
|
795
|
+
* List of files or directories to include or exclude to specifying the `NestJS`
|
|
664
796
|
* controllers.
|
|
665
797
|
*/
|
|
666
|
-
export interface IInput
|
|
667
|
-
{
|
|
798
|
+
export interface IInput {
|
|
668
799
|
/**
|
|
669
|
-
* List of files or directories containing the NestJS controller classes.
|
|
800
|
+
* List of files or directories containing the `NestJS` controller classes.
|
|
670
801
|
*/
|
|
671
802
|
include: string[];
|
|
672
803
|
|
|
@@ -679,8 +810,7 @@ export namespace IConfiguration
|
|
|
679
810
|
/**
|
|
680
811
|
* Building `swagger.json` is also possible.
|
|
681
812
|
*/
|
|
682
|
-
export interface ISwagger
|
|
683
|
-
{
|
|
813
|
+
export interface ISwagger {
|
|
684
814
|
/**
|
|
685
815
|
* Output path of the `swagger.json`.
|
|
686
816
|
*
|
|
@@ -692,8 +822,7 @@ export namespace IConfiguration
|
|
|
692
822
|
}
|
|
693
823
|
}
|
|
694
824
|
```
|
|
695
|
-
|
|
696
|
-
When you've completed to reading the `IConfiguration` interface, let's make the `nestia.config.ts` file directly. At first, move to your project directory. Note that the project directory means the top level directory of your project, where configuration files like `package.json` or `tsconfig.json` are placed in. After the movement, make the new `nestia` configuration file and write some script like below:
|
|
825
|
+
</details>
|
|
697
826
|
|
|
698
827
|
```typescript
|
|
699
828
|
import type { IConfiguration } from "nestia";
|
|
@@ -714,18 +843,7 @@ export default NESTIA_CONFIG;
|
|
|
714
843
|
|
|
715
844
|
## Appendix
|
|
716
845
|
### Dependencies of the SDK
|
|
717
|
-
An SDK library generated by
|
|
718
|
-
|
|
719
|
-
```json
|
|
720
|
-
{
|
|
721
|
-
"name": "payments-server-api",
|
|
722
|
-
"dependencies": {
|
|
723
|
-
"nestia-fetcher": "^2.0.1",
|
|
724
|
-
"typescript-is": "^0.19.0",
|
|
725
|
-
"typescript-json": "^2.0.9"
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
```
|
|
846
|
+
An SDK library generated by `nestia` requires [nestia-fetcher](https://github.com/samchon/nestia-fetcher) module. Also, [typescript-is](https://github.com/woutervh-/typescript-is) and [typescript-json](https://github.com/samchon/typescript-json) modules can be required following your `nestia.config.ts` configuration file.
|
|
729
847
|
|
|
730
848
|
The `npx nestia install` command installs those dependencies with the `package.json` configuration.
|
|
731
849
|
|
|
@@ -742,7 +860,7 @@ https://github.com/samchon/backend
|
|
|
742
860
|
|
|
743
861
|
I support template backend project using this `nestia` library, `samchon/backend`.
|
|
744
862
|
|
|
745
|
-
Reading the README content of the backend template repository, you can find lots of example backend projects who've been generated from the backend. Furthermore, those example projects guide how to generate SDK library from
|
|
863
|
+
Reading the README content of the backend template repository, you can find lots of example backend projects who've been generated from the backend. Furthermore, those example projects guide how to generate SDK library from `nestia` and how to distribute the SDK library thorugh the NPM module.
|
|
746
864
|
|
|
747
865
|
Therefore, if you're planning to compose your own backend project using this `nestia`, I recommend you to create the repository and learn from the `samchon/backend` template project.
|
|
748
866
|
|
|
@@ -762,4 +880,4 @@ The Archidraw is a great IT company developing 3D interior editor and lots of so
|
|
|
762
880
|
> - 회사소개서: [archidraw.pdf](https://github.com/archidraw/payments/files/7696710/archidraw.pdf)
|
|
763
881
|
> - 기술 스택: React + TypeScript
|
|
764
882
|
> - 이력서: 자유 양식
|
|
765
|
-
> - 지원처: samchon@archisketch.com
|
|
883
|
+
> - 지원처: samchon@archisketch.com
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControllerAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyses/ControllerAnalyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAM9C,yBAAiB,kBAAkB,CACnC;IACI,SAAgB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,GAAG,MAAM,EAAE,CAc7G;
|
|
1
|
+
{"version":3,"file":"ControllerAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyses/ControllerAnalyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAM9C,yBAAiB,kBAAkB,CACnC;IACI,SAAgB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,GAAG,MAAM,EAAE,CAc7G;CA+JJ"}
|
|
@@ -93,8 +93,8 @@ var ControllerAnalyzer;
|
|
|
93
93
|
var runtime = controller.functions.find(function (f) { return f.name === identifier.escapedText; });
|
|
94
94
|
if (runtime === undefined)
|
|
95
95
|
return "continue";
|
|
96
|
-
var
|
|
97
|
-
ret.push(
|
|
96
|
+
var routes = _Analyze_function(checker, controller, genericDict, runtime, property);
|
|
97
|
+
ret.push.apply(ret, __spreadArray([], __read(routes), false));
|
|
98
98
|
};
|
|
99
99
|
try {
|
|
100
100
|
for (var _b = __values(classType.getProperties()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
@@ -115,6 +115,7 @@ var ControllerAnalyzer;
|
|
|
115
115
|
FUNCTION
|
|
116
116
|
--------------------------------------------------------- */
|
|
117
117
|
function _Analyze_function(checker, controller, genericDict, func, symbol) {
|
|
118
|
+
var e_2, _a, e_3, _b;
|
|
118
119
|
// PREPARE ASSETS
|
|
119
120
|
var type = checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration);
|
|
120
121
|
var signature = checker.getSignaturesOfType(type, typescript_1.default.SignatureKind.Call)[0];
|
|
@@ -127,12 +128,38 @@ var ControllerAnalyzer;
|
|
|
127
128
|
var imports = importDict
|
|
128
129
|
.toJSON()
|
|
129
130
|
.map(function (pair) { return [pair.first, pair.second.toJSON()]; });
|
|
130
|
-
//
|
|
131
|
-
var
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
// CONSTRUCT COMMON DATA
|
|
132
|
+
var common = __assign(__assign({}, func), { parameters: parameters, output: output, imports: imports, symbol: "".concat(controller.name, ".").concat(func.name, "()"), comments: signature.getDocumentationComment(undefined), tags: signature.getJsDocTags() });
|
|
133
|
+
// CONFIGURE PATHS
|
|
134
|
+
var pathList = [];
|
|
135
|
+
try {
|
|
136
|
+
for (var _c = __values(controller.paths), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
137
|
+
var controllerPath = _d.value;
|
|
138
|
+
try {
|
|
139
|
+
for (var _e = (e_3 = void 0, __values(func.paths)), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
140
|
+
var filePath = _f.value;
|
|
141
|
+
var path = path_1.default.join(controllerPath, filePath).split("\\").join("/");
|
|
142
|
+
pathList.push(_Normalize_path(path));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
146
|
+
finally {
|
|
147
|
+
try {
|
|
148
|
+
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
149
|
+
}
|
|
150
|
+
finally { if (e_3) throw e_3.error; }
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
155
|
+
finally {
|
|
156
|
+
try {
|
|
157
|
+
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
158
|
+
}
|
|
159
|
+
finally { if (e_2) throw e_2.error; }
|
|
160
|
+
}
|
|
134
161
|
// RETURNS
|
|
135
|
-
return __assign(__assign({},
|
|
162
|
+
return pathList.map(function (path) { return (__assign(__assign({}, common), { path: path })); });
|
|
136
163
|
}
|
|
137
164
|
function _Normalize_path(path) {
|
|
138
165
|
if (path[0] !== "/")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReflectAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyses/ReflectAnalyzer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAQxD,yBAAiB,eAAe,CAChC;IACI,SAAsB,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAiBxF;
|
|
1
|
+
{"version":3,"file":"ReflectAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyses/ReflectAnalyzer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAQxD,yBAAiB,eAAe,CAChC;IACI,SAAsB,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAiBxF;CAqNJ"}
|