@nestia/sdk 7.0.0-dev.20250607 → 7.0.0

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/LICENSE +21 -21
  2. package/README.md +92 -92
  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/executable/internal/NestiaConfigLoader.js +4 -4
  15. package/lib/executable/sdk.js +12 -12
  16. package/package.json +5 -5
  17. package/src/INestiaConfig.ts +269 -269
  18. package/src/NestiaSdkApplication.ts +307 -307
  19. package/src/NestiaSwaggerComposer.ts +138 -138
  20. package/src/analyses/AccessorAnalyzer.ts +67 -67
  21. package/src/analyses/ConfigAnalyzer.ts +155 -155
  22. package/src/analyses/ExceptionAnalyzer.ts +154 -154
  23. package/src/analyses/GenericAnalyzer.ts +49 -49
  24. package/src/analyses/ImportAnalyzer.ts +171 -171
  25. package/src/analyses/PathAnalyzer.ts +69 -69
  26. package/src/analyses/ReflectControllerAnalyzer.ts +105 -105
  27. package/src/analyses/ReflectHttpOperationAnalyzer.ts +183 -183
  28. package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +71 -71
  29. package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +348 -348
  30. package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +127 -127
  31. package/src/analyses/ReflectMetadataAnalyzer.ts +44 -44
  32. package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +172 -172
  33. package/src/analyses/SecurityAnalyzer.ts +25 -25
  34. package/src/analyses/TypedHttpRouteAnalyzer.ts +204 -204
  35. package/src/analyses/TypedWebSocketRouteAnalyzer.ts +33 -33
  36. package/src/decorators/OperationMetadata.ts +15 -15
  37. package/src/executable/internal/CommandParser.ts +15 -15
  38. package/src/executable/internal/NestiaConfigLoader.ts +78 -78
  39. package/src/executable/internal/NestiaSdkCommand.ts +103 -103
  40. package/src/executable/sdk.ts +75 -75
  41. package/src/generates/CloneGenerator.ts +66 -66
  42. package/src/generates/E2eGenerator.ts +32 -32
  43. package/src/generates/SdkGenerator.ts +160 -160
  44. package/src/generates/SwaggerGenerator.ts +284 -284
  45. package/src/generates/internal/E2eFileProgrammer.ts +205 -205
  46. package/src/generates/internal/FilePrinter.ts +53 -53
  47. package/src/generates/internal/ImportDictionary.ts +163 -163
  48. package/src/generates/internal/SdkAliasCollection.ts +255 -255
  49. package/src/generates/internal/SdkDistributionComposer.ts +103 -103
  50. package/src/generates/internal/SdkFileProgrammer.ts +116 -116
  51. package/src/generates/internal/SdkHttpCloneProgrammer.ts +124 -124
  52. package/src/generates/internal/SdkHttpCloneReferencer.ts +75 -75
  53. package/src/generates/internal/SdkHttpFunctionProgrammer.ts +276 -276
  54. package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +500 -500
  55. package/src/generates/internal/SdkHttpParameterProgrammer.ts +178 -178
  56. package/src/generates/internal/SdkHttpRouteProgrammer.ts +107 -107
  57. package/src/generates/internal/SdkHttpSimulationProgrammer.ts +340 -340
  58. package/src/generates/internal/SdkImportWizard.ts +55 -55
  59. package/src/generates/internal/SdkRouteDirectory.ts +18 -18
  60. package/src/generates/internal/SdkTypeProgrammer.ts +384 -384
  61. package/src/generates/internal/SdkTypeTagProgrammer.ts +102 -102
  62. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +366 -366
  63. package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +87 -87
  64. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +279 -279
  65. package/src/generates/internal/SwaggerDescriptionComposer.ts +64 -64
  66. package/src/generates/internal/SwaggerOperationComposer.ts +119 -119
  67. package/src/generates/internal/SwaggerOperationParameterComposer.ts +177 -177
  68. package/src/generates/internal/SwaggerOperationResponseComposer.ts +110 -110
  69. package/src/index.ts +4 -4
  70. package/src/module.ts +3 -3
  71. package/src/structures/INestiaProject.ts +13 -13
  72. package/src/structures/INestiaSdkInput.ts +20 -20
  73. package/src/structures/IReflectApplication.ts +8 -8
  74. package/src/structures/IReflectController.ts +15 -15
  75. package/src/structures/IReflectHttpOperation.ts +26 -26
  76. package/src/structures/IReflectHttpOperationException.ts +19 -19
  77. package/src/structures/IReflectHttpOperationParameter.ts +81 -81
  78. package/src/structures/IReflectHttpOperationSuccess.ts +22 -22
  79. package/src/structures/IReflectOperationError.ts +26 -26
  80. package/src/structures/IReflectType.ts +4 -4
  81. package/src/structures/IReflectTypeImport.ts +4 -4
  82. package/src/structures/IReflectWebSocketOperation.ts +17 -17
  83. package/src/structures/IReflectWebSocketOperationParameter.ts +38 -38
  84. package/src/structures/ITypedApplication.ts +11 -11
  85. package/src/structures/ITypedHttpRoute.ts +41 -41
  86. package/src/structures/ITypedHttpRouteException.ts +15 -15
  87. package/src/structures/ITypedHttpRouteParameter.ts +41 -41
  88. package/src/structures/ITypedHttpRouteSuccess.ts +22 -22
  89. package/src/structures/ITypedWebSocketRoute.ts +24 -24
  90. package/src/structures/ITypedWebSocketRouteParameter.ts +3 -3
  91. package/src/structures/MethodType.ts +5 -5
  92. package/src/structures/ParamCategory.ts +1 -1
  93. package/src/structures/TypeEntry.ts +22 -22
  94. package/src/transform.ts +9 -9
  95. package/src/transformers/IOperationMetadata.ts +44 -44
  96. package/src/transformers/ISdkOperationTransformerContext.ts +8 -8
  97. package/src/transformers/SdkOperationProgrammer.ts +209 -209
  98. package/src/transformers/SdkOperationTransformer.ts +253 -253
  99. package/src/transformers/TextPlainValidator.ts +17 -17
  100. package/src/typings/get-function-location.d.ts +7 -7
  101. package/src/utils/ArrayUtil.ts +26 -26
  102. package/src/utils/FileRetriever.ts +22 -22
  103. package/src/utils/MapUtil.ts +14 -14
  104. package/src/utils/MetadataUtil.ts +26 -26
  105. package/src/utils/PathUtil.ts +10 -10
  106. package/src/utils/SourceFinder.ts +66 -66
  107. package/src/utils/StringUtil.ts +17 -17
  108. package/src/utils/StripEnums.ts +5 -5
  109. package/src/utils/VersioningStrategy.ts +28 -28
  110. package/src/validators/HttpHeadersValidator.ts +34 -34
  111. package/src/validators/HttpQueryValidator.ts +34 -34
@@ -1,366 +1,366 @@
1
- import ts from "typescript";
2
- import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
3
- import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
4
- import { TypeFactory } from "typia/lib/factories/TypeFactory";
5
-
6
- import { INestiaProject } from "../../structures/INestiaProject";
7
- import { ITypedWebSocketRoute } from "../../structures/ITypedWebSocketRoute";
8
- import { FilePrinter } from "./FilePrinter";
9
- import { ImportDictionary } from "./ImportDictionary";
10
- import { SdkAliasCollection } from "./SdkAliasCollection";
11
- import { SdkWebSocketParameterProgrammer } from "./SdkWebSocketParameterProgrammer";
12
-
13
- export namespace SdkWebSocketNamespaceProgrammer {
14
- export const write =
15
- (project: INestiaProject) =>
16
- (importer: ImportDictionary) =>
17
- (route: ITypedWebSocketRoute): ts.ModuleDeclaration =>
18
- ts.factory.createModuleDeclaration(
19
- [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
20
- ts.factory.createIdentifier(route.name),
21
- ts.factory.createModuleBlock([
22
- ...writeTypes(project)(importer)(route),
23
- FilePrinter.enter(),
24
- writePath(project)(route),
25
- ]),
26
- ts.NodeFlags.Namespace,
27
- );
28
-
29
- const writeTypes =
30
- (project: INestiaProject) =>
31
- (importer: ImportDictionary) =>
32
- (route: ITypedWebSocketRoute): ts.TypeAliasDeclaration[] => {
33
- const output: ts.TypeAliasDeclaration[] = [];
34
- const declare = (name: string, type: ts.TypeNode) =>
35
- output.push(
36
- ts.factory.createTypeAliasDeclaration(
37
- [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
38
- name,
39
- undefined,
40
- type,
41
- ),
42
- );
43
-
44
- if (project.config.keyword === true)
45
- declare("Props", SdkAliasCollection.websocketProps(route));
46
- declare(
47
- "Output",
48
- ts.factory.createTypeLiteralNode([
49
- ts.factory.createPropertySignature(
50
- undefined,
51
- "connector",
52
- undefined,
53
- ts.factory.createTypeReferenceNode(
54
- importer.external({
55
- type: false,
56
- library: "tgrid",
57
- instance: "WebSocketConnector",
58
- }),
59
- [
60
- ts.factory.createTypeReferenceNode("Header"),
61
- ts.factory.createTypeReferenceNode("Provider"),
62
- ts.factory.createTypeReferenceNode("Listener"),
63
- ],
64
- ),
65
- ),
66
- ts.factory.createPropertySignature(
67
- undefined,
68
- "driver",
69
- undefined,
70
- ts.factory.createTypeReferenceNode(
71
- importer.external({
72
- type: true,
73
- library: "tgrid",
74
- instance: "Driver",
75
- }),
76
- [ts.factory.createTypeReferenceNode("Listener")],
77
- ),
78
- ),
79
- ]),
80
- );
81
-
82
- declare(
83
- "Header",
84
- SdkAliasCollection.name({
85
- type: (route.header?.type ?? route.acceptor.type.typeArguments?.[0])!,
86
- }),
87
- );
88
- declare(
89
- "Provider",
90
- SdkAliasCollection.name({
91
- type:
92
- route.driver?.type.typeArguments?.[0] ??
93
- route.acceptor.type.typeArguments?.[2]!,
94
- }),
95
- );
96
- declare(
97
- "Listener",
98
- SdkAliasCollection.name({
99
- type: route.acceptor.type.typeArguments?.[1]!,
100
- }),
101
- );
102
- if (route.query) declare("Query", SdkAliasCollection.name(route.query));
103
- return output;
104
- };
105
-
106
- const writePath =
107
- (project: INestiaProject) =>
108
- (route: ITypedWebSocketRoute): ts.VariableStatement => {
109
- const out = (body: ts.ConciseBody) =>
110
- constant("path")(
111
- ts.factory.createArrowFunction(
112
- [],
113
- [],
114
- SdkWebSocketParameterProgrammer.getParameterDeclarations({
115
- project,
116
- route,
117
- provider: false,
118
- prefix: false,
119
- }),
120
- undefined,
121
- undefined,
122
- body,
123
- ),
124
- );
125
- if (route.pathParameters.length === 0 && route.query === null)
126
- return out(ts.factory.createStringLiteral(route.path));
127
-
128
- const access = (key: string) =>
129
- project.config.keyword === true
130
- ? ts.factory.createPropertyAccessExpression(
131
- ts.factory.createIdentifier("props"),
132
- key,
133
- )
134
- : ts.factory.createIdentifier(key);
135
- const template = () => {
136
- const split: string[] = route.path.split(":");
137
- if (split.length === 1)
138
- return ts.factory.createStringLiteral(route.path);
139
- return ts.factory.createTemplateExpression(
140
- ts.factory.createTemplateHead(split[0]),
141
- split.slice(1).map((s, i, arr) => {
142
- const name: string = s.split("/")[0];
143
- return ts.factory.createTemplateSpan(
144
- ts.factory.createCallExpression(
145
- ts.factory.createIdentifier("encodeURIComponent"),
146
- undefined,
147
- [
148
- ts.factory.createBinaryExpression(
149
- ts.factory.createCallChain(
150
- ts.factory.createPropertyAccessChain(
151
- access(
152
- route.pathParameters.find((p) => p.field === name)!
153
- .name,
154
- ),
155
- ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
156
- "toString",
157
- ),
158
- undefined,
159
- undefined,
160
- [],
161
- ),
162
- ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
163
- ts.factory.createStringLiteral("null"),
164
- ),
165
- ],
166
- ),
167
- (i !== arr.length - 1
168
- ? ts.factory.createTemplateMiddle
169
- : ts.factory.createTemplateTail)(s.substring(name.length)),
170
- );
171
- }),
172
- );
173
- };
174
- if (route.query === null) return out(template());
175
-
176
- const block = (expr: ts.Expression) => {
177
- const computeName = (str: string): string =>
178
- [...route.pathParameters, ...(route.query ? [route.query] : [])].find(
179
- (p) => p.name === str,
180
- ) !== undefined
181
- ? computeName("_" + str)
182
- : str;
183
- const variables: string = computeName("variables");
184
- return ts.factory.createBlock(
185
- [
186
- local(variables)("URLSearchParams")(
187
- ts.factory.createNewExpression(
188
- ts.factory.createIdentifier("URLSearchParams"),
189
- [],
190
- [],
191
- ),
192
- ),
193
- ts.factory.createForOfStatement(
194
- undefined,
195
- ts.factory.createVariableDeclarationList(
196
- [
197
- ts.factory.createVariableDeclaration(
198
- ts.factory.createArrayBindingPattern([
199
- ts.factory.createBindingElement(
200
- undefined,
201
- undefined,
202
- ts.factory.createIdentifier("key"),
203
- undefined,
204
- ),
205
- ts.factory.createBindingElement(
206
- undefined,
207
- undefined,
208
- ts.factory.createIdentifier("value"),
209
- undefined,
210
- ),
211
- ]),
212
- undefined,
213
- undefined,
214
- undefined,
215
- ),
216
- ],
217
- ts.NodeFlags.Const,
218
- ),
219
- ts.factory.createCallExpression(
220
- ts.factory.createIdentifier("Object.entries"),
221
- undefined,
222
- [
223
- ts.factory.createAsExpression(
224
- expr,
225
- TypeFactory.keyword("any"),
226
- ),
227
- ],
228
- ),
229
- ts.factory.createIfStatement(
230
- ts.factory.createStrictEquality(
231
- ts.factory.createIdentifier("undefined"),
232
- ts.factory.createIdentifier("value"),
233
- ),
234
- ts.factory.createContinueStatement(),
235
- ts.factory.createIfStatement(
236
- ts.factory.createCallExpression(
237
- ts.factory.createIdentifier("Array.isArray"),
238
- undefined,
239
- [ts.factory.createIdentifier("value")],
240
- ),
241
- ts.factory.createExpressionStatement(
242
- ts.factory.createCallExpression(
243
- ts.factory.createPropertyAccessExpression(
244
- ts.factory.createIdentifier("value"),
245
- ts.factory.createIdentifier("forEach"),
246
- ),
247
- undefined,
248
- [
249
- ts.factory.createArrowFunction(
250
- undefined,
251
- undefined,
252
- [IdentifierFactory.parameter("elem")],
253
- undefined,
254
- undefined,
255
- ts.factory.createCallExpression(
256
- IdentifierFactory.access(
257
- ts.factory.createIdentifier(variables),
258
- "append",
259
- ),
260
- undefined,
261
- [
262
- ts.factory.createIdentifier("key"),
263
- ts.factory.createCallExpression(
264
- ts.factory.createIdentifier("String"),
265
- undefined,
266
- [ts.factory.createIdentifier("elem")],
267
- ),
268
- ],
269
- ),
270
- ),
271
- ],
272
- ),
273
- ),
274
- ts.factory.createExpressionStatement(
275
- ts.factory.createCallExpression(
276
- IdentifierFactory.access(
277
- ts.factory.createIdentifier(variables),
278
- "set",
279
- ),
280
- undefined,
281
- [
282
- ts.factory.createIdentifier("key"),
283
- ts.factory.createCallExpression(
284
- ts.factory.createIdentifier("String"),
285
- undefined,
286
- [ts.factory.createIdentifier("value")],
287
- ),
288
- ],
289
- ),
290
- ),
291
- ),
292
- ),
293
- ),
294
- local("location")("string")(template()),
295
- ts.factory.createReturnStatement(
296
- ts.factory.createConditionalExpression(
297
- ts.factory.createStrictEquality(
298
- ExpressionFactory.number(0),
299
- IdentifierFactory.access(
300
- ts.factory.createIdentifier(variables),
301
- "size",
302
- ),
303
- ),
304
- undefined,
305
- ts.factory.createIdentifier("location"),
306
- undefined,
307
- ts.factory.createTemplateExpression(
308
- ts.factory.createTemplateHead(""),
309
- [
310
- ts.factory.createTemplateSpan(
311
- ts.factory.createIdentifier("location"),
312
- ts.factory.createTemplateMiddle("?"),
313
- ),
314
- ts.factory.createTemplateSpan(
315
- ts.factory.createCallExpression(
316
- IdentifierFactory.access(
317
- ts.factory.createIdentifier(variables),
318
- "toString",
319
- ),
320
- undefined,
321
- undefined,
322
- ),
323
- ts.factory.createTemplateTail(""),
324
- ),
325
- ],
326
- ),
327
- ),
328
- ),
329
- ],
330
- true,
331
- );
332
- };
333
- return out(block(access(route.query.name)));
334
- };
335
- }
336
-
337
- const local = (name: string) => (type: string) => (expression: ts.Expression) =>
338
- ts.factory.createVariableStatement(
339
- [],
340
- ts.factory.createVariableDeclarationList(
341
- [
342
- ts.factory.createVariableDeclaration(
343
- name,
344
- undefined,
345
- ts.factory.createTypeReferenceNode(type),
346
- expression,
347
- ),
348
- ],
349
- ts.NodeFlags.Const,
350
- ),
351
- );
352
- const constant = (name: string) => (expression: ts.Expression) =>
353
- ts.factory.createVariableStatement(
354
- [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
355
- ts.factory.createVariableDeclarationList(
356
- [
357
- ts.factory.createVariableDeclaration(
358
- name,
359
- undefined,
360
- undefined,
361
- expression,
362
- ),
363
- ],
364
- ts.NodeFlags.Const,
365
- ),
366
- );
1
+ import ts from "typescript";
2
+ import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
3
+ import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
4
+ import { TypeFactory } from "typia/lib/factories/TypeFactory";
5
+
6
+ import { INestiaProject } from "../../structures/INestiaProject";
7
+ import { ITypedWebSocketRoute } from "../../structures/ITypedWebSocketRoute";
8
+ import { FilePrinter } from "./FilePrinter";
9
+ import { ImportDictionary } from "./ImportDictionary";
10
+ import { SdkAliasCollection } from "./SdkAliasCollection";
11
+ import { SdkWebSocketParameterProgrammer } from "./SdkWebSocketParameterProgrammer";
12
+
13
+ export namespace SdkWebSocketNamespaceProgrammer {
14
+ export const write =
15
+ (project: INestiaProject) =>
16
+ (importer: ImportDictionary) =>
17
+ (route: ITypedWebSocketRoute): ts.ModuleDeclaration =>
18
+ ts.factory.createModuleDeclaration(
19
+ [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
20
+ ts.factory.createIdentifier(route.name),
21
+ ts.factory.createModuleBlock([
22
+ ...writeTypes(project)(importer)(route),
23
+ FilePrinter.enter(),
24
+ writePath(project)(route),
25
+ ]),
26
+ ts.NodeFlags.Namespace,
27
+ );
28
+
29
+ const writeTypes =
30
+ (project: INestiaProject) =>
31
+ (importer: ImportDictionary) =>
32
+ (route: ITypedWebSocketRoute): ts.TypeAliasDeclaration[] => {
33
+ const output: ts.TypeAliasDeclaration[] = [];
34
+ const declare = (name: string, type: ts.TypeNode) =>
35
+ output.push(
36
+ ts.factory.createTypeAliasDeclaration(
37
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
38
+ name,
39
+ undefined,
40
+ type,
41
+ ),
42
+ );
43
+
44
+ if (project.config.keyword === true)
45
+ declare("Props", SdkAliasCollection.websocketProps(route));
46
+ declare(
47
+ "Output",
48
+ ts.factory.createTypeLiteralNode([
49
+ ts.factory.createPropertySignature(
50
+ undefined,
51
+ "connector",
52
+ undefined,
53
+ ts.factory.createTypeReferenceNode(
54
+ importer.external({
55
+ type: false,
56
+ library: "tgrid",
57
+ instance: "WebSocketConnector",
58
+ }),
59
+ [
60
+ ts.factory.createTypeReferenceNode("Header"),
61
+ ts.factory.createTypeReferenceNode("Provider"),
62
+ ts.factory.createTypeReferenceNode("Listener"),
63
+ ],
64
+ ),
65
+ ),
66
+ ts.factory.createPropertySignature(
67
+ undefined,
68
+ "driver",
69
+ undefined,
70
+ ts.factory.createTypeReferenceNode(
71
+ importer.external({
72
+ type: true,
73
+ library: "tgrid",
74
+ instance: "Driver",
75
+ }),
76
+ [ts.factory.createTypeReferenceNode("Listener")],
77
+ ),
78
+ ),
79
+ ]),
80
+ );
81
+
82
+ declare(
83
+ "Header",
84
+ SdkAliasCollection.name({
85
+ type: (route.header?.type ?? route.acceptor.type.typeArguments?.[0])!,
86
+ }),
87
+ );
88
+ declare(
89
+ "Provider",
90
+ SdkAliasCollection.name({
91
+ type:
92
+ route.driver?.type.typeArguments?.[0] ??
93
+ route.acceptor.type.typeArguments?.[2]!,
94
+ }),
95
+ );
96
+ declare(
97
+ "Listener",
98
+ SdkAliasCollection.name({
99
+ type: route.acceptor.type.typeArguments?.[1]!,
100
+ }),
101
+ );
102
+ if (route.query) declare("Query", SdkAliasCollection.name(route.query));
103
+ return output;
104
+ };
105
+
106
+ const writePath =
107
+ (project: INestiaProject) =>
108
+ (route: ITypedWebSocketRoute): ts.VariableStatement => {
109
+ const out = (body: ts.ConciseBody) =>
110
+ constant("path")(
111
+ ts.factory.createArrowFunction(
112
+ [],
113
+ [],
114
+ SdkWebSocketParameterProgrammer.getParameterDeclarations({
115
+ project,
116
+ route,
117
+ provider: false,
118
+ prefix: false,
119
+ }),
120
+ undefined,
121
+ undefined,
122
+ body,
123
+ ),
124
+ );
125
+ if (route.pathParameters.length === 0 && route.query === null)
126
+ return out(ts.factory.createStringLiteral(route.path));
127
+
128
+ const access = (key: string) =>
129
+ project.config.keyword === true
130
+ ? ts.factory.createPropertyAccessExpression(
131
+ ts.factory.createIdentifier("props"),
132
+ key,
133
+ )
134
+ : ts.factory.createIdentifier(key);
135
+ const template = () => {
136
+ const split: string[] = route.path.split(":");
137
+ if (split.length === 1)
138
+ return ts.factory.createStringLiteral(route.path);
139
+ return ts.factory.createTemplateExpression(
140
+ ts.factory.createTemplateHead(split[0]),
141
+ split.slice(1).map((s, i, arr) => {
142
+ const name: string = s.split("/")[0];
143
+ return ts.factory.createTemplateSpan(
144
+ ts.factory.createCallExpression(
145
+ ts.factory.createIdentifier("encodeURIComponent"),
146
+ undefined,
147
+ [
148
+ ts.factory.createBinaryExpression(
149
+ ts.factory.createCallChain(
150
+ ts.factory.createPropertyAccessChain(
151
+ access(
152
+ route.pathParameters.find((p) => p.field === name)!
153
+ .name,
154
+ ),
155
+ ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
156
+ "toString",
157
+ ),
158
+ undefined,
159
+ undefined,
160
+ [],
161
+ ),
162
+ ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
163
+ ts.factory.createStringLiteral("null"),
164
+ ),
165
+ ],
166
+ ),
167
+ (i !== arr.length - 1
168
+ ? ts.factory.createTemplateMiddle
169
+ : ts.factory.createTemplateTail)(s.substring(name.length)),
170
+ );
171
+ }),
172
+ );
173
+ };
174
+ if (route.query === null) return out(template());
175
+
176
+ const block = (expr: ts.Expression) => {
177
+ const computeName = (str: string): string =>
178
+ [...route.pathParameters, ...(route.query ? [route.query] : [])].find(
179
+ (p) => p.name === str,
180
+ ) !== undefined
181
+ ? computeName("_" + str)
182
+ : str;
183
+ const variables: string = computeName("variables");
184
+ return ts.factory.createBlock(
185
+ [
186
+ local(variables)("URLSearchParams")(
187
+ ts.factory.createNewExpression(
188
+ ts.factory.createIdentifier("URLSearchParams"),
189
+ [],
190
+ [],
191
+ ),
192
+ ),
193
+ ts.factory.createForOfStatement(
194
+ undefined,
195
+ ts.factory.createVariableDeclarationList(
196
+ [
197
+ ts.factory.createVariableDeclaration(
198
+ ts.factory.createArrayBindingPattern([
199
+ ts.factory.createBindingElement(
200
+ undefined,
201
+ undefined,
202
+ ts.factory.createIdentifier("key"),
203
+ undefined,
204
+ ),
205
+ ts.factory.createBindingElement(
206
+ undefined,
207
+ undefined,
208
+ ts.factory.createIdentifier("value"),
209
+ undefined,
210
+ ),
211
+ ]),
212
+ undefined,
213
+ undefined,
214
+ undefined,
215
+ ),
216
+ ],
217
+ ts.NodeFlags.Const,
218
+ ),
219
+ ts.factory.createCallExpression(
220
+ ts.factory.createIdentifier("Object.entries"),
221
+ undefined,
222
+ [
223
+ ts.factory.createAsExpression(
224
+ expr,
225
+ TypeFactory.keyword("any"),
226
+ ),
227
+ ],
228
+ ),
229
+ ts.factory.createIfStatement(
230
+ ts.factory.createStrictEquality(
231
+ ts.factory.createIdentifier("undefined"),
232
+ ts.factory.createIdentifier("value"),
233
+ ),
234
+ ts.factory.createContinueStatement(),
235
+ ts.factory.createIfStatement(
236
+ ts.factory.createCallExpression(
237
+ ts.factory.createIdentifier("Array.isArray"),
238
+ undefined,
239
+ [ts.factory.createIdentifier("value")],
240
+ ),
241
+ ts.factory.createExpressionStatement(
242
+ ts.factory.createCallExpression(
243
+ ts.factory.createPropertyAccessExpression(
244
+ ts.factory.createIdentifier("value"),
245
+ ts.factory.createIdentifier("forEach"),
246
+ ),
247
+ undefined,
248
+ [
249
+ ts.factory.createArrowFunction(
250
+ undefined,
251
+ undefined,
252
+ [IdentifierFactory.parameter("elem")],
253
+ undefined,
254
+ undefined,
255
+ ts.factory.createCallExpression(
256
+ IdentifierFactory.access(
257
+ ts.factory.createIdentifier(variables),
258
+ "append",
259
+ ),
260
+ undefined,
261
+ [
262
+ ts.factory.createIdentifier("key"),
263
+ ts.factory.createCallExpression(
264
+ ts.factory.createIdentifier("String"),
265
+ undefined,
266
+ [ts.factory.createIdentifier("elem")],
267
+ ),
268
+ ],
269
+ ),
270
+ ),
271
+ ],
272
+ ),
273
+ ),
274
+ ts.factory.createExpressionStatement(
275
+ ts.factory.createCallExpression(
276
+ IdentifierFactory.access(
277
+ ts.factory.createIdentifier(variables),
278
+ "set",
279
+ ),
280
+ undefined,
281
+ [
282
+ ts.factory.createIdentifier("key"),
283
+ ts.factory.createCallExpression(
284
+ ts.factory.createIdentifier("String"),
285
+ undefined,
286
+ [ts.factory.createIdentifier("value")],
287
+ ),
288
+ ],
289
+ ),
290
+ ),
291
+ ),
292
+ ),
293
+ ),
294
+ local("location")("string")(template()),
295
+ ts.factory.createReturnStatement(
296
+ ts.factory.createConditionalExpression(
297
+ ts.factory.createStrictEquality(
298
+ ExpressionFactory.number(0),
299
+ IdentifierFactory.access(
300
+ ts.factory.createIdentifier(variables),
301
+ "size",
302
+ ),
303
+ ),
304
+ undefined,
305
+ ts.factory.createIdentifier("location"),
306
+ undefined,
307
+ ts.factory.createTemplateExpression(
308
+ ts.factory.createTemplateHead(""),
309
+ [
310
+ ts.factory.createTemplateSpan(
311
+ ts.factory.createIdentifier("location"),
312
+ ts.factory.createTemplateMiddle("?"),
313
+ ),
314
+ ts.factory.createTemplateSpan(
315
+ ts.factory.createCallExpression(
316
+ IdentifierFactory.access(
317
+ ts.factory.createIdentifier(variables),
318
+ "toString",
319
+ ),
320
+ undefined,
321
+ undefined,
322
+ ),
323
+ ts.factory.createTemplateTail(""),
324
+ ),
325
+ ],
326
+ ),
327
+ ),
328
+ ),
329
+ ],
330
+ true,
331
+ );
332
+ };
333
+ return out(block(access(route.query.name)));
334
+ };
335
+ }
336
+
337
+ const local = (name: string) => (type: string) => (expression: ts.Expression) =>
338
+ ts.factory.createVariableStatement(
339
+ [],
340
+ ts.factory.createVariableDeclarationList(
341
+ [
342
+ ts.factory.createVariableDeclaration(
343
+ name,
344
+ undefined,
345
+ ts.factory.createTypeReferenceNode(type),
346
+ expression,
347
+ ),
348
+ ],
349
+ ts.NodeFlags.Const,
350
+ ),
351
+ );
352
+ const constant = (name: string) => (expression: ts.Expression) =>
353
+ ts.factory.createVariableStatement(
354
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
355
+ ts.factory.createVariableDeclarationList(
356
+ [
357
+ ts.factory.createVariableDeclaration(
358
+ name,
359
+ undefined,
360
+ undefined,
361
+ expression,
362
+ ),
363
+ ],
364
+ ts.NodeFlags.Const,
365
+ ),
366
+ );