@nestia/sdk 13.0.4 → 14.0.1

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 (186) hide show
  1. package/README.md +1 -1
  2. package/assets/bundle/distribute/package.json +2 -2
  3. package/assets/bundle/distribute/tsconfig.json +15 -105
  4. package/lib/INestiaConfig.d.ts +19 -10
  5. package/lib/NestiaSdkApplication.js +58 -27
  6. package/lib/NestiaSdkApplication.js.map +1 -1
  7. package/lib/NestiaSwaggerComposer.js +11 -10
  8. package/lib/NestiaSwaggerComposer.js.map +1 -1
  9. package/lib/analyses/ConfigAnalyzer.js +4 -4
  10. package/lib/analyses/ConfigAnalyzer.js.map +1 -1
  11. package/lib/analyses/ParameterNameAnalyzer.d.ts +20 -0
  12. package/lib/analyses/ParameterNameAnalyzer.js +48 -0
  13. package/lib/analyses/ParameterNameAnalyzer.js.map +1 -0
  14. package/lib/analyses/PathAnalyzer.d.ts +30 -0
  15. package/lib/analyses/PathAnalyzer.js +108 -16
  16. package/lib/analyses/PathAnalyzer.js.map +1 -1
  17. package/lib/analyses/ReflectControllerAnalyzer.js +2 -1
  18. package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
  19. package/lib/analyses/ReflectHttpOperationAnalyzer.js +7 -7
  20. package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
  21. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js +122 -23
  22. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js.map +1 -1
  23. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +5 -2
  24. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -1
  25. package/lib/analyses/ReflectMcpOperationAnalyzer.js +5 -2
  26. package/lib/analyses/ReflectMcpOperationAnalyzer.js.map +1 -1
  27. package/lib/analyses/ReflectWebSocketOperationAnalyzer.js +6 -3
  28. package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -1
  29. package/lib/analyses/SecurityAnalyzer.d.ts +10 -0
  30. package/lib/analyses/SecurityAnalyzer.js +24 -19
  31. package/lib/analyses/SecurityAnalyzer.js.map +1 -1
  32. package/lib/analyses/SwaggerExampleAnalyzer.d.ts +15 -0
  33. package/lib/analyses/SwaggerExampleAnalyzer.js +20 -0
  34. package/lib/analyses/SwaggerExampleAnalyzer.js.map +1 -0
  35. package/lib/analyses/TypedHttpRouteAnalyzer.js +30 -21
  36. package/lib/analyses/TypedHttpRouteAnalyzer.js.map +1 -1
  37. package/lib/analyses/TypedWebSocketRouteAnalyzer.js +1 -1
  38. package/lib/analyses/TypedWebSocketRouteAnalyzer.js.map +1 -1
  39. package/lib/executable/internal/NestiaSdkWatcher.js +3 -3
  40. package/lib/executable/internal/NestiaSdkWatcher.js.map +1 -1
  41. package/lib/executable/sdk.js +16 -1
  42. package/lib/executable/sdk.js.map +1 -1
  43. package/lib/factories/ExpressionFactory.d.ts +3 -0
  44. package/lib/factories/ExpressionFactory.js +6 -2
  45. package/lib/factories/ExpressionFactory.js.map +1 -1
  46. package/lib/factories/LiteralFactory.js +3 -1
  47. package/lib/factories/LiteralFactory.js.map +1 -1
  48. package/lib/generates/SdkGenerator.js +3 -3
  49. package/lib/generates/SdkGenerator.js.map +1 -1
  50. package/lib/generates/SwaggerGenerator.js +135 -27
  51. package/lib/generates/SwaggerGenerator.js.map +1 -1
  52. package/lib/generates/internal/FilePrinter.d.ts +14 -0
  53. package/lib/generates/internal/FilePrinter.js +31 -0
  54. package/lib/generates/internal/FilePrinter.js.map +1 -1
  55. package/lib/generates/internal/ImportDictionary.d.ts +2 -0
  56. package/lib/generates/internal/ImportDictionary.js +13 -0
  57. package/lib/generates/internal/ImportDictionary.js.map +1 -1
  58. package/lib/generates/internal/SdkAliasCollection.d.ts +2 -1
  59. package/lib/generates/internal/SdkAliasCollection.js +8 -4
  60. package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
  61. package/lib/generates/internal/SdkDistributionComposer.js +72 -14
  62. package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
  63. package/lib/generates/internal/SdkFileProgrammer.js +83 -12
  64. package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
  65. package/lib/generates/internal/SdkHttpFunctionProgrammer.js +21 -23
  66. package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
  67. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +27 -34
  68. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
  69. package/lib/generates/internal/SdkHttpParameterProgrammer.d.ts +40 -1
  70. package/lib/generates/internal/SdkHttpParameterProgrammer.js +105 -6
  71. package/lib/generates/internal/SdkHttpParameterProgrammer.js.map +1 -1
  72. package/lib/generates/internal/SdkHttpRouteProgrammer.js +16 -32
  73. package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -1
  74. package/lib/generates/internal/SdkHttpSimulationProgrammer.js +18 -14
  75. package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
  76. package/lib/generates/internal/SdkMcpRouteProgrammer.js +39 -11
  77. package/lib/generates/internal/SdkMcpRouteProgrammer.js.map +1 -1
  78. package/lib/generates/internal/SdkPathTemplate.d.ts +21 -0
  79. package/lib/generates/internal/SdkPathTemplate.js +50 -0
  80. package/lib/generates/internal/SdkPathTemplate.js.map +1 -0
  81. package/lib/generates/internal/SdkTypeProgrammer.js +15 -15
  82. package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
  83. package/lib/generates/internal/SdkTypeTagProgrammer.d.ts +20 -1
  84. package/lib/generates/internal/SdkTypeTagProgrammer.js +386 -67
  85. package/lib/generates/internal/SdkTypeTagProgrammer.js.map +1 -1
  86. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +27 -36
  87. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
  88. package/lib/generates/internal/SdkWebSocketParameterProgrammer.d.ts +35 -1
  89. package/lib/generates/internal/SdkWebSocketParameterProgrammer.js +72 -5
  90. package/lib/generates/internal/SdkWebSocketParameterProgrammer.js.map +1 -1
  91. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +57 -33
  92. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
  93. package/lib/generates/internal/SwaggerOperationComposer.js +19 -8
  94. package/lib/generates/internal/SwaggerOperationComposer.js.map +1 -1
  95. package/lib/generates/internal/SwaggerOperationParameterComposer.d.ts +1 -1
  96. package/lib/generates/internal/SwaggerOperationParameterComposer.js +201 -19
  97. package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -1
  98. package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +2 -0
  99. package/lib/generates/internal/SwaggerOperationResponseComposer.js +39 -7
  100. package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -1
  101. package/lib/internal/legacy.d.ts +49 -18
  102. package/lib/internal/legacy.js +84 -25
  103. package/lib/internal/legacy.js.map +1 -1
  104. package/lib/structures/IOperationMetadata.d.ts +22 -0
  105. package/lib/structures/IReflectHttpOperationException.d.ts +3 -2
  106. package/lib/structures/IReflectHttpOperationParameter.d.ts +8 -3
  107. package/lib/structures/IReflectHttpOperationSuccess.d.ts +4 -3
  108. package/lib/structures/ITypedHttpRoute.d.ts +8 -0
  109. package/lib/structures/ITypedHttpRouteException.d.ts +3 -1
  110. package/lib/structures/ITypedHttpRouteParameter.d.ts +3 -1
  111. package/lib/structures/ITypedHttpRouteSuccess.d.ts +3 -1
  112. package/lib/structures/ITypedWebSocketRoute.d.ts +8 -0
  113. package/lib/utils/SourceFinder.d.ts +10 -0
  114. package/lib/utils/SourceFinder.js +27 -4
  115. package/lib/utils/SourceFinder.js.map +1 -1
  116. package/lib/utils/VersioningStrategy.d.ts +13 -1
  117. package/lib/utils/VersioningStrategy.js +24 -12
  118. package/lib/utils/VersioningStrategy.js.map +1 -1
  119. package/native/go.mod +1 -1
  120. package/native/go.sum +2 -2
  121. package/native/sdk/sdk_http_rules.go +210 -0
  122. package/native/sdk/sdk_metadata_json.go +73 -3
  123. package/native/sdk/sdk_transform.go +801 -49
  124. package/package.json +8 -8
  125. package/src/INestiaConfig.ts +19 -10
  126. package/src/NestiaSdkApplication.ts +63 -34
  127. package/src/NestiaSwaggerComposer.ts +11 -8
  128. package/src/analyses/ConfigAnalyzer.ts +3 -3
  129. package/src/analyses/ParameterNameAnalyzer.ts +51 -0
  130. package/src/analyses/PathAnalyzer.ts +106 -14
  131. package/src/analyses/ReflectControllerAnalyzer.ts +2 -1
  132. package/src/analyses/ReflectHttpOperationAnalyzer.ts +4 -4
  133. package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +122 -39
  134. package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +6 -7
  135. package/src/analyses/ReflectMcpOperationAnalyzer.ts +6 -2
  136. package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +7 -3
  137. package/src/analyses/SecurityAnalyzer.ts +30 -20
  138. package/src/analyses/SwaggerExampleAnalyzer.ts +23 -0
  139. package/src/analyses/TypedHttpRouteAnalyzer.ts +29 -20
  140. package/src/analyses/TypedWebSocketRouteAnalyzer.ts +1 -0
  141. package/src/executable/internal/NestiaSdkWatcher.ts +2 -2
  142. package/src/executable/sdk.ts +24 -1
  143. package/src/factories/ExpressionFactory.ts +8 -2
  144. package/src/factories/LiteralFactory.ts +7 -2
  145. package/src/generates/SdkGenerator.ts +3 -3
  146. package/src/generates/SwaggerGenerator.ts +173 -32
  147. package/src/generates/internal/FilePrinter.ts +28 -0
  148. package/src/generates/internal/ImportDictionary.ts +11 -0
  149. package/src/generates/internal/SdkAliasCollection.ts +11 -4
  150. package/src/generates/internal/SdkDistributionComposer.ts +89 -15
  151. package/src/generates/internal/SdkFileProgrammer.ts +108 -16
  152. package/src/generates/internal/SdkHttpFunctionProgrammer.ts +28 -30
  153. package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +34 -64
  154. package/src/generates/internal/SdkHttpParameterProgrammer.ts +193 -13
  155. package/src/generates/internal/SdkHttpRouteProgrammer.ts +17 -31
  156. package/src/generates/internal/SdkHttpSimulationProgrammer.ts +51 -14
  157. package/src/generates/internal/SdkMcpRouteProgrammer.ts +112 -15
  158. package/src/generates/internal/SdkPathTemplate.ts +73 -0
  159. package/src/generates/internal/SdkTypeProgrammer.ts +19 -22
  160. package/src/generates/internal/SdkTypeTagProgrammer.ts +506 -78
  161. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +43 -68
  162. package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +126 -5
  163. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +71 -48
  164. package/src/generates/internal/SwaggerOperationComposer.ts +20 -6
  165. package/src/generates/internal/SwaggerOperationParameterComposer.ts +279 -30
  166. package/src/generates/internal/SwaggerOperationResponseComposer.ts +55 -11
  167. package/src/internal/legacy.ts +114 -26
  168. package/src/structures/IOperationMetadata.ts +28 -0
  169. package/src/structures/IReflectHttpOperationException.ts +7 -2
  170. package/src/structures/IReflectHttpOperationParameter.ts +9 -2
  171. package/src/structures/IReflectHttpOperationSuccess.ts +8 -3
  172. package/src/structures/ITypedHttpRoute.ts +8 -0
  173. package/src/structures/ITypedHttpRouteException.ts +4 -1
  174. package/src/structures/ITypedHttpRouteParameter.ts +3 -1
  175. package/src/structures/ITypedHttpRouteSuccess.ts +4 -1
  176. package/src/structures/ITypedWebSocketRoute.ts +8 -0
  177. package/src/utils/SourceFinder.ts +25 -4
  178. package/src/utils/VersioningStrategy.ts +28 -13
  179. package/lib/validators/HttpHeadersValidator.d.ts +0 -11
  180. package/lib/validators/HttpHeadersValidator.js +0 -15
  181. package/lib/validators/HttpHeadersValidator.js.map +0 -1
  182. package/lib/validators/HttpQueryValidator.d.ts +0 -10
  183. package/lib/validators/HttpQueryValidator.js +0 -14
  184. package/lib/validators/HttpQueryValidator.js.map +0 -1
  185. package/src/validators/HttpHeadersValidator.ts +0 -12
  186. package/src/validators/HttpQueryValidator.ts +0 -11
