@autobe/compiler 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) 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 +10 -127
  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 +2 -2
  11. package/lib/AutoBeTypeScriptCompiler.js +3 -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.d.ts +1 -0
  24. package/lib/raw/AutoBeCompilerTemplate.js +10 -0
  25. package/lib/raw/AutoBeCompilerTemplate.js.map +1 -0
  26. package/lib/raw/{external.json → nestjs.json} +67 -67
  27. package/lib/raw/test.json +1252 -0
  28. package/lib/test/programmers/AutoBeTestAccessorProgrammer.d.ts +8 -0
  29. package/lib/test/programmers/AutoBeTestAccessorProgrammer.js +19 -0
  30. package/lib/test/programmers/AutoBeTestAccessorProgrammer.js.map +1 -0
  31. package/lib/test/programmers/AutoBeTestFunctionalProgrammer.d.ts +12 -0
  32. package/lib/test/programmers/AutoBeTestFunctionalProgrammer.js +29 -0
  33. package/lib/test/programmers/AutoBeTestFunctionalProgrammer.js.map +1 -0
  34. package/lib/test/programmers/AutoBeTestLiteralProgrammer.d.ts +12 -0
  35. package/lib/test/programmers/AutoBeTestLiteralProgrammer.js +24 -0
  36. package/lib/test/programmers/AutoBeTestLiteralProgrammer.js.map +1 -0
  37. package/lib/test/programmers/AutoBeTestOperatorProgrammer.d.ts +10 -0
  38. package/lib/test/programmers/AutoBeTestOperatorProgrammer.js +38 -0
  39. package/lib/test/programmers/AutoBeTestOperatorProgrammer.js.map +1 -0
  40. package/lib/test/programmers/AutoBeTestPredicateProgrammer.d.ts +9 -0
  41. package/lib/test/programmers/AutoBeTestPredicateProgrammer.js +84 -0
  42. package/lib/test/programmers/AutoBeTestPredicateProgrammer.js.map +1 -0
  43. package/lib/test/programmers/AutoBeTestRandomProgrammer.d.ts +14 -0
  44. package/lib/test/programmers/AutoBeTestRandomProgrammer.js +151 -0
  45. package/lib/test/programmers/AutoBeTestRandomProgrammer.js.map +1 -0
  46. package/lib/test/programmers/AutoBeTestStatementProgrammer.d.ts +11 -0
  47. package/lib/test/programmers/AutoBeTestStatementProgrammer.js +81 -0
  48. package/lib/test/programmers/AutoBeTestStatementProgrammer.js.map +1 -0
  49. package/lib/test/programmers/IAutoBeTestApiFunction.d.ts +5 -0
  50. package/lib/{raw/AutoBeCompilerConstants.js → test/programmers/IAutoBeTestApiFunction.js} +1 -1
  51. package/lib/test/programmers/IAutoBeTestApiFunction.js.map +1 -0
  52. package/lib/test/programmers/IAutoBeTestProgrammerContext.d.ts +9 -0
  53. package/lib/test/programmers/IAutoBeTestProgrammerContext.js +3 -0
  54. package/lib/test/programmers/IAutoBeTestProgrammerContext.js.map +1 -0
  55. package/lib/test/programmers/writeTestExpression.d.ts +4 -0
  56. package/lib/test/programmers/writeTestExpression.js +13 -0
  57. package/lib/test/programmers/writeTestExpression.js.map +1 -0
  58. package/lib/test/programmers/writeTestFunction.d.ts +2 -0
  59. package/lib/test/programmers/writeTestFunction.js +63 -0
  60. package/lib/test/programmers/writeTestFunction.js.map +1 -0
  61. package/lib/test/programmers/writeTestStatement.d.ts +4 -0
  62. package/lib/test/programmers/writeTestStatement.js +10 -0
  63. package/lib/test/programmers/writeTestStatement.js.map +1 -0
  64. package/lib/utils/FilePrinter.d.ts +10 -0
  65. package/lib/utils/FilePrinter.js +54 -0
  66. package/lib/utils/FilePrinter.js.map +1 -0
  67. package/package.json +10 -8
  68. package/src/AutoBeCompiler.ts +4 -0
  69. package/src/AutoBeInterfaceCompiler.ts +10 -135
  70. package/src/AutoBePrismaCompiler.ts +2 -2
  71. package/src/AutoBeTestCompiler.ts +95 -0
  72. package/src/AutoBeTypeScriptCompiler.ts +7 -7
  73. package/src/index.ts +3 -2
  74. package/src/interface/transformOpenApi.ts +54 -0
  75. package/src/prisma/validatePrismaApplication.ts +1 -1
  76. package/src/prisma/writePrismaApplication.ts +1 -1
  77. package/src/raw/AutoBeCompilerTemplate.ts +6 -0
  78. package/src/raw/{external.json → nestjs.json} +67 -67
  79. package/src/raw/test.json +1252 -0
  80. package/src/test/programmers/AutoBeTestAccessorProgrammer.ts +42 -0
  81. package/src/test/programmers/AutoBeTestFunctionalProgrammer.ts +87 -0
  82. package/src/test/programmers/AutoBeTestLiteralProgrammer.ts +65 -0
  83. package/src/test/programmers/AutoBeTestOperatorProgrammer.ts +84 -0
  84. package/src/test/programmers/AutoBeTestPredicateProgrammer.ts +127 -0
  85. package/src/test/programmers/AutoBeTestRandomProgrammer.ts +314 -0
  86. package/src/test/programmers/AutoBeTestStatementProgrammer.ts +154 -0
  87. package/src/test/programmers/IAutoBeTestApiFunction.ts +6 -0
  88. package/src/test/programmers/IAutoBeTestProgrammerContext.ts +11 -0
  89. package/src/test/programmers/writeTestExpression.ts +24 -0
  90. package/src/test/programmers/writeTestFunction.ts +100 -0
  91. package/src/test/programmers/writeTestStatement.ts +15 -0
  92. package/src/utils/FilePrinter.ts +56 -0
  93. package/lib/raw/AutoBeCompilerConstants.d.ts +0 -3
  94. package/lib/raw/AutoBeCompilerConstants.js.map +0 -1
  95. package/lib/utils/StringUtil.d.ts +0 -4
  96. package/lib/utils/StringUtil.js +0 -43
  97. package/lib/utils/StringUtil.js.map +0 -1
  98. package/src/raw/AutoBeCompilerConstants.ts +0 -3
  99. 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,3 +0,0 @@
