@nestia/sdk 2.0.0-dev.20230831-4 → 2.0.0-dev.20230901

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 (56) hide show
  1. package/assets/bundle/api/utils/NestiaSimulator.ts +1 -23
  2. package/lib/NestiaSdkApplication.js +1 -1
  3. package/lib/NestiaSdkApplication.js.map +1 -1
  4. package/lib/analyses/ControllerAnalyzer.js +11 -5
  5. package/lib/analyses/ControllerAnalyzer.js.map +1 -1
  6. package/lib/analyses/ExceptionAnalyzer.js +7 -2
  7. package/lib/analyses/ExceptionAnalyzer.js.map +1 -1
  8. package/lib/analyses/ImportAnalyzer.js +1 -1
  9. package/lib/analyses/ImportAnalyzer.js.map +1 -1
  10. package/lib/analyses/ReflectAnalyzer.js +0 -10
  11. package/lib/analyses/ReflectAnalyzer.js.map +1 -1
  12. package/lib/executable/internal/NestiaSdkConfig.js +37 -46
  13. package/lib/executable/internal/NestiaSdkConfig.js.map +1 -1
  14. package/lib/generates/SwaggerGenerator.d.ts +10 -0
  15. package/lib/generates/SwaggerGenerator.js +29 -497
  16. package/lib/generates/SwaggerGenerator.js.map +1 -1
  17. package/lib/generates/internal/E2eFileProgrammer.js +5 -44
  18. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  19. package/lib/generates/internal/SdkFunctionProgrammer.js +12 -10
  20. package/lib/generates/internal/SdkFunctionProgrammer.js.map +1 -1
  21. package/lib/generates/internal/SdkSimulationProgrammer.js +4 -4
  22. package/lib/generates/internal/SdkSimulationProgrammer.js.map +1 -1
  23. package/lib/generates/internal/SwaggerSchemaGenerator.d.ts +19 -0
  24. package/lib/generates/internal/SwaggerSchemaGenerator.js +301 -0
  25. package/lib/generates/internal/SwaggerSchemaGenerator.js.map +1 -0
  26. package/lib/generates/internal/SwaggerSchemaValidator.d.ts +7 -0
  27. package/lib/generates/internal/SwaggerSchemaValidator.js +200 -0
  28. package/lib/generates/internal/SwaggerSchemaValidator.js.map +1 -0
  29. package/lib/structures/IController.d.ts +0 -4
  30. package/lib/structures/IRoute.d.ts +6 -3
  31. package/lib/structures/ISwaggerError.d.ts +6 -0
  32. package/lib/structures/ISwaggerError.js +3 -0
  33. package/lib/structures/ISwaggerError.js.map +1 -0
  34. package/lib/structures/ISwaggerRoute.d.ts +2 -1
  35. package/lib/structures/ISwaggerSchemaTuple.d.ts +6 -0
  36. package/lib/structures/ISwaggerSchemaTuple.js +3 -0
  37. package/lib/structures/ISwaggerSchemaTuple.js.map +1 -0
  38. package/lib/structures/ITypeTuple.d.ts +1 -1
  39. package/package.json +5 -5
  40. package/src/NestiaSdkApplication.ts +1 -1
  41. package/src/analyses/ControllerAnalyzer.ts +13 -4
  42. package/src/analyses/ExceptionAnalyzer.ts +3 -2
  43. package/src/analyses/ImportAnalyzer.ts +1 -1
  44. package/src/analyses/ReflectAnalyzer.ts +0 -10
  45. package/src/generates/SwaggerGenerator.ts +86 -478
  46. package/src/generates/internal/E2eFileProgrammer.ts +7 -49
  47. package/src/generates/internal/SdkFunctionProgrammer.ts +13 -11
  48. package/src/generates/internal/SdkSimulationProgrammer.ts +5 -5
  49. package/src/generates/internal/SwaggerSchemaGenerator.ts +433 -0
  50. package/src/generates/internal/SwaggerSchemaValidator.ts +222 -0
  51. package/src/structures/IController.ts +0 -4
  52. package/src/structures/IRoute.ts +6 -3
  53. package/src/structures/ISwaggerError.ts +8 -0
  54. package/src/structures/ISwaggerRoute.ts +2 -1
  55. package/src/structures/ISwaggerSchemaTuple.ts +7 -0
  56. package/src/structures/ITypeTuple.ts +1 -1