@@ -1,8 +1,15 @@
1
- import { type Node, SyntaxKind, type TypeNode, factory } from "@ttsc/factory";
1
+ import {
2
+ type Expression,
3
+ type Node,
4
+ SyntaxKind,
5
+ type TypeNode,
6
+ factory,
7
+ } from "@ttsc/factory";
2
8
 
3
9
  import { INestiaProject } from "../../structures/INestiaProject";
4
10
  import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
5
11
  import { ITypedHttpRouteParameter } from "../../structures/ITypedHttpRouteParameter";
12
+ import { StringUtil } from "../../utils/StringUtil";
6
13
  import { ImportDictionary } from "./ImportDictionary";
7
14
  import { SdkAliasCollection } from "./SdkAliasCollection";
8
15
 
@@ -14,6 +21,157 @@ export namespace SdkHttpParameterProgrammer {
14
21
  parameter: ITypedHttpRouteParameter;
15
22
  }
16
23
 
24
+ /**
25
+ * The identifiers one route's SDK function, `path()`, and `simulate()` use,
26
+ * decided once so the three cannot disagree.
27
+ *
28
+ * A user parameter shares those scopes with identifiers the SDK writes: its
29
+ * own `connection` and `props` parameters and locals, and names it cannot
30
+ * change — the route's function and namespace, which are public, and the
31
+ * imports, namespace members, and globals the bodies reference. Nothing kept
32
+ * them apart, so a parameter named like its method or `connection` produced
33
+ * an SDK that does not compile (#1647).
34
+ *
35
+ * The SDK's own identifiers are escaped with `_` prefixes, as it already
36
+ * escaped `output` and `variables`. A user parameter keeps its name, which an
37
+ * IDE shows and which is a `props` key in keyword mode, unless the name is
38
+ * one the SDK cannot change; then the positional parameter alone is renamed,
39
+ * which positional callers never see. The fixed names are only those the
40
+ * generated code actually references for this route and configuration, and an
41
+ * own identifier yields only to the names its scope can see, so nothing is
42
+ * renamed where no name is shadowed.
43
+ */
44
+ export interface INames {
45
+ connection: string;
46
+ props: string;
47
+ output: string;
48
+ assert: string;
49
+ variables: string;
50
+ location: string;
51
+ key: string;
52
+ value: string;
53
+ elem: string;
54
+
55
+ /** Local identifier of a significant parameter in positional mode. */
56
+ parameter: (p: ITypedHttpRouteParameter) => string;
57
+
58
+ /** Reads a significant parameter: `props.<name>` or its local. */
59
+ access: (p: ITypedHttpRouteParameter) => Expression;
60
+ }
61
+
62
+ export const getNames = (props: {
63
+ project: INestiaProject;
64
+ route: ITypedHttpRoute;
65
+ }): INames => {
66
+ const { project, route } = props;
67
+ const parameters: ITypedHttpRouteParameter[] = getSignificant(route, true);
68
+ const simulate: boolean =
69
+ project.config.simulate === true && parameters.length !== 0;
70
+
71
+ // names each scope references and the SDK cannot change
72
+ const functional: string[] = [
73
+ route.name,
74
+ !!route.body?.encrypted || route.success.encrypted
75
+ ? "EncryptedFetcher"
76
+ : "PlainFetcher",
77
+ ...(project.config.assert === true ? ["typia"] : []),
78
+ ...(route.success.setHeaders.some((h) => h.type === "assigner")
79
+ ? ["Object"]
80
+ : []),
81
+ ];
82
+ const path: string[] = [
83
+ ...(route.pathParameters.length !== 0 ? ["PathParameter"] : []),
84
+ ...(route.queryObject !== null || route.queryParameters.length !== 0
85
+ ? ["URLSearchParams", "Object", "Array", "String", "undefined"]
86
+ : []),
87
+ ];
88
+ const simulation: string[] = simulate
89
+ ? ["NestiaSimulator", "METADATA", "path", "random", "typia"]
90
+ : [];
91
+
92
+ const locals: Map<ITypedHttpRouteParameter, string> = new Map();
93
+ if (project.config.keyword !== true)
94
+ for (const p of parameters)
95
+ locals.set(
96
+ p,
97
+ StringUtil.escapeDuplicate([
98
+ ...functional,
99
+ ...simulation,
100
+ ...(p.category !== "body" ? path : []),
101
+ ...parameters.filter((q) => q !== p).map((q) => q.name),
102
+ ...locals.values(),
103
+ ])(p.name),
104
+ );
105
+ // An SDK-own identifier avoids the fixed names and the other own ones of
106
+ // its scope, and the positional parameters whose values its scope reads
107
+ // where it is visible: the SDK function's and simulate()'s parameters and
108
+ // locals see every one; in path(), `variables` and `location` see its
109
+ // parameters, the loop's `key` and `value` the query values its header
110
+ // reads, and `elem` none.
111
+ const declared = (list: ITypedHttpRouteParameter[]): string[] =>
112
+ list
113
+ .map((p) => locals.get(p))
114
+ .filter((name): name is string => name !== undefined);
115
+ const queries: ITypedHttpRouteParameter[] = [
116
+ ...route.queryParameters,
117
+ ...(route.queryObject ? [route.queryObject] : []),
118
+ ];
119
+ const own =
120
+ (fixed: string[], reads: string[], taken: string[]) =>
121
+ (name: string): string => {
122
+ const escaped: string = StringUtil.escapeDuplicate([
123
+ ...fixed,
124
+ ...reads,
125
+ ...taken,
126
+ ])(name);
127
+ taken.push(escaped);
128
+ return escaped;
129
+ };
130
+ const every: string[] = declared(parameters);
131
+ const shared: string[] = [];
132
+ const $props: string = own(
133
+ [...functional, ...path, ...simulation],
134
+ every,
135
+ shared,
136
+ )("props");
137
+ const $connection: string = own(
138
+ [...functional, ...simulation],
139
+ every,
140
+ shared,
141
+ )("connection");
142
+ const inPath: string[] = [...shared];
143
+ const names: Omit<INames, "parameter" | "access"> = {
144
+ props: $props,
145
+ connection: $connection,
146
+ output: own(functional, every, [...shared])("output"),
147
+ assert: own(simulation, every, [...shared])("assert"),
148
+ variables: own(
149
+ path,
150
+ declared([...route.pathParameters, ...queries]),
151
+ inPath,
152
+ )("variables"),
153
+ location: own(
154
+ path,
155
+ declared([...route.pathParameters, ...queries]),
156
+ inPath,
157
+ )("location"),
158
+ key: own(path, declared(queries), inPath)("key"),
159
+ value: own(path, declared(queries), inPath)("value"),
160
+ elem: own(path, [], inPath)("elem"),
161
+ };
162
+ return {
163
+ ...names,
164
+ parameter: (p) => locals.get(p) ?? p.name,
165
+ access: (p) =>
166
+ project.config.keyword === true
167
+ ? factory.createPropertyAccessExpression(
168
+ factory.createIdentifier(names.props),
169
+ p.name,
170
+ )
171
+ : factory.createIdentifier(locals.get(p) ?? p.name),
172
+ };
173
+ };
174
+
17
175
  export const getAll = (
18
176
  route: ITypedHttpRoute,
19
177
  ): ITypedHttpRouteParameter[] => [
@@ -113,7 +271,8 @@ export namespace SdkHttpParameterProgrammer {
113
271
  }): Node[] => {
114
272
  const entries: IEntry[] = getEntries(props);
115
273
  if (entries.length === 0) return [];
116
- else if (props.project.config.keyword === true) {
274
+ const names: INames = getNames(props);
275
+ if (props.project.config.keyword === true) {
117
276
  const typeName: string = props.prefix
118
277
  ? `${props.route.name}.Props`
119
278
  : "Props";
@@ -130,25 +289,45 @@ export namespace SdkHttpParameterProgrammer {
130
289
  factory.createParameterDeclaration(
131
290
  undefined,
132
291
  undefined,
133
- "props",
292
+ names.props,
134
293
  undefined,
135
294
  node,
136
295
  undefined,
137
296
  ),
138
297
  ];
139
298
  }
140
- return entries.map((e) =>
141
- factory.createParameterDeclaration(
299
+ // a required parameter cannot follow an optional one (TS1016), so an
300
+ // optional parameter before a required one trades its `?` for `undefined`
301
+ // in its type
302
+ return entries.map((e, i) => {
303
+ const trailing: boolean =
304
+ e.required === false &&
305
+ entries.slice(i + 1).every((next) => next.required === false);
306
+ return factory.createParameterDeclaration(
142
307
  undefined,
143
308
  undefined,
144
- e.key,
145
- e.required ? undefined : factory.createToken(SyntaxKind.QuestionToken),
146
- e.type,
309
+ names.parameter(e.parameter),
310
+ trailing ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
311
+ e.required || trailing ? e.type : undefinable(props.project, e),
147
312
  undefined,
148
- ),
149
- );
313
+ );
314
+ });
150
315
  };
151
316
 
317
+ // a cloned field's type admits `undefined` when optional, and a reflected
318
+ // field's does when its name says so (`mode: string | undefined`, not
319
+ // `mode?: string`); the `Query` and `Body` aliases are not inspected
320
+ const undefinable = (project: INestiaProject, e: IEntry): TypeNode =>
321
+ e.parameter.category !== "body" &&
322
+ e.parameter.field !== null &&
323
+ (project.config.clone === true ||
324
+ e.parameter.type.name.split("|").some((t) => t.trim() === "undefined"))
325
+ ? e.type
326
+ : factory.createUnionTypeNode([
327
+ e.type,
328
+ factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword),
329
+ ]);
330
+
152
331
  export const getArguments = (props: {
153
332
  project: INestiaProject;
154
333
  route: ITypedHttpRoute;
@@ -156,8 +335,9 @@ export namespace SdkHttpParameterProgrammer {
156
335
  }): Node[] => {
157
336
  const parameters = getSignificant(props.route, props.body);
158
337
  if (parameters.length === 0) return [];
159
- else if (props.project.config.keyword === true)
160
- return [factory.createIdentifier("props")];
161
- return parameters.map((p) => factory.createIdentifier(p.name));
338
+ const names: INames = getNames(props);
339
+ if (props.project.config.keyword === true)
340
+ return [factory.createIdentifier(names.props)];
341
+ return parameters.map((p) => factory.createIdentifier(names.parameter(p)));
162
342
  };
163
343
  }
