@nestia/sdk 8.1.0 → 9.0.0-dev.20251107

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