@nestia/sdk 12.0.0-dev.20260601.1 → 12.0.0-dev.20260612.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +93 -93
  3. package/assets/bundle/api/HttpError.ts +1 -1
  4. package/assets/bundle/api/IConnection.ts +1 -1
  5. package/assets/bundle/api/Primitive.ts +1 -1
  6. package/assets/bundle/api/Resolved.ts +1 -1
  7. package/assets/bundle/api/index.ts +4 -4
  8. package/assets/bundle/api/module.ts +6 -6
  9. package/assets/bundle/distribute/README.md +37 -37
  10. package/assets/bundle/distribute/package.json +28 -28
  11. package/assets/bundle/distribute/tsconfig.json +109 -109
  12. package/assets/bundle/e2e/index.ts +42 -42
  13. package/assets/config/nestia.config.ts +97 -97
  14. package/lib/NestiaSdkApplication.js +29 -7
  15. package/lib/NestiaSdkApplication.js.map +1 -1
  16. package/lib/NestiaSwaggerComposer.js +21 -13
  17. package/lib/NestiaSwaggerComposer.js.map +1 -1
  18. package/lib/analyses/AccessorAnalyzer.d.ts +4 -1
  19. package/lib/analyses/AccessorAnalyzer.js.map +1 -1
  20. package/lib/analyses/ConfigAnalyzer.js +1 -1
  21. package/lib/analyses/PathAnalyzer.d.ts +18 -3
  22. package/lib/analyses/PathAnalyzer.js +32 -0
  23. package/lib/analyses/PathAnalyzer.js.map +1 -1
  24. package/lib/analyses/ReflectControllerAnalyzer.js +3 -2
  25. package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
  26. package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +1 -1
  27. package/lib/analyses/ReflectHttpOperationAnalyzer.js +1 -1
  28. package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
  29. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.d.ts +1 -1
  30. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +53 -20
  31. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -1
  32. package/lib/analyses/ReflectMcpOperationAnalyzer.d.ts +14 -0
  33. package/lib/analyses/ReflectMcpOperationAnalyzer.js +79 -0
  34. package/lib/analyses/ReflectMcpOperationAnalyzer.js.map +1 -0
  35. package/lib/analyses/TypedMcpRouteAnalyzer.d.ts +9 -0
  36. package/lib/analyses/TypedMcpRouteAnalyzer.js +31 -0
  37. package/lib/analyses/TypedMcpRouteAnalyzer.js.map +1 -0
  38. package/lib/executable/internal/NestiaConfigLoader.js +5 -1
  39. package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
  40. package/lib/executable/internal/NestiaSdkCommand.js +30 -14
  41. package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
  42. package/lib/executable/internal/NestiaSdkWatcher.d.ts +10 -0
  43. package/lib/executable/internal/NestiaSdkWatcher.js +322 -0
  44. package/lib/executable/internal/NestiaSdkWatcher.js.map +1 -0
  45. package/lib/executable/sdk.js +12 -12
  46. package/lib/executable/sdk.js.map +1 -1
  47. package/lib/generates/CloneGenerator.js +4 -2
  48. package/lib/generates/CloneGenerator.js.map +1 -1
  49. package/lib/generates/SdkGenerator.js +50 -1
  50. package/lib/generates/SdkGenerator.js.map +1 -1
  51. package/lib/generates/SwaggerGenerator.js +18 -2
  52. package/lib/generates/SwaggerGenerator.js.map +1 -1
  53. package/lib/generates/internal/E2eFileProgrammer.js +3 -1
  54. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  55. package/lib/generates/internal/ImportDictionary.d.ts +1 -0
  56. package/lib/generates/internal/ImportDictionary.js +9 -4
  57. package/lib/generates/internal/ImportDictionary.js.map +1 -1
  58. package/lib/generates/internal/SdkAliasCollection.d.ts +2 -0
  59. package/lib/generates/internal/SdkAliasCollection.js +11 -2
  60. package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
  61. package/lib/generates/internal/SdkDistributionComposer.d.ts +1 -0
  62. package/lib/generates/internal/SdkDistributionComposer.js +3 -0
  63. package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
  64. package/lib/generates/internal/SdkFileProgrammer.js +4 -1
  65. package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
  66. package/lib/generates/internal/SdkHttpCloneReferencer.d.ts +1 -1
  67. package/lib/generates/internal/SdkHttpCloneReferencer.js +42 -9
  68. package/lib/generates/internal/SdkHttpCloneReferencer.js.map +1 -1
  69. package/lib/generates/internal/SdkHttpFunctionProgrammer.js +3 -4
  70. package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
  71. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +2 -1
  72. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
  73. package/lib/generates/internal/SdkHttpSimulationProgrammer.js +6 -3
  74. package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
  75. package/lib/generates/internal/SdkMcpRouteProgrammer.d.ts +15 -0
  76. package/lib/generates/internal/SdkMcpRouteProgrammer.js +148 -0
  77. package/lib/generates/internal/SdkMcpRouteProgrammer.js.map +1 -0
  78. package/lib/generates/internal/SdkRouteDirectory.d.ts +2 -1
  79. package/lib/generates/internal/SdkRouteDirectory.js.map +1 -1
  80. package/lib/generates/internal/SdkWebSocketCloneProgrammer.d.ts +6 -0
  81. package/lib/generates/internal/SdkWebSocketCloneProgrammer.js +283 -0
  82. package/lib/generates/internal/SdkWebSocketCloneProgrammer.js.map +1 -0
  83. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +11 -9
  84. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
  85. package/lib/generates/internal/SwaggerOperationParameterComposer.js +10 -2
  86. package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -1
  87. package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +1 -1
  88. package/lib/generates/internal/SwaggerOperationResponseComposer.js +6 -1
  89. package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -1
  90. package/lib/generates/internal/SwaggerReadonlyArrayEmender.d.ts +9 -0
  91. package/lib/generates/internal/SwaggerReadonlyArrayEmender.js +174 -0
  92. package/lib/generates/internal/SwaggerReadonlyArrayEmender.js.map +1 -0
  93. package/lib/structures/INestiaSdkInput.d.ts +9 -2
  94. package/lib/structures/IReflectController.d.ts +2 -1
  95. package/lib/structures/IReflectHttpOperationSuccess.d.ts +4 -2
  96. package/lib/structures/IReflectMcpOperation.d.ts +35 -0
  97. package/lib/structures/IReflectMcpOperation.js +3 -0
  98. package/lib/structures/IReflectMcpOperation.js.map +1 -0
  99. package/lib/structures/IReflectMcpOperationParameter.d.ts +19 -0
  100. package/lib/structures/IReflectMcpOperationParameter.js +3 -0
  101. package/lib/structures/IReflectMcpOperationParameter.js.map +1 -0
  102. package/lib/structures/ITypedApplication.d.ts +2 -1
  103. package/lib/structures/ITypedHttpRouteSuccess.d.ts +3 -1
  104. package/lib/structures/ITypedMcpRoute.d.ts +31 -0
  105. package/lib/structures/ITypedMcpRoute.js +3 -0
  106. package/lib/structures/ITypedMcpRoute.js.map +1 -0
  107. package/lib/utils/HttpResponseContentTypeUtil.d.ts +5 -0
  108. package/lib/utils/HttpResponseContentTypeUtil.js +22 -0
  109. package/lib/utils/HttpResponseContentTypeUtil.js.map +1 -0
  110. package/native/go.mod +52 -52
  111. package/native/go.sum +84 -54
  112. package/native/sdk/register.go +322 -165
  113. package/native/sdk/sdk.go +17 -17
  114. package/native/sdk/sdk_metadata_json.go +327 -327
  115. package/native/sdk/sdk_transform.go +1879 -1549
  116. package/package.json +11 -9
  117. package/src/INestiaConfig.ts +267 -267
  118. package/src/NestiaSdkApplication.ts +39 -8
  119. package/src/NestiaSwaggerComposer.ts +153 -142
  120. package/src/analyses/AccessorAnalyzer.ts +64 -67
  121. package/src/analyses/ConfigAnalyzer.ts +330 -330
  122. package/src/analyses/ImportAnalyzer.ts +92 -92
  123. package/src/analyses/PathAnalyzer.ts +130 -69
  124. package/src/analyses/ReflectControllerAnalyzer.ts +112 -105
  125. package/src/analyses/ReflectHttpOperationAnalyzer.ts +183 -183
  126. package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +90 -90
  127. package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +350 -350
  128. package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +163 -130
  129. package/src/analyses/ReflectMcpOperationAnalyzer.ts +124 -0
  130. package/src/analyses/ReflectMetadataAnalyzer.ts +44 -44
  131. package/src/analyses/SecurityAnalyzer.ts +25 -25
  132. package/src/analyses/TypedMcpRouteAnalyzer.ts +34 -0
  133. package/src/decorators/OperationMetadata.ts +29 -29
  134. package/src/executable/internal/CommandParser.ts +15 -15
  135. package/src/executable/internal/NestiaConfigLoader.ts +451 -446
  136. package/src/executable/internal/NestiaSdkCommand.ts +124 -106
  137. package/src/executable/internal/NestiaSdkWatcher.ts +342 -0
  138. package/src/executable/sdk.ts +90 -88
  139. package/src/generates/CloneGenerator.ts +73 -66
  140. package/src/generates/E2eGenerator.ts +32 -32
  141. package/src/generates/SdkGenerator.ts +176 -118
  142. package/src/generates/SwaggerGenerator.ts +342 -310
  143. package/src/generates/internal/E2eFileProgrammer.ts +240 -233
  144. package/src/generates/internal/FilePrinter.ts +65 -65
  145. package/src/generates/internal/ImportDictionary.ts +209 -204
  146. package/src/generates/internal/SdkAliasCollection.ts +274 -261
  147. package/src/generates/internal/SdkDistributionComposer.ts +123 -116
  148. package/src/generates/internal/SdkFileProgrammer.ts +116 -112
  149. package/src/generates/internal/SdkHttpCloneProgrammer.ts +126 -126
  150. package/src/generates/internal/SdkHttpCloneReferencer.ts +131 -77
  151. package/src/generates/internal/SdkHttpFunctionProgrammer.ts +301 -301
  152. package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +520 -510
  153. package/src/generates/internal/SdkHttpParameterProgrammer.ts +165 -165
  154. package/src/generates/internal/SdkHttpRouteProgrammer.ts +109 -109
  155. package/src/generates/internal/SdkHttpSimulationProgrammer.ts +331 -314
  156. package/src/generates/internal/SdkImportWizard.ts +62 -62
  157. package/src/generates/internal/SdkMcpRouteProgrammer.ts +452 -0
  158. package/src/generates/internal/SdkRouteDirectory.ts +21 -18
  159. package/src/generates/internal/SdkTypeTagProgrammer.ts +114 -114
  160. package/src/generates/internal/SdkWebSocketCloneProgrammer.ts +319 -0
  161. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +389 -389
  162. package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +89 -89
  163. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +331 -323
  164. package/src/generates/internal/SwaggerDescriptionComposer.ts +64 -64
  165. package/src/generates/internal/SwaggerOperationComposer.ts +119 -119
  166. package/src/generates/internal/SwaggerOperationParameterComposer.ts +175 -162
  167. package/src/generates/internal/SwaggerOperationResponseComposer.ts +115 -110
  168. package/src/generates/internal/SwaggerReadonlyArrayEmender.ts +262 -0
  169. package/src/index.ts +4 -4
  170. package/src/internal/legacy.ts +492 -492
  171. package/src/module.ts +4 -4
  172. package/src/structures/INestiaProject.ts +10 -10
  173. package/src/structures/INestiaSdkInput.ts +27 -20
  174. package/src/structures/IOperationMetadata.ts +41 -41
  175. package/src/structures/IReflectController.ts +18 -15
  176. package/src/structures/IReflectHttpOperation.ts +26 -26
  177. package/src/structures/IReflectHttpOperationException.ts +18 -18
  178. package/src/structures/IReflectHttpOperationParameter.ts +79 -79
  179. package/src/structures/IReflectHttpOperationSuccess.ts +18 -21
  180. package/src/structures/IReflectImport.ts +6 -6
  181. package/src/structures/IReflectMcpOperation.ts +38 -0
  182. package/src/structures/IReflectMcpOperationParameter.ts +27 -0
  183. package/src/structures/IReflectOperationError.ts +26 -26
  184. package/src/structures/IReflectType.ts +4 -4
  185. package/src/structures/IReflectWebSocketOperation.ts +17 -17
  186. package/src/structures/ITypedApplication.ts +12 -11
  187. package/src/structures/ITypedHttpRoute.ts +41 -41
  188. package/src/structures/ITypedHttpRouteException.ts +15 -15
  189. package/src/structures/ITypedHttpRouteParameter.ts +41 -41
  190. package/src/structures/ITypedHttpRouteSuccess.ts +18 -22
  191. package/src/structures/ITypedMcpRoute.ts +33 -0
  192. package/src/structures/ITypedWebSocketRoute.ts +24 -24
  193. package/src/structures/ITypedWebSocketRouteParameter.ts +3 -3
  194. package/src/transform.ts +59 -59
  195. package/src/typings/get-function-location.d.ts +7 -7
  196. package/src/utils/ArrayUtil.ts +26 -26
  197. package/src/utils/EmittedJavaScriptPatcher.ts +88 -88
  198. package/src/utils/FileRetriever.ts +22 -22
  199. package/src/utils/HttpResponseContentTypeUtil.ts +30 -0
  200. package/src/utils/MapUtil.ts +14 -14
  201. package/src/utils/PathUtil.ts +10 -10
  202. package/src/utils/SourceFinder.ts +63 -63
  203. package/src/utils/StringUtil.ts +17 -17
  204. package/src/utils/TsConfigReader.ts +108 -108
  205. package/src/utils/TtscExecutor.ts +68 -68
  206. package/src/utils/VersioningStrategy.ts +28 -28
  207. package/src/validators/HttpHeadersValidator.ts +11 -11
  208. package/src/validators/HttpQueryValidator.ts +11 -11
  209. package/src/validators/TextPlainValidator.ts +17 -17
@@ -1,162 +1,175 @@
1
- import { JsonSchemasProgrammer, MetadataObjectType } from "../../internal/legacy";
2
- import { OpenApi } from "@typia/interface";
3
- import { VariadicSingleton } from "tstl";
4
- import { IJsDocTagInfo, IJsonSchemaCollection } from "typia";
5
-
6
- import { INestiaConfig } from "../../INestiaConfig";
7
- import { ITypedHttpRouteParameter } from "../../structures/ITypedHttpRouteParameter";
8
- import { SwaggerDescriptionComposer } from "./SwaggerDescriptionComposer";
9
-
10
- export namespace SwaggerOperationParameterComposer {
11
- export interface IProps<Parameter extends ITypedHttpRouteParameter> {
12
- config: Omit<INestiaConfig.ISwaggerConfig, "output">;
13
- document: OpenApi.IDocument;
14
- schema: OpenApi.IJsonSchema;
15
- jsDocTags: IJsDocTagInfo[];
16
- parameter: Parameter;
17
- }
18
-
19
- export const compose = (
20
- props: IProps<ITypedHttpRouteParameter>,
21
- ): OpenApi.IOperation.IParameter[] =>
22
- props.parameter.category === "body"
23
- ? []
24
- : props.parameter.category === "param"
25
- ? [path({ ...props, parameter: props.parameter })]
26
- : props.parameter.category === "query"
27
- ? query({ ...props, parameter: props.parameter })
28
- : header({ ...props, parameter: props.parameter });
29
-
30
- export const body = (
31
- props: Omit<IProps<ITypedHttpRouteParameter.IBody>, "config" | "document">,
32
- ): OpenApi.IOperation.IRequestBody => {
33
- const description: string | undefined =
34
- props.parameter.description ??
35
- SwaggerDescriptionComposer.descriptionFromJsDocTag({
36
- jsDocTags: props.jsDocTags,
37
- tag: "param",
38
- parameter: props.parameter.name,
39
- });
40
- return {
41
- description: props.parameter.encrypted
42
- ? `${warning.get(!!description)}${description ?? ""}`
43
- : description,
44
- content: {
45
- [props.parameter.contentType]: {
46
- schema: props.schema,
47
- example: props.parameter.example,
48
- examples: props.parameter.examples,
49
- },
50
- },
51
- required: props.parameter.metadata.required,
52
- ...(props.parameter.encrypted ? { "x-nestia-encrypted": true } : {}),
53
- };
54
- };
55
-
56
- const path = (
57
- props: Omit<IProps<ITypedHttpRouteParameter.IPath>, "config" | "document">,
58
- ): OpenApi.IOperation.IParameter => ({
59
- name: props.parameter.field,
60
- in: "path",
61
- schema: props.schema,
62
- required: props.parameter.metadata.required,
63
- description: parameterDescription(props),
64
- example: props.parameter.example,
65
- examples: props.parameter.examples,
66
- });
67
-
68
- const query = (
69
- props: IProps<ITypedHttpRouteParameter.IQuery>,
70
- ): OpenApi.IOperation.IParameter[] => decomposible(props);
71
-
72
- const header = (
73
- props: IProps<ITypedHttpRouteParameter.IHeaders>,
74
- ): OpenApi.IOperation.IParameter[] => decomposible(props);
75
-
76
- const parameterDescription = (
77
- props: Pick<IProps<ITypedHttpRouteParameter>, "parameter" | "jsDocTags">,
78
- ): string | undefined => {
79
- return (
80
- props.parameter.description ??
81
- props.parameter.jsDocTags.find((tag) => tag.name === "description")
82
- ?.text?.[0]?.text ??
83
- props.jsDocTags
84
- .find(
85
- (tag) =>
86
- tag.name === "param" &&
87
- tag.text?.[0]?.text === props.parameter.name,
88
- )
89
- ?.text?.map((e) => e.text)
90
- .join("")
91
- .substring(props.parameter.name.length)
92
- .trim()
93
- );
94
- };
95
-
96
- const decomposible = (
97
- props: IProps<
98
- ITypedHttpRouteParameter.IHeaders | ITypedHttpRouteParameter.IQuery
99
- >,
100
- ): OpenApi.IOperation.IParameter[] => {
101
- const param: OpenApi.IOperation.IParameter = {
102
- name: props.parameter.field ?? props.parameter.name,
103
- in: props.parameter.category === "query" ? "query" : "header",
104
- schema: props.schema,
105
- description: parameterDescription(props),
106
- required: props.parameter.metadata.required,
107
- example: props.parameter.example,
108
- examples: props.parameter.examples,
109
- };
110
- if (
111
- props.config.decompose === false ||
112
- props.parameter.metadata.objects.length === 0
113
- )
114
- return [param];
115
- return (props.parameter.metadata.objects[0]!.type as MetadataObjectType).properties.filter((p) =>
116
- p.jsDocTags.every(
117
- (tag) => tag.name !== "hidden" && tag.name !== "ignore",
118
- ),
119
- ).map((p) => {
120
- const json: IJsonSchemaCollection = JsonSchemasProgrammer.writeSchemas({
121
- version: "3.1",
122
- metadatas: [p.value],
123
- }) as IJsonSchemaCollection;
124
- if (Object.keys(json.components.schemas ?? {}).length !== 0) {
125
- props.document.components ??= {};
126
- props.document.components.schemas ??= {};
127
- Object.assign(
128
- props.document.components.schemas,
129
- json.components.schemas,
130
- );
131
- }
132
- return {
133
- name: p.key.constants[0]!.values[0]!.value as string,
134
- in: props.parameter.category === "query" ? "query" : "header",
135
- schema: json.schemas[0]!,
136
- required: p.value.required,
137
- description: SwaggerDescriptionComposer.compose({
138
- description: p.description ?? null,
139
- jsDocTags: p.jsDocTags,
140
- kind: "title",
141
- }).description,
142
- };
143
- });
144
- };
145
- }
146
-
147
- const warning = new VariadicSingleton((described: boolean): string => {
148
- const summary = "Request body must be encrypted.";
149
- const component =
150
- "[EncryptedBody](https://github.com/samchon/@nestia/core#encryptedbody)";
151
- const content: string[] = [
152
- "## Warning",
153
- "",
154
- summary,
155
- "",
156
- `The request body data would be encrypted as "AES-128(256) / CBC mode / PKCS#5 Padding / Base64 Encoding", through the ${component} component.`,
157
- "",
158
- `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.`,
159
- ];
160
- if (described === true) content.push("", "----------------", "", "");
161
- return content.join("\n");
162
- });
1
+ import { OpenApi } from "@typia/interface";
2
+ import { VariadicSingleton } from "tstl";
3
+ import { IJsDocTagInfo, IJsonSchemaCollection } from "typia";
4
+
5
+ import { INestiaConfig } from "../../INestiaConfig";
6
+ import {
7
+ JsonSchemasProgrammer,
8
+ MetadataObjectType,
9
+ } from "../../internal/legacy";
10
+ import { ITypedHttpRouteParameter } from "../../structures/ITypedHttpRouteParameter";
11
+ import { SwaggerDescriptionComposer } from "./SwaggerDescriptionComposer";
12
+ import { SwaggerReadonlyArrayEmender } from "./SwaggerReadonlyArrayEmender";
13
+
14
+ export namespace SwaggerOperationParameterComposer {
15
+ export interface IProps<Parameter extends ITypedHttpRouteParameter> {
16
+ config: Omit<INestiaConfig.ISwaggerConfig, "output">;
17
+ document: OpenApi.IDocument;
18
+ schema: OpenApi.IJsonSchema;
19
+ jsDocTags: IJsDocTagInfo[];
20
+ parameter: Parameter;
21
+ }
22
+
23
+ export const compose = (
24
+ props: IProps<ITypedHttpRouteParameter>,
25
+ ): OpenApi.IOperation.IParameter[] =>
26
+ props.parameter.category === "body"
27
+ ? []
28
+ : props.parameter.category === "param"
29
+ ? [path({ ...props, parameter: props.parameter })]
30
+ : props.parameter.category === "query"
31
+ ? query({ ...props, parameter: props.parameter })
32
+ : header({ ...props, parameter: props.parameter });
33
+
34
+ export const body = (
35
+ props: Omit<IProps<ITypedHttpRouteParameter.IBody>, "config" | "document">,
36
+ ): OpenApi.IOperation.IRequestBody => {
37
+ const description: string | undefined =
38
+ props.parameter.description ??
39
+ SwaggerDescriptionComposer.descriptionFromJsDocTag({
40
+ jsDocTags: props.jsDocTags,
41
+ tag: "param",
42
+ parameter: props.parameter.name,
43
+ });
44
+ return {
45
+ description: props.parameter.encrypted
46
+ ? `${warning.get(!!description)}${description ?? ""}`
47
+ : description,
48
+ content: {
49
+ [props.parameter.contentType]: {
50
+ schema: props.schema,
51
+ example: props.parameter.example,
52
+ examples: props.parameter.examples,
53
+ },
54
+ },
55
+ required: props.parameter.metadata.required,
56
+ ...(props.parameter.encrypted ? { "x-nestia-encrypted": true } : {}),
57
+ };
58
+ };
59
+
60
+ const path = (
61
+ props: Omit<IProps<ITypedHttpRouteParameter.IPath>, "config" | "document">,
62
+ ): OpenApi.IOperation.IParameter => ({
63
+ name: props.parameter.field,
64
+ in: "path",
65
+ schema: props.schema,
66
+ required: props.parameter.metadata.required,
67
+ description: parameterDescription(props),
68
+ example: props.parameter.example,
69
+ examples: props.parameter.examples,
70
+ });
71
+
72
+ const query = (
73
+ props: IProps<ITypedHttpRouteParameter.IQuery>,
74
+ ): OpenApi.IOperation.IParameter[] => decomposible(props);
75
+
76
+ const header = (
77
+ props: IProps<ITypedHttpRouteParameter.IHeaders>,
78
+ ): OpenApi.IOperation.IParameter[] => decomposible(props);
79
+
80
+ const parameterDescription = (
81
+ props: Pick<IProps<ITypedHttpRouteParameter>, "parameter" | "jsDocTags">,
82
+ ): string | undefined => {
83
+ return (
84
+ props.parameter.description ??
85
+ props.parameter.jsDocTags.find((tag) => tag.name === "description")
86
+ ?.text?.[0]?.text ??
87
+ props.jsDocTags
88
+ .find(
89
+ (tag) =>
90
+ tag.name === "param" &&
91
+ tag.text?.[0]?.text === props.parameter.name,
92
+ )
93
+ ?.text?.map((e) => e.text)
94
+ .join("")
95
+ .substring(props.parameter.name.length)
96
+ .trim()
97
+ );
98
+ };
99
+
100
+ const decomposible = (
101
+ props: IProps<
102
+ ITypedHttpRouteParameter.IHeaders | ITypedHttpRouteParameter.IQuery
103
+ >,
104
+ ): OpenApi.IOperation.IParameter[] => {
105
+ const param: OpenApi.IOperation.IParameter = {
106
+ name: props.parameter.field ?? props.parameter.name,
107
+ in: props.parameter.category === "query" ? "query" : "header",
108
+ schema: props.schema,
109
+ description: parameterDescription(props),
110
+ required: props.parameter.metadata.required,
111
+ example: props.parameter.example,
112
+ examples: props.parameter.examples,
113
+ };
114
+ if (
115
+ props.config.decompose === false ||
116
+ props.parameter.metadata.objects.length === 0
117
+ )
118
+ return [param];
119
+ return (
120
+ props.parameter.metadata.objects[0]!.type as MetadataObjectType
121
+ ).properties
122
+ .filter((p) =>
123
+ p.jsDocTags.every(
124
+ (tag) => tag.name !== "hidden" && tag.name !== "ignore",
125
+ ),
126
+ )
127
+ .map((p) => {
128
+ const json: IJsonSchemaCollection = JsonSchemasProgrammer.writeSchemas({
129
+ version: "3.1",
130
+ metadatas: [p.value],
131
+ }) as IJsonSchemaCollection;
132
+ SwaggerReadonlyArrayEmender.emend({
133
+ components: json.components,
134
+ schema: json.schemas[0],
135
+ metadata: p.value,
136
+ });
137
+ if (Object.keys(json.components.schemas ?? {}).length !== 0) {
138
+ props.document.components ??= {};
139
+ props.document.components.schemas ??= {};
140
+ Object.assign(
141
+ props.document.components.schemas,
142
+ json.components.schemas,
143
+ );
144
+ }
145
+ return {
146
+ name: p.key.constants[0]!.values[0]!.value as string,
147
+ in: props.parameter.category === "query" ? "query" : "header",
148
+ schema: json.schemas[0]!,
149
+ required: p.value.required,
150
+ description: SwaggerDescriptionComposer.compose({
151
+ description: p.description ?? null,
152
+ jsDocTags: p.jsDocTags,
153
+ kind: "title",
154
+ }).description,
155
+ };
156
+ });
157
+ };
158
+ }
159
+
160
+ const warning = new VariadicSingleton((described: boolean): string => {
161
+ const summary = "Request body must be encrypted.";
162
+ const component =
163
+ "[EncryptedBody](https://github.com/samchon/@nestia/core#encryptedbody)";
164
+ const content: string[] = [
165
+ "## Warning",
166
+ "",
167
+ summary,
168
+ "",
169
+ `The request body data would be encrypted as "AES-128(256) / CBC mode / PKCS#5 Padding / Base64 Encoding", through the ${component} component.`,
170
+ "",
171
+ `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.`,
172
+ ];
173
+ if (described === true) content.push("", "----------------", "", "");
174
+ return content.join("\n");
175
+ });
@@ -1,110 +1,115 @@
1
- import { MetadataSchema } from "../../internal/legacy";
2
- import { OpenApi } from "@typia/interface";
3
- import { VariadicSingleton } from "tstl";
4
-
5
- import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
6
- import { StringUtil } from "../../utils/StringUtil";
7
- import { SwaggerDescriptionComposer } from "./SwaggerDescriptionComposer";
8
-
9
- export namespace SwaggerOperationResponseComposer {
10
- export const compose = (props: {
11
- schema: (metadata: MetadataSchema) => OpenApi.IJsonSchema | undefined;
12
- route: ITypedHttpRoute;
13
- }): Record<string, OpenApi.IOperation.IResponse> => {
14
- const output: Record<string, OpenApi.IOperation.IResponse> = {};
15
- // FROM DECORATOR
16
- for (const [status, error] of Object.entries(props.route.exceptions))
17
- output[status] = {
18
- description: error.description ?? undefined,
19
- content: {
20
- "application/json": {
21
- schema: props.schema(error.metadata),
22
- example: error.example,
23
- examples: error.examples,
24
- },
25
- },
26
- };
27
-
28
- // FROM COMMENTS
29
- for (const tag of props.route.jsDocTags) {
30
- if (tag.name !== "throw" && tag.name !== "throws") continue;
31
- const text: string | undefined = tag.text?.find(
32
- (elem) => elem.kind === "text",
33
- )?.text;
34
- if (text === undefined) continue;
35
-
36
- const elements: string[] = text.split(" ").map((str) => str.trim());
37
- const status: string = elements[0]!;
38
- if (
39
- isNaN(Number(status)) &&
40
- status !== "2XX" &&
41
- status !== "3XX" &&
42
- status !== "4XX" &&
43
- status !== "5XX"
44
- )
45
- continue;
46
-
47
- const description: string | undefined =
48
- elements.length === 1 ? undefined : elements.slice(1).join(" ");
49
- const oldbie = output[status];
50
- if (description && oldbie !== undefined)
51
- oldbie.description ??= description;
52
- else if (oldbie === undefined)
53
- output[status] = {
54
- description: description,
55
- content: {
56
- "application/json": {
57
- schema: {},
58
- },
59
- },
60
- };
61
- }
62
-
63
- // SUCCESS
64
- const description: string | undefined =
65
- SwaggerDescriptionComposer.descriptionFromJsDocTag({
66
- jsDocTags: props.route.jsDocTags,
67
- tag: "returns",
68
- }) ??
69
- SwaggerDescriptionComposer.descriptionFromJsDocTag({
70
- jsDocTags: props.route.jsDocTags,
71
- tag: "return",
72
- });
73
- output[
74
- props.route.success.status ??
75
- (props.route.method.toLowerCase() === "post" ? 201 : 200)
76
- ] = {
77
- description: props.route.success.encrypted
78
- ? `${warning.get(!!description, props.route.method)}${description ?? ""}`
79
- : (description ?? ""),
80
- content: props.route.success.contentType
81
- ? {
82
- [props.route.success.contentType]: {
83
- schema: props.schema(props.route.success.metadata),
84
- example: props.route.success.example,
85
- examples: props.route.success.examples,
86
- },
87
- }
88
- : undefined,
89
- ...(props.route.success.encrypted ? { "x-nestia-encrypted": true } : {}),
90
- };
91
- return output;
92
- };
93
- }
94
-
95
- const warning = new VariadicSingleton((described: boolean, method: string) => {
96
- const summary: string = "Response data have been encrypted.";
97
- const component: string = `[EncryptedRoute.${StringUtil.capitalize(method)}](https://github.com/samchon/@nestia/core#encryptedroute)`;
98
-
99
- const content: string[] = [
100
- "## Warning",
101
- "",
102
- summary,
103
- "",
104
- `The response body data would be encrypted as "AES-128(256) / CBC mode / PKCS#5 Padding / Base64 Encoding", through the ${component} component.`,
105
- "",
106
- `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.`,
107
- ];
108
- if (described === true) content.push("", "----------------", "", "");
109
- return content.join("\n");
110
- });
1
+ import { OpenApi } from "@typia/interface";
2
+ import { VariadicSingleton } from "tstl";
3
+
4
+ import { MetadataSchema } from "../../internal/legacy";
5
+ import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
6
+ import { StringUtil } from "../../utils/StringUtil";
7
+ import { SwaggerDescriptionComposer } from "./SwaggerDescriptionComposer";
8
+
9
+ export namespace SwaggerOperationResponseComposer {
10
+ export const compose = (props: {
11
+ schema: (metadata: MetadataSchema) => OpenApi.IJsonSchema | undefined;
12
+ route: ITypedHttpRoute;
13
+ }): Record<string, OpenApi.IOperation.IResponse> => {
14
+ const output: Record<string, OpenApi.IOperation.IResponse> = {};
15
+ // FROM DECORATOR
16
+ for (const [status, error] of Object.entries(props.route.exceptions))
17
+ output[status] = {
18
+ description: error.description ?? undefined,
19
+ content: {
20
+ "application/json": {
21
+ schema: props.schema(error.metadata),
22
+ example: error.example,
23
+ examples: error.examples,
24
+ },
25
+ },
26
+ };
27
+
28
+ // FROM COMMENTS
29
+ for (const tag of props.route.jsDocTags) {
30
+ if (tag.name !== "throw" && tag.name !== "throws") continue;
31
+ const text: string | undefined = tag.text?.find(
32
+ (elem) => elem.kind === "text",
33
+ )?.text;
34
+ if (text === undefined) continue;
35
+
36
+ const elements: string[] = text.split(" ").map((str) => str.trim());
37
+ const status: string = elements[0]!;
38
+ if (
39
+ isNaN(Number(status)) &&
40
+ status !== "2XX" &&
41
+ status !== "3XX" &&
42
+ status !== "4XX" &&
43
+ status !== "5XX"
44
+ )
45
+ continue;
46
+
47
+ const description: string | undefined =
48
+ elements.length === 1 ? undefined : elements.slice(1).join(" ");
49
+ const oldbie = output[status];
50
+ if (description && oldbie !== undefined)
51
+ oldbie.description ??= description;
52
+ else if (oldbie === undefined)
53
+ output[status] = {
54
+ description: description,
55
+ content: {
56
+ "application/json": {
57
+ schema: {},
58
+ },
59
+ },
60
+ };
61
+ }
62
+
63
+ // SUCCESS
64
+ const description: string | undefined =
65
+ SwaggerDescriptionComposer.descriptionFromJsDocTag({
66
+ jsDocTags: props.route.jsDocTags,
67
+ tag: "returns",
68
+ }) ??
69
+ SwaggerDescriptionComposer.descriptionFromJsDocTag({
70
+ jsDocTags: props.route.jsDocTags,
71
+ tag: "return",
72
+ });
73
+ output[
74
+ props.route.success.status ??
75
+ (props.route.method.toLowerCase() === "post" ? 201 : 200)
76
+ ] = {
77
+ description: props.route.success.encrypted
78
+ ? `${warning.get(!!description, props.route.method)}${description ?? ""}`
79
+ : (description ?? ""),
80
+ content: props.route.success.contentType
81
+ ? {
82
+ [props.route.success.contentType]: {
83
+ schema: props.route.success.binary
84
+ ? {
85
+ format: "binary",
86
+ type: "string",
87
+ }
88
+ : props.schema(props.route.success.metadata),
89
+ example: props.route.success.example,
90
+ examples: props.route.success.examples,
91
+ },
92
+ }
93
+ : undefined,
94
+ ...(props.route.success.encrypted ? { "x-nestia-encrypted": true } : {}),
95
+ };
96
+ return output;
97
+ };
98
+ }
99
+
100
+ const warning = new VariadicSingleton((described: boolean, method: string) => {
101
+ const summary: string = "Response data have been encrypted.";
102
+ const component: string = `[EncryptedRoute.${StringUtil.capitalize(method)}](https://github.com/samchon/@nestia/core#encryptedroute)`;
103
+
104
+ const content: string[] = [
105
+ "## Warning",
106
+ "",
107
+ summary,
108
+ "",
109
+ `The response body data would be encrypted as "AES-128(256) / CBC mode / PKCS#5 Padding / Base64 Encoding", through the ${component} component.`,
110
+ "",
111
+ `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.`,
112
+ ];
113
+ if (described === true) content.push("", "----------------", "", "");
114
+ return content.join("\n");
115
+ });