@autobe/compiler 0.9.2 → 0.10.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 (95) hide show
  1. package/lib/AutoBeCompiler.d.ts +2 -1
  2. package/lib/AutoBeCompiler.js +2 -0
  3. package/lib/AutoBeCompiler.js.map +1 -1
  4. package/lib/AutoBeInterfaceCompiler.js +7 -125
  5. package/lib/AutoBeInterfaceCompiler.js.map +1 -1
  6. package/lib/AutoBePrismaCompiler.d.ts +2 -2
  7. package/lib/AutoBeTestCompiler.d.ts +8 -0
  8. package/lib/AutoBeTestCompiler.js +86 -0
  9. package/lib/AutoBeTestCompiler.js.map +1 -0
  10. package/lib/AutoBeTypeScriptCompiler.d.ts +3 -2
  11. package/lib/AutoBeTypeScriptCompiler.js +7 -3
  12. package/lib/AutoBeTypeScriptCompiler.js.map +1 -1
  13. package/lib/index.d.ts +3 -2
  14. package/lib/index.js +3 -2
  15. package/lib/index.js.map +1 -1
  16. package/lib/interface/transformOpenApi.d.ts +3 -0
  17. package/lib/interface/transformOpenApi.js +56 -0
  18. package/lib/interface/transformOpenApi.js.map +1 -0
  19. package/lib/prisma/validatePrismaApplication.js +9 -9
  20. package/lib/prisma/validatePrismaApplication.js.map +1 -1
  21. package/lib/prisma/writePrismaApplication.js +3 -3
  22. package/lib/prisma/writePrismaApplication.js.map +1 -1
  23. package/lib/raw/AutoBeCompilerTemplate.js +3 -0
  24. package/lib/raw/AutoBeCompilerTemplate.js.map +1 -1
  25. package/lib/raw/{external.json → nestjs.json} +73 -77
  26. package/lib/raw/test.json +1252 -0
  27. package/lib/test/programmers/AutoBeTestAccessorProgrammer.d.ts +8 -0
  28. package/lib/test/programmers/AutoBeTestAccessorProgrammer.js +19 -0
  29. package/lib/test/programmers/AutoBeTestAccessorProgrammer.js.map +1 -0
  30. package/lib/test/programmers/AutoBeTestFunctionalProgrammer.d.ts +12 -0
  31. package/lib/test/programmers/AutoBeTestFunctionalProgrammer.js +29 -0
  32. package/lib/test/programmers/AutoBeTestFunctionalProgrammer.js.map +1 -0
  33. package/lib/test/programmers/AutoBeTestLiteralProgrammer.d.ts +12 -0
  34. package/lib/test/programmers/AutoBeTestLiteralProgrammer.js +24 -0
  35. package/lib/test/programmers/AutoBeTestLiteralProgrammer.js.map +1 -0
  36. package/lib/test/programmers/AutoBeTestOperatorProgrammer.d.ts +10 -0
  37. package/lib/test/programmers/AutoBeTestOperatorProgrammer.js +38 -0
  38. package/lib/test/programmers/AutoBeTestOperatorProgrammer.js.map +1 -0
  39. package/lib/test/programmers/AutoBeTestPredicateProgrammer.d.ts +9 -0
  40. package/lib/test/programmers/AutoBeTestPredicateProgrammer.js +84 -0
  41. package/lib/test/programmers/AutoBeTestPredicateProgrammer.js.map +1 -0
  42. package/lib/test/programmers/AutoBeTestRandomProgrammer.d.ts +14 -0
  43. package/lib/test/programmers/AutoBeTestRandomProgrammer.js +151 -0
  44. package/lib/test/programmers/AutoBeTestRandomProgrammer.js.map +1 -0
  45. package/lib/test/programmers/AutoBeTestStatementProgrammer.d.ts +11 -0
  46. package/lib/test/programmers/AutoBeTestStatementProgrammer.js +81 -0
  47. package/lib/test/programmers/AutoBeTestStatementProgrammer.js.map +1 -0
  48. package/lib/test/programmers/IAutoBeTestApiFunction.d.ts +5 -0
  49. package/lib/test/programmers/IAutoBeTestApiFunction.js +3 -0
  50. package/lib/test/programmers/IAutoBeTestApiFunction.js.map +1 -0
  51. package/lib/test/programmers/IAutoBeTestProgrammerContext.d.ts +9 -0
  52. package/lib/test/programmers/IAutoBeTestProgrammerContext.js +3 -0
  53. package/lib/test/programmers/IAutoBeTestProgrammerContext.js.map +1 -0
  54. package/lib/test/programmers/writeTestExpression.d.ts +4 -0
  55. package/lib/test/programmers/writeTestExpression.js +13 -0
  56. package/lib/test/programmers/writeTestExpression.js.map +1 -0
  57. package/lib/test/programmers/writeTestFunction.d.ts +2 -0
  58. package/lib/test/programmers/writeTestFunction.js +63 -0
  59. package/lib/test/programmers/writeTestFunction.js.map +1 -0
  60. package/lib/test/programmers/writeTestStatement.d.ts +4 -0
  61. package/lib/test/programmers/writeTestStatement.js +10 -0
  62. package/lib/test/programmers/writeTestStatement.js.map +1 -0
  63. package/lib/utils/FilePrinter.d.ts +10 -0
  64. package/lib/utils/FilePrinter.js +54 -0
  65. package/lib/utils/FilePrinter.js.map +1 -0
  66. package/package.json +8 -7
  67. package/src/AutoBeCompiler.ts +4 -0
  68. package/src/AutoBeInterfaceCompiler.ts +8 -133
  69. package/src/AutoBePrismaCompiler.ts +2 -2
  70. package/src/AutoBeTestCompiler.ts +95 -0
  71. package/src/AutoBeTypeScriptCompiler.ts +12 -7
  72. package/src/index.ts +3 -2
  73. package/src/interface/transformOpenApi.ts +54 -0
  74. package/src/prisma/validatePrismaApplication.ts +1 -1
  75. package/src/prisma/writePrismaApplication.ts +1 -1
  76. package/src/raw/AutoBeCompilerTemplate.ts +3 -0
  77. package/src/raw/{external.json → nestjs.json} +73 -77
  78. package/src/raw/test.json +1252 -0
  79. package/src/test/programmers/AutoBeTestAccessorProgrammer.ts +42 -0
  80. package/src/test/programmers/AutoBeTestFunctionalProgrammer.ts +87 -0
  81. package/src/test/programmers/AutoBeTestLiteralProgrammer.ts +65 -0
  82. package/src/test/programmers/AutoBeTestOperatorProgrammer.ts +84 -0
  83. package/src/test/programmers/AutoBeTestPredicateProgrammer.ts +127 -0
  84. package/src/test/programmers/AutoBeTestRandomProgrammer.ts +314 -0
  85. package/src/test/programmers/AutoBeTestStatementProgrammer.ts +154 -0
  86. package/src/test/programmers/IAutoBeTestApiFunction.ts +6 -0
  87. package/src/test/programmers/IAutoBeTestProgrammerContext.ts +11 -0
  88. package/src/test/programmers/writeTestExpression.ts +24 -0
  89. package/src/test/programmers/writeTestFunction.ts +100 -0
  90. package/src/test/programmers/writeTestStatement.ts +15 -0
  91. package/src/utils/FilePrinter.ts +56 -0
  92. package/lib/utils/StringUtil.d.ts +0 -4
  93. package/lib/utils/StringUtil.js +0 -43
  94. package/lib/utils/StringUtil.js.map +0 -1
  95. package/src/utils/StringUtil.ts +0 -45