1
- export declare const enum AutoBeCompilerConstants {
2
- README = "# AutoBE Generated Backend Server\n\n![AutoBE Logo](https://github.com/user-attachments/assets/a90d14be-fd50-4dc7-ae9d-ca66c2124f31)\n\nA backend repository generated by [`@autobe`](https://github.com/wrtnlabs/autobe).\n\nThis backend program was automatically generated using [`@autobe`](https://github.com/wrtnlabs/autobe), the AI vibe coding agent for backend servers of below stack.\n\n- TypeScript\n- NestJS / Nestia\n- Prisma\n- Postgres\n\n## Project Structure\n\nThis template project has categorized directories like below.\n\nAt first, [`@autobe`](https://github.com/wrtnlabs/autobe) generated files are placed like below:\n\n- analysis agent: [docs/analysis](docs/analysis)\n- prisma agent\n - [prisma/schema](prisma/schema)\n - [docs/ERD.md](docs/ERD.md)\n- interface agent\n - [src/api/structures](src/api/structures): DTO structures\n - [src/api/controllers](src/controllers): API controller classes\n - [test/features](test/features): List of e2e test functions\n\nFrom a source code perspective, all backend files are organized within the `src` directory.\n\nWhen you build the TypeScript source files, compiled files will be placed in the `lib` directory according to the [tsconfig.json](tsconfig.json) configuration.\n\nOtherwise you build client [SDK](https://nestia.io/docs/sdk) library for npm publishing and their compiled files would be placed into the [packages/api](packages/api) directory.\n\n - [packages/api](packages/api): SDK module built by `npm run build:api`\n - [src](src): Backend source directory\n - [src/api](src/api): Client SDK that would be published to the `@ORGANIZATION/PROJECT-api`\n - [src/api/functional](src/api/functional): API functions generated by the [`nestia`](https://github.com/samchon/nestia)\n - [src/api/structures](src/api/structures): DTO structures\n - [src/controllers](src/controllers): Controller classes of the Main Program\n - [**test/**](test): Test Automation Program\n - [test/features](test/features): List of test functions\n - [nestia.config.ts](nestia.config.ts): Configuration file of [`nestia`](https://github.com/samchon/nestia)\n - [package.json](package.json): NPM configuration\n - [tsconfig.json](tsconfig.json): TypeScript configuration for the main program\n\n## NPM Run Commands\n\nList of the run commands defined in the [package.json](package.json) are like below:\n\n - Test\n - **`test`**: Run test automation program\n - `benchmark`: Run performance benchmark program\n - Build\n - `build`: Build everything\n - `build:main`: Build main program (`src` directory)\n - `build:test` Build test automation program (`test` directory)\n - `build:sdk`: Build SDK into main program only\n - `build:swagger`: Build Swagger Documents\n - **`dev`**: Incremental build for development (test program)\n - Deploy\n - `package:api`: Build and deploy the SDK library to the NPM\n - `start`: Start the backend server\n - `start:dev`: Start the backend server with incremental build and reload\n - Webpack\n - `webpack`: Run webpack bundler\n - `webpack:start`: Start the backend server built by webpack\n - `webpack:test`: Run test program to the webpack built\n\n## Specialization\n\nTransform this template project to be yours.\n\nWhen you've created a new backend project through this template project, you can specialize it to be suitable for you by changing some words. Replace below words through IDE specific function like `Edit > Replace in Files` (*Ctrl + Shift + H*), who've been supported by the VSCode.\n\n| Before | After\n|--------------|----------------------------------------\n| ORGANIZATION | Your account or corporation name\n| PROJECT | Your own project name\n| AUTHOR | Author name\n| https://github.com/samchon/nestia-start | Your repository URL"
3
- }