@nestia/migrate 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 (41) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +93 -93
  3. package/lib/NestiaMigrateApplication.js +341 -341
  4. package/lib/bundles/NEST_TEMPLATE.js +48 -48
  5. package/lib/bundles/NEST_TEMPLATE.js.map +1 -1
  6. package/lib/bundles/SDK_TEMPLATE.js +21 -21
  7. package/lib/bundles/SDK_TEMPLATE.js.map +1 -1
  8. package/lib/executable/migrate.js +0 -0
  9. package/lib/index.mjs +469 -469
  10. package/lib/index.mjs.map +1 -1
  11. package/package.json +10 -8
  12. package/src/NestiaMigrateApplication.ts +168 -168
  13. package/src/analyzers/NestiaMigrateControllerAnalyzer.ts +51 -51
  14. package/src/bundles/NEST_TEMPLATE.ts +48 -48
  15. package/src/bundles/SDK_TEMPLATE.ts +21 -21
  16. package/src/executable/NestiaMigrateCommander.ts +104 -104
  17. package/src/executable/NestiaMigrateInquirer.ts +106 -106
  18. package/src/executable/bundle.js +129 -125
  19. package/src/executable/migrate.ts +0 -0
  20. package/src/factories/TypeLiteralFactory.ts +57 -57
  21. package/src/module.ts +7 -7
  22. package/src/programmers/NestiaMigrateApiFileProgrammer.ts +55 -55
  23. package/src/programmers/NestiaMigrateApiFunctionProgrammer.ts +347 -347
  24. package/src/programmers/NestiaMigrateApiNamespaceProgrammer.ts +517 -517
  25. package/src/programmers/NestiaMigrateApiSimulationProgrammer.ts +308 -308
  26. package/src/programmers/NestiaMigrateApiStartProgrammer.ts +197 -197
  27. package/src/programmers/NestiaMigrateDtoProgrammer.ts +98 -98
  28. package/src/programmers/NestiaMigrateE2eFileProgrammer.ts +153 -153
  29. package/src/programmers/NestiaMigrateE2eProgrammer.ts +48 -48
  30. package/src/programmers/NestiaMigrateImportProgrammer.ts +118 -118
  31. package/src/programmers/NestiaMigrateNestControllerProgrammer.ts +69 -69
  32. package/src/programmers/NestiaMigrateNestMethodProgrammer.ts +409 -409
  33. package/src/programmers/NestiaMigrateSchemaProgrammer.ts +465 -465
  34. package/src/programmers/index.ts +15 -15
  35. package/src/structures/INestiaMigrateContext.ts +9 -9
  36. package/src/structures/INestiaMigrateController.ts +8 -8
  37. package/src/structures/INestiaMigrateDto.ts +8 -8
  38. package/src/structures/INestiaMigrateProgram.ts +11 -11
  39. package/src/structures/index.ts +4 -4
  40. package/src/utils/FilePrinter.ts +49 -49
  41. package/src/utils/StringUtil.ts +114 -114