@@ -0,0 +1,222 @@
1
+ import { MetadataFactory } from "typia/lib/factories/MetadataFactory";
2
+ import { Metadata } from "typia/lib/schemas/metadata/Metadata";
3
+ import { MetadataArray } from "typia/lib/schemas/metadata/MetadataArray";
4
+
5
+ export namespace SwaggerSchemaValidator {
6
+ export const path = (meta: Metadata): string[] => {
7
+ const errors: string[] = [];
8
+ const insert = (msg: string) => errors.push(msg);
9
+
10
+ if (meta.any) insert("do not allow any type");
11
+ if (meta.isRequired() === false)
12
+ insert("do not allow undefindable type");
13
+
14
+ const atomics = CoreMetadataUtil.atomics(meta);
15
+ const expected: number =
16
+ meta.atomics.length +
17
+ meta.templates.length +
18
+ meta.constants
19
+ .map((c) => c.values.length)
20
+ .reduce((a, b) => a + b, 0);
21
+ if (meta.size() !== expected || atomics.size === 0)
22
+ insert("only atomic or constant types are allowed");
23
+ if (atomics.size > 1) insert("do not allow union type");
24
+
25
+ return errors;
26
+ };
27
+
28
+ export const query = (
29
+ meta: Metadata,
30
+ explore: MetadataFactory.IExplore,
31
+ ): string[] => {
32
+ const errors: string[] = [];
33
+ const insert = (msg: string) => errors.push(msg);
34
+
35
+ if (explore.top === true) {
36
+ // TOP MUST BE ONLY OBJECT
37
+ if (meta.objects.length !== 1 || meta.bucket() !== 1)
38
+ insert("only one object type is allowed.");
39
+ if (meta.nullable === true)
40
+ insert("query parameters cannot be null.");
41
+ if (meta.isRequired() === false)
42
+ insert("query parameters cannot be undefined.");
43
+ } else if (
44
+ explore.nested !== null &&
45
+ explore.nested instanceof MetadataArray
46
+ ) {
47
+ const atomics = CoreMetadataUtil.atomics(meta);
48
+ const expected: number =
49
+ meta.atomics.length +
50
+ meta.templates.length +
51
+ meta.constants
52
+ .map((c) => c.values.length)
53
+ .reduce((a, b) => a + b, 0);
54
+ if (atomics.size > 1) insert("union type is not allowed in array.");
55
+ if (meta.nullable) insert("nullable type is not allowed in array.");
56
+ if (meta.isRequired() === false)
57
+ insert("optional type is not allowed in array.");
58
+ if (meta.size() !== expected)
59
+ insert("only atomic or constant types are allowed in array.");
60
+ } else if (explore.object && explore.property !== null) {
61
+ //----
62
+ // COMMON
63
+ //----
64
+ // PROPERTY MUST BE SOLE
65
+ if (typeof explore.property === "object")
66
+ insert("dynamic property is not allowed.");
67
+ // MUST BE LOWER-CASE
68
+ if (
69
+ typeof explore.property === "string" &&
70
+ explore.property !== explore.property.toLowerCase()
71
+ )
72
+ insert("property name must be lower-case.");
73
+ // DO NOT ALLOW TUPLE TYPE
74
+ if (meta.tuples.length) insert("tuple type is not allowed.");
75
+ // DO NOT ALLOW UNION TYPE
76
+ if (CoreMetadataUtil.isUnion(meta))
77
+ insert("union type is not allowed.");
78
+ // DO NOT ALLOW NESTED OBJECT
79
+ if (
80
+ meta.objects.length ||
81
+ meta.sets.length ||
82
+ meta.maps.length ||
83
+ meta.natives.length
84
+ )
85
+ insert("nested object type is not allowed.");
86
+
87
+ //----
88
+ // ARRAY CASES
89
+ //----
90
+ const isArray: boolean =
91
+ meta.arrays.length > 1 || meta.tuples.length > 1;
92
+ // ARRAY TYPE MUST BE REQUIRED
93
+ if (isArray && meta.isRequired() === false)
94
+ insert("optional type is not allowed when array.");
95
+ // SET-COOKIE MUST BE ARRAY
96
+ if (explore.property === "set-cookie" && !isArray)
97
+ insert("set-cookie property must be array.");
98
+ }
99
+ return errors;
100
+ };
101
+
102
+ export const headers = (
103
+ meta: Metadata,
104
+ explore: MetadataFactory.IExplore,
105
+ ): string[] => {
106
+ const errors: string[] = [];
107
+ const insert = (msg: string) => errors.push(msg);
108
+
109
+ if (explore.top === true) {
110
+ // TOP MUST BE ONLY OBJECT
111
+ if (meta.objects.length !== 1 || meta.bucket() !== 1)
112
+ insert("only one object type is allowed.");
113
+ if (meta.nullable === true) insert("headers cannot be null.");
114
+ if (meta.isRequired() === false) insert("headers cannot be null.");
115
+ } else if (
116
+ explore.nested !== null &&
117
+ explore.nested instanceof MetadataArray
118
+ ) {
119
+ const atomics = CoreMetadataUtil.atomics(meta);
120
+ const expected: number =
121
+ meta.atomics.length +
122
+ meta.templates.length +
123
+ meta.constants
124
+ .map((c) => c.values.length)
125
+ .reduce((a, b) => a + b, 0);
126
+ if (atomics.size > 1) insert("union type is not allowed in array.");
127
+ if (meta.nullable) insert("nullable type is not allowed in array.");
128
+ if (meta.isRequired() === false)
129
+ insert("optional type is not allowed.");
130
+ if (meta.size() !== expected)
131
+ insert("only atomic or constant types are allowed in array.");
132
+ } else if (explore.object && explore.property !== null) {
133
+ //----
134
+ // COMMON
135
+ //----
136
+ // PROPERTY MUST BE SOLE
137
+ if (typeof explore.property === "object")
138
+ insert("dynamic property is not allowed.");
139
+ // MUST BE LOWER-CASE
140
+ if (
141
+ typeof explore.property === "string" &&
142
+ explore.property !== explore.property.toLowerCase()
143
+ )
144
+ insert("property name must be lower-case.");
145
+ // DO NOT ALLOW TUPLE TYPE
146
+ if (meta.tuples.length) insert("tuple type is not allowed.");
147
+ // DO NOT ALLOW UNION TYPE
148
+ if (CoreMetadataUtil.isUnion(meta))
149
+ insert("union type is not allowed.");
150
+ // DO NOT ALLOW NESTED OBJECT
151
+ if (
152
+ meta.objects.length ||
153
+ meta.sets.length ||
154
+ meta.maps.length ||
155
+ meta.natives.length
156
+ )
157
+ insert("nested object type is not allowed.");
158
+ // DO NOT ALLOW NULLABLE
159
+ if (meta.nullable) insert("nullable type is not allowed.");
160
+
161
+ //----
162
+ // ARRAY CASES
163
+ //----
164
+ const isArray: boolean = meta.arrays.length > 1;
165
+ // ARRAY TYPE MUST BE REQUIRED
166
+ if (isArray && meta.isRequired() === false)
167
+ insert("optional type is not allowed when array.");
168
+ // SET-COOKIE MUST BE ARRAY
169
+ if (explore.property === "set-cookie" && !isArray)
170
+ insert("set-cookie property must be array.");
171
+ // MUST BE SINGULAR CASE
172
+ if (
173
+ typeof explore.property === "string" &&
174
+ SINGULAR.has(explore.property) &&
175
+ isArray
176
+ )
177
+ insert("property cannot be array.");
178
+ }
179
+ return errors;
180
+ };
181
+ }
182
+
183
+ namespace CoreMetadataUtil {
184
+ export const atomics = (
185
+ meta: Metadata,
186
+ ): Set<"boolean" | "bigint" | "number" | "string"> =>
187
+ new Set([
188
+ ...meta.atomics.map((a) => a.type),
189
+ ...meta.constants.map((c) => c.type),
190
+ ...(meta.templates.length ? (["string"] as const) : []),
191
+ ]);
192
+
193
+ export const isUnion = (meta: Metadata): boolean =>
194
+ atomics(meta).size +
195
+ meta.arrays.length +
196
+ meta.tuples.length +
197
+ meta.natives.length +
198
+ meta.maps.length +
199
+ meta.objects.length >
200
+ 1;
201
+ }
202
+
203
+ const SINGULAR: Set<string> = new Set([
204
+ "age",
205
+ "authorization",
206
+ "content-length",
207
+ "content-type",
208
+ "etag",
209
+ "expires",
210
+ "from",
211
+ "host",
212
+ "if-modified-since",
213
+ "if-unmodified-since",
214
+ "last-modified",
215
+ "location",
216
+ "max-forwards",
217
+ "proxy-authorization",
218
+ "referer",
219
+ "retry-after",
220
+ "server",
221
+ "user-agent",
222
+ ]);
@@ -67,10 +67,6 @@ export namespace IController {
67
67
  index: number;
68
68
  name: string;
69
69
  field: string | undefined;
70
- meta?: {
71
- type: string;
72
- nullable: boolean;
73
- };
74
70
  }