@@ -0,0 +1,314 @@
1
+ import { AutoBeTest } from "@autobe/interface";
2
+ import ts from "typescript";
3
+ import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
4
+
5
+ import { IAutoBeTestProgrammerContext } from "./IAutoBeTestProgrammerContext";
6
+ import { writeTestExpression } from "./writeTestExpression";
7
+
8
+ export namespace AutoBeTestRandomProgrammer {
9
+ export const pickRandom = (
10
+ ctx: IAutoBeTestProgrammerContext,
11
+ expr: AutoBeTest.IPickRandom,
12
+ ): ts.CallExpression =>
13
+ ts.factory.createCallExpression(
14
+ ts.factory.createPropertyAccessExpression(
15
+ ts.factory.createIdentifier(
16
+ ctx.importer.external({
17
+ type: "instance",
18
+ library: "@nestia/e2e",
19
+ name: "RandomGenerator",
20
+ }),
21
+ ),
22
+ "pick",
23
+ ),
24
+ undefined,
25
+ [writeTestExpression(ctx, expr.array)],
26
+ );
27
+
28
+ export const sampleRandom = (
29
+ ctx: IAutoBeTestProgrammerContext,
30
+ expr: AutoBeTest.ISampleRandom,
31
+ ): ts.CallExpression =>
32
+ ExpressionFactory.currying({
33
+ function: ts.factory.createPropertyAccessExpression(
34
+ ts.factory.createIdentifier(
35
+ ctx.importer.external({
36
+ type: "instance",
37
+ library: "@nestia/e2e",
38
+ name: "RandomGenerator",
39
+ }),
40
+ ),
41
+ "sample",
42
+ ),
43
+ arguments: [
44
+ writeTestExpression(ctx, expr.array),
45
+ writeTestExpression(ctx, expr.count),
46
+ ],
47
+ });
48
+
49
+ export const booleanRandom = (
50
+ _ctx: IAutoBeTestProgrammerContext,
51
+ expr: AutoBeTest.IBooleanRandom,
52
+ ): ts.BinaryExpression =>
53
+ ts.factory.createLessThanEquals(
54
+ ts.factory.createCallExpression(
55
+ ts.factory.createPropertyAccessExpression(
56
+ ts.factory.createIdentifier("Math"),
57
+ "random",
58
+ ),
59
+ undefined,
60
+ undefined,
61
+ ),
62
+ ts.factory.createNumericLiteral(expr.probability ?? 0.5),
63
+ );
64
+
65
+ export const integerRandom = (
66
+ ctx: IAutoBeTestProgrammerContext,
67
+ expr: AutoBeTest.IIntegerRandom,
68
+ ): ts.CallExpression => {
69
+ const intersection: ts.TypeNode[] = [
70
+ ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
71
+ createTypiaTag(ctx, "Type", [
72
+ ts.factory.createLiteralTypeNode(
73
+ ts.factory.createStringLiteral("int32"),
74
+ ),
75
+ ]),
76
+ ];
77
+ if (expr.minimum !== null && expr.minimum !== undefined)
78
+ intersection.push(
79
+ createTypiaTag(ctx, "Minimum", [
80
+ ts.factory.createLiteralTypeNode(
81
+ ts.factory.createNumericLiteral(expr.minimum),
82
+ ),
83
+ ]),
84
+ );
85
+ if (expr.maximum !== null && expr.maximum !== undefined)
86
+ intersection.push(
87
+ createTypiaTag(ctx, "Maximum", [
88
+ ts.factory.createLiteralTypeNode(
89
+ ts.factory.createNumericLiteral(expr.maximum),
90
+ ),
91
+ ]),
92
+ );
93
+ if (expr.multipleOf !== null && expr.multipleOf !== undefined)
94
+ intersection.push(
95
+ createTypiaTag(ctx, "MultipleOf", [
96
+ ts.factory.createLiteralTypeNode(
97
+ ts.factory.createNumericLiteral(expr.multipleOf),
98
+ ),
99
+ ]),
100
+ );
101
+ return createTypiaRandom(ctx, intersection);
102
+ };
103
+
104
+ export const numberRandom = (
105
+ ctx: IAutoBeTestProgrammerContext,
106
+ expr: AutoBeTest.INumberRandom,
107
+ ): ts.CallExpression => {
108
+ const intersection: ts.TypeNode[] = [
109
+ ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
110
+ ];
111
+ if (expr.minimum !== null && expr.minimum !== undefined)
112
+ intersection.push(
113
+ createTypiaTag(ctx, "Minimum", [
114
+ ts.factory.createLiteralTypeNode(
115
+ ts.factory.createNumericLiteral(expr.minimum),
116
+ ),
117
+ ]),
118
+ );
119
+ if (expr.maximum !== null && expr.maximum !== undefined)
120
+ intersection.push(
121
+ createTypiaTag(ctx, "Maximum", [
122
+ ts.factory.createLiteralTypeNode(
123
+ ts.factory.createNumericLiteral(expr.maximum),
124
+ ),
125
+ ]),
126
+ );
127
+ if (expr.multipleOf !== null && expr.multipleOf !== undefined)
128
+ intersection.push(
129
+ createTypiaTag(ctx, "MultipleOf", [
130
+ ts.factory.createLiteralTypeNode(
131
+ ts.factory.createNumericLiteral(expr.multipleOf),
132
+ ),
133
+ ]),
134
+ );
135
+ return createTypiaRandom(ctx, intersection);
136
+ };
137
+
138
+ export const stringRandom = (
139
+ ctx: IAutoBeTestProgrammerContext,
140
+ expr: AutoBeTest.IStringRandom,
141
+ ): ts.CallExpression => {
142
+ const intersection: ts.TypeNode[] = [
143
+ ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
144
+ ];
145
+ if (expr.minLength !== null && expr.minLength !== undefined)
146
+ intersection.push(
147
+ createTypiaTag(ctx, "MinLength", [
148
+ ts.factory.createLiteralTypeNode(
149
+ ts.factory.createNumericLiteral(expr.minLength),
150
+ ),
151
+ ]),
152
+ );
153
+ if (expr.maxLength !== null && expr.maxLength !== undefined)
154
+ intersection.push(
155
+ createTypiaTag(ctx, "MaxLength", [
156
+ ts.factory.createLiteralTypeNode(
157
+ ts.factory.createNumericLiteral(expr.maxLength),
158
+ ),
159
+ ]),
160
+ );
161
+ return createTypiaRandom(ctx, intersection);
162
+ };
163
+
164
+ export const formatRandom = (
165
+ ctx: IAutoBeTestProgrammerContext,
166
+ expr: AutoBeTest.IFormatRandom,
167
+ ): ts.CallExpression =>
168
+ ts.factory.createCallExpression(
169
+ ts.factory.createPropertyAccessExpression(
170
+ ts.factory.createIdentifier(
171
+ ctx.importer.external({
172
+ type: "default",
173
+ library: "typia",
174
+ name: "typia",
175
+ }),
176
+ ),
177
+ "random",
178
+ ),
179
+ [
180
+ ts.factory.createIntersectionTypeNode([
181
+ ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
182
+ ts.factory.createTypeReferenceNode(
183
+ ts.factory.createQualifiedName(
184
+ ts.factory.createIdentifier(
185
+ ctx.importer.external({
186
+ type: "instance",
187
+ library: "typia",
188
+ name: "tags",
189
+ }),
190
+ ),
191
+ ts.factory.createIdentifier("Format"),
192
+ ),
193
+ [
194
+ ts.factory.createLiteralTypeNode(
195
+ ts.factory.createStringLiteral(expr.format),
196
+ ),
197
+ ],
198
+ ),
199
+ ]),
200
+ ],
201
+ [],
202
+ );
203
+
204
+ export const patternRandom = (
205
+ ctx: IAutoBeTestProgrammerContext,
206
+ expr: AutoBeTest.IPatternRandom,
207
+ ): ts.CallExpression =>
208
+ ts.factory.createCallExpression(
209
+ ts.factory.createPropertyAccessExpression(
210
+ ts.factory.createIdentifier(
211
+ ctx.importer.external({
212
+ type: "default",
213
+ library: "typia",
214
+ name: "typia",
215
+ }),
216
+ ),
217
+ "random",
218
+ ),
219
+ [
220
+ ts.factory.createIntersectionTypeNode([
221
+ ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
222
+ ts.factory.createTypeReferenceNode(
223
+ ts.factory.createQualifiedName(
224
+ ts.factory.createIdentifier(
225
+ ctx.importer.external({
226
+ type: "instance",
227
+ library: "typia",
228
+ name: "tags",
229
+ }),
230
+ ),
231
+ ts.factory.createIdentifier("Pattern"),
232
+ ),
233
+ [
234
+ ts.factory.createLiteralTypeNode(
235
+ ts.factory.createStringLiteral(expr.pattern),
236
+ ),
237
+ ],
238
+ ),
239
+ ]),
240
+ ],
241
+ [],
242
+ );
243
+
244
+ export const keywordRandom = (
245
+ ctx: IAutoBeTestProgrammerContext,
246
+ expr: AutoBeTest.IKeywordRandom,
247
+ ): ts.Expression => {
248
+ let value: ts.Expression = ts.factory.createPropertyAccessExpression(
249
+ ts.factory.createIdentifier(
250
+ ctx.importer.external({
251
+ type: "instance",
252
+ library: "@nestia/e2e",
253
+ name: "RandomGenerator",
254
+ }),
255
+ ),
256
+ expr.keyword,
257
+ );
258
+ new Array(KEYWORD_CURRYING_COUNT[expr.keyword]).fill(0).forEach(() => {
259
+ value = ts.factory.createCallExpression(value, undefined, undefined);
260
+ });
261
+ return value;
262
+ };
263
+ }
264
+
265
+ const createTypiaTag = (
266
+ ctx: IAutoBeTestProgrammerContext,
267
+ name: string,
268
+ typeArguments: ts.TypeNode[],
269
+ ) =>
270
+ ts.factory.createTypeReferenceNode(
271
+ ts.factory.createQualifiedName(
272
+ ts.factory.createIdentifier(
273
+ ctx.importer.external({
274
+ type: "instance",
275
+ library: "typia",
276
+ name: "tags",
277
+ }),
278
+ ),
279
+ ts.factory.createIdentifier(name),
280
+ ),
281
+ typeArguments,
282
+ );
283
+
284
+ const createTypiaRandom = (
285
+ ctx: IAutoBeTestProgrammerContext,
286
+ typeArguments: ts.TypeNode[] = [],
287
+ ) =>
288
+ ts.factory.createCallExpression(
289
+ ts.factory.createPropertyAccessExpression(
290
+ ts.factory.createIdentifier(
291
+ ctx.importer.external({
292
+ type: "default",
293
+ library: "typia",
294
+ name: "typia",
295
+ }),
296
+ ),
297
+ "random",
298
+ ),
299
+ typeArguments.length === 0
300
+ ? undefined
301
+ : typeArguments.length === 1
302
+ ? typeArguments
303
+ : [ts.factory.createIntersectionTypeNode(typeArguments)],
304
+ undefined,
305
+ );
306
+
307
+ const KEYWORD_CURRYING_COUNT = {
308
+ alphabets: 1,
309
+ alphaNumeric: 1,
310
+ mobile: 1,
311
+ name: 1,
312
+ paragraph: 2,
313
+ content: 3,
314
+ };
@@ -0,0 +1,154 @@
1
+ import { AutoBeTest } from "@autobe/interface";
2
+ import ts from "typescript";
3
+
4
+ import { FilePrinter } from "../../utils/FilePrinter";
5
+ import { IAutoBeTestApiFunction } from "./IAutoBeTestApiFunction";
6
+ import { IAutoBeTestProgrammerContext } from "./IAutoBeTestProgrammerContext";
7
+ import { writeTestExpression } from "./writeTestExpression";
8
+ import { writeTestStatement } from "./writeTestStatement";
9
+
10
+ export namespace AutoBeTestStatementProgrammer {
11
+ export const block = (
12
+ ctx: IAutoBeTestProgrammerContext,
13
+ stmt: AutoBeTest.IBlock,
14
+ ): ts.Block =>
15
+ ts.factory.createBlock(
16
+ stmt.statements
17
+ .map((child, i) => [
18
+ ...writeTestStatement(ctx, child).filter((childStmt, j) =>
19
+ j === 0
20
+ ? ts.addSyntheticLeadingComment(
21
+ childStmt,
22
+ ts.SyntaxKind.SingleLineCommentTrivia,
23
+ JSON.stringify(child),
24
+ true,
25
+ )
26
+ : childStmt,
27
+ ),
28
+ ...(i !== 0 ? [FilePrinter.newLine()] : []),
29
+ ])
30
+ .flat(),
31
+ true,
32
+ );
33
+
34
+ export const expressionStatement = (
35
+ ctx: IAutoBeTestProgrammerContext,
36
+ stmt: AutoBeTest.IExpressionStatement,
37
+ ): ts.ExpressionStatement =>
38
+ ts.factory.createExpressionStatement(
39
+ writeTestExpression(ctx, stmt.expression),
40
+ );
41
+
42
+ // export const variableDeclaration = (
43
+ // ctx: IAutoBeTestProgrammerContext,
44
+ // stmt: AutoBeTest.IVariableDeclaration,
45
+ // ): ts.VariableStatement => {
46
+ // const typeNode: ts.TypeNode = NestiaMigrateSchemaProgrammer.write({
47
+ // components: ctx.document.components,
48
+ // importer: ctx.importer,
49
+ // schema: OpenApiV3_1Emender.convertSchema(ctx.document.components)(
50
+ // stmt.schema,
51
+ // ),
52
+ // });
53
+ // return ts.factory.createVariableStatement(
54
+ // undefined,
55
+ // ts.factory.createVariableDeclarationList(
56
+ // [
57
+ // ts.factory.createVariableDeclaration(
58
+ // stmt.name,
59
+ // undefined,
60
+ // typeNode,
61
+ // undefined,
62
+ // ),
63
+ // ],
64
+ // stmt.mutability === "const" ? ts.NodeFlags.Constant : ts.NodeFlags.Let,
65
+ // ),
66
+ // );
67
+ // };
68
+
69
+ export const ifStatement = (
70
+ ctx: IAutoBeTestProgrammerContext,
71
+ stmt: AutoBeTest.IIfStatement,
72
+ ): ts.IfStatement =>
73
+ ts.factory.createIfStatement(
74
+ writeTestExpression(ctx, stmt.condition),
75
+ block(ctx, stmt.thenStatement),
76
+ stmt.elseStatement
77
+ ? stmt.elseStatement.type === "ifStatement"
78
+ ? ifStatement(ctx, stmt.elseStatement)
79
+ : block(ctx, stmt.elseStatement)
80
+ : undefined,
81
+ );
82
+
83
+ export const returnStatement = (
84
+ ctx: IAutoBeTestProgrammerContext,
85
+ stmt: AutoBeTest.IReturnStatement,
86
+ ): ts.ReturnStatement =>
87
+ ts.factory.createReturnStatement(writeTestExpression(ctx, stmt.expression));
88
+
89
+ export const throwStatement = (
90
+ ctx: IAutoBeTestProgrammerContext,
91
+ stmt: AutoBeTest.IThrowStatement,
92
+ ): ts.ThrowStatement =>
93
+ ts.factory.createThrowStatement(writeTestExpression(ctx, stmt.expression));
94
+
95
+ export const apiOperateStatement = (
96
+ ctx: IAutoBeTestProgrammerContext,
97
+ stmt: AutoBeTest.IApiOperateStatement,
98
+ ): ts.Statement[] => {
99
+ // find the function
100
+ const func: IAutoBeTestApiFunction = ctx.endpoints.get(stmt.endpoint);
101
+ if (!!stmt.variableName?.length && !!func.operation.responseBody)
102
+ ctx.importer.dto(func.operation.responseBody.typeName);
103
+
104
+ // make await function call expression
105
+ const initializer: ts.AwaitExpression = ts.factory.createAwaitExpression(
106
+ ts.factory.createCallExpression(
107
+ ts.factory.createIdentifier(func.accessor),
108
+ [],
109
+ [
110
+ ts.factory.createIdentifier("connection"),
111
+ ...(stmt.argument ? [writeTestExpression(ctx, stmt.argument)] : []),
112
+ ],
113
+ ),
114
+ );
115
+ if (stmt.variableName === null || stmt.variableName === undefined)
116
+ return [ts.factory.createExpressionStatement(initializer)];
117
+
118
+ const variable: ts.VariableStatement = ts.factory.createVariableStatement(
119
+ undefined,
120
+ ts.factory.createVariableDeclarationList(
121
+ [
122
+ ts.factory.createVariableDeclaration(
123
+ stmt.variableName,
124
+ undefined,
125
+ !!func.operation.responseBody
126
+ ? ts.factory.createTypeReferenceNode(
127
+ func.operation.responseBody.typeName,
128
+ )
129
+ : ts.factory.createKeywordTypeNode(
130
+ ts.SyntaxKind.UndefinedKeyword,
131
+ ),
132
+ initializer,
133
+ ),
134
+ ],
135
+ ts.NodeFlags.Const,
136
+ ),
137
+ );
138
+ const assertion = ts.factory.createCallExpression(
139
+ ts.factory.createPropertyAccessExpression(
140
+ ts.factory.createIdentifier(
141
+ ctx.importer.external({
142
+ type: "default",
143
+ library: "typia",
144
+ name: "typia",
145
+ }),
146
+ ),
147
+ "assert",
148
+ ),
149
+ undefined,
150
+ [ts.factory.createIdentifier(stmt.variableName)],
151
+ );
152
+ return [variable, ts.factory.createExpressionStatement(assertion)];
153
+ };
154
+ }
@@ -0,0 +1,6 @@
1
+ import { AutoBeOpenApi } from "@autobe/interface";
2
+
3
+ export interface IAutoBeTestApiFunction {
4
+ operation: AutoBeOpenApi.IOperation;
5
+ accessor: string;
6
+ }
@@ -0,0 +1,11 @@
1
+ import { AutoBeOpenApi } from "@autobe/interface";
2
+ import { NestiaMigrateImportProgrammer } from "@nestia/migrate/lib/programmers/NestiaMigrateImportProgrammer";
3
+ import { HashMap } from "tstl";
4
+
5
+ import { IAutoBeTestApiFunction } from "./IAutoBeTestApiFunction";
6
+
7
+ export interface IAutoBeTestProgrammerContext {
8
+ importer: NestiaMigrateImportProgrammer;
9
+ document: AutoBeOpenApi.IDocument;
10
+ endpoints: HashMap<AutoBeOpenApi.IEndpoint, IAutoBeTestApiFunction>;
11
+ }
@@ -0,0 +1,24 @@
1
+ import { AutoBeTest } from "@autobe/interface";
2
+ import ts from "typescript";
3
+
4
+ import { AutoBeTestAccessorProgrammer } from "./AutoBeTestAccessorProgrammer";
5
+ import { AutoBeTestFunctionalProgrammer } from "./AutoBeTestFunctionalProgrammer";
6
+ import { AutoBeTestLiteralProgrammer } from "./AutoBeTestLiteralProgrammer";
7
+ import { AutoBeTestOperatorProgrammer } from "./AutoBeTestOperatorProgrammer";
8
+ import { AutoBeTestPredicateProgrammer } from "./AutoBeTestPredicateProgrammer";
9
+ import { AutoBeTestRandomProgrammer } from "./AutoBeTestRandomProgrammer";
10
+ import { IAutoBeTestProgrammerContext } from "./IAutoBeTestProgrammerContext";
11
+
12
+ export const writeTestExpression = (
13
+ ctx: IAutoBeTestProgrammerContext,
14
+ expr: AutoBeTest.IExpression,
15
+ ): ts.Expression => factory[expr.type](ctx, expr as any);
16
+
17
+ const factory = {
18
+ ...AutoBeTestLiteralProgrammer,
19
+ ...AutoBeTestOperatorProgrammer,
20
+ ...AutoBeTestAccessorProgrammer,
21
+ ...AutoBeTestFunctionalProgrammer,
22
+ ...AutoBeTestRandomProgrammer,
23
+ ...AutoBeTestPredicateProgrammer,
24
+ };
@@ -0,0 +1,100 @@
1
+ import { AutoBeOpenApi, IAutoBeTestWriteProps } from "@autobe/interface";
2
+ import { AutoBeEndpointComparator } from "@autobe/utils";
3
+ import { NestiaMigrateImportProgrammer } from "@nestia/migrate/lib/programmers/NestiaMigrateImportProgrammer";
4
+ import { HttpMigration, IHttpMigrateApplication } from "@samchon/openapi";
5
+ import { HashMap, Pair } from "tstl";
6
+ import ts, { FunctionDeclaration } from "typescript";
7
+
8
+ import { transformOpenApiDocument } from "../../interface/transformOpenApi";
9
+ import { FilePrinter } from "../../utils/FilePrinter";
10
+ import { AutoBeTestStatementProgrammer } from "./AutoBeTestStatementProgrammer";
11
+ import { IAutoBeTestApiFunction } from "./IAutoBeTestApiFunction";
12
+ import { IAutoBeTestProgrammerContext } from "./IAutoBeTestProgrammerContext";
13
+
14
+ export function writeTestFunction(props: IAutoBeTestWriteProps): string {
15
+ const ctx: IAutoBeTestProgrammerContext = {
16
+ importer: new NestiaMigrateImportProgrammer(),
17
+ document: props.document,
18
+ endpoints: associate(props.document),
19
+ };
20
+ const decla: FunctionDeclaration = ts.factory.createFunctionDeclaration(
21
+ [
22
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
23
+ ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword),
24
+ ],
25
+ undefined,
26
+ props.scenario.functionName,
27
+ undefined,
28
+ [
29
+ ts.factory.createParameterDeclaration(
30
+ undefined,
31
+ undefined,
32
+ "connection",
33
+ undefined,
34
+ ts.factory.createTypeReferenceNode(
35
+ `${ctx.importer.external({
36
+ type: "default",
37
+ name: "api",
38
+ library: `@ORGANIZATION/PROJECT-api`,
39
+ })}.IConnection`,
40
+ ),
41
+ ),
42
+ ],
43
+ undefined,
44
+ AutoBeTestStatementProgrammer.block(ctx, {
45
+ type: "block",
46
+ statements: props.function.statements,
47
+ }),
48
+ );
49
+ return FilePrinter.write({
50
+ statements: [
51
+ ...ctx.importer.toStatements(
52
+ (key) => `@ORGANIZATION/PROJECT-api/lib/structures/${key}`,
53
+ ),
54
+ FilePrinter.newLine(),
55
+ FilePrinter.description(decla, props.scenario.draft),
56
+ ],
57
+ });
58
+ }
59
+
60
+ function associate(
61
+ document: AutoBeOpenApi.IDocument,
62
+ ): HashMap<AutoBeOpenApi.IEndpoint, IAutoBeTestApiFunction> {
63
+ // associate operations and functions
64
+ const operations: HashMap<AutoBeOpenApi.IEndpoint, AutoBeOpenApi.IOperation> =
65
+ new HashMap(
66
+ document.operations.map(
67
+ (o) =>
68
+ new Pair(
69
+ {
70
+ method: o.method,
71
+ path: o.path,
72
+ },
73
+ o,
74
+ ),
75
+ ),
76
+ AutoBeEndpointComparator.hashCode,
77
+ AutoBeEndpointComparator.equals,
78
+ );
79
+ const functions: HashMap<AutoBeOpenApi.IEndpoint, IAutoBeTestApiFunction> =
80
+ new HashMap(
81
+ AutoBeEndpointComparator.hashCode,
82
+ AutoBeEndpointComparator.equals,
83
+ );
84
+
85
+ // from migrate application
86
+ const migrate: IHttpMigrateApplication = HttpMigration.application(
87
+ transformOpenApiDocument(document),
88
+ );
89
+ for (const route of migrate.routes) {
90
+ const endpoint: AutoBeOpenApi.IEndpoint = {
91
+ path: route.path,
92
+ method: route.method as "get",
93
+ };
94
+ functions.emplace(endpoint, {
95
+ accessor: "api.functional." + route.accessor.join("."),
96
+ operation: operations.get(endpoint),
97
+ });
98
+ }
99
+ return functions;
100
+ }
@@ -0,0 +1,15 @@
1
+ import { AutoBeTest } from "@autobe/interface";
2
+ import ts from "typescript";
3
+
4
+ import { AutoBeTestStatementProgrammer } from "./AutoBeTestStatementProgrammer";
5
+ import { IAutoBeTestProgrammerContext } from "./IAutoBeTestProgrammerContext";
6
+
7
+ export const writeTestStatement = (
8
+ ctx: IAutoBeTestProgrammerContext,
9
+ stmt: AutoBeTest.IStatement,
10
+ ): ts.Statement[] => {
11
+ const next: ts.Statement | ts.Statement[] = AutoBeTestStatementProgrammer[
12
+ stmt.type
13
+ ](ctx, stmt as any);
14
+ return Array.isArray(next) ? next : [next];
15
+ };
@@ -0,0 +1,56 @@
1
+ import sortImport from "@trivago/prettier-plugin-sort-imports";
2
+ import import2 from "import2";
3
+ import { format } from "prettier";
4
+ import ts from "typescript";
5
+
6
+ export namespace FilePrinter {
7
+ export const description = <Node extends ts.Node>(
8
+ node: Node,
9
+ comment: string,
10
+ ): Node => {
11
+ if (comment.length === 0) return node;
12
+ ts.addSyntheticLeadingComment(
13
+ node,
14
+ ts.SyntaxKind.MultiLineCommentTrivia,
15
+ ["*", ...comment.split("\n").map((str) => ` * ${str}`), ""].join("\n"),
16
+ true,
17
+ );
18
+ return node;
19
+ };
20
+
21
+ export const newLine = () =>
22
+ ts.factory.createExpressionStatement(ts.factory.createIdentifier("\n"));
23
+
24
+ export const write = (props: {
25
+ statements: ts.Statement[];
26
+ top?: string;
27
+ }): string => {
28
+ const script: string = ts
29
+ .createPrinter({
30
+ newLine: ts.NewLineKind.LineFeed,
31
+ })
32
+ .printFile(
33
+ ts.factory.createSourceFile(
34
+ props.statements,
35
+ ts.factory.createToken(ts.SyntaxKind.EndOfFileToken),
36
+ ts.NodeFlags.None,
37
+ ),
38
+ );
39
+ return (props.top ?? "") + script;
40
+ };
41
+
42
+ export const beautify = async (script: string): Promise<string> => {
43
+ try {
44
+ return await format(script, {
45
+ parser: "typescript",
46
+ plugins: [sortImport, await import2("prettier-plugin-jsdoc")],
47
+ importOrder: ["<THIRD_PARTY_MODULES>", "^[./]"],
48
+ importOrderSeparation: true,
49
+ importOrderSortSpecifiers: true,
50
+ importOrderParserPlugins: ["decorators-legacy", "typescript", "jsx"],
51
+ });
52
+ } catch {
53
+ return script;
54
+ }
55
+ };
56
+ }
@@ -1,4 +0,0 @@
1
- export declare namespace StringUtil {
2
- function trim(strings: TemplateStringsArray, ...values: any[]): string;
3
- function singleLine(strings: TemplateStringsArray, ...values: any[]): string;
4
- }