nestia 2.1.2 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,373 +1,344 @@
1
1
  # Nestia
2
- Automatic `SDK` and `swagger.json` generator for the NestJS.
2
+ Automatic `SDK` and `Swagger` generator for the `NestJS`.
3
3
 
4
- [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia/blob/master/LICENSE)
5
- [![npm version](https://badge.fury.io/js/nestia.svg)](https://www.npmjs.com/package/nestia)
6
- [![Downloads](https://img.shields.io/npm/dm/nestia.svg)](https://www.npmjs.com/package/nestia)
7
- [![Build Status](https://github.com/samchon/nestia/workflows/build/badge.svg)](https://github.com/samchon/nestia/actions?query=workflow%3Abuild)
4
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia/blob/master/LICENSE)
5
+ [![npm version](https://badge.fury.io/js/nestia.svg)](https://www.npmjs.com/package/nestia)
6
+ [![Downloads](https://img.shields.io/npm/dm/nestia.svg)](https://www.npmjs.com/package/nestia)
7
+ [![Build Status](https://github.com/samchon/nestia/workflows/build/badge.svg)](https://github.com/samchon/nestia/actions?query=workflow%3Abuild)
8
+ [![Guide Documents](https://img.shields.io/badge/wiki-documentation-forestgreen)](https://github.com/samchon/nestia/wiki)
9
+
10
+ - Github: https://github.com/samchon/nestia
11
+ - NPM: https://www.npmjs.com/packages/nestia
12
+ - Guide Documents: https://github.com/samchon/nestia/wiki
8
13
 
9
14
  ```bash
10
15
  # INSTALL NESTIA
11
16
  npm install --save-dev nestia
12
17
 
13
- # WHEN ALL OF THE CONTROLLRES ARE GATHERED INTO A DIRECTORY
18
+ # BUILDING SDK LIBRARY
14
19
  npx nestia sdk "src/controller" --out "src/api"
15
-
16
- # REGULAR NESTJS PATTERN
17
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"
18
24
 
19
25
  # BUILDING SWAGGER.JSON IS ALSO POSSIBLE
20
26
  npx nestia swagger "src/controller" -- out "swagger.json"
21
27
  ```
22
28
 
23
- Don't write any `swagger` comment and DTO decorator. Just run the [nestia](https://github.com/samchon/nestia) up.
29
+ Don't write any swagger comment and DTO decorator. Just run the `nestia` up.
24
30
 
25
31
  - No swagger comment/decorator
26
32
  - No DTO comment/decorator
27
- - Only pure NestJS code is required
28
- - [Guide Documents (Wiki)](https://github.com/samchon/nestia/wiki), if you want to know more
29
-
30
- When you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments or DTO decorators.
31
-
32
- You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level. With the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the `await` symbol.
33
-
34
- > Even generating the `swagger.json` without any swagger comment and DTO decorator is also possible. When generating the `swagger.json`, no DTO comment and decorator is required, either. Use only the pure interface definitions.
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
37
+
38
+ The `nestia` is an evolved automatic `SDK` and `Swagger` generator than ever, who does not require any type of swagger comment or DTO decorator function, by analyzing your `NestJS` developed backend server code in the compilation level (`nestia` utilizes the TypeScript Compiler API).
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`.
41
+
42
+ Components | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`
43
+ -----------|---|---|---
44
+ DTO with pure interface | ✔ | ✔ | ❌
45
+ descriptions by comments | ✔ | ✔ | ❌
46
+ Simple structure | ✔ | ✔ | ✔
47
+ Generic typed structure | ✔ | ✔ | ❌
48
+ Union typed structure | ✔ | ✔ | ▲
49
+ Intersection typed structure | ✔ | ✔ | ▲
50
+ Conditional typed structure | ✔ | ▲ | ❌
51
+ Auto completion | ✔ | ❌ | ❌
52
+ Type hints | ✔ | ❌ | ❌
53
+ 2x faster `JSON.stringify()` | ✔ | ❌ | ❌
54
+ Ensure type safety | ✔ | ❌ | ❌
35
55
 
36
56
  ```typescript
37
- import api from "@samchon/bbs-api";
38
- import { IBbsArticle } from "@samchon/bbs-api/lib/structures/bbs/IBbsArticle";
39
- import { IPage } from "@samchon/bbs-api/lib/structures/common/IPage";
40
-
41
- export async function test_article_read(connection: api.IConnection): Promise<void>
57
+ // IMPORT SDK LIBRARY WHO'VE BEEN GENERATED BY THE NESTIA
58
+ import api from "@samchon/shopping-api";
59
+ import { IPage } from "@samchon/shopping-api/lib/structures/IPage";
60
+ import { ISale } from "@samchon/shopping-api/lib/structures/ISale";
61
+ import { ISaleArticleComment } from "@samchon/shopping-api/lib/structures/ISaleArticleComment";
62
+ import { ISaleQuestion } from "@samchon/shopping-api/lib/structures/ISaleQuestion";
63
+
64
+ export async function trace_sale_question_and_comment
65
+ (connection: api.IConnection): Promise<void>
42
66
  {
43
- // LIST UP ARTICLE SUMMARIES
44
- const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index
67
+ // LIST UP SALE SUMMARIES
68
+ const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index
45
69
  (
46
70
  connection,
47
- "free",
71
+ "general",
48
72
  { limit: 100, page: 1 }
49
73
  );
50
74
 
51
- // READ AN ARTICLE DETAILY
52
- const article: IBbsArticle = await api.functional.bbs.articles.at
75
+ // PICK A SALE
76
+ const sale: ISale = await api.functional.shoppings.sales.at
53
77
  (
54
- connection,
55
- "free",
78
+ connection,
56
79
  index.data[0].id
57
80
  );
58
- console.log(article.title, aritlce.body, article.files);
59
- }
60
- ```
61
-
62
-
81
+ console.log("sale", sale);
63
82
 
83
+ // WRITE A QUESTION
84
+ const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store
85
+ (
86
+ connection,
87
+ "general",
88
+ sale.id,
89
+ {
90
+ title: "How to use this product?",
91
+ body: "The description is not fully enough. Can you introduce me more?",
92
+ files: []
93
+ }
94
+ );
95
+ console.log("question", question);
64
96
 
65
- ## Usage
66
- ### Installation
67
- ```bash
68
- npm install --save-dev nestia
69
- ```
70
-
71
- Installing the [nestia](https://github.com/samchon/nestia) is very easy.
72
-
73
- Just type the `npm install --save-dev nestia` command in your NestJS backend project.
74
-
75
- ### SDK generation
76
- ```bash
77
- npx nestia sdk <source_controller_directory> --out <output_sdk_directory>
78
-
79
- npx nestia sdk "src/**/*.controller.ts" --out "src/api"
80
- npx nestia sdk "src/controllers" --out "src/api"
81
- npx nestia sdk "src/controllers/consumers" "src/controllers/sellers" --out "src/api"
82
- npx nestia sdk "src/controllers" --exclude "src/**/Fake*.ts" --out "src/api"
97
+ // WRITE A COMMENT
98
+ const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store
99
+ (
100
+ connection,
101
+ "general",
102
+ sale.id,
103
+ question.id,
104
+ {
105
+ body: "p.s) Can you send me a detailed catalogue?",
106
+ anonymous: false
107
+ }
108
+ );
109
+ console.log("comment", comment);
110
+ }
83
111
  ```
84
112
 
85
- To generate a SDK library through the [nestia](https://github.com/samchon/nestia) is very easy.
86
-
87
- Just type the `nestia sdk <input> --out <output>` command in the console. When there're multiple source directories containing the NestJS controller classes, type all of them separating by a `space` word. If you want to exclude some directories or files from the SDK generation, the `--exclude` option would be useful.
88
-
89
- Also, when generating a SDK using the cli options, `compilerOptions` would follow the `tsconfig.json`, that is configured for the backend server. If no `tsconfig.json` file exists in your project, the configuration would be default option (`ES5` with `strict` mode). If you want to use different `compilerOptions` with the `tsconfig.json`, you should configure the [nestia.config.ts](#nestiaconfigts).
90
-
91
- ### Swagger generation
92
- ```bash
93
- npx nestia <source_controller_of_directory> --out <output_path>
94
-
95
- npx nestia swagger "src/**/*.controller.ts" --out "./"
96
- npx nestia swagger "src/controllers" --out "./swagger.json"
97
- npx nestia swagger "src/consumers" "src/sellers" --out "actors.json"
98
- npx nestia swagger "src/controllers" --exclude "src/**/Fake*.ts" -out "./"
99
- ```
100
113
 
101
- The [nestia](https://github.com/samchon/nestia) even supports the `swagger.json` generation and it's also extermely easy.
102
114
 
103
- Jsut type the `nestia swagger <input> --out <output>` command in the console. When there're multiple source directories containing the NestJS controller classes, type all of them separating by a `space` word. If you want to exclude some directories or files from the `swagger.json` generation, the `--exclude` option would be useful.
104
115
 
105
- Also, when generating a SDK using the cli options, `compilerOptions` would follow the `tsconfig.json`, that is configured for the backend server. If no `tsconfig.json` file exists in your project, the configuration would be default option (`ES5` with `strict` mode). If you want to use different `compilerOptions` with the `tsconfig.json`, you should configure the [nestia.config.ts](#nestiaconfigts).
116
+ ## Demonstrations
117
+ ### Pure DTO Interface
118
+ The `nestia` can utilize the pure interface type as DTO.
106
119
 
107
- ### Dependencies
108
- ```bash
109
- npx nestia install
110
- ```
120
+ Unlike the legacy `@nestjs/swagger` who requires a class with decorator functions when defining the DTO, the `nestia` can use the pure interface directly. Also, `nestia` can use the descriptive comments of the pure DTO interface, too.
111
121
 
112
- SDK library generated by the [nestia](https://github.com/samchon/nestia) requires the [nestia-fetcher](https://github.com/samchon/nestia-fetcher) module. Also, the [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](#nestiaconfigts) options.
122
+ Furthermore, as the `nestia` can use the pure interface type directly, it's possible to define a generic typed DTO interface with inheritance. Of course, using alis type or union typed DTO are also possibble, too. Besides, `@nestjs/swagger` never can construct such generic typed DTO and constructing union typed DTO is possible but extremely difficult.
113
123
 
114
- The `npx nestia install` command installs those dependencies with `package.json` configuration.
124
+ - Simple [`ISaleArticleComment`](https://github.com/samchon/nestia/tree/master/demo/simple/src/api/structures/ISaleArticleComment.ts)
125
+ - Generic interfaces
126
+ - grandparent interface, [`ISaleArticle<Content>`](https://github.com/samchon/nestia/tree/master/demo/generic/src/api/structures/ISaleArticle.ts)
127
+ - parent interface, [`ISaleInquiry<Content>`](https://github.com/samchon/nestia/tree/master/demo/generic/src/api/structures/ISaleInquiry.ts)
128
+ - 1st sub-type interface, [`ISaleQuestion`](https://github.com/samchon/nestia/tree/master/demo/generic/src/api/structures/ISaleQuestion.ts)
129
+ - 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/generic/src/api/structures/ISaleArticle.ts)
115
131
 
116
- ```json
117
- {
118
- "name": "payments-server-api",
119
- "dependencies": {
120
- "nestia-fetcher": "^2.0.1",
121
- "typescript-is": "^0.19.0",
122
- "typescript-json": "^2.0.9"
123
- }
124
- }
125
- ```
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".
126
133
 
134
+ > The below example code would be shown by clicking the arrow button or text.
127
135
 
136
+ <details>
137
+ <summary>
138
+ Pure DTO interface, of the <code>nestia</code>
139
+ </summary>
128
140
 
129
- ## Advanced
130
- ### `nestia.config.ts`
131
141
  ```typescript
132
142
  /**
133
- * Definition for the `nestia.config.ts` file.
143
+ * Comment wrote on a sale related article.
144
+ *
145
+ * When an article of a sale has been enrolled, all of the participants like consumers and
146
+ * sellers can write a comment on that article. However, when the writer is a consumer, the
147
+ * consumer can hide its name through the annoymous option.
148
+ *
149
+ * Also, writing a reply comment for a specific comment is possible and in that case, the
150
+ * {@link ISaleArticleComment.parent_id} property would be activated.
134
151
  *
135
152
  * @author Jeongho Nam - https://github.com/samchon
136
153
  */
137
- export interface IConfiguration
154
+ export interface ISaleArticleComment
138
155
  {
139
156
  /**
140
- * List of files or directories containing the NestJS controller classes.
157
+ * Primary Key.
141
158
  */
142
- input: string | string[] | IConfiguration.IInput;
159
+ id: number;
143
160
 
144
161
  /**
145
- * Output directory that SDK would be placed in.
162
+ * Parent comment ID.
163
+ *
164
+ * Only When this comment has been written as a reply.
146
165
  */
147
- output?: string;
166
+ parent_id: number | null;
148
167
 
149
168
  /**
150
- * Compiler options for the TypeScript.
151
- *
152
- * If omitted, the configuration would follow the `tsconfig.json`.
169
+ * Type of the writer.
153
170
  */
154
- compilerOptions?: ts.CompilerOptions;
171
+ writer_type: "seller" | "consumer";
155
172
 
156
173
  /**
157
- * Whether to assert parameter types or not.
174
+ * Name of the writer.
158
175
  *
159
- * If you configure this option to be `true`, all of the function parameters would be
160
- * checked through the [typescript-is](https://github.com/woutervh-/typescript-is).
176
+ * When this is a type of anonymous comment, writer name would be hidden.
161
177
  */
162
- assert?: boolean;
178
+ writer_name: string | null;
163
179
 
164
180
  /**
165
- * Whether to optimize JSON string conversion 2x faster or not.
181
+ * Contents of the comments.
166
182
  *
167
- * If you configure this option to be `true`, the SDK library would utilize the
168
- * [typescript-json](https://github.com/samchon/typescript-json) and the JSON string
169
- * conversion speed really be 2x faster.
183
+ * When the comment writer tries to modify content, it would not modify the comment
184
+ * content but would be accumulated. Therefore, all of the people can read how
185
+ * the content has been changed.
170
186
  */
171
- json?: boolean;
187
+ contents: ISaleArticleComment.IContent[];
172
188
 
173
189
  /**
174
- * Building `swagger.json` is also possible.
190
+ * Creation time.
175
191
  */
176
- swagger?: IConfiguration.ISwagger;
192
+ created_at: string;
177
193
  }
178
- export namespace IConfiguration
194
+ export namespace ISaleArticleComment
179
195
  {
180
196
  /**
181
- * List of files or directories to include or exclude to specifying the NestJS
182
- * controllers.
197
+ * Store info.
183
198
  */
184
- export interface IInput
199
+ export interface IStore
185
200
  {
186
201
  /**
187
- * List of files or directories containing the NestJS controller classes.
202
+ * Body of the content.
188
203
  */
189
- include: string[];
204
+ body: string;
190
205
 
191
206
  /**
192
- * List of files or directories to be excluded.
207
+ * Whether to hide the writer name or not.
193
208
  */
194
- exclude?: string[];
209
+ annonymous: boolean;
195
210
  }
196
211
 
197
212
  /**
198
- * Building `swagger.json` is also possible.
213
+ * Content info.
199
214
  */
200
- export interface ISwagger
215
+ export interface IContent
201
216
  {
202
217
  /**
203
- * Output path of the `swagger.json`.
204
- *
205
- * If you've configure only directory, the file name would be `swagger.json`.
206
- * Otherwise you configure file name and extension, the `swagger.json` file would
207
- * be renamed to what you've configured.
218
+ * Primary Key.
208
219
  */
209
- output: string;
220
+ id: string;
221
+
222
+ /**
223
+ * Body of the content.
224
+ */
225
+ body: string;
226
+
227
+ /**
228
+ * Creation time.
229
+ */
230
+ created_at: string;
210
231
  }
211
232
  }
212
233
  ```
234
+ </details>
213
235
 
214
- Instead of specifying `input` and `output` directories using the cli options, you can specify those directories as an independent configuration file. It's the `nestia.config.ts` and with the `nestia.config.ts` file, you also configure independent TypeScript compiler option from the `tsconfig.json`.
215
-
216
- Write below content as the `nestia.config.ts` file and place it onto the root directory of your backend project. After the configuration, you can generate the SDK only with the `npx nestia sdk` command, without any directory specification.
236
+ <details>
237
+ <summary>
238
+ Legacy DTO class, of the <code>@nestjs/swagger</code>
239
+ </summary>
217
240
 
218
241
  ```typescript
219
- import type nestia from "nestia";
220
-
221
- const config: nestia.IConfiguration = {
222
- input: "src/controllers",
223
- output: "src/api",
224
- assert: false
225
- };
226
- export default config;
227
- ```
228
-
229
- > Alternative options for the regular NestJS project:
230
- >
231
- > ```typescript
232
- > export = {
233
- > input: "src/**/*.controller.ts",
234
- > /* input: {
235
- > include: ["src/controllers/**\/*.controller.ts"],
236
- > exclude: ["src/controllers/**\/fake_*.controller.ts"]
237
- > },*/
238
- > output: "src/api",
239
- > assert: true
240
- > }
241
- > ```
242
-
243
-
244
-
245
- ### Recommended Structures
246
- When developing a NestJS backend server with this [nestia](https://github.com/samchon/nestia), I recommend you to follow below directory structure. The key princinple of below structure is to gathering all of the DTO interface structures into the `src/api/structures` directory and gather all of the controller classes into the `src/controllers` directory.
242
+ export class SaleArticleComment
243
+ {
244
+ @ApiProperty({
245
+ description:
246
+ `Comment wrote on a sale related article.
247
247
 
248
- If you place the SDK onto the `src/api` directory and gather all of the DTO interface structures into the `src/api/structures` directory, you can publish the SDK library very easily without any special configuration. Also when you're develop the test automation program, you can implement the API testing features very convenienty through the automatically generated SDK through this [nestia](https://github.com/samchon/nestia).
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
249
 
250
- - src
251
- - api
252
- - **functional**: automatically generated SDK functions
253
- - **structures**: DTO structures
254
- - controllers
255
- - providers
256
- - models
257
- - **test**: Test automation program using SDK functions
258
- - package.json
259
- - tsconfig.json
260
- - nestia.config.ts
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
+ })
252
+ id: number;
261
253
 
262
- For your deep understanding about this directory structure with this [nestia](https://github.com/samchon/nestia), I've prepared an example backend project. Looking around the example repository and reading the [README.md](https://github.com/samchon/backend#13-directories) of it, you can feel that such directory structure is how convenient for SDK publishing and test automation program implementation.
254
+ @ApiProperty({
255
+ type: "number",
256
+ nullable: true,
257
+ description:
258
+ `Parent comment ID.
263
259
 
264
- - https://github.com/samchon/backend
260
+ Only When this comment has been written as a reply.`
261
+ })
262
+ parent_id: number | null;
265
263
 
264
+ @ApiProperty({
265
+ type: "string",
266
+ description: "Type of the writer."
267
+ })
268
+ writer_type: "seller" | "consumer";
266
269
 
270
+ @ApiProperty({
271
+ type: "string",
272
+ nullable: true,
273
+ description:
274
+ `Name of the writer.
267
275
 
276
+ When this is a type of anonymous comment, writer name would be hidden.`
277
+ })
278
+ writer_name: string | null;
268
279
 
269
- ## Demonstration
270
- To demonstrate which SDK codes would be generated by this [nestia](https://github.com/samchon/nestia):
280
+ @ApiProperty({
281
+ type: "array",
282
+ items: {
283
+ schema: { $ref: getSchemaPath(SaleArticleComment.Content) }
284
+ },
285
+ description:
286
+ `Contents of the comments.
271
287
 
272
- - Representative files
273
- - [DTO interface used in the RestAPI](https://github.com/samchon/nestia/tree/master/demo/simple/src/api/structures/ISaleArticleComment.ts)
274
- - [Controllers of the NestJS](https://github.com/samchon/nestia/tree/master/demo/simple/src/controllers/ConsumerSaleArticleCommentsController.ts)
275
- - [SDK generated by this **nestia**](https://github.com/samchon/nestia/tree/master/demo/simple/src/api/functional/consumers/sales/articles/comments/index.ts)
276
- - [`swagger.json` generated by this **nestia**](https://github.com/samchon/nestia/tree/master/demo/simple/swagger.json)
277
- - Demonstration Projects
278
- - [encrypt](https://github.com/samchon/nestia/tree/master/demo/encrypt): Request and response body are fully encrypted
279
- - [generic](https://github.com/samchon/nestia/tree/master/demo/generic): Generic typed controller classes
280
- - [recursive](https://github.com/samchon/nestia/tree/master/demo/recursive): Recursive DTO interface, [swagger editor](https://editor.swagger.io) can't expresss it
281
- - [simple](https://github.com/samchon/nestia/tree/master/demo/simple): Simple DTO interface and controller class
282
- - [union](https://github.com/samchon/nestia/tree/master/demo/union): Only [nestia](https://github.com/samchon/nestia) can handle the union typed DTO interface
288
+ 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.`
289
+ })
290
+ contents: SaleArticleComment.Content[];
283
291
 
284
- ### DTO
285
- Using pure interface type as DTO is possible.
292
+ @ApiProperty({
293
+ description: "Creation time."
294
+ })
295
+ created_at: string;
296
+ }
297
+ ```
298
+ </details>
286
299
 
287
- You dont' need to define any extra comment or decorator function to make the DTO (Data Transfer Object). Just define the DTO as a pure interface structure, then [nestia](https://github.com/samchon/nestia) will do everything instead of you.
288
300
 
289
- If you're afraiding because your type is union or intersection, I can say that it does not matter. Even when generic or conditional type comes, it does not matter. Just enjoy the pure TypeScript type.
290
301
 
291
- ```typescript
292
- /**
293
- * Comment wrote on a sale related article.
294
- *
295
- * @author Jeongho Nam - https://github.com/samchon
296
- */
297
- export interface ISaleComment
298
- {
299
- /**
300
- * Primary Key.
301
- */
302
- id: number;
303
302
 
304
- /**
305
- * Type of the writer.
306
- */
307
- writer_type: "seller" | "consumer";
303
+ ### Advanced Controller Class
304
+ Controller also can use the generic arguments.
308
305
 
309
- /**
310
- * Name of the writer.
311
- */
312
- writer_name: string;
306
+ In the previous [Pure DTO Interface](#pure-dto-interface) corner, we've learned that the `nestia` can use the pure interface type as the DTO. Also, we've learned that using the pure interface type as DTO means that making generic typed interface or union typed interface as the DTO are also possible, too.
313
307
 
314
- /**
315
- * Contents of the comments.
316
- *
317
- * When the comment writer tries to modify content, it would not modify the comment
318
- * content but would be accumulated. Therefore, all of the people can read how
319
- * the content has been changed.
320
- */
321
- contents: ISaleComment.IContent[];
308
+ In the Controller case, it's the same with the upper interface story. In the `nestia`, as using generic typed interface as DTO was possible, defining generic typed controller class is also possible, too. By defining the generic typed controller class as the super type class, you can extremely reduce both duplicated code and duplicated description comments.
322
309
 
323
- /**
324
- * Creation time.
325
- */
326
- created_at: string;
327
- }
310
+ Look at the below code and feel how the `nestia` is powerful. I repeat that, `@nestjs/swagger` never can construct such generic or union typed controller classes, either.
328
311
 
329
- export namespace ISaleComment
330
- {
331
- /**
332
- * Store info.
333
- */
334
- export interface IStore
335
- {
336
- /**
337
- * Body of the content.
338
- */
339
- body: string;
340
- }
312
+ - Simple [`CustomerSaleArticleCommentsController`](https://github.com/samchon/nestia/blob/master/demo/simple/src/controllers/ConsumerSaleArticleCommentsController.ts)
313
+ - Generic controllers
314
+ - abstract controller, [`SaleInquiriesController<Content, Store, Json>`](https://github.com/samchon/nestia/tree/master/demo/generic/src/controllers/SaleInquiriesController.ts)
315
+ - 1st sub-type controller, [`ConsumerSaleQuestionsController`](https://github.com/samchon/nestia/tree/master/demo/generic/src/controllers/ConsumerSaleQuestionsController.ts)
316
+ - 2nd sub-type controller, [`ConsumerSaleQuestionsController`](https://github.com/samchon/nestia/tree/master/demo/generic/src/controllers/ConsumerSaleQuestionsController.ts)
317
+ - Union controller, [`ConsumerSaleEntireArticlesController`](https://github.com/samchon/nestia/tree/master/demo/union/src/controllers/ConsumerSaleEntireArticlesController.ts)
341
318
 
342
- /**
343
- * Content info.
344
- */
345
- export interface IContent extends IStore
346
- {
347
- /**
348
- * Creation time.
349
- */
350
- created_at: string;
351
- }
352
- }
353
- ```
319
+ ```typescript
320
+ import * as express from "express";
321
+ import * as nest from "@nestjs/common";
322
+ import helper from "nestia-helper";
354
323
 
355
- ### Controller
356
- If you've decided to adapt this [nestia](https://github.com/samchon/nestia) and you want to generate the SDK directly, you don't need any extra work. Just keep you controller class down and do noting. The only one exceptional case that you need an extra dedication is, when you want to explain about the API function to the client developers through the comments.
324
+ import { ISaleInquiry } from "@api/structures/ISaleInquiry";
357
325
 
358
- ```typescript
359
- @nest.Controller("consumers/:section/sales/:saleId/questions")
360
- export class ConsumerSaleQuestionsController
326
+ export abstract class SaleInquiriesController<
327
+ Content extends ISaleInquiry.IContent,
328
+ Store extends ISaleInquiry.IStore,
329
+ Json extends ISaleInquiry<Content>>
361
330
  {
362
331
  /**
363
- * Store a new question.
332
+ * Store a new inquiry.
333
+ *
334
+ * Write a new article inquirying about a sale.
364
335
  *
365
336
  * @param request Instance of the Express.Request
366
337
  * @param section Code of the target section
367
338
  * @param saleId ID of the target sale
368
339
  * @param input Content to archive
340
+ * @return Newly archived inquiry
369
341
  *
370
- * @return Newly archived question
371
342
  * @throw 400 bad request error when type of the input data is not valid
372
343
  * @throw 401 unauthorized error when you've not logged in yet
373
344
  */
@@ -375,40 +346,101 @@ export class ConsumerSaleQuestionsController
375
346
  public store
376
347
  (
377
348
  @nest.Request() request: express.Request,
378
- @nest.Param("section") section: string,
379
- @nest.Param("saleId") saleId: number,
380
- @nest.Body() input: ISaleQuestion.IStore
381
- ): Promise<ISaleQuestion>;
349
+ @helper.TypedParam("section", "string") section: string,
350
+ @helper.TypedParam("saleId", "string") saleId: string,
351
+ @nest.Body() input: Store
352
+ ): Promise<Json>;
353
+
354
+ /**
355
+ * Update an inquiry.
356
+ *
357
+ * Update ordinary inquiry article. However, it would not modify the content reocrd
358
+ * {@link ISaleInquiry.IContent}, but be accumulated into the {@link ISaleInquiry.contents}.
359
+ * Therefore, all of the poeple can read how the content has been changed.
360
+ *
361
+ * @param request Instance of the Express.Request
362
+ * @param section Code of the target section
363
+ * @param saleId ID of the target sale
364
+ * @param id ID of the target article to be updated
365
+ * @param input New content to be overwritten
366
+ * @return The newly created content record
367
+ *
368
+ * @throw 400 bad request error when type of the input data is not valid
369
+ * @throw 401 unauthorized error when you've not logged in yet
370
+ * @throw 403 forbidden error when the article is not yours
371
+ */
372
+ @nest.Put(":id")
373
+ public update
374
+ (
375
+ @nest.Request() request: express.Request,
376
+ @helper.TypedParam("section", "string") section: string,
377
+ @helper.TypedParam("saleId", "string") saleId: string,
378
+ @helper.TypedParam("id", "number") id: number,
379
+ @nest.Body() input: Store
380
+ ): Promise<Json>;
382
381
  }
383
382
  ```
384
383
 
385
- ### SDK
386
- When you run the [nestia](https://github.com/samchon/nestia) up using the upper controller class `ConsumerSaleQuestionsController`, the [nestia](https://github.com/samchon/nestia) would generate below function for the client developers, by analyzing the `ConsumerSaleQuestionsController` class in the compilation and runtime level.
387
384
 
388
- As you can see, the comments from the `ConsumerSaleQuestionsController.store()` are fully copied to the SDK function. Therefore, if you want to deliver detailed description about the API function, writing the detailed comment would be tne best choice.
385
+
386
+
387
+ ### Software Development Kit
388
+ > `Swagger` is torturing the client developers.
389
+ >
390
+ > If you're a backend developer and you deliver a `Swagger` to your companion client developers, the client developers should analyze the `Swagger` and implement duplicated router functions with DTO interfaces by themselves. During those jobs, if the client developers take a mistake by mis-reading the `Swagger`, it becomes the critical runtime error directly.
391
+ >
392
+ > Why do you torture 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 and don't need to implement the duplicated DTO interfaces and router functions, either.
393
+ >
394
+ > Therefore, just build the SDK through this `nestia` and delivers 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
+
396
+ Looking at the SDK library file, generated by the `nestia`, it seems perfect.
397
+
398
+ Exact route method, path and parameters are constructed and DTO structures are perfectly imported. Also, descriptive comments written on the controller class methods, DTO interfaces and their properties are exactly revied in the SDK library.
399
+
400
+ Furthermore, there's not any problem even when the generic typed abstract controller classes with generic typed DTO comes. The `nestia` will specialize the generic arguments exactly, by analyzing your `NestJS` developed backend server code, in the compilation level.
401
+
402
+ - [simple/.../comments/index.ts](https://github.com/samchon/nestia/blob/master/demo/simple/src/api/functional/consumers/sales/articles/comments/index.ts)
403
+ - [generic/.../questions/index.ts](https://github.com/samchon/nestia/tree/master/demo/generic/src/api/functional/consumers/sales/questions/index.ts)
404
+ - [generic/.../reviews/index.ts](https://github.com/samchon/nestia/tree/master/demo/generic/src/api/functional/consumers/sales/reviews/index.ts)
405
+ - [union/.../entire_articles/index.ts](https://github.com/samchon/nestia/tree/master/demo/union/src/api/functional/consumers/sales/entire_articles/index.ts)
389
406
 
390
407
  ```typescript
391
408
  /**
392
- * Store a new question.
409
+ * @packageDocumentation
410
+ * @module api.functional.consumers.sales.reviews
411
+ * @nestia Generated by Nestia - https://github.com/samchon/nestia
412
+ */
413
+ //================================================================
414
+ import { Fetcher, Primitive } from "nestia-fetcher";
415
+ import type { IConnection } from "nestia-fetcher";
416
+ import { createStringifier } from "typescript-json";
417
+
418
+ import type { ISaleReview } from "./../../../../structures/ISaleReview";
419
+ import type { ISaleInquiry } from "./../../../../structures/ISaleInquiry";
420
+
421
+ /**
422
+ * Store a new inquiry.
423
+ *
424
+ * Write a new article inquirying about a sale.
393
425
  *
394
426
  * @param connection connection Information of the remote HTTP(s) server with headers (+encryption password)
395
427
  * @param request Instance of the Express.Request
396
428
  * @param section Code of the target section
397
429
  * @param saleId ID of the target sale
398
430
  * @param input Content to archive
399
- * @return Newly archived question
431
+ * @return Newly archived inquiry
400
432
  * @throw 400 bad request error when type of the input data is not valid
401
433
  * @throw 401 unauthorized error when you've not logged in yet
402
434
  *
435
+ * @controller ConsumerSaleReviewsController.store()
436
+ * @path POST /consumers/:section/sales/:saleId/reviews
403
437
  * @nestia Generated by Nestia - https://github.com/samchon/nestia
404
- * @controller ConsumerSaleQuestionsController.store()
405
- * @path POST /consumers/:section/sales/:saleId/questions/
406
438
  */
407
439
  export function store
408
440
  (
409
441
  connection: IConnection,
410
442
  section: string,
411
- saleId: number,
443
+ saleId: string,
412
444
  input: Primitive<store.Input>
413
445
  ): Promise<store.Output>
414
446
  {
@@ -418,249 +450,316 @@ export function store
418
450
  store.ENCRYPTED,
419
451
  store.METHOD,
420
452
  store.path(section, saleId),
421
- input
453
+ input,
454
+ store.stringify
422
455
  );
423
456
  }
424
457
  export namespace store
425
458
  {
426
- export type Input = Primitive<ISaleInquiry.IStore>;
427
- export type Output = Primitive<ISaleInquiry<ISaleArticle.IContent>>;
459
+ export type Input = Primitive<ISaleReview.IStore>;
460
+ export type Output = Primitive<ISaleInquiry<ISaleReview.IContent>>;
428
461
 
429
462
  export const METHOD = "POST" as const;
430
- export const PATH: string = "/consumers/:section/sales/:saleId/questions";
463
+ export const PATH: string = "/consumers/:section/sales/:saleId/reviews";
431
464
  export const ENCRYPTED: Fetcher.IEncrypted = {
432
- request: true,
433
- response: true,
465
+ request: false,
466
+ response: false,
434
467
  };
435
468
 
436
- export function path(section: string, saleId: number): string
469
+ export function path(section: string, saleId: string): string
437
470
  {
438
- return `/consumers/${section}/sales/${saleId}/questions`;
471
+ return `/consumers/${section}/sales/${saleId}/reviews`;
439
472
  }
473
+ export const stringify = createStringifier<Input>();
440
474
  }
441
- ```
442
475
 
443
- ### `swagger.json`
444
- Even the `swagger.json` generation does not require any swagger comment and DTO decorator.
476
+ /**
477
+ * Update an inquiry.
478
+ *
479
+ * Update ordinary inquiry article. However, it would not modify the content reocrd
480
+ * {@link ISaleInquiry.IContent}, but be accumulated into the {@link ISaleInquiry.contents}.
481
+ * Therefore, all of the poeple can read how the content has been changed.
482
+ *
483
+ * @param connection connection Information of the remote HTTP(s) server with headers (+encryption password)
484
+ * @param request Instance of the Express.Request
485
+ * @param section Code of the target section
486
+ * @param saleId ID of the target sale
487
+ * @param id ID of the target article to be updated
488
+ * @param input New content to be overwritten
489
+ * @return The newly created content record
490
+ * @throw 400 bad request error when type of the input data is not valid
491
+ * @throw 401 unauthorized error when you've not logged in yet
492
+ * @throw 403 forbidden error when the article is not yours
493
+ *
494
+ * @controller ConsumerSaleReviewsController.update()
495
+ * @path PUT /consumers/:section/sales/:saleId/reviews/:id
496
+ * @nestia Generated by Nestia - https://github.com/samchon/nestia
497
+ */
498
+ export function update
499
+ (
500
+ connection: IConnection,
501
+ section: string,
502
+ saleId: string,
503
+ id: number,
504
+ input: Primitive<update.Input>
505
+ ): Promise<update.Output>
506
+ {
507
+ return Fetcher.fetch
508
+ (
509
+ connection,
510
+ update.ENCRYPTED,
511
+ update.METHOD,
512
+ update.path(section, saleId, id),
513
+ input,
514
+ update.stringify
515
+ );
516
+ }
517
+ export namespace update
518
+ {
519
+ export type Input = Primitive<ISaleReview.IStore>;
520
+ export type Output = Primitive<ISaleInquiry<ISaleReview.IContent>>;
445
521
 
446
- The [nestia](https://github.com/samchon/nestia) will generate the perfect `swagger.json` automatically, by analyzing your source code (DTO interface and controller class) in the compilation and runtime level. Furthermore, your descriptive comments would be automatically assigned into the adequate `description` property in the `swagger.json`.
522
+ export const METHOD = "PUT" as const;
523
+ export const PATH: string = "/consumers/:section/sales/:saleId/reviews/:id";
524
+ export const ENCRYPTED: Fetcher.IEncrypted = {
525
+ request: false,
526
+ response: false,
527
+ };
447
528
 
448
- ```json
449
- {
450
- "paths": {
451
- "/consumers/{section}/sales/{saleId}/comments/{articleId}": {
452
- "post": {
453
- "tags": [],
454
- "parameters": [
455
- {
456
- "name": "section",
457
- "in": "path",
458
- "description": "Code of the target section",
459
- "schema": {
460
- "type": "string",
461
- "nullable": false
462
- },
463
- "required": true
464
- },
465
- {
466
- "name": "saleId",
467
- "in": "path",
468
- "description": "ID of the target sale",
469
- "schema": {
470
- "type": "number",
471
- "nullable": false
472
- },
473
- "required": true
474
- },
475
- {
476
- "name": "articleId",
477
- "in": "path",
478
- "description": "ID of the target article",
479
- "schema": {
480
- "type": "number",
481
- "nullable": false
482
- },
483
- "required": true
484
- }
485
- ],
486
- "requestBody": {
487
- "description": "Content to write",
488
- "content": {
489
- "application/json": {
490
- "schema": {
491
- "$ref": "#/components/schemas/ISaleComment.IStore"
492
- }
493
- }
494
- },
495
- "required": true
496
- },
497
- "responses": {
498
- "201": {
499
- "description": "Newly archived comment",
500
- "content": {
501
- "application/json": {
502
- "schema": {
503
- "$ref": "#/components/schemas/ISaleComment"
504
- }
505
- }
506
- }
507
- },
508
- "400": {
509
- "description": "bad request error when type of the input data is not valid"
510
- },
511
- "401": {
512
- "description": "unauthorized error when you've not logged in yet"
513
- },
514
- "403": {
515
- "description": "forbidden error when you're a seller and the sale is not yours"
516
- },
517
- "404": {
518
- "description": "not found error when unable to find the matched record"
519
- }
520
- },
521
- "description": "Store a new comment."
522
- }
523
- }
524
- },
525
- "components": {
526
- "schemas": {
527
- "ISaleComment": {
528
- "type": "object",
529
- "properties": {
530
- "id": {
531
- "description": "Primary Key.",
532
- "type": "number",
533
- "nullable": false
534
- },
535
- "writer_type": {
536
- "description": "Type of the writer.",
537
- "type": "string",
538
- "nullable": false
539
- },
540
- "writer_name": {
541
- "description": "Name of the writer.",
542
- "type": "string",
543
- "nullable": false
544
- },
545
- "contents": {
546
- "description": "Contents of the comments.\n\nWhen the comment writer tries to modify content, it would not modify the comment\ncontent but would be accumulated. Therefore, all of the people can read how\nthe content has been changed.",
547
- "type": "array",
548
- "items": {
549
- "$ref": "#/components/schemas/ISaleComment.IContent"
550
- },
551
- "nullable": false
552
- },
553
- "created_at": {
554
- "description": "Creation time.",
555
- "type": "string",
556
- "nullable": false
557
- }
558
- },
559
- "nullable": false,
560
- "required": [
561
- "id",
562
- "writer_type",
563
- "writer_name",
564
- "contents",
565
- "created_at"
566
- ],
567
- "description": "Comment wrote on an article."
568
- },
569
- "ISaleComment.IContent": {
570
- "type": "object",
571
- "properties": {
572
- "created_at": {
573
- "description": "Creation time.",
574
- "type": "string",
575
- "nullable": false
576
- },
577
- "body": {
578
- "description": "Body of the content.",
579
- "type": "string",
580
- "nullable": false
581
- }
582
- },
583
- "nullable": false,
584
- "required": [
585
- "created_at",
586
- "body"
587
- ],
588
- "description": "Content info."
589
- },
590
- "ISaleComment.IStore": {
591
- "type": "object",
592
- "properties": {
593
- "body": {
594
- "description": "Body of the content.",
595
- "type": "string",
596
- "nullable": false
597
- }
598
- },
599
- "nullable": false,
600
- "required": [
601
- "body"
602
- ],
603
- "description": "Store info."
604
- }
529
+ export function path(section: string, saleId: string, id: number): string
530
+ {
531
+ return `/consumers/${section}/sales/${saleId}/reviews/${id}`;
605
532
  }
606
- }
533
+ export const stringify = createStringifier<Input>();
607
534
  }
608
535
  ```
609
536
 
610
537
 
611
538
 
612
539
 
540
+ ### Swagger
541
+ Building `Swagger` is also possible and even much powerful.
613
542
 
614
- ## Appendix
615
- ### Template Project
616
- https://github.com/samchon/backend
543
+ Although I think the `Swagger` is a typical tool that torturing the client developers, the `nestia` also can build the `swagger.json` file. Even `Swagger` generator of the `nestia` is much powerful and convenient than the `@nestjs/swagger`. It doesn't require any type of the swagger comment or DTO decorator function and just using the pure interface type as DTO is possible.
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`.
546
+
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 the generic typed DTO interfaces or controller classes come. Furthermore, traveling the `description` properties of the [generic/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Funion%2Fswagger.json), comments written on the generic interfaces and controllers are exactly revived in each route functions and schema definitions.
548
+
549
+ - View in the `Swagger Editor`
550
+ - [simple/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Fsimple%2Fswagger.json)
551
+ - [generic/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Fgeneric%2Fswagger.json)
552
+ - [union/swagger.json](https://editor.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsamchon%2Fnestia%2Fmaster%2Fdemo%2Funion%2Fswagger.json)
553
+
554
+ ![Swagger Editor](https://github.com/samchon/nestia/wiki/images/swagger-editor-comment.png)
555
+
556
+
557
+
558
+
559
+ ## Configuration
560
+ Components | `nestia.config.ts` | `CLI` | `@nestjs/swagger`
561
+ -----------------------------|--------------------|-------|------------------
562
+ Swagger Generation | ✔ | ✔ | ✔
563
+ SDK Generation | ✔ | ✔ | ❌
564
+ 2x faster `JSON.stringify()` | ✔ | ❌ | ❌
565
+ Type check in runtime | ✔ | ❌ | ❌
566
+ Custom compiler options | ✔ | ❌ | ❌
567
+
568
+ You can configure the nestia builder options by two ways: `CLI` or `configuration file`.
569
+
570
+ The CLI (Command Line Interface) is easy to use, because it does not require any type of configuration file wrinting. However, it's not safe thing that repeating the same command whenever generating the SDK or `swagger.json` through the CLI, because command miswriting can be happened.
571
+
572
+ ```bash
573
+ # BASIC COMMAND
574
+ npx nestia <nestia|swagger> <source_directories_or_patterns> \
575
+ --exclude <exclude_directory_or_pattern> \
576
+ --out <output_directory_or_file>
577
+
578
+ # EXAMPLES
579
+ npx nestia nestia "src/controllers" --out "src/api"
580
+ npx nestia swagger "src/**/*.controller.ts" -- out "swagger.json"
581
+ npx nestia swagger "src/main/controllers" "src/sub/controllers" \
582
+ --exclude "src/main/test" \
583
+ --out "composite.swagger.json"
584
+
585
+ # ONLY WHEN NESTIA.CONFIG.TS EXISTS
586
+ npx nestia nestia
587
+ npx nestia swagger
588
+ ```
589
+
590
+ Otherwise, configuration file `nestia.config.ts` may hard to construct and the construction would be annoying and inconvenient, such configuration would be useful within framework of the reusability. Also, the configuration file `nestia.config.ts` use much detailed options than the `CLI` and its content can be ensured its safety by TypeScript compiler through the `IConfigruation` interface type.
591
+
592
+ ```typescript
593
+ /**
594
+ * Definition for the `nestia.config.ts` file.
595
+ *
596
+ * @author Jeongho Nam - https://github.com/samchon
597
+ */
598
+ export interface IConfiguration
599
+ {
600
+ /**
601
+ * List of files or directories containing the NestJS controller classes.
602
+ */
603
+ input: string | string[] | IConfiguration.IInput;
617
604
 
618
- I support template backend project using this [nestia](https://github.com/samchon/nestia) library, [backend](https://github.com/samchon/backend).
605
+ /**
606
+ * Output directory that SDK would be placed in.
607
+ *
608
+ * If not configured, you can't build the SDK library.
609
+ */
610
+ output?: string;
611
+
612
+ /**
613
+ * Compiler options for the TypeScript.
614
+ *
615
+ * If you've omitted this property or the assigned property cannot fully cover the
616
+ * `tsconfig.json`, the properties from the `tsconfig.json` would be assigned to here.
617
+ * Otherwise, this property has been configured and it's detailed values are different
618
+ * with the `tsconfig.json`, this property values would be overwritten.
619
+ *
620
+ * ```typescript
621
+ * import ts from "typescript";
622
+ *
623
+ * const tsconfig: ts.TsConfig;
624
+ * const nestiaConfig: IConfiguration;
625
+ *
626
+ * const compilerOptions: ts.CompilerOptions = {
627
+ * ...tsconfig.compilerOptions,
628
+ * ...(nestiaConfig.compilerOptions || {})
629
+ * }
630
+ * ```
631
+ */
632
+ compilerOptions?: ts.CompilerOptions;
633
+
634
+ /**
635
+ * Whether to assert parameter types or not.
636
+ *
637
+ * If you configure this property to be `true`, all of the function parameters would be
638
+ * checked through the [typescript-is](https://github.com/woutervh-/typescript-is). This
639
+ * option would make your SDK library slower, but would be much safer in the type level
640
+ * even in the runtime environment.
641
+ */
642
+ assert?: boolean;
643
+
644
+ /**
645
+ * Whether to optimize JSON string conversion 2x faster or not.
646
+ *
647
+ * If you configure this property to be `true`, the SDK library would utilize the
648
+ * [typescript-json](https://github.com/samchon/typescript-json) and the JSON string
649
+ * conversion speed really be 2x faster.
650
+ */
651
+ json?: boolean;
652
+
653
+ /**
654
+ * Building `swagger.json` is also possible.
655
+ *
656
+ * If not specified, you can't build the `swagger.json`.
657
+ */
658
+ swagger?: IConfiguration.ISwagger;
659
+ }
660
+ export namespace IConfiguration
661
+ {
662
+ /**
663
+ * List of files or directories to include or exclude to specifying the NestJS
664
+ * controllers.
665
+ */
666
+ export interface IInput
667
+ {
668
+ /**
669
+ * List of files or directories containing the NestJS controller classes.
670
+ */
671
+ include: string[];
672
+
673
+ /**
674
+ * List of files or directories to be excluded.
675
+ */
676
+ exclude?: string[];
677
+ }
678
+
679
+ /**
680
+ * Building `swagger.json` is also possible.
681
+ */
682
+ export interface ISwagger
683
+ {
684
+ /**
685
+ * Output path of the `swagger.json`.
686
+ *
687
+ * If you've configured only directory, the file name would be the `swagger.json`.
688
+ * Otherwise you've configured the full path with file name and extension, the
689
+ * `swagger.json` file would be renamed to it.
690
+ */
691
+ output: string;
692
+ }
693
+ }
694
+ ```
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:
619
697
 
620
- Reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, those example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.
698
+ ```typescript
699
+ import type { IConfiguration } from "nestia";
700
+
701
+ export const NESTIA_CONFIG: IConfiguration = {
702
+ input: "./src/controllers",
703
+ output: "./src/api",
704
+ json: true,
705
+ swagger: {
706
+ output: "./public/swagger.json"
707
+ }
708
+ };
709
+ export default NESTIA_CONFIG;
710
+ ```
621
711
 
622
- Therefore, if you're planning to compose your own backend project using this [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.
623
712
 
624
- ### Nestia-Helper
625
- https://github.com/samchon/nestia-helper
626
713
 
627
- Helper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).
628
714
 
629
- [nestia-helper](https://github.com/samchon/nestia-helper) is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this [nestia-helper](https://github.com/samchon/nestia-helper) are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.
715
+ ## Appendix
716
+ ### Dependencies of the SDK
717
+ An SDK library generated by the `nestia` requires the [nestia-fetcher](https://github.com/samchon/nestia-fetcher) module. Also, the [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 options.
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
+ ```
630
729
 
631
- Of course, this [nestia-helper](https://github.com/samchon/nestia-helper) is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this [nestia-helper](https://github.com/samchon/nestia-helper). However, as decorator functions of this [nestia-helper](https://github.com/samchon/nestia-helper) is enough strong, I recommend you to adapt this [nestia-helper](https://github.com/samchon/nestia-helper) when using `NestJS` and [nestia](https://github.com/samchon/nestia).
730
+ The `npx nestia install` command installs those dependencies with the `package.json` configuration.
632
731
 
633
- - Supported decorator functions
634
- - [EncryptedController](https://github.com/samchon/nestia-helper#encryptedcontroller), [EncryptedModule](https://github.com/samchon/nestia-helper#encryptedmodule)
635
- - [TypedRoute](https://github.com/samchon/nestia-helper#typedroute), [EncryptedRoute](https://github.com/samchon/nestia-helper#encryptedroute)
636
- - [TypedParam](https://github.com/samchon/nestia-helper#typedparam), [EncryptedBody](https://github.com/samchon/nestia-helper#encryptedbody), [PlainBody](https://github.com/samchon/nestia-helper#plainbody)
637
- - [ExceptionManager](https://github.com/samchon/nestia-helper#exceptionmanager)
732
+ ```bash
733
+ # MOVE TO THE DISTRIBUTION DIRECTORY
734
+ cd packages/api
638
735
 
639
- ### Safe-TypeORM
640
- https://github.com/samchon/safe-typeorm
736
+ # INSTALL DEPENDENCIES OF THE SDK
737
+ npx nestia install
738
+ ```
641
739
 
642
- [safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.
740
+ ### Template Repository
741
+ https://github.com/samchon/backend
643
742
 
644
- Therefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.
743
+ I support template backend project using this `nestia` library, `samchon/backend`.
645
744
 
646
- - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),
647
- - Errors would be detected in the **compilation** level
648
- - **Auto Completion** would be provided
649
- - **Type Hint** would be supported
650
- - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently
651
- - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)
652
- - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done
653
- - Exact JSON **type** would be automatically **deduced**
654
- - The **performance** would be **automatically tuned**
655
- - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records
656
- - Sequence of tables would be automatically sorted by analyzing dependencies
657
- - The **performance** would be **automatically tuned**
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 the `nestia` and how to distribute the SDK library thorugh the NPM module.
658
746
 
659
- ![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demo/safe-query-builder.gif)
747
+ 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.
660
748
 
661
749
  ### Archidraw
662
750
  https://www.archisketch.com/
663
751
 
664
752
  I have special thanks to the Archidraw, where I'm working for.
665
753
 
666
- The Archidraw is a great IT company developing 3D interior editor and lots of solutions based on the 3D assets. Also, the Archidraw is the first company who had adopted this [nestia](https://github.com/samchon/nestia) on their commercial backend project, even this [nestia](https://github.com/samchon/nestia) was in the alpha level.
754
+ The Archidraw is a great IT company developing 3D interior editor and lots of solutions based on the 3D assets. Also, the Archidraw is the first company who had adopted this nestia on their commercial backend project, even this nestia was in the alpha level.
755
+
756
+ > 저희 회사 "아키드로우" 에서, 삼촌과 함께 일할 프론트 개발자 분들을, 최고의 대우로 모십니다.
757
+ >
758
+ > "아키드로우" 는 3D (인테리어) 에디터 및 이에 관한 파생 솔루션들을 만드는 회사입니다. 다만 저희 회사의 주력 제품이 3D 에디터라 하여, 반드시 3D 내지 랜더링에 능숙해야 하는 것은 아니니, 일반적인 프론트 개발자 분들도 망설임없이 지원해주십시오.
759
+ >
760
+ > 그리고 저희 회사는 분위기가 다들 친하고 즐겁게 지내는 분위기입니다. 더하여 위 `nestia` 나 [typescript-json](https://github.com/samchon/typescript-json) 및 [payments](https://github.com/archidraw/payments) 등, 제법 합리적(?)이고 재미난 프로젝트들을 다양하게 체험해보실 수 있습니다.
761
+ >
762
+ > - 회사소개서: [archidraw.pdf](https://github.com/archidraw/payments/files/7696710/archidraw.pdf)
763
+ > - 기술 스택: React + TypeScript
764
+ > - 이력서: 자유 양식
765
+ > - 지원처: samchon@archisketch.com
@@ -104,7 +104,7 @@ var SchemaFactory;
104
104
  else
105
105
  return {
106
106
  description: meta.description,
107
- anyOf: unions
107
+ oneOf: unions
108
108
  };
109
109
  }
110
110
  SchemaFactory.schema = schema;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestia",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "Automatic SDK and Document generator for the NestJS",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",