75
71
 
76
72
  export interface IException {
@@ -1,7 +1,6 @@
1
1
  import ts from "typescript";
2
2
 
3
3
  import { IController } from "./IController";
4
- import { ITypeTuple } from "./ITypeTuple";
5
4
 
6
5
  export interface IRoute {
7
6
  name: string;
@@ -18,6 +17,7 @@ export interface IRoute {
18
17
  location: string;
19
18
  symbol: string;
20
19
  description?: string;
20
+ operationId?: string;
21
21
  tags: ts.JSDocTagInfo[];
22
22
  setHeaders: Array<
23
23
  | { type: "setter"; source: string; target?: string }
@@ -30,9 +30,12 @@ export interface IRoute {
30
30
  export namespace IRoute {
31
31
  export type IParameter = IController.IParameter & {
32
32
  optional: boolean;
33
- type: ITypeTuple;
33
+ type: ts.Type;
34
+ typeName: string;
34
35
  };
35
- export interface IOutput extends ITypeTuple {
36
+ export interface IOutput {
37
+ type: ts.Type;
38
+ typeName: string;
36
39
  description?: string;
37
40
  contentType: "application/json" | "text/plain";
38
41
  }
@@ -0,0 +1,8 @@
1
+ import { MetadataFactory } from "typia/lib/factories/MetadataFactory";
2
+
3
+ import { IRoute } from "./IRoute";
4
+
5
+ export interface ISwaggerError extends MetadataFactory.IError {
6
+ route: IRoute;
7
+ from: string;
8
+ }
@@ -1,9 +1,10 @@
1
1
  import { IJsonSchema } from "typia";
2
- import { IJsDocTagInfo } from "typia/lib/metadata/IJsDocTagInfo";
2
+ import { IJsDocTagInfo } from "typia/lib/schemas/metadata/IJsDocTagInfo";
3
3
 
4
4
  export interface ISwaggerRoute {
5
5
  deprecated?: boolean;
6
6
  security?: Record<string, string[]>[];
7
+ operationId?: string;
7
8
  tags: string[];
8
9
  parameters: ISwaggerRoute.IParameter[];
9
10
  requestBody?: ISwaggerRoute.IRequestBody;
@@ -0,0 +1,7 @@
1
+ import { IJsonSchema } from "typia";
2
+ import { Metadata } from "typia/lib/schemas/metadata/Metadata";
3
+
4
+ export interface ISwaggerSchemaTuple {
5
+ metadata: Metadata;
6
+ schema: IJsonSchema;
7
+ }
@@ -2,5 +2,5 @@ import ts from "typescript";
2
2
 
3
3
  export interface ITypeTuple {
4
4
  type: ts.Type;
5
- name: string;
5
+ typeName: string;
6
6
  }