@nestia/sdk 2.4.2 → 2.4.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.
Files changed (111) hide show
  1. package/lib/NestiaSdkApplication.js +2 -6
  2. package/lib/NestiaSdkApplication.js.map +1 -1
  3. package/lib/analyses/AccessorAnalyzer.js.map +1 -1
  4. package/lib/analyses/ConfigAnalyzer.js +4 -8
  5. package/lib/analyses/ConfigAnalyzer.js.map +1 -1
  6. package/lib/analyses/ControllerAnalyzer.js +6 -8
  7. package/lib/analyses/ControllerAnalyzer.js.map +1 -1
  8. package/lib/analyses/ExceptionAnalyzer.js.map +1 -1
  9. package/lib/analyses/GenericAnalyzer.js +1 -2
  10. package/lib/analyses/GenericAnalyzer.js.map +1 -1
  11. package/lib/analyses/ImportAnalyzer.js +4 -4
  12. package/lib/analyses/ImportAnalyzer.js.map +1 -1
  13. package/lib/analyses/PathAnalyzer.js.map +1 -1
  14. package/lib/analyses/ReflectAnalyzer.js +7 -8
  15. package/lib/analyses/ReflectAnalyzer.js.map +1 -1
  16. package/lib/analyses/SecurityAnalyzer.js.map +1 -1
  17. package/lib/executable/internal/CommandParser.js.map +1 -1
  18. package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
  19. package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
  20. package/lib/executable/sdk.js +11 -11
  21. package/lib/executable/sdk.js.map +1 -1
  22. package/lib/generates/E2eGenerator.js.map +1 -1
  23. package/lib/generates/SdkGenerator.js.map +1 -1
  24. package/lib/generates/SwaggerGenerator.js +5 -11
  25. package/lib/generates/SwaggerGenerator.js.map +1 -1
  26. package/lib/generates/internal/E2eFileProgrammer.js +2 -8
  27. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  28. package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
  29. package/lib/generates/internal/SdkDtoGenerator.js +3 -9
  30. package/lib/generates/internal/SdkDtoGenerator.js.map +1 -1
  31. package/lib/generates/internal/SdkFileProgrammer.js +4 -4
  32. package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
  33. package/lib/generates/internal/SdkFunctionProgrammer.js +12 -20
  34. package/lib/generates/internal/SdkFunctionProgrammer.js.map +1 -1
  35. package/lib/generates/internal/SdkImportWizard.js.map +1 -1
  36. package/lib/generates/internal/SdkRouteDirectory.js +1 -3
  37. package/lib/generates/internal/SdkRouteDirectory.js.map +1 -1
  38. package/lib/generates/internal/SdkSimulationProgrammer.js +5 -7
  39. package/lib/generates/internal/SdkSimulationProgrammer.js.map +1 -1
  40. package/lib/generates/internal/SdkTypeDefiner.js +2 -5
  41. package/lib/generates/internal/SdkTypeDefiner.js.map +1 -1
  42. package/lib/generates/internal/SwaggerSchemaGenerator.js +29 -44
  43. package/lib/generates/internal/SwaggerSchemaGenerator.js.map +1 -1
  44. package/lib/generates/internal/SwaggerSchemaValidator.js +3 -9
  45. package/lib/generates/internal/SwaggerSchemaValidator.js.map +1 -1
  46. package/lib/structures/MethodType.js +1 -7
  47. package/lib/structures/MethodType.js.map +1 -1
  48. package/lib/structures/TypeEntry.js.map +1 -1
  49. package/lib/utils/ArrayUtil.js.map +1 -1
  50. package/lib/utils/FileRetriever.js.map +1 -1
  51. package/lib/utils/ImportDictionary.js +1 -4
  52. package/lib/utils/ImportDictionary.js.map +1 -1
  53. package/lib/utils/MapUtil.js.map +1 -1
  54. package/lib/utils/PathUtil.js.map +1 -1
  55. package/lib/utils/SourceFinder.js.map +1 -1
  56. package/package.json +4 -7
  57. package/src/INestiaConfig.ts +234 -234
  58. package/src/NestiaSdkApplication.ts +253 -268
  59. package/src/analyses/AccessorAnalyzer.ts +60 -60
  60. package/src/analyses/ConfigAnalyzer.ts +147 -164
  61. package/src/analyses/ControllerAnalyzer.ts +379 -399
  62. package/src/analyses/ExceptionAnalyzer.ts +115 -124
  63. package/src/analyses/GenericAnalyzer.ts +51 -57
  64. package/src/analyses/ImportAnalyzer.ts +138 -159
  65. package/src/analyses/PathAnalyzer.ts +98 -100
  66. package/src/analyses/ReflectAnalyzer.ts +425 -433
  67. package/src/analyses/SecurityAnalyzer.ts +20 -20
  68. package/src/executable/internal/CommandParser.ts +15 -15
  69. package/src/executable/internal/NestiaConfigLoader.ts +67 -68
  70. package/src/executable/internal/NestiaSdkCommand.ts +60 -64
  71. package/src/executable/sdk.ts +73 -73
  72. package/src/generates/E2eGenerator.ts +64 -67
  73. package/src/generates/SdkGenerator.ts +96 -100
  74. package/src/generates/SwaggerGenerator.ts +372 -410
  75. package/src/generates/internal/E2eFileProgrammer.ts +123 -129
  76. package/src/generates/internal/SdkDistributionComposer.ts +91 -91
  77. package/src/generates/internal/SdkDtoGenerator.ts +424 -450
  78. package/src/generates/internal/SdkFileProgrammer.ts +106 -111
  79. package/src/generates/internal/SdkFunctionProgrammer.ts +466 -501
  80. package/src/generates/internal/SdkImportWizard.ts +55 -55
  81. package/src/generates/internal/SdkRouteDirectory.ts +17 -19
  82. package/src/generates/internal/SdkSimulationProgrammer.ts +133 -142
  83. package/src/generates/internal/SdkTypeDefiner.ts +119 -124
  84. package/src/generates/internal/SwaggerSchemaGenerator.ts +382 -401
  85. package/src/generates/internal/SwaggerSchemaValidator.ts +198 -210
  86. package/src/index.ts +4 -4
  87. package/src/module.ts +2 -2
  88. package/src/structures/IController.ts +79 -81
  89. package/src/structures/IErrorReport.ts +6 -6
  90. package/src/structures/INestiaProject.ts +13 -13
  91. package/src/structures/INormalizedInput.ts +20 -20
  92. package/src/structures/IRoute.ts +40 -41
  93. package/src/structures/ISwagger.ts +91 -91
  94. package/src/structures/ISwaggerComponents.ts +29 -29
  95. package/src/structures/ISwaggerError.ts +8 -8
  96. package/src/structures/ISwaggerInfo.ts +80 -80
  97. package/src/structures/ISwaggerLazyProperty.ts +7 -7
  98. package/src/structures/ISwaggerLazySchema.ts +7 -7
  99. package/src/structures/ISwaggerRoute.ts +51 -51
  100. package/src/structures/ISwaggerSecurityScheme.ts +65 -65
  101. package/src/structures/ITypeTuple.ts +6 -6
  102. package/src/structures/MethodType.ts +5 -11
  103. package/src/structures/ParamCategory.ts +1 -1
  104. package/src/structures/TypeEntry.ts +22 -22
  105. package/src/utils/ArrayUtil.ts +26 -26
  106. package/src/utils/FileRetriever.ts +22 -22
  107. package/src/utils/ImportDictionary.ts +125 -128
  108. package/src/utils/MapUtil.ts +14 -14
  109. package/src/utils/PathUtil.ts +10 -10
  110. package/src/utils/SourceFinder.ts +66 -70
  111. package/src/utils/StripEnums.ts +5 -10
