@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.
- package/LICENSE +21 -21
- package/README.md +93 -93
- package/lib/NestiaMigrateApplication.js +341 -341
- package/lib/bundles/NEST_TEMPLATE.js +48 -48
- package/lib/bundles/NEST_TEMPLATE.js.map +1 -1
- package/lib/bundles/SDK_TEMPLATE.js +21 -21
- package/lib/bundles/SDK_TEMPLATE.js.map +1 -1
- package/lib/executable/migrate.js +0 -0
- package/lib/index.mjs +469 -469
- package/lib/index.mjs.map +1 -1
- package/package.json +10 -8
- package/src/NestiaMigrateApplication.ts +168 -168
- package/src/analyzers/NestiaMigrateControllerAnalyzer.ts +51 -51
- package/src/bundles/NEST_TEMPLATE.ts +48 -48
- package/src/bundles/SDK_TEMPLATE.ts +21 -21
- package/src/executable/NestiaMigrateCommander.ts +104 -104
- package/src/executable/NestiaMigrateInquirer.ts +106 -106
- package/src/executable/bundle.js +129 -125
- package/src/executable/migrate.ts +0 -0
- package/src/factories/TypeLiteralFactory.ts +57 -57
- package/src/module.ts +7 -7
- package/src/programmers/NestiaMigrateApiFileProgrammer.ts +55 -55
- package/src/programmers/NestiaMigrateApiFunctionProgrammer.ts +347 -347
- package/src/programmers/NestiaMigrateApiNamespaceProgrammer.ts +517 -517
- package/src/programmers/NestiaMigrateApiSimulationProgrammer.ts +308 -308
- package/src/programmers/NestiaMigrateApiStartProgrammer.ts +197 -197
- package/src/programmers/NestiaMigrateDtoProgrammer.ts +98 -98
- package/src/programmers/NestiaMigrateE2eFileProgrammer.ts +153 -153
- package/src/programmers/NestiaMigrateE2eProgrammer.ts +48 -48
- package/src/programmers/NestiaMigrateImportProgrammer.ts +118 -118
- package/src/programmers/NestiaMigrateNestControllerProgrammer.ts +69 -69
- package/src/programmers/NestiaMigrateNestMethodProgrammer.ts +409 -409
- package/src/programmers/NestiaMigrateSchemaProgrammer.ts +465 -465
- package/src/programmers/index.ts +15 -15
- package/src/structures/INestiaMigrateContext.ts +9 -9
- package/src/structures/INestiaMigrateController.ts +8 -8
- package/src/structures/INestiaMigrateDto.ts +8 -8
- package/src/structures/INestiaMigrateProgram.ts +11 -11
- package/src/structures/index.ts +4 -4
- package/src/utils/FilePrinter.ts +49 -49
- package/src/utils/StringUtil.ts +114 -114
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
import * as prettierPluginSortImport from "@trivago/prettier-plugin-sort-imports";
|
|
2
|
-
import {
|
|
3
|
-
OpenApiV3,
|
|
4
|
-
OpenApiV3_1,
|
|
5
|
-
OpenApiV3_2,
|
|
6
|
-
SwaggerV2,
|
|
7
|
-
} from "@typia/interface";
|
|
8
|
-
import fs from "fs";
|
|
9
|
-
import path from "path";
|
|
10
|
-
import { format } from "prettier";
|
|
11
|
-
import * as prettierPluginJsDoc from "prettier-plugin-jsdoc";
|
|
12
|
-
import typia, { IValidation, tags } from "typia";
|
|
13
|
-
|
|
14
|
-
import { NestiaMigrateApplication } from "../NestiaMigrateApplication";
|
|
15
|
-
import { NestiaMigrateFileArchiver } from "../archivers/NestiaMigrateFileArchiver";
|
|
16
|
-
import { NestiaMigrateInquirer } from "./NestiaMigrateInquirer";
|
|
17
|
-
|
|
18
|
-
export namespace NestiaMigrateCommander {
|
|
19
|
-
export const main = async (): Promise<void> => {
|
|
20
|
-
const resolve = (str: string | undefined) =>
|
|
21
|
-
str ? path.resolve(str).split("\\").join("/") : undefined;
|
|
22
|
-
const options: NestiaMigrateInquirer.IOutput =
|
|
23
|
-
await NestiaMigrateInquirer.parse();
|
|
24
|
-
|
|
25
|
-
// VALIDATE OUTPUT DIRECTORY
|
|
26
|
-
const parent: string = resolve(options.output + "/..")!;
|
|
27
|
-
if (fs.existsSync(options.output))
|
|
28
|
-
halt("Response directory already exists.");
|
|
29
|
-
else if (fs.existsSync(parent) === false)
|
|
30
|
-
halt("Response directory's parent directory does not exist.");
|
|
31
|
-
else if (fs.statSync(parent).isDirectory() === false)
|
|
32
|
-
halt("Response directory's parent is not a directory.");
|
|
33
|
-
|
|
34
|
-
// READ SWAGGER
|
|
35
|
-
const document:
|
|
36
|
-
| SwaggerV2.IDocument
|
|
37
|
-
| OpenApiV3.IDocument
|
|
38
|
-
| OpenApiV3_1.IDocument
|
|
39
|
-
| OpenApiV3_2.IDocument = await (async () => {
|
|
40
|
-
if (typia.is<string & tags.Format<"uri">>(options.input)) {
|
|
41
|
-
const response: Response = await fetch(options.input);
|
|
42
|
-
const content: string = await response.text();
|
|
43
|
-
return JSON.parse(content);
|
|
44
|
-
}
|
|
45
|
-
if (fs.existsSync(options.input) === false)
|
|
46
|
-
halt("Unable to find the input swagger.json file.");
|
|
47
|
-
const stats: fs.Stats = fs.statSync(options.input);
|
|
48
|
-
if (stats.isFile() === false)
|
|
49
|
-
halt("The input swagger.json is not a file.");
|
|
50
|
-
const content: string = await fs.promises.readFile(
|
|
51
|
-
options.input,
|
|
52
|
-
"utf-8",
|
|
53
|
-
);
|
|
54
|
-
return JSON.parse(content);
|
|
55
|
-
})();
|
|
56
|
-
|
|
57
|
-
const result: IValidation<NestiaMigrateApplication> =
|
|
58
|
-
NestiaMigrateApplication.validate(document);
|
|
59
|
-
if (result.success === false) {
|
|
60
|
-
console.log(result.errors);
|
|
61
|
-
throw new Error(
|
|
62
|
-
`Invalid swagger file (must follow the OpenAPI 3.0 spec).`,
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const app: NestiaMigrateApplication = result.data;
|
|
67
|
-
const files: Record<string, string> =
|
|
68
|
-
options.mode === "nest" ? app.nest(options) : app.sdk(options);
|
|
69
|
-
if (app.getData().errors)
|
|
70
|
-
for (const error of app.getData().errors)
|
|
71
|
-
console.error(
|
|
72
|
-
`Failed to migrate ${error.method} ${error.path}`,
|
|
73
|
-
...error.messages.map((msg) => ` - ${msg}`),
|
|
74
|
-
);
|
|
75
|
-
await NestiaMigrateFileArchiver.archive({
|
|
76
|
-
mkdir: fs.promises.mkdir,
|
|
77
|
-
writeFile: async (file, content) =>
|
|
78
|
-
fs.promises.writeFile(file, await beautify(content), "utf-8"),
|
|
79
|
-
root: options.output,
|
|
80
|
-
files,
|
|
81
|
-
});
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const beautify = async (script: string): Promise<string> => {
|
|
85
|
-
try {
|
|
86
|
-
return await format(script, {
|
|
87
|
-
parser: "typescript",
|
|
88
|
-
plugins: [prettierPluginSortImport, prettierPluginJsDoc],
|
|
89
|
-
importOrder: ["<THIRD_PARTY_MODULES>", "^[./]"],
|
|
90
|
-
importOrderSeparation: true,
|
|
91
|
-
importOrderSortSpecifiers: true,
|
|
92
|
-
importOrderParserPlugins: ["decorators-legacy", "typescript", "jsx"],
|
|
93
|
-
bracketSpacing: true,
|
|
94
|
-
});
|
|
95
|
-
} catch {
|
|
96
|
-
return script;
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const halt = (desc: string): never => {
|
|
101
|
-
console.error(desc);
|
|
102
|
-
process.exit(-1);
|
|
103
|
-
};
|
|
104
|
-
}
|
|
1
|
+
import * as prettierPluginSortImport from "@trivago/prettier-plugin-sort-imports";
|
|
2
|
+
import {
|
|
3
|
+
OpenApiV3,
|
|
4
|
+
OpenApiV3_1,
|
|
5
|
+
OpenApiV3_2,
|
|
6
|
+
SwaggerV2,
|
|
7
|
+
} from "@typia/interface";
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import { format } from "prettier";
|
|
11
|
+
import * as prettierPluginJsDoc from "prettier-plugin-jsdoc";
|
|
12
|
+
import typia, { IValidation, tags } from "typia";
|
|
13
|
+
|
|
14
|
+
import { NestiaMigrateApplication } from "../NestiaMigrateApplication";
|
|
15
|
+
import { NestiaMigrateFileArchiver } from "../archivers/NestiaMigrateFileArchiver";
|
|
16
|
+
import { NestiaMigrateInquirer } from "./NestiaMigrateInquirer";
|
|
17
|
+
|
|
18
|
+
export namespace NestiaMigrateCommander {
|
|
19
|
+
export const main = async (): Promise<void> => {
|
|
20
|
+
const resolve = (str: string | undefined) =>
|
|
21
|
+
str ? path.resolve(str).split("\\").join("/") : undefined;
|
|
22
|
+
const options: NestiaMigrateInquirer.IOutput =
|
|
23
|
+
await NestiaMigrateInquirer.parse();
|
|
24
|
+
|
|
25
|
+
// VALIDATE OUTPUT DIRECTORY
|
|
26
|
+
const parent: string = resolve(options.output + "/..")!;
|
|
27
|
+
if (fs.existsSync(options.output))
|
|
28
|
+
halt("Response directory already exists.");
|
|
29
|
+
else if (fs.existsSync(parent) === false)
|
|
30
|
+
halt("Response directory's parent directory does not exist.");
|
|
31
|
+
else if (fs.statSync(parent).isDirectory() === false)
|
|
32
|
+
halt("Response directory's parent is not a directory.");
|
|
33
|
+
|
|
34
|
+
// READ SWAGGER
|
|
35
|
+
const document:
|
|
36
|
+
| SwaggerV2.IDocument
|
|
37
|
+
| OpenApiV3.IDocument
|
|
38
|
+
| OpenApiV3_1.IDocument
|
|
39
|
+
| OpenApiV3_2.IDocument = await (async () => {
|
|
40
|
+
if (typia.is<string & tags.Format<"uri">>(options.input)) {
|
|
41
|
+
const response: Response = await fetch(options.input);
|
|
42
|
+
const content: string = await response.text();
|
|
43
|
+
return JSON.parse(content);
|
|
44
|
+
}
|
|
45
|
+
if (fs.existsSync(options.input) === false)
|
|
46
|
+
halt("Unable to find the input swagger.json file.");
|
|
47
|
+
const stats: fs.Stats = fs.statSync(options.input);
|
|
48
|
+
if (stats.isFile() === false)
|
|
49
|
+
halt("The input swagger.json is not a file.");
|
|
50
|
+
const content: string = await fs.promises.readFile(
|
|
51
|
+
options.input,
|
|
52
|
+
"utf-8",
|
|
53
|
+
);
|
|
54
|
+
return JSON.parse(content);
|
|
55
|
+
})();
|
|
56
|
+
|
|
57
|
+
const result: IValidation<NestiaMigrateApplication> =
|
|
58
|
+
NestiaMigrateApplication.validate(document);
|
|
59
|
+
if (result.success === false) {
|
|
60
|
+
console.log(result.errors);
|
|
61
|
+
throw new Error(
|
|
62
|
+
`Invalid swagger file (must follow the OpenAPI 3.0 spec).`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const app: NestiaMigrateApplication = result.data;
|
|
67
|
+
const files: Record<string, string> =
|
|
68
|
+
options.mode === "nest" ? app.nest(options) : app.sdk(options);
|
|
69
|
+
if (app.getData().errors)
|
|
70
|
+
for (const error of app.getData().errors)
|
|
71
|
+
console.error(
|
|
72
|
+
`Failed to migrate ${error.method} ${error.path}`,
|
|
73
|
+
...error.messages.map((msg) => ` - ${msg}`),
|
|
74
|
+
);
|
|
75
|
+
await NestiaMigrateFileArchiver.archive({
|
|
76
|
+
mkdir: fs.promises.mkdir,
|
|
77
|
+
writeFile: async (file, content) =>
|
|
78
|
+
fs.promises.writeFile(file, await beautify(content), "utf-8"),
|
|
79
|
+
root: options.output,
|
|
80
|
+
files,
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const beautify = async (script: string): Promise<string> => {
|
|
85
|
+
try {
|
|
86
|
+
return await format(script, {
|
|
87
|
+
parser: "typescript",
|
|
88
|
+
plugins: [prettierPluginSortImport, prettierPluginJsDoc],
|
|
89
|
+
importOrder: ["<THIRD_PARTY_MODULES>", "^[./]"],
|
|
90
|
+
importOrderSeparation: true,
|
|
91
|
+
importOrderSortSpecifiers: true,
|
|
92
|
+
importOrderParserPlugins: ["decorators-legacy", "typescript", "jsx"],
|
|
93
|
+
bracketSpacing: true,
|
|
94
|
+
});
|
|
95
|
+
} catch {
|
|
96
|
+
return script;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const halt = (desc: string): never => {
|
|
101
|
+
console.error(desc);
|
|
102
|
+
process.exit(-1);
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
import { program } from "commander";
|
|
2
|
-
import { createPromptModule } from "inquirer";
|
|
3
|
-
|
|
4
|
-
export namespace NestiaMigrateInquirer {
|
|
5
|
-
export interface IOutput {
|
|
6
|
-
mode: "nest" | "sdk";
|
|
7
|
-
input: string;
|
|
8
|
-
output: string;
|
|
9
|
-
keyword: boolean;
|
|
10
|
-
simulate: boolean;
|
|
11
|
-
e2e: boolean;
|
|
12
|
-
package: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const parse = async (): Promise<IOutput> => {
|
|
16
|
-
// PREPARE ASSETS
|
|
17
|
-
program.option("--mode [nest/sdk]", "migration mode");
|
|
18
|
-
program.option(
|
|
19
|
-
"--input [swagger.json]",
|
|
20
|
-
"location of target swagger.json file",
|
|
21
|
-
);
|
|
22
|
-
program.option("--output [directory]", "output directory path");
|
|
23
|
-
program.option("--keyword [boolean]", "Keyword parameter mode");
|
|
24
|
-
program.option("--simulate [boolean]", "Mockup simulator");
|
|
25
|
-
program.option("--e2e [boolean]", "Generate E2E tests");
|
|
26
|
-
program.option("--package [name]", "Package name");
|
|
27
|
-
|
|
28
|
-
// INTERNAL PROCEDURES
|
|
29
|
-
const questioned = { value: false };
|
|
30
|
-
const action = (closure: (options: Partial<IOutput>) => Promise<IOutput>) =>
|
|
31
|
-
new Promise<IOutput>((resolve, reject) => {
|
|
32
|
-
program.action(async (options) => {
|
|
33
|
-
try {
|
|
34
|
-
resolve(await closure(options));
|
|
35
|
-
} catch (exp) {
|
|
36
|
-
reject(exp);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
program.parseAsync().catch(reject);
|
|
40
|
-
});
|
|
41
|
-
const select =
|
|
42
|
-
(name: string) =>
|
|
43
|
-
(message: string) =>
|
|
44
|
-
async <Choice extends string>(
|
|
45
|
-
choices: Choice[],
|
|
46
|
-
filter?: (value: string) => Choice,
|
|
47
|
-
): Promise<Choice> => {
|
|
48
|
-
questioned.value = true;
|
|
49
|
-
return (
|
|
50
|
-
await createPromptModule()({
|
|
51
|
-
type: "list",
|
|
52
|
-
name: name,
|
|
53
|
-
message: message,
|
|
54
|
-
choices: choices,
|
|
55
|
-
filter,
|
|
56
|
-
})
|
|
57
|
-
)[name];
|
|
58
|
-
};
|
|
59
|
-
const input = (name: string) => async (message: string) =>
|
|
60
|
-
(
|
|
61
|
-
await createPromptModule()({
|
|
62
|
-
type: "input",
|
|
63
|
-
name,
|
|
64
|
-
message,
|
|
65
|
-
})
|
|
66
|
-
)[name];
|
|
67
|
-
|
|
68
|
-
// DO CONSTRUCT
|
|
69
|
-
return action(async (partial) => {
|
|
70
|
-
partial.mode ??= await select("mode")("Migration mode")(
|
|
71
|
-
["NestJS" as "nest", "SDK" as "sdk"],
|
|
72
|
-
(value) => (value === "NestJS" ? "nest" : "sdk"),
|
|
73
|
-
);
|
|
74
|
-
partial.input ??= await input("input")("Swagger file location");
|
|
75
|
-
partial.output ??= await input("output")("Response directory path");
|
|
76
|
-
partial.package ??= await input("package")("Package name");
|
|
77
|
-
partial.keyword ??=
|
|
78
|
-
(await select("keyword")("Keyword parameter mode")([
|
|
79
|
-
"true",
|
|
80
|
-
"false",
|
|
81
|
-
])) === "true";
|
|
82
|
-
|
|
83
|
-
if (partial.keyword)
|
|
84
|
-
partial.keyword = (partial.keyword as any) === "true";
|
|
85
|
-
else
|
|
86
|
-
partial.keyword =
|
|
87
|
-
(await select("keyword")("Keyword parameter mode")([
|
|
88
|
-
"true",
|
|
89
|
-
"false",
|
|
90
|
-
])) === "true";
|
|
91
|
-
if (partial.simulate)
|
|
92
|
-
partial.simulate = (partial.simulate as any) === "true";
|
|
93
|
-
else
|
|
94
|
-
partial.simulate =
|
|
95
|
-
(await select("simulate")("Mokup Simulator")(["true", "false"])) ===
|
|
96
|
-
"true";
|
|
97
|
-
|
|
98
|
-
if (partial.e2e) partial.e2e = (partial.e2e as any) === "true";
|
|
99
|
-
else
|
|
100
|
-
partial.e2e =
|
|
101
|
-
(await select("e2e")("Generate E2E tests")(["true", "false"])) ===
|
|
102
|
-
"true";
|
|
103
|
-
return partial as IOutput;
|
|
104
|
-
});
|
|
105
|
-
};
|
|
106
|
-
}
|
|
1
|
+
import { program } from "commander";
|
|
2
|
+
import { createPromptModule } from "inquirer";
|
|
3
|
+
|
|
4
|
+
export namespace NestiaMigrateInquirer {
|
|
5
|
+
export interface IOutput {
|
|
6
|
+
mode: "nest" | "sdk";
|
|
7
|
+
input: string;
|
|
8
|
+
output: string;
|
|
9
|
+
keyword: boolean;
|
|
10
|
+
simulate: boolean;
|
|
11
|
+
e2e: boolean;
|
|
12
|
+
package: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const parse = async (): Promise<IOutput> => {
|
|
16
|
+
// PREPARE ASSETS
|
|
17
|
+
program.option("--mode [nest/sdk]", "migration mode");
|
|
18
|
+
program.option(
|
|
19
|
+
"--input [swagger.json]",
|
|
20
|
+
"location of target swagger.json file",
|
|
21
|
+
);
|
|
22
|
+
program.option("--output [directory]", "output directory path");
|
|
23
|
+
program.option("--keyword [boolean]", "Keyword parameter mode");
|
|
24
|
+
program.option("--simulate [boolean]", "Mockup simulator");
|
|
25
|
+
program.option("--e2e [boolean]", "Generate E2E tests");
|
|
26
|
+
program.option("--package [name]", "Package name");
|
|
27
|
+
|
|
28
|
+
// INTERNAL PROCEDURES
|
|
29
|
+
const questioned = { value: false };
|
|
30
|
+
const action = (closure: (options: Partial<IOutput>) => Promise<IOutput>) =>
|
|
31
|
+
new Promise<IOutput>((resolve, reject) => {
|
|
32
|
+
program.action(async (options) => {
|
|
33
|
+
try {
|
|
34
|
+
resolve(await closure(options));
|
|
35
|
+
} catch (exp) {
|
|
36
|
+
reject(exp);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
program.parseAsync().catch(reject);
|
|
40
|
+
});
|
|
41
|
+
const select =
|
|
42
|
+
(name: string) =>
|
|
43
|
+
(message: string) =>
|
|
44
|
+
async <Choice extends string>(
|
|
45
|
+
choices: Choice[],
|
|
46
|
+
filter?: (value: string) => Choice,
|
|
47
|
+
): Promise<Choice> => {
|
|
48
|
+
questioned.value = true;
|
|
49
|
+
return (
|
|
50
|
+
await createPromptModule()({
|
|
51
|
+
type: "list",
|
|
52
|
+
name: name,
|
|
53
|
+
message: message,
|
|
54
|
+
choices: choices,
|
|
55
|
+
filter,
|
|
56
|
+
})
|
|
57
|
+
)[name];
|
|
58
|
+
};
|
|
59
|
+
const input = (name: string) => async (message: string) =>
|
|
60
|
+
(
|
|
61
|
+
await createPromptModule()({
|
|
62
|
+
type: "input",
|
|
63
|
+
name,
|
|
64
|
+
message,
|
|
65
|
+
})
|
|
66
|
+
)[name];
|
|
67
|
+
|
|
68
|
+
// DO CONSTRUCT
|
|
69
|
+
return action(async (partial) => {
|
|
70
|
+
partial.mode ??= await select("mode")("Migration mode")(
|
|
71
|
+
["NestJS" as "nest", "SDK" as "sdk"],
|
|
72
|
+
(value) => (value === "NestJS" ? "nest" : "sdk"),
|
|
73
|
+
);
|
|
74
|
+
partial.input ??= await input("input")("Swagger file location");
|
|
75
|
+
partial.output ??= await input("output")("Response directory path");
|
|
76
|
+
partial.package ??= await input("package")("Package name");
|
|
77
|
+
partial.keyword ??=
|
|
78
|
+
(await select("keyword")("Keyword parameter mode")([
|
|
79
|
+
"true",
|
|
80
|
+
"false",
|
|
81
|
+
])) === "true";
|
|
82
|
+
|
|
83
|
+
if (partial.keyword)
|
|
84
|
+
partial.keyword = (partial.keyword as any) === "true";
|
|
85
|
+
else
|
|
86
|
+
partial.keyword =
|
|
87
|
+
(await select("keyword")("Keyword parameter mode")([
|
|
88
|
+
"true",
|
|
89
|
+
"false",
|
|
90
|
+
])) === "true";
|
|
91
|
+
if (partial.simulate)
|
|
92
|
+
partial.simulate = (partial.simulate as any) === "true";
|
|
93
|
+
else
|
|
94
|
+
partial.simulate =
|
|
95
|
+
(await select("simulate")("Mokup Simulator")(["true", "false"])) ===
|
|
96
|
+
"true";
|
|
97
|
+
|
|
98
|
+
if (partial.e2e) partial.e2e = (partial.e2e as any) === "true";
|
|
99
|
+
else
|
|
100
|
+
partial.e2e =
|
|
101
|
+
(await select("e2e")("Generate E2E tests")(["true", "false"])) ===
|
|
102
|
+
"true";
|
|
103
|
+
return partial as IOutput;
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
}
|