@@ -1,347 +1,347 @@
1
- import { IdentifierFactory, StatementFactory } from "@typia/core";
2
- import { IHttpMigrateRoute, OpenApi } from "@typia/interface";
3
- import { NamingConvention } from "@typia/utils";
4
- import ts from "typescript";
5
-
6
- import { INestiaMigrateConfig } from "../structures/INestiaMigrateConfig";
7
- import { FilePrinter } from "../utils/FilePrinter";
8
- import { NestiaMigrateImportProgrammer } from "./NestiaMigrateImportProgrammer";
9
- import { NestiaMigrateSchemaProgrammer } from "./NestiaMigrateSchemaProgrammer";
10
-
11
- export namespace NestiaMigrateApiFunctionProgrammer {
12
- export interface IContext {
13
- config: INestiaMigrateConfig;
14
- components: OpenApi.IComponents;
15
- importer: NestiaMigrateImportProgrammer;
16
- route: IHttpMigrateRoute;
17
- }
18
-
19
- export const write = (ctx: IContext): ts.FunctionDeclaration =>
20
- FilePrinter.description(
21
- ts.factory.createFunctionDeclaration(
22
- [
23
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
24
- ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword),
25
- ],
26
- undefined,
27
- ctx.route.accessor.at(-1)!,
28
- undefined,
29
- writeParameterDeclarations(ctx),
30
- ts.factory.createTypeReferenceNode("Promise", [
31
- ts.factory.createTypeReferenceNode(
32
- ctx.route.success === null
33
- ? "void"
34
- : `${ctx.route.accessor.at(-1)!}.Response`,
35
- ),
36
- ]),
37
- ts.factory.createBlock(writeBody(ctx), true),
38
- ),
39
- writeDescription(ctx.config, ctx.route),
40
- );
41
-
42
- export const writeParameterDeclarations = (
43
- ctx: IContext,
44
- connectionName?: string,
45
- ): ts.ParameterDeclaration[] => {
46
- const connection: ts.ParameterDeclaration = IdentifierFactory.parameter(
47
- connectionName ?? "connection",
48
- ts.factory.createTypeReferenceNode(
49
- ctx.importer.external({
50
- type: "instance",
51
- library: "@nestia/fetcher",
52
- name: "IConnection",
53
- }),
54
- ctx.route.headers
55
- ? [
56
- ts.factory.createTypeReferenceNode(
57
- `${ctx.route.accessor.at(-1)!}.Headers`,
58
- ),
59
- ]
60
- : undefined,
61
- ),
62
- );
63
- if (ctx.config.keyword === true) {
64
- const isProps: boolean =
65
- ctx.route.parameters.length > 0 ||
66
- !!ctx.route.query ||
67
- !!ctx.route.body;
68
- if (isProps === false) return [connection];
69
- return [
70
- connection,
71
- ts.factory.createParameterDeclaration(
72
- undefined,
73
- undefined,
74
- "props",
75
- undefined,
76
- ts.factory.createTypeReferenceNode(
77
- `${ctx.route.accessor.at(-1)!}.Props`,
78
- ),
79
- ),
80
- ];
81
- }
82
- return [
83
- connection,
84
- ...ctx.route.parameters.map((p) =>
85
- IdentifierFactory.parameter(
86
- p.key,
87
- NestiaMigrateSchemaProgrammer.write({
88
- components: ctx.components,
89
- importer: ctx.importer,
90
- schema: p.schema,
91
- }),
92
- ),
93
- ),
94
- ...(ctx.route.query
95
- ? [
96
- IdentifierFactory.parameter(
97
- ctx.route.query.key,
98
- ts.factory.createTypeReferenceNode(
99
- `${ctx.route.accessor.at(-1)!}.Query`,
100
- ),
101
- ),
102
- ]
103
- : []),
104
- ...(ctx.route.body
105
- ? [
106
- IdentifierFactory.parameter(
107
- ctx.route.body.key,
108
- ts.factory.createTypeReferenceNode(
109
- `${ctx.route.accessor.at(-1)!}.Body`,
110
- ),
111
- (ctx.route.body.type === "application/json" ||
112
- ctx.route.body.type === "text/plain") &&
113
- ctx.route.operation().requestBody?.required === false
114
- ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
115
- : undefined,
116
- ),
117
- ]
118
- : []),
119
- ];
120
- };
121
-
122
- const writeDescription = (
123
- config: INestiaMigrateConfig,
124
- route: IHttpMigrateRoute,
125
- ): string => {
126
- const comment: string = route.comment();
127
- return [
128
- config.keyword === true
129
- ? comment.split("@param ").join("@param props.")
130
- : comment,
131
- `@path ${route.emendedPath}`,
132
- `@accessor api.functional.${route.accessor.join(".")}`,
133
- `@${config.author?.tag ?? "nestia"} ${config.author?.value ?? "Generated by Nestia - https://github.com/samchon/nestia"}`,
134
- ].join("\n");
135
- };
136
-
137
- const writeBody = (ctx: IContext): ts.Statement[] => {
138
- const encrypted: boolean = !!ctx.route.success?.["x-nestia-encrypted"];
139
- const contentType: string = ctx.route.body?.type ?? "application/json";
140
-
141
- const property = (key: string): ts.Expression =>
142
- ctx.config.keyword === true
143
- ? IdentifierFactory.access(ts.factory.createIdentifier("props"), key)
144
- : ts.factory.createIdentifier(key);
145
- const fetch = () =>
146
- ts.factory.createAwaitExpression(
147
- ts.factory.createCallExpression(
148
- IdentifierFactory.access(
149
- ts.factory.createIdentifier(
150
- ctx.importer.external({
151
- type: "instance",
152
- library: `@nestia/fetcher`,
153
- name: encrypted ? "EncryptedFetcher" : "PlainFetcher",
154
- }),
155
- ),
156
- "fetch",
157
- ),
158
- undefined,
159
- [
160
- contentType && contentType !== "multipart/form-data"
161
- ? ts.factory.createObjectLiteralExpression(
162
- [
163
- ts.factory.createSpreadAssignment(
164
- ts.factory.createIdentifier("connection"),
165
- ),
166
- ts.factory.createPropertyAssignment(
167
- "headers",
168
- ts.factory.createObjectLiteralExpression(
169
- [
170
- ts.factory.createSpreadAssignment(
171
- IdentifierFactory.access(
172
- ts.factory.createIdentifier("connection"),
173
- "headers",
174
- ),
175
- ),
176
- ts.factory.createPropertyAssignment(
177
- ts.factory.createStringLiteral("Content-Type"),
178
- ts.factory.createStringLiteral(contentType),
179
- ),
180
- ],
181
- true,
182
- ),
183
- ),
184
- ],
185
- true,
186
- )
187
- : ts.factory.createIdentifier("connection"),
188
- ts.factory.createObjectLiteralExpression(
189
- [
190
- ts.factory.createSpreadAssignment(
191
- IdentifierFactory.access(
192
- ts.factory.createIdentifier(ctx.route.accessor.at(-1)!),
193
- "METADATA",
194
- ),
195
- ),
196
- ts.factory.createPropertyAssignment(
197
- "path",
198
- ts.factory.createCallExpression(
199
- IdentifierFactory.access(
200
- ts.factory.createIdentifier(ctx.route.accessor.at(-1)!),
201
- "path",
202
- ),
203
- undefined,
204
- getArguments(ctx, false),
205
- ),
206
- ),
207
- ts.factory.createPropertyAssignment(
208
- "status",
209
- ts.factory.createNull(),
210
- ),
211
- ],
212
- true,
213
- ),
214
- ...(ctx.route.body ? [property(ctx.route.body.key)] : []),
215
- ],
216
- ),
217
- );
218
-
219
- const value: ts.Expression =
220
- ctx.config.simulate !== true
221
- ? fetch()
222
- : ts.factory.createConditionalExpression(
223
- ts.factory.createStrictEquality(
224
- ts.factory.createTrue(),
225
- ts.factory.createIdentifier("connection.simulate"),
226
- ),
227
- undefined,
228
- ts.factory.createCallExpression(
229
- ts.factory.createIdentifier(
230
- `${ctx.route.accessor.at(-1)!}.simulate`,
231
- ),
232
- [],
233
- [
234
- ts.factory.createIdentifier("connection"),
235
- ...getArguments(ctx, true),
236
- ],
237
- ),
238
- undefined,
239
- fetch(),
240
- );
241
- const headers: Array<IAssignHeader | ISetHeader> = getHeaders(
242
- ctx.route.comment(),
243
- );
244
- if (headers.length === 0) return [ts.factory.createReturnStatement(value)];
245
- return [
246
- StatementFactory.constant({
247
- name: "output",
248
- type: ts.factory.createTypeReferenceNode(
249
- `${ctx.route.accessor.at(-1)!}.Response`,
250
- ),
251
- value,
252
- }),
253
- ts.factory.createExpressionStatement(
254
- ts.factory.createBinaryExpression(
255
- ts.factory.createIdentifier("connection.headers"),
256
- ts.factory.createToken(ts.SyntaxKind.QuestionQuestionEqualsToken),
257
- ts.factory.createObjectLiteralExpression([]),
258
- ),
259
- ),
260
- ...headers.map((h) =>
261
- ts.factory.createExpressionStatement(
262
- h.type === "assign"
263
- ? ts.factory.createCallExpression(
264
- ts.factory.createIdentifier("Object.assign"),
265
- undefined,
266
- [
267
- ts.factory.createIdentifier("connection.headers"),
268
- ts.factory.createIdentifier(`output.${h.accessor}`),
269
- ],
270
- )
271
- : ts.factory.createBinaryExpression(
272
- ts.factory.createIdentifier(
273
- `connection.headers${
274
- NamingConvention.variable(h.property)
275
- ? `.${h.property}`
276
- : `[${JSON.stringify(h.property)}]`
277
- }`,
278
- ),
279
- ts.factory.createToken(ts.SyntaxKind.EqualsToken),
280
- ts.factory.createIdentifier(`output.${h.accessor}`),
281
- ),
282
- ),
283
- ),
284
- ts.factory.createReturnStatement(ts.factory.createIdentifier("output")),
285
- ];
286
- };
287
-
288
- const getArguments = (ctx: IContext, body: boolean): ts.Expression[] => {
289
- if (
290
- ctx.route.parameters.length === 0 &&
291
- ctx.route.query === null &&
292
- (body === false || ctx.route.body === null)
293
- )
294
- return [];
295
- else if (ctx.config.keyword === true)
296
- return [ts.factory.createIdentifier("props")];
297
- return [
298
- ...ctx.route.parameters.map((p) => ts.factory.createIdentifier(p.key)),
299
- ...(ctx.route.query
300
- ? [ts.factory.createIdentifier(ctx.route.query.key)]
301
- : []),
302
- ...(body && ctx.route.body
303
- ? [ts.factory.createIdentifier(ctx.route.body.key)]
304
- : []),
305
- ];
306
- };
307
-
308
- const getHeaders = (
309
- description: string,
310
- ): Array<IAssignHeader | ISetHeader> => {
311
- const directives: Array<IAssignHeader | ISetHeader> = [];
312
- for (const line of description.split("\n").map((l) => l.trim())) {
313
- if (line.startsWith("@setHeader ")) {
314
- const parts: string[] = line
315
- .substring("@setHeader ".length)
316
- .trim()
317
- .split(/\s+/);
318
- if (parts.length >= 2)
319
- directives.push({
320
- type: "set",
321
- accessor: parts[0]!,
322
- property: parts[1]!,
323
- });
324
- } else if (line.startsWith("@assignHeaders ")) {
325
- const accessor: string = line
326
- .substring("@assignHeaders ".length)
327
- .trim();
328
- if (accessor.length !== 0)
329
- directives.push({
330
- type: "assign",
331
- accessor,
332
- });
333
- }
334
- }
335
- return directives;
336
- };
337
- }
338
-
339
- interface IAssignHeader {
340
- type: "assign";
341
- accessor: string;
342
- }
343
- interface ISetHeader {
344
- type: "set";
345
- accessor: string;
346
- property: string;
347
- }
1
+ import { IdentifierFactory, StatementFactory } from "@typia/core";
2
+ import { IHttpMigrateRoute, OpenApi } from "@typia/interface";
3
+ import { NamingConvention } from "@typia/utils";
4
+ import ts from "typescript";
5
+
6
+ import { INestiaMigrateConfig } from "../structures/INestiaMigrateConfig";
7
+ import { FilePrinter } from "../utils/FilePrinter";
8
+ import { NestiaMigrateImportProgrammer } from "./NestiaMigrateImportProgrammer";
9
+ import { NestiaMigrateSchemaProgrammer } from "./NestiaMigrateSchemaProgrammer";
10
+
11
+ export namespace NestiaMigrateApiFunctionProgrammer {
12
+ export interface IContext {
13
+ config: INestiaMigrateConfig;
14
+ components: OpenApi.IComponents;
15
+ importer: NestiaMigrateImportProgrammer;
16
+ route: IHttpMigrateRoute;
17
+ }
18
+
19
+ export const write = (ctx: IContext): ts.FunctionDeclaration =>
20
+ FilePrinter.description(
21
+ ts.factory.createFunctionDeclaration(
22
+ [
23
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
24
+ ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword),
25
+ ],
26
+ undefined,
27
+ ctx.route.accessor.at(-1)!,
28
+ undefined,
29
+ writeParameterDeclarations(ctx),
30
+ ts.factory.createTypeReferenceNode("Promise", [
31
+ ts.factory.createTypeReferenceNode(
32
+ ctx.route.success === null
33
+ ? "void"
34
+ : `${ctx.route.accessor.at(-1)!}.Response`,
35
+ ),
36
+ ]),
37
+ ts.factory.createBlock(writeBody(ctx), true),
38
+ ),
39
+ writeDescription(ctx.config, ctx.route),
40
+ );
41
+
42
+ export const writeParameterDeclarations = (
43
+ ctx: IContext,
44
+ connectionName?: string,
45
+ ): ts.ParameterDeclaration[] => {
46
+ const connection: ts.ParameterDeclaration = IdentifierFactory.parameter(
47
+ connectionName ?? "connection",
48
+ ts.factory.createTypeReferenceNode(
49
+ ctx.importer.external({
50
+ type: "instance",
51
+ library: "@nestia/fetcher",
52
+ name: "IConnection",
53
+ }),
54
+ ctx.route.headers
55
+ ? [
56
+ ts.factory.createTypeReferenceNode(
57
+ `${ctx.route.accessor.at(-1)!}.Headers`,
58
+ ),
59
+ ]
60
+ : undefined,
61
+ ),
62
+ );
63
+ if (ctx.config.keyword === true) {
64
+ const isProps: boolean =
65
+ ctx.route.parameters.length > 0 ||
66
+ !!ctx.route.query ||
67
+ !!ctx.route.body;
68
+ if (isProps === false) return [connection];
69
+ return [
70
+ connection,
71
+ ts.factory.createParameterDeclaration(
72
+ undefined,
73
+ undefined,
74
+ "props",
75
+ undefined,
76
+ ts.factory.createTypeReferenceNode(
77
+ `${ctx.route.accessor.at(-1)!}.Props`,
78
+ ),
79
+ ),
80
+ ];
81
+ }
82
+ return [
83
+ connection,
84
+ ...ctx.route.parameters.map((p) =>
85
+ IdentifierFactory.parameter(
86
+ p.key,
87
+ NestiaMigrateSchemaProgrammer.write({
88
+ components: ctx.components,
89
+ importer: ctx.importer,
90
+ schema: p.schema,
91
+ }),
92
+ ),
93
+ ),
94
+ ...(ctx.route.query
95
+ ? [
96
+ IdentifierFactory.parameter(
97
+ ctx.route.query.key,
98
+ ts.factory.createTypeReferenceNode(
99
+ `${ctx.route.accessor.at(-1)!}.Query`,
100
+ ),
101
+ ),
102
+ ]
103
+ : []),
104
+ ...(ctx.route.body
105
+ ? [
106
+ IdentifierFactory.parameter(
107
+ ctx.route.body.key,
108
+ ts.factory.createTypeReferenceNode(
109
+ `${ctx.route.accessor.at(-1)!}.Body`,
110
+ ),
111
+ (ctx.route.body.type === "application/json" ||
112
+ ctx.route.body.type === "text/plain") &&
113
+ ctx.route.operation().requestBody?.required === false
114
+ ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
115
+ : undefined,
116
+ ),
117
+ ]
118
+ : []),
119
+ ];
120
+ };
121
+
122
+ const writeDescription = (
123
+ config: INestiaMigrateConfig,
124
+ route: IHttpMigrateRoute,
125
+ ): string => {
126
+ const comment: string = route.comment();
127
+ return [
128
+ config.keyword === true
129
+ ? comment.split("@param ").join("@param props.")
130
+ : comment,
131
+ `@path ${route.emendedPath}`,
132
+ `@accessor api.functional.${route.accessor.join(".")}`,
133
+ `@${config.author?.tag ?? "nestia"} ${config.author?.value ?? "Generated by Nestia - https://github.com/samchon/nestia"}`,
134
+ ].join("\n");
135
+ };
136
+
137
+ const writeBody = (ctx: IContext): ts.Statement[] => {
138
+ const encrypted: boolean = !!ctx.route.success?.["x-nestia-encrypted"];
139
+ const contentType: string = ctx.route.body?.type ?? "application/json";
140
+
141
+ const property = (key: string): ts.Expression =>
142
+ ctx.config.keyword === true
143
+ ? IdentifierFactory.access(ts.factory.createIdentifier("props"), key)
144
+ : ts.factory.createIdentifier(key);
145
+ const fetch = () =>
146
+ ts.factory.createAwaitExpression(
147
+ ts.factory.createCallExpression(
148
+ IdentifierFactory.access(
149
+ ts.factory.createIdentifier(
150
+ ctx.importer.external({
151
+ type: "instance",
152
+ library: `@nestia/fetcher`,
153
+ name: encrypted ? "EncryptedFetcher" : "PlainFetcher",
154
+ }),
155
+ ),
156
+ "fetch",
157
+ ),
158
+ undefined,
159
+ [
160
+ contentType && contentType !== "multipart/form-data"
161
+ ? ts.factory.createObjectLiteralExpression(
162
+ [
163
+ ts.factory.createSpreadAssignment(
164
+ ts.factory.createIdentifier("connection"),
165
+ ),
166
+ ts.factory.createPropertyAssignment(
167
+ "headers",
168
+ ts.factory.createObjectLiteralExpression(
169
+ [
170
+ ts.factory.createSpreadAssignment(
171
+ IdentifierFactory.access(
172
+ ts.factory.createIdentifier("connection"),
173
+ "headers",
174
+ ),
175
+ ),
176
+ ts.factory.createPropertyAssignment(
177
+ ts.factory.createStringLiteral("Content-Type"),
178
+ ts.factory.createStringLiteral(contentType),
179
+ ),
180
+ ],
181
+ true,
182
+ ),
183
+ ),
184
+ ],
185
+ true,
186
+ )
187
+ : ts.factory.createIdentifier("connection"),
188
+ ts.factory.createObjectLiteralExpression(
189
+ [
190
+ ts.factory.createSpreadAssignment(
191
+ IdentifierFactory.access(
192
+ ts.factory.createIdentifier(ctx.route.accessor.at(-1)!),
193
+ "METADATA",
194
+ ),
195
+ ),
196
+ ts.factory.createPropertyAssignment(
197
+ "path",
198
+ ts.factory.createCallExpression(
199
+ IdentifierFactory.access(
200
+ ts.factory.createIdentifier(ctx.route.accessor.at(-1)!),
201
+ "path",
202
+ ),
203
+ undefined,
204
+ getArguments(ctx, false),
205
+ ),
206
+ ),
207
+ ts.factory.createPropertyAssignment(
208
+ "status",
209
+ ts.factory.createNull(),
210
+ ),
211
+ ],
212
+ true,
213
+ ),
214
+ ...(ctx.route.body ? [property(ctx.route.body.key)] : []),
215
+ ],
216
+ ),
217
+ );
218
+
219
+ const value: ts.Expression =
220
+ ctx.config.simulate !== true
221
+ ? fetch()
222
+ : ts.factory.createConditionalExpression(
223
+ ts.factory.createStrictEquality(
224
+ ts.factory.createTrue(),
225
+ ts.factory.createIdentifier("connection.simulate"),
226
+ ),
227
+ undefined,
228
+ ts.factory.createCallExpression(
229
+ ts.factory.createIdentifier(
230
+ `${ctx.route.accessor.at(-1)!}.simulate`,
231
+ ),
232
+ [],
233
+ [
234
+ ts.factory.createIdentifier("connection"),
235
+ ...getArguments(ctx, true),
236
+ ],
237
+ ),
238
+ undefined,
239
+ fetch(),
240
+ );
241
+ const headers: Array<IAssignHeader | ISetHeader> = getHeaders(
242
+ ctx.route.comment(),
243
+ );
244
+ if (headers.length === 0) return [ts.factory.createReturnStatement(value)];
245
+ return [
246
+ StatementFactory.constant({
247
+ name: "output",
248
+ type: ts.factory.createTypeReferenceNode(
249
+ `${ctx.route.accessor.at(-1)!}.Response`,
250
+ ),
251
+ value,
252
+ }),
253
+ ts.factory.createExpressionStatement(
254
+ ts.factory.createBinaryExpression(
255
+ ts.factory.createIdentifier("connection.headers"),
256
+ ts.factory.createToken(ts.SyntaxKind.QuestionQuestionEqualsToken),
257
+ ts.factory.createObjectLiteralExpression([]),
258
+ ),
259
+ ),
260
+ ...headers.map((h) =>
261
+ ts.factory.createExpressionStatement(
262
+ h.type === "assign"
263
+ ? ts.factory.createCallExpression(
264
+ ts.factory.createIdentifier("Object.assign"),
265
+ undefined,
266
+ [
267
+ ts.factory.createIdentifier("connection.headers"),
268
+ ts.factory.createIdentifier(`output.${h.accessor}`),
269
+ ],
270
+ )
271
+ : ts.factory.createBinaryExpression(
272
+ ts.factory.createIdentifier(
273
+ `connection.headers${
274
+ NamingConvention.variable(h.property)
275
+ ? `.${h.property}`
276
+ : `[${JSON.stringify(h.property)}]`
277
+ }`,
278
+ ),
279
+ ts.factory.createToken(ts.SyntaxKind.EqualsToken),
280
+ ts.factory.createIdentifier(`output.${h.accessor}`),
281
+ ),
282
+ ),
283
+ ),
284
+ ts.factory.createReturnStatement(ts.factory.createIdentifier("output")),
285
+ ];
286
+ };
287
+
288
+ const getArguments = (ctx: IContext, body: boolean): ts.Expression[] => {
289
+ if (
290
+ ctx.route.parameters.length === 0 &&
291
+ ctx.route.query === null &&
292
+ (body === false || ctx.route.body === null)
293
+ )
294
+ return [];
295
+ else if (ctx.config.keyword === true)
296
+ return [ts.factory.createIdentifier("props")];
297
+ return [
298
+ ...ctx.route.parameters.map((p) => ts.factory.createIdentifier(p.key)),
299
+ ...(ctx.route.query
300
+ ? [ts.factory.createIdentifier(ctx.route.query.key)]
301
+ : []),
302
+ ...(body && ctx.route.body
303
+ ? [ts.factory.createIdentifier(ctx.route.body.key)]
304
+ : []),
305
+ ];
306
+ };
307
+
308
+ const getHeaders = (
309
+ description: string,
310
+ ): Array<IAssignHeader | ISetHeader> => {
311
+ const directives: Array<IAssignHeader | ISetHeader> = [];
312
+ for (const line of description.split("\n").map((l) => l.trim())) {
313
+ if (line.startsWith("@setHeader ")) {
314
+ const parts: string[] = line
315
+ .substring("@setHeader ".length)
316
+ .trim()
317
+ .split(/\s+/);
318
+ if (parts.length >= 2)
319
+ directives.push({
320
+ type: "set",
321
+ accessor: parts[0]!,
322
+ property: parts[1]!,
323
+ });
324
+ } else if (line.startsWith("@assignHeaders ")) {
325
+ const accessor: string = line
326
+ .substring("@assignHeaders ".length)
327
+ .trim();
328
+ if (accessor.length !== 0)
329
+ directives.push({
330
+ type: "assign",
331
+ accessor,
332
+ });
333
+ }
334
+ }
335
+ return directives;
336
+ };
337
+ }
338
+
339
+ interface IAssignHeader {
340
+ type: "assign";
341
+ accessor: string;
342
+ }
343
+ interface ISetHeader {
344
+ type: "set";
345
+ accessor: string;
346
+ property: string;
347
+ }