@@ -1,6 +1,5 @@
1
- import { Singleton } from "tstl";
1
+ import { Singleton, VariadicSingleton } from "tstl";
2
2
  import ts from "typescript";
3
-
4
3
  import { IJsonSchema } from "typia";
5
4
  import { MetadataCollection } from "typia/lib/factories/MetadataCollection";
6
5
  import { MetadataFactory } from "typia/lib/factories/MetadataFactory";
@@ -16,432 +15,414 @@ import { ISwaggerRoute } from "../../structures/ISwaggerRoute";
16
15
  import { SwaggerSchemaValidator } from "./SwaggerSchemaValidator";
17
16
 
18
17
  export namespace SwaggerSchemaGenerator {
19
- export interface IProps {
20
- config: INestiaConfig.ISwaggerConfig;
21
- checker: ts.TypeChecker;
22
- collection: MetadataCollection;
23
- lazySchemas: Array<ISwaggerLazySchema>;
24
- lazyProperties: Array<ISwaggerLazyProperty>;
25
- errors: ISwaggerError[];
26
- }
27
-
28
- export const response =
29
- (props: IProps) =>
30
- (route: IRoute): ISwaggerRoute.IResponseBody => {
31
- const output: ISwaggerRoute.IResponseBody = {};
18
+ export interface IProps {
19
+ config: INestiaConfig.ISwaggerConfig;
20
+ checker: ts.TypeChecker;
21
+ collection: MetadataCollection;
22
+ lazySchemas: Array<ISwaggerLazySchema>;
23
+ lazyProperties: Array<ISwaggerLazyProperty>;
24
+ errors: ISwaggerError[];
25
+ }
32
26
 
33
- //----
34
- // EXCEPTION STATUSES
35
- //----
36
- // FROM DECORATOR
37
- for (const [status, exp] of Object.entries(route.exceptions)) {
38
- const result = MetadataFactory.analyze(props.checker)({
39
- escape: true,
40
- constant: true,
41
- absorb: false,
42
- validate: (meta) => {
43
- const bigint: boolean =
44
- meta.atomics.some((a) => a.type === "bigint") ||
45
- meta.constants.some((a) => a.type === "bigint");
46
- return bigint ? ["bigint type is not allowed."] : [];
47
- },
48
- })(props.collection)(exp.type);
49
- if (result.success === false)
50
- props.errors.push(
51
- ...result.errors.map((e) => ({
52
- ...e,
53
- route,
54
- from: `response(status: ${status})`,
55
- })),
56
- );
27
+ export const response =
28
+ (props: IProps) =>
29
+ (route: IRoute): ISwaggerRoute.IResponseBody => {
30
+ const output: ISwaggerRoute.IResponseBody = {};
57
31
 
58
- output[status] = {
59
- description: exp.description ?? "",
60
- content: {
61
- "application/json": {
62
- schema: coalesce(props)(result),
63
- },
64
- },
65
- };
66
- }
32
+ //----
33
+ // EXCEPTION STATUSES
34
+ //----
35
+ // FROM DECORATOR
36
+ for (const [status, exp] of Object.entries(route.exceptions)) {
37
+ const result = MetadataFactory.analyze(props.checker)({
38
+ escape: true,
39
+ constant: true,
40
+ absorb: false,
41
+ validate: (meta) => {
42
+ const bigint: boolean =
43
+ meta.atomics.some((a) => a.type === "bigint") ||
44
+ meta.constants.some((a) => a.type === "bigint");
45
+ return bigint ? ["bigint type is not allowed."] : [];
46
+ },
47
+ })(props.collection)(exp.type);
48
+ if (result.success === false)
49
+ props.errors.push(
50
+ ...result.errors.map((e) => ({
51
+ ...e,
52
+ route,
53
+ from: `response(status: ${status})`,
54
+ })),
55
+ );
67
56
 
68
- // FROM COMMENT TAGS -> ANY
69
- for (const tag of route.jsDocTags) {
70
- if (tag.name !== "throw" && tag.name !== "throws") continue;
57
+ output[status] = {
58
+ description: exp.description ?? "",
59
+ content: {
60
+ "application/json": {
61
+ schema: coalesce(props)(result),
62
+ },
63
+ },
64
+ };
65
+ }
71
66
 
72
- const text: string | undefined = tag.text?.find(
73
- (elem) => elem.kind === "text",
74
- )?.text;
75
- if (text === undefined) continue;
67
+ // FROM COMMENT TAGS -> ANY
68
+ for (const tag of route.jsDocTags) {
69
+ if (tag.name !== "throw" && tag.name !== "throws") continue;
76
70
 
77
- const elements: string[] = text
78
- .split(" ")
79
- .map((str) => str.trim());
80
- const status: string = elements[0];
81
- if (
82
- isNaN(Number(status)) &&
83
- status !== "2XX" &&
84
- status !== "3XX" &&
85
- status !== "4XX" &&
86
- status !== "5XX"
87
- )
88
- continue;
71
+ const text: string | undefined = tag.text?.find(
72
+ (elem) => elem.kind === "text",
73
+ )?.text;
74
+ if (text === undefined) continue;
89
75
 
90
- const description: string | undefined =
91
- elements.length === 1
92
- ? undefined
93
- : elements.slice(1).join(" ");
94
- const oldbie = output[status];
95
- if (description && oldbie !== undefined)
96
- oldbie.description = description;
97
- else if (oldbie === undefined)
98
- output[status] = {
99
- description: description ?? "",
100
- content: {
101
- "application/json": {
102
- schema: {},
103
- },
104
- },
105
- };
106
- }
76
+ const elements: string[] = text.split(" ").map((str) => str.trim());
77
+ const status: string = elements[0];
78
+ if (
79
+ isNaN(Number(status)) &&
80
+ status !== "2XX" &&
81
+ status !== "3XX" &&
82
+ status !== "4XX" &&
83
+ status !== "5XX"
84
+ )
85
+ continue;
107
86
 
108
- //----
109
- // SUCCESS
110
- //----
111
- // STATUS
112
- const status: string =
113
- route.status !== undefined
114
- ? String(route.status)
115
- : route.method === "GET" ||
116
- route.method === "HEAD" ||
117
- route.method === "DELETE"
118
- ? "200"
119
- : "201";
87
+ const description: string | undefined =
88
+ elements.length === 1 ? undefined : elements.slice(1).join(" ");
89
+ const oldbie = output[status];
90
+ if (description && oldbie !== undefined)
91
+ oldbie.description = description;
92
+ else if (oldbie === undefined)
93
+ output[status] = {
94
+ description: description ?? "",
95
+ content: {
96
+ "application/json": {
97
+ schema: {},
98
+ },
99
+ },
100
+ };
101
+ }
120
102
 
121
- // SCHEMA
122
- const result = MetadataFactory.analyze(props.checker)({
123
- escape: true,
124
- constant: true,
125
- absorb: false,
126
- validate: (meta) => {
127
- const bigint: boolean =
128
- meta.atomics.some((a) => a.type === "bigint") ||
129
- meta.constants.some((a) => a.type === "bigint");
130
- return bigint ? ["bigint type is not allowed."] : [];
131
- },
132
- })(props.collection)(route.output.type);
133
- if (result.success === false)
134
- props.errors.push(
135
- ...result.errors.map((e) => ({
136
- ...e,
137
- route,
138
- from: "response",
139
- })),
140
- );
103
+ //----
104
+ // SUCCESS
105
+ //----
106
+ // STATUS
107
+ const status: string =
108
+ route.status !== undefined
109
+ ? String(route.status)
110
+ : route.method === "GET" ||
111
+ route.method === "HEAD" ||
112
+ route.method === "DELETE"
113
+ ? "200"
114
+ : "201";
141
115
 
142
- // DO ASSIGN
143
- const description =
144
- describe(route, "return") ?? describe(route, "returns");
145
- output[status] = {
146
- description: route.encrypted
147
- ? `${warning
148
- .get(!!description)
149
- .get("response", route.method)}${description ?? ""}`
150
- : description ?? "",
151
- content:
152
- route.output.typeName === "void"
153
- ? undefined
154
- : {
155
- [route.output.contentType]: {
156
- schema: coalesce(props)(result),
157
- },
158
- },
159
- "x-nestia-encrypted": route.encrypted,
160
- };
161
- return output;
162
- };
116
+ // SCHEMA
117
+ const result = MetadataFactory.analyze(props.checker)({
118
+ escape: true,
119
+ constant: true,
120
+ absorb: false,
121
+ validate: (meta) => {
122
+ const bigint: boolean =
123
+ meta.atomics.some((a) => a.type === "bigint") ||
124
+ meta.constants.some((a) => a.type === "bigint");
125
+ return bigint ? ["bigint type is not allowed."] : [];
126
+ },
127
+ })(props.collection)(route.output.type);
128
+ if (result.success === false)
129
+ props.errors.push(
130
+ ...result.errors.map((e) => ({
131
+ ...e,
132
+ route,
133
+ from: "response",
134
+ })),
135
+ );
163
136
 
164
- export const body =
165
- (props: IProps) =>
166
- (route: IRoute) =>
167
- (param: IRoute.IParameter): ISwaggerRoute.IRequestBody => {
168
- // ANALZE TYPE WITH VALIDATION
169
- const result = MetadataFactory.analyze(props.checker)({
170
- escape: true,
171
- constant: true,
172
- absorb: true,
173
- validate: (meta) => {
174
- const bigint: boolean =
175
- meta.atomics.some((a) => a.type === "bigint") ||
176
- meta.constants.some((a) => a.type === "bigint");
177
- return bigint ? ["bigint type is not allowed."] : [];
137
+ // DO ASSIGN
138
+ const description =
139
+ describe(route, "return") ?? describe(route, "returns");
140
+ output[status] = {
141
+ description: route.encrypted
142
+ ? `${warning.get(!!description, "response", route.method)}${
143
+ description ?? ""
144
+ }`
145
+ : description ?? "",
146
+ content:
147
+ route.output.typeName === "void"
148
+ ? undefined
149
+ : {
150
+ [route.output.contentType]: {
151
+ schema: coalesce(props)(result),
178
152
  },
179
- })(props.collection)(param.type);
180
- if (result.success === false)
181
- props.errors.push(
182
- ...result.errors.map((e) => ({
183
- ...e,
184
- route,
185
- from: param.name,
186
- })),
187
- );
188
-
189
- // LIST UP PROPERTIES
190
- const contentType =
191
- param.custom && param.category === "body"
192
- ? param.contentType
193
- : "application/json";
194
- const encrypted: boolean =
195
- param.custom && param.category === "body" && param.encrypted;
196
- const description: string | undefined = describe(
197
- route,
198
- "param",
199
- param.name,
200
- );
153
+ },
154
+ "x-nestia-encrypted": route.encrypted,
155
+ };
156
+ return output;
157
+ };
201
158
 
202
- // RETURNS WITH LAZY CONSTRUCTION
203
- const schema: IJsonSchema = coalesce(props)(result);
204
- return {
205
- description: encrypted
206
- ? `${warning.get(!!description).get("request")}${
207
- description ?? ""
208
- }`
209
- : description,
210
- content: {
211
- [contentType]: {
212
- schema,
213
- },
214
- },
215
- required: true,
216
- "x-nestia-encrypted": encrypted,
217
- };
218
- };
159
+ export const body =
160
+ (props: IProps) =>
161
+ (route: IRoute) =>
162
+ (param: IRoute.IParameter): ISwaggerRoute.IRequestBody => {
163
+ // ANALZE TYPE WITH VALIDATION
164
+ const result = MetadataFactory.analyze(props.checker)({
165
+ escape: true,
166
+ constant: true,
167
+ absorb: true,
168
+ validate: (meta) => {
169
+ const bigint: boolean =
170
+ meta.atomics.some((a) => a.type === "bigint") ||
171
+ meta.constants.some((a) => a.type === "bigint");
172
+ return bigint ? ["bigint type is not allowed."] : [];
173
+ },
174
+ })(props.collection)(param.type);
175
+ if (result.success === false)
176
+ props.errors.push(
177
+ ...result.errors.map((e) => ({
178
+ ...e,
179
+ route,
180
+ from: param.name,
181
+ })),
182
+ );
219
183
 
220
- export const parameter =
221
- (props: IProps) =>
222
- (route: IRoute) =>
223
- (param: IRoute.IParameter): ISwaggerRoute.IParameter[] =>
224
- param.category === "headers"
225
- ? headers(props)(route)(param)
226
- : param.category === "param"
227
- ? [path(props)(route)(param)]
228
- : query(props)(route)(param);
184
+ // LIST UP PROPERTIES
185
+ const contentType =
186
+ param.custom && param.category === "body"
187
+ ? param.contentType
188
+ : "application/json";
189
+ const encrypted: boolean =
190
+ param.custom && param.category === "body" && param.encrypted;
191
+ const description: string | undefined = describe(
192
+ route,
193
+ "param",
194
+ param.name,
195
+ );
229
196
 
230
- const path =
231
- (props: IProps) =>
232
- (route: IRoute) =>
233
- (param: IRoute.IParameter): ISwaggerRoute.IParameter => {
234
- // ANALZE TYPE WITH VALIDATION
235
- const result = MetadataFactory.analyze(props.checker)({
236
- escape: false,
237
- constant: true,
238
- absorb: true,
239
- validate: SwaggerSchemaValidator.path,
240
- })(props.collection)(param.type);
241
- if (result.success === false)
242
- props.errors.push(
243
- ...result.errors.map((e) => ({
244
- ...e,
245
- route,
246
- from: param.name,
247
- })),
248
- );
197
+ // RETURNS WITH LAZY CONSTRUCTION
198
+ const schema: IJsonSchema = coalesce(props)(result);
199
+ return {
200
+ description: encrypted
201
+ ? `${warning.get(!!description, "request")}${description ?? ""}`
202
+ : description,
203
+ content: {
204
+ [contentType]: {
205
+ schema,
206
+ },
207
+ },
208
+ required: true,
209
+ "x-nestia-encrypted": encrypted,
210
+ };
211
+ };
249
212
 
250
- // RETURNS WITH LAZY CONSTRUCTION
251
- return lazy(props)(route)(param, result);
252
- };
213
+ export const parameter =
214
+ (props: IProps) =>
215
+ (route: IRoute) =>
216
+ (param: IRoute.IParameter): ISwaggerRoute.IParameter[] =>
217
+ param.category === "headers"
218
+ ? headers(props)(route)(param)
219
+ : param.category === "param"
220
+ ? [path(props)(route)(param)]
221
+ : query(props)(route)(param);
253
222
 
254
- const headers =
255
- (props: IProps) =>
256
- (route: IRoute) =>
257
- (param: IRoute.IParameter): ISwaggerRoute.IParameter[] =>
258
- decomposible(props)(route)(param)(
259
- MetadataFactory.analyze(props.checker)({
260
- escape: false,
261
- constant: true,
262
- absorb: true,
263
- validate: param.custom
264
- ? SwaggerSchemaValidator.headers
265
- : undefined,
266
- })(props.collection)(param.type),
267
- );
223
+ const path =
224
+ (props: IProps) =>
225
+ (route: IRoute) =>
226
+ (param: IRoute.IParameter): ISwaggerRoute.IParameter => {
227
+ // ANALZE TYPE WITH VALIDATION
228
+ const result = MetadataFactory.analyze(props.checker)({
229
+ escape: false,
230
+ constant: true,
231
+ absorb: true,
232
+ validate: SwaggerSchemaValidator.path,
233
+ })(props.collection)(param.type);
234
+ if (result.success === false)
235
+ props.errors.push(
236
+ ...result.errors.map((e) => ({
237
+ ...e,
238
+ route,
239
+ from: param.name,
240
+ })),
241
+ );
268
242
 
269
- const query =
270
- (props: IProps) =>
271
- (route: IRoute) =>
272
- (param: IRoute.IParameter): ISwaggerRoute.IParameter[] =>
273
- decomposible(props)(route)(param)(
274
- MetadataFactory.analyze(props.checker)({
275
- escape: false,
276
- constant: true,
277
- absorb: true,
278
- validate: param.custom
279
- ? SwaggerSchemaValidator.query
280
- : undefined,
281
- })(props.collection)(param.type),
282
- );
243
+ // RETURNS WITH LAZY CONSTRUCTION
244
+ return lazy(props)(route)(param, result);
245
+ };
283
246
 
284
- const decomposible =
285
- (props: IProps) =>
286
- (route: IRoute) =>
287
- (param: IRoute.IParameter) =>
288
- (
289
- result: ValidationPipe<Metadata, MetadataFactory.IError>,
290
- ): ISwaggerRoute.IParameter[] => {
291
- const decoded: ISwaggerRoute.IParameter = lazy(props)(route)(
292
- param,
293
- result,
294
- );
295
- if (result.success === false) {
296
- props.errors.push(
297
- ...result.errors.map((e) => ({
298
- ...e,
299
- route,
300
- from: param.name,
301
- })),
302
- );
303
- return [decoded];
304
- } else if (
305
- props.config.decompose !== true ||
306
- result.data.objects.length === 0
307
- )
308
- return [decoded];
247
+ const headers =
248
+ (props: IProps) =>
249
+ (route: IRoute) =>
250
+ (param: IRoute.IParameter): ISwaggerRoute.IParameter[] =>
251
+ decomposible(props)(route)(param)(
252
+ MetadataFactory.analyze(props.checker)({
253
+ escape: false,
254
+ constant: true,
255
+ absorb: true,
256
+ validate: param.custom ? SwaggerSchemaValidator.headers : undefined,
257
+ })(props.collection)(param.type),
258
+ );
309
259
 
310
- return result.data.objects[0].properties
311
- .filter((p) =>
312
- p.jsDocTags.every((tag) => tag.name !== "hidden"),
313
- )
314
- .map((p) => {
315
- const schema: IJsonSchema = {};
316
- props.lazyProperties.push({
317
- schema,
318
- object: result.data.objects[0].name,
319
- property: p.key.constants[0].values[0] as string,
320
- });
321
- return {
322
- name: p.key.constants[0].values[0] as string,
323
- in:
324
- param.category === "headers"
325
- ? "header"
326
- : param.category,
327
- schema,
328
- description: p.description ?? undefined,
329
- required: p.value.isRequired(),
330
- };
331
- });
332
- };
260
+ const query =
261
+ (props: IProps) =>
262
+ (route: IRoute) =>
263
+ (param: IRoute.IParameter): ISwaggerRoute.IParameter[] =>
264
+ decomposible(props)(route)(param)(
265
+ MetadataFactory.analyze(props.checker)({
266
+ escape: false,
267
+ constant: true,
268
+ absorb: true,
269
+ validate: param.custom ? SwaggerSchemaValidator.query : undefined,
270
+ })(props.collection)(param.type),
271
+ );
333
272
 
334
- const lazy =
335
- (props: IProps) =>
336
- (route: IRoute) =>
337
- (
338
- param: IRoute.IParameter,
339
- result: ValidationPipe<Metadata, MetadataFactory.IError>,
340
- ): ISwaggerRoute.IParameter => {
341
- const schema: IJsonSchema = coalesce(props)(result);
342
- return {
343
- name: param.field ?? param.name,
344
- in:
345
- param.category === "headers"
346
- ? "header"
347
- : param.category === "param"
348
- ? "path"
349
- : param.category,
350
- schema,
351
- description: describe(route, "param", param.name) ?? "",
352
- required: result.success ? result.data.isRequired() : true,
353
- };
354
- };
273
+ const decomposible =
274
+ (props: IProps) =>
275
+ (route: IRoute) =>
276
+ (param: IRoute.IParameter) =>
277
+ (
278
+ result: ValidationPipe<Metadata, MetadataFactory.IError>,
279
+ ): ISwaggerRoute.IParameter[] => {
280
+ const decoded: ISwaggerRoute.IParameter = lazy(props)(route)(
281
+ param,
282
+ result,
283
+ );
284
+ if (result.success === false) {
285
+ props.errors.push(
286
+ ...result.errors.map((e) => ({
287
+ ...e,
288
+ route,
289
+ from: param.name,
290
+ })),
291
+ );
292
+ return [decoded];
293
+ } else if (
294
+ props.config.decompose !== true ||
295
+ result.data.objects.length === 0
296
+ )
297
+ return [decoded];
355
298
 
356
- const coalesce =
357
- (props: IProps) =>
358
- (
359
- result: ValidationPipe<Metadata, MetadataFactory.IError>,
360
- ): IJsonSchema => {
361
- const schema: IJsonSchema = {} as any;
362
- props.lazySchemas.push({
363
- metadata: result.success ? result.data : any.get(),
364
- schema,
365
- });
366
- return schema;
367
- };
299
+ return result.data.objects[0].properties
300
+ .filter((p) => p.jsDocTags.every((tag) => tag.name !== "hidden"))
301
+ .map((p) => {
302
+ const schema: IJsonSchema = {};
303
+ props.lazyProperties.push({
304
+ schema,
305
+ object: result.data.objects[0].name,
306
+ property: p.key.constants[0].values[0] as string,
307
+ });
308
+ return {
309
+ name: p.key.constants[0].values[0] as string,
310
+ in: param.category === "headers" ? "header" : param.category,
311
+ schema,
312
+ description: p.description ?? undefined,
313
+ required: p.value.isRequired(),
314
+ };
315
+ });
316
+ };
368
317
 
369
- const describe = (
370
- route: IRoute,
371
- tagName: string,
372
- parameterName?: string,
373
- ): string | undefined => {
374
- const parametric: (elem: ts.JSDocTagInfo) => boolean = parameterName
375
- ? (tag) =>
376
- tag.text!.find(
377
- (elem) =>
378
- elem.kind === "parameterName" &&
379
- elem.text === parameterName,
380
- ) !== undefined
381
- : () => true;
318
+ const lazy =
319
+ (props: IProps) =>
320
+ (route: IRoute) =>
321
+ (
322
+ param: IRoute.IParameter,
323
+ result: ValidationPipe<Metadata, MetadataFactory.IError>,
324
+ ): ISwaggerRoute.IParameter => {
325
+ const schema: IJsonSchema = coalesce(props)(result);
326
+ return {
327
+ name: param.field ?? param.name,
328
+ in:
329
+ param.category === "headers"
330
+ ? "header"
331
+ : param.category === "param"
332
+ ? "path"
333
+ : param.category,
334
+ schema,
335
+ description: describe(route, "param", param.name) ?? "",
336
+ required: result.success ? result.data.isRequired() : true,
337
+ };
338
+ };
382
339
 
383
- const tag: ts.JSDocTagInfo | undefined = route.jsDocTags.find(
384
- (tag) => tag.name === tagName && tag.text && parametric(tag),
385
- );
386
- return tag && tag.text
387
- ? tag.text.find((elem) => elem.kind === "text")?.text
388
- : undefined;
340
+ const coalesce =
341
+ (props: IProps) =>
342
+ (result: ValidationPipe<Metadata, MetadataFactory.IError>): IJsonSchema => {
343
+ const schema: IJsonSchema = {} as any;
344
+ props.lazySchemas.push({
345
+ metadata: result.success ? result.data : any.get(),
346
+ schema,
347
+ });
348
+ return schema;
389
349
  };
350
+
351
+ const describe = (
352
+ route: IRoute,
353
+ tagName: string,
354
+ parameterName?: string,
355
+ ): string | undefined => {
356
+ const parametric: (elem: ts.JSDocTagInfo) => boolean = parameterName
357
+ ? (tag) =>
358
+ tag.text!.find(
359
+ (elem) =>
360
+ elem.kind === "parameterName" && elem.text === parameterName,
361
+ ) !== undefined
362
+ : () => true;
363
+
364
+ const tag: ts.JSDocTagInfo | undefined = route.jsDocTags.find(
365
+ (tag) => tag.name === tagName && tag.text && parametric(tag),
366
+ );
367
+ return tag && tag.text
368
+ ? tag.text.find((elem) => elem.kind === "text")?.text
369
+ : undefined;
370
+ };
390
371
  }
391
372
 
392
- const warning = new Singleton((described: boolean) => {
393
- return new Singleton((type: "request" | "response", method?: string) => {
394
- const summary =
395
- type === "request"
396
- ? "Request body must be encrypted."
397
- : "Response data have been encrypted.";
398
- const component =
399
- type === "request"
400
- ? "[EncryptedBody](https://github.com/samchon/@nestia/core#encryptedbody)"
401
- : `[EncryptedRoute.${method![0].toUpperCase()}.${method!
402
- .substring(1)
403
- .toLowerCase()}](https://github.com/samchon/@nestia/core#encryptedroute)`;
373
+ const warning = new VariadicSingleton(
374
+ (described: boolean, type: "request" | "response", method?: string) => {
375
+ const summary =
376
+ type === "request"
377
+ ? "Request body must be encrypted."
378
+ : "Response data have been encrypted.";
379
+ const component =
380
+ type === "request"
381
+ ? "[EncryptedBody](https://github.com/samchon/@nestia/core#encryptedbody)"
382
+ : `[EncryptedRoute.${method![0].toUpperCase()}.${method!
383
+ .substring(1)
384
+ .toLowerCase()}](https://github.com/samchon/@nestia/core#encryptedroute)`;
404
385
 
405
- const content: string[] = [
406
- "## Warning",
407
- "",
408
- summary,
409
- "",
410
- `The ${type} body data would be encrypted as "AES-128(256) / CBC mode / PKCS#5 Padding / Base64 Encoding", through the ${component} component.`,
411
- "",
412
- `Therefore, just utilize this swagger editor only for referencing. If you need to call the real API, using [SDK](https://github.com/samchon/nestia#software-development-kit) would be much better.`,
413
- ];
414
- if (described === true) content.push("----------------", "");
415
- return content.join("\n");
416
- });
417
- });
386
+ const content: string[] = [
387
+ "## Warning",
388
+ "",
389
+ summary,
390
+ "",
391
+ `The ${type} body data would be encrypted as "AES-128(256) / CBC mode / PKCS#5 Padding / Base64 Encoding", through the ${component} component.`,
392
+ "",
393
+ `Therefore, just utilize this swagger editor only for referencing. If you need to call the real API, using [SDK](https://github.com/samchon/nestia#software-development-kit) would be much better.`,
394
+ ];
395
+ if (described === true) content.push("", "----------------", "", "");
396
+ return content.join("\n");
397
+ },
398
+ );
418
399
 
419
400
  const any = new Singleton(() =>
420
- Metadata.from(
421
- {
422
- any: true,
423
- required: true,
424
- optional: false,
425
- nullable: false,
426
- functional: false,
427
- atomics: [],
428
- constants: [],
429
- templates: [],
430
- escaped: null,
431
- rest: null,
432
- arrays: [],
433
- tuples: [],
434
- objects: [],
435
- aliases: [],
436
- natives: [],
437
- sets: [],
438
- maps: [],
439
- },
440
- {
441
- aliases: new Map(),
442
- arrays: new Map(),
443
- tuples: new Map(),
444
- objects: new Map(),
445
- },
446
- ),
401
+ Metadata.from(
402
+ {
403
+ any: true,
404
+ required: true,
405
+ optional: false,
406
+ nullable: false,
407
+ functional: false,
408
+ atomics: [],
409
+ constants: [],
410
+ templates: [],
411
+ escaped: null,
412
+ rest: null,
413
+ arrays: [],
414
+ tuples: [],
415
+ objects: [],
416
+ aliases: [],
417
+ natives: [],
418
+ sets: [],
419
+ maps: [],
420
+ },
421
+ {
422
+ aliases: new Map(),
423
+ arrays: new Map(),
424
+ tuples: new Map(),
425
+ objects: new Map(),
426
+ },
427
+ ),
447
428
  );