@@ -1,7 +1,6 @@
1
1
  import { type Node } from "@ttsc/factory";
2
2
  import { IJsDocTagInfo } from "typia";
3
3
 
4
- import { INestiaConfig } from "../../INestiaConfig";
5
4
  import { INestiaProject } from "../../structures/INestiaProject";
6
5
  import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
7
6
  import { FilePrinter } from "./FilePrinter";
@@ -17,12 +16,17 @@ export namespace SdkHttpRouteProgrammer {
17
16
  (route: ITypedHttpRoute): Node[] => [
18
17
  FilePrinter.description(
19
18
  SdkHttpFunctionProgrammer.write(project)(importer)(route),
20
- describe(project.config, route),
19
+ describe(project, route),
21
20
  ),
22
21
  SdkHttpNamespaceProgrammer.write(project)(importer)(route),
23
22
  ];
24
23
 
25
- const describe = (config: INestiaConfig, route: ITypedHttpRoute): string => {
24
+ const describe = (
25
+ project: INestiaProject,
26
+ route: ITypedHttpRoute,
27
+ ): string => {
28
+ const names: SdkHttpParameterProgrammer.INames =
29
+ SdkHttpParameterProgrammer.getNames({ project, route });
26
30
  // MAIN DESCRIPTION
27
31
  const descriptionComments: string[] = route.description
28
32
  ? route.description.split("\n")
@@ -37,23 +41,15 @@ export namespace SdkHttpRouteProgrammer {
37
41
  ?.text ??
38
42
  route.jsDocTags
39
43
  .find((tag) => tag.name === "param" && tag.text?.[0]?.text === p.name)
40
- ?.text?.map((e) => e.text)
41
- .join("")
42
- .substring(p.name.length);
44
+ ?.text?.find((e) => e.kind === "text")?.text;
43
45
  if (!description?.length) continue;
44
46
 
45
- const name: string = config.keyword === true ? `props.${p.name}` : p.name;
46
- tagComments.push(
47
- `@param ${name} ${description
48
- .split("\n")
49
- .map((str) => str.trim())
50
- .map((str, i) => {
51
- if (i === 0) return str;
52
- const rpad: number = p.name.length + 8;
53
- return `${" ".repeat(rpad)}${str}`;
54
- })
55
- .join("\n")}`,
56
- );
47
+ // the name the SDK function declares, which yields on a collision
48
+ const name: string =
49
+ project.config.keyword === true
50
+ ? `${names.props}.${p.name}`
51
+ : names.parameter(p);
52
+ tagComments.push(FilePrinter.jsDocTag(`param ${name}`, description));
57
53
  }
58
54
 
59
55
  // COMMENT TAGS
@@ -62,18 +58,7 @@ export namespace SdkHttpRouteProgrammer {
62
58
  );
63
59
  if (tags.length !== 0) {
64
60
  const content: string[] = tags.map((t) =>
65
- t.text?.length
66
- ? `@${t.name} ${t.text
67
- .map((e) => e.text)
68
- .join("")
69
- .split("\n")
70
- .map((str) => str.trim())
71
- .map((str, i) => {
72
- if (i === 0) return str;
73
- return `${" ".repeat(t.name.length + 1)} ${str}`;
74
- })
75
- .join("\n")}`
76
- : `@${t.name}`,
61
+ FilePrinter.jsDocTag(t.name, t.text?.map((e) => e.text).join("") ?? ""),
77
62
  );
78
63
  tagComments.push(...new Set(content));
79
64
  }
@@ -100,7 +85,8 @@ export namespace SdkHttpRouteProgrammer {
100
85
  ...(descriptionComments.length && tagComments.length ? [""] : []),
101
86
  ...tagComments,
102
87
  ...(descriptionComments.length && tagComments.length ? [""] : []),
103
- `@controller ${route.controller.class.name}.${route.name}`,
88
+ // the public name, kept by a route declared under a local one
89
+ `@controller ${route.controller.class.name}.${route.key}`,
104
90
  `@path ${route.method} ${route.path}`,
105
91
  `@accessor api.functional.${route.accessor.join(".")}`,
106
92
  `@nestia Generated by Nestia - https://github.com/samchon/nestia`,
@@ -65,6 +65,8 @@ export namespace SdkHttpSimulationProgrammer {
65
65
  (project: INestiaProject) =>
66
66
  (importer: ImportDictionary) =>
67
67
  (route: ITypedHttpRoute): Node => {
68
+ const names: SdkHttpParameterProgrammer.INames =
69
+ SdkHttpParameterProgrammer.getNames({ project, route });
68
70
  const output: boolean =
69
71
  project.config.propagate === true ||
70
72
  route.success.binary === true ||
@@ -82,9 +84,9 @@ export namespace SdkHttpSimulationProgrammer {
82
84
  [
83
85
  IdentifierFactory.parameter(
84
86
  SdkHttpParameterProgrammer.getSignificant(route, true).length !==
85
- 0
86
- ? "connection"
87
- : "_connection",
87
+ 0 || route.headerObject !== null
88
+ ? names.connection
89
+ : `_${names.connection}`,
88
90
  factory.createTypeReferenceNode(
89
91
  SdkImportWizard.IConnection(importer),
90
92
  route.headerObject
@@ -104,7 +106,7 @@ export namespace SdkHttpSimulationProgrammer {
104
106
  undefined,
105
107
  factory.createBlock(
106
108
  [
107
- ...assert(project)(importer)(route),
109
+ ...assert(project)(importer)(route)(names),
108
110
  factory.createReturnStatement(
109
111
  project.config.propagate
110
112
  ? factory.createAsExpression(
@@ -145,13 +147,14 @@ export namespace SdkHttpSimulationProgrammer {
145
147
  const assert =
146
148
  (project: INestiaProject) =>
147
149
  (importer: ImportDictionary) =>
148
- (route: ITypedHttpRoute): Statement[] => {
150
+ (route: ITypedHttpRoute) =>
151
+ (names: SdkHttpParameterProgrammer.INames): Statement[] => {
149
152
  const parameters = SdkHttpParameterProgrammer.getSignificant(route, true);
150
- if (parameters.length === 0) return [];
153
+ if (parameters.length === 0 && route.headerObject === null) return [];
151
154
 
152
155
  const typia = SdkImportWizard.typia(importer);
153
156
  const validator = StatementFactory.constant({
154
- name: "assert",
157
+ name: names.assert,
155
158
  value: factory.createCallExpression(
156
159
  IdentifierFactory.access(
157
160
  factory.createIdentifier(
@@ -174,7 +177,10 @@ export namespace SdkHttpSimulationProgrammer {
174
177
  ),
175
178
  factory.createPropertyAssignment(
176
179
  "host",
177
- factory.createIdentifier("connection.host"),
180
+ IdentifierFactory.access(
181
+ factory.createIdentifier(names.connection),
182
+ "host",
183
+ ),
178
184
  ),
179
185
  factory.createPropertyAssignment(
180
186
  "path",
@@ -205,7 +211,7 @@ export namespace SdkHttpSimulationProgrammer {
205
211
  factory.createCallExpression(
206
212
  (() => {
207
213
  const base = IdentifierFactory.access(
208
- factory.createIdentifier("assert"),
214
+ factory.createIdentifier(names.assert),
209
215
  p.category,
210
216
  );
211
217
  if (p.category !== "param") return base;
@@ -227,17 +233,48 @@ export namespace SdkHttpSimulationProgrammer {
227
233
  "assert",
228
234
  ),
229
235
  undefined,
230
- [
231
- project.config.keyword === true
232
- ? factory.createIdentifier(`props.${p.name}`)
233
- : factory.createIdentifier(p.name),
234
- ],
236
+ [names.access(p)],
235
237
  ),
236
238
  ),
237
239
  ],
238
240
  ),
239
241
  )
240
242
  .map(factory.createExpressionStatement);
243
+ // the headers travel in the connection, validated as the server does
244
+ if (route.headerObject !== null)
245
+ individual.push(
246
+ factory.createExpressionStatement(
247
+ factory.createCallExpression(
248
+ IdentifierFactory.access(
249
+ factory.createIdentifier(names.assert),
250
+ "headers",
251
+ ),
252
+ undefined,
253
+ [
254
+ factory.createArrowFunction(
255
+ undefined,
256
+ undefined,
257
+ [],
258
+ undefined,
259
+ undefined,
260
+ factory.createCallExpression(
261
+ IdentifierFactory.access(
262
+ factory.createIdentifier(typia),
263
+ "assert",
264
+ ),
265
+ [factory.createTypeReferenceNode(`${route.name}.Headers`)],
266
+ [
267
+ IdentifierFactory.access(
268
+ factory.createIdentifier(names.connection),
269
+ "headers",
270
+ ),
271
+ ],
272
+ ),
273
+ ),
274
+ ],
275
+ ),
276
+ ),
277
+ );
241
278
  return [
242
279
  validator,
243
280
  ...(project.config.propagate !== true