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