@lakutata/cli 1.0.36 → 2.1.0-alpha.4
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/CHANGELOG.md +52 -0
- package/README.md +6 -26
- package/package.json +28 -56
- package/src/CLIApp.ts +86 -0
- package/src/controllers/CommandLineController.ts +34 -0
- package/src/lib/ProjectTypeConfig.ts +20 -0
- package/src/lib/SpecialChar.ts +8 -0
- package/src/lib/components/DeGitPuller.ts +41 -0
- package/src/lib/components/Spinner.ts +48 -0
- package/src/lib/providers/Creator.ts +125 -0
- package/src/lib/providers/Information.ts +221 -0
- package/src/options/CreateProjectOptions.ts +82 -0
- package/src/options/LakutataInfoOptions.ts +4 -0
- package/tsconfig.json +3 -33
- package/.eslintrc.json +0 -47
- package/.idea/codeStyles/Project.xml +0 -18
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/dbnavigator.xml +0 -457
- package/.idea/inspectionProfiles/Project_Default.xml +0 -10
- package/.idea/lakutata-cli.iml +0 -14
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/LICENSE +0 -21
- package/assets/lakutata-banner.png +0 -0
- package/assets/lakutata_logo.jpg +0 -0
- package/build/CLI.d.ts +0 -2
- package/build/CLI.js +0 -13
- package/build/CLI.js.map +0 -1
- package/build/Deploy.d.ts +0 -1
- package/build/Deploy.js +0 -133
- package/build/Deploy.js.map +0 -1
- package/build/constants/GitIgnore.d.ts +0 -1
- package/build/constants/GitIgnore.js +0 -157
- package/build/constants/GitIgnore.js.map +0 -1
- package/build/constants/LicenseList.d.ts +0 -4
- package/build/constants/LicenseList.js +0 -68
- package/build/constants/LicenseList.js.map +0 -1
- package/build/interfaces/IApplicationInfo.d.ts +0 -4
- package/build/interfaces/IApplicationInfo.js +0 -3
- package/build/interfaces/IApplicationInfo.js.map +0 -1
- package/build/interfaces/IComponentInfo.d.ts +0 -4
- package/build/interfaces/IComponentInfo.js +0 -3
- package/build/interfaces/IComponentInfo.js.map +0 -1
- package/build/interfaces/IGenerator.d.ts +0 -3
- package/build/interfaces/IGenerator.js +0 -3
- package/build/interfaces/IGenerator.js.map +0 -1
- package/build/interfaces/IModuleInfo.d.ts +0 -4
- package/build/interfaces/IModuleInfo.js +0 -3
- package/build/interfaces/IModuleInfo.js.map +0 -1
- package/build/interfaces/IPluginInfo.d.ts +0 -4
- package/build/interfaces/IPluginInfo.js +0 -3
- package/build/interfaces/IPluginInfo.js.map +0 -1
- package/build/interfaces/IPreparePackageConfigOptions.d.ts +0 -19
- package/build/interfaces/IPreparePackageConfigOptions.js +0 -3
- package/build/interfaces/IPreparePackageConfigOptions.js.map +0 -1
- package/build/interfaces/IProjectGeneratorOptions.d.ts +0 -16
- package/build/interfaces/IProjectGeneratorOptions.js +0 -3
- package/build/interfaces/IProjectGeneratorOptions.js.map +0 -1
- package/build/interfaces/IProjectInfo.d.ts +0 -14
- package/build/interfaces/IProjectInfo.js +0 -3
- package/build/interfaces/IProjectInfo.js.map +0 -1
- package/build/lib/LatestVersion.d.ts +0 -1
- package/build/lib/LatestVersion.js +0 -13
- package/build/lib/LatestVersion.js.map +0 -1
- package/build/lib/generators/application/ApplicationGenerator.d.ts +0 -18
- package/build/lib/generators/application/ApplicationGenerator.js +0 -84
- package/build/lib/generators/application/ApplicationGenerator.js.map +0 -1
- package/build/lib/generators/application/files/AppFile.d.ts +0 -8
- package/build/lib/generators/application/files/AppFile.js +0 -36
- package/build/lib/generators/application/files/AppFile.js.map +0 -1
- package/build/lib/generators/application/files/ConfigFile.d.ts +0 -9
- package/build/lib/generators/application/files/ConfigFile.js +0 -81
- package/build/lib/generators/application/files/ConfigFile.js.map +0 -1
- package/build/lib/generators/component/ComponentGenerator.d.ts +0 -17
- package/build/lib/generators/component/ComponentGenerator.js +0 -75
- package/build/lib/generators/component/ComponentGenerator.js.map +0 -1
- package/build/lib/generators/component/files/ComponentFile.d.ts +0 -8
- package/build/lib/generators/component/files/ComponentFile.js +0 -45
- package/build/lib/generators/component/files/ComponentFile.js.map +0 -1
- package/build/lib/generators/component/files/ComponentTestFile.d.ts +0 -8
- package/build/lib/generators/component/files/ComponentTestFile.js +0 -35
- package/build/lib/generators/component/files/ComponentTestFile.js.map +0 -1
- package/build/lib/generators/module/ModuleGenerator.d.ts +0 -17
- package/build/lib/generators/module/ModuleGenerator.js +0 -85
- package/build/lib/generators/module/ModuleGenerator.js.map +0 -1
- package/build/lib/generators/module/files/ModuleFile.d.ts +0 -8
- package/build/lib/generators/module/files/ModuleFile.js +0 -116
- package/build/lib/generators/module/files/ModuleFile.js.map +0 -1
- package/build/lib/generators/module/files/ModuleTestFile.d.ts +0 -8
- package/build/lib/generators/module/files/ModuleTestFile.js +0 -35
- package/build/lib/generators/module/files/ModuleTestFile.js.map +0 -1
- package/build/lib/generators/plugin/PluginGenerator.d.ts +0 -17
- package/build/lib/generators/plugin/PluginGenerator.js +0 -75
- package/build/lib/generators/plugin/PluginGenerator.js.map +0 -1
- package/build/lib/generators/plugin/files/PluginFile.d.ts +0 -8
- package/build/lib/generators/plugin/files/PluginFile.js +0 -50
- package/build/lib/generators/plugin/files/PluginFile.js.map +0 -1
- package/build/lib/generators/plugin/files/PluginTestFile.d.ts +0 -8
- package/build/lib/generators/plugin/files/PluginTestFile.js +0 -35
- package/build/lib/generators/plugin/files/PluginTestFile.js.map +0 -1
- package/build/lib/generators/project/ProjectGenerator.d.ts +0 -27
- package/build/lib/generators/project/ProjectGenerator.js +0 -157
- package/build/lib/generators/project/ProjectGenerator.js.map +0 -1
- package/build/lib/generators/project/ProjectSourceFile.d.ts +0 -5
- package/build/lib/generators/project/ProjectSourceFile.js +0 -7
- package/build/lib/generators/project/ProjectSourceFile.js.map +0 -1
- package/build/lib/generators/project/configs/ProjectEslintrcConfig.d.ts +0 -37
- package/build/lib/generators/project/configs/ProjectEslintrcConfig.js +0 -51
- package/build/lib/generators/project/configs/ProjectEslintrcConfig.js.map +0 -1
- package/build/lib/generators/project/configs/ProjectPackageConfig.d.ts +0 -1
- package/build/lib/generators/project/configs/ProjectPackageConfig.js +0 -32
- package/build/lib/generators/project/configs/ProjectPackageConfig.js.map +0 -1
- package/build/lib/generators/project/configs/ProjectTypescriptConfig.d.ts +0 -25
- package/build/lib/generators/project/configs/ProjectTypescriptConfig.js +0 -39
- package/build/lib/generators/project/configs/ProjectTypescriptConfig.js.map +0 -1
- package/build/lib/manipulators/CreateComponentManipulator.d.ts +0 -3
- package/build/lib/manipulators/CreateComponentManipulator.js +0 -71
- package/build/lib/manipulators/CreateComponentManipulator.js.map +0 -1
- package/build/lib/manipulators/CreateDockerFileManipulator.d.ts +0 -3
- package/build/lib/manipulators/CreateDockerFileManipulator.js +0 -124
- package/build/lib/manipulators/CreateDockerFileManipulator.js.map +0 -1
- package/build/lib/manipulators/CreateModuleManipulator.d.ts +0 -3
- package/build/lib/manipulators/CreateModuleManipulator.js +0 -142
- package/build/lib/manipulators/CreateModuleManipulator.js.map +0 -1
- package/build/lib/manipulators/CreatePluginManipulator.d.ts +0 -3
- package/build/lib/manipulators/CreatePluginManipulator.js +0 -76
- package/build/lib/manipulators/CreatePluginManipulator.js.map +0 -1
- package/build/lib/manipulators/CreateProcessManipulator.d.ts +0 -3
- package/build/lib/manipulators/CreateProcessManipulator.js +0 -61
- package/build/lib/manipulators/CreateProcessManipulator.js.map +0 -1
- package/build/lib/manipulators/CreateThreadManipulator.d.ts +0 -3
- package/build/lib/manipulators/CreateThreadManipulator.js +0 -61
- package/build/lib/manipulators/CreateThreadManipulator.js.map +0 -1
- package/build/lib/manipulators/application/ApplicationIndexManipulator.d.ts +0 -1
- package/build/lib/manipulators/application/ApplicationIndexManipulator.js +0 -162
- package/build/lib/manipulators/application/ApplicationIndexManipulator.js.map +0 -1
- package/build/lib/menus/MainMenu.d.ts +0 -1
- package/build/lib/menus/MainMenu.js +0 -160
- package/build/lib/menus/MainMenu.js.map +0 -1
- package/build/lib/menus/initializeMenus/InitializeApplicationProject.d.ts +0 -1
- package/build/lib/menus/initializeMenus/InitializeApplicationProject.js +0 -93
- package/build/lib/menus/initializeMenus/InitializeApplicationProject.js.map +0 -1
- package/build/lib/menus/initializeMenus/InitializeComponentProject.d.ts +0 -1
- package/build/lib/menus/initializeMenus/InitializeComponentProject.js +0 -93
- package/build/lib/menus/initializeMenus/InitializeComponentProject.js.map +0 -1
- package/build/lib/menus/initializeMenus/InitializeModuleProject.d.ts +0 -1
- package/build/lib/menus/initializeMenus/InitializeModuleProject.js +0 -93
- package/build/lib/menus/initializeMenus/InitializeModuleProject.js.map +0 -1
- package/build/lib/menus/initializeMenus/InitializePluginProject.d.ts +0 -1
- package/build/lib/menus/initializeMenus/InitializePluginProject.js +0 -93
- package/build/lib/menus/initializeMenus/InitializePluginProject.js.map +0 -1
- package/build/lib/menus/manipulateMenus/ManipulateApplicationProject.d.ts +0 -1
- package/build/lib/menus/manipulateMenus/ManipulateApplicationProject.js +0 -60
- package/build/lib/menus/manipulateMenus/ManipulateApplicationProject.js.map +0 -1
- package/build/lib/menus/manipulateMenus/ManipulateComponentProject.d.ts +0 -1
- package/build/lib/menus/manipulateMenus/ManipulateComponentProject.js +0 -9
- package/build/lib/menus/manipulateMenus/ManipulateComponentProject.js.map +0 -1
- package/build/lib/menus/manipulateMenus/ManipulateModuleProject.d.ts +0 -1
- package/build/lib/menus/manipulateMenus/ManipulateModuleProject.js +0 -49
- package/build/lib/menus/manipulateMenus/ManipulateModuleProject.js.map +0 -1
- package/build/lib/menus/manipulateMenus/ManipulatePluginProject.d.ts +0 -1
- package/build/lib/menus/manipulateMenus/ManipulatePluginProject.js +0 -9
- package/build/lib/menus/manipulateMenus/ManipulatePluginProject.js.map +0 -1
- package/src/CLI.ts +0 -7
- package/src/Deploy.ts +0 -128
- package/src/constants/GitIgnore.ts +0 -153
- package/src/constants/LicenseList.ts +0 -64
- package/src/interfaces/IApplicationInfo.ts +0 -5
- package/src/interfaces/IComponentInfo.ts +0 -5
- package/src/interfaces/IGenerator.ts +0 -3
- package/src/interfaces/IModuleInfo.ts +0 -5
- package/src/interfaces/IPluginInfo.ts +0 -5
- package/src/interfaces/IPreparePackageConfigOptions.ts +0 -11
- package/src/interfaces/IProjectGeneratorOptions.ts +0 -15
- package/src/interfaces/IProjectInfo.ts +0 -10
- package/src/lib/LatestVersion.ts +0 -6
- package/src/lib/generators/application/ApplicationGenerator.ts +0 -97
- package/src/lib/generators/application/files/AppFile.ts +0 -35
- package/src/lib/generators/application/files/ConfigFile.ts +0 -82
- package/src/lib/generators/component/ComponentGenerator.ts +0 -87
- package/src/lib/generators/component/files/ComponentFile.ts +0 -45
- package/src/lib/generators/component/files/ComponentTestFile.ts +0 -36
- package/src/lib/generators/module/ModuleGenerator.ts +0 -97
- package/src/lib/generators/module/files/ModuleFile.ts +0 -116
- package/src/lib/generators/module/files/ModuleTestFile.ts +0 -36
- package/src/lib/generators/plugin/PluginGenerator.ts +0 -87
- package/src/lib/generators/plugin/files/PluginFile.ts +0 -50
- package/src/lib/generators/plugin/files/PluginTestFile.ts +0 -36
- package/src/lib/generators/project/ProjectGenerator.ts +0 -205
- package/src/lib/generators/project/ProjectSourceFile.ts +0 -7
- package/src/lib/generators/project/configs/ProjectEslintrcConfig.ts +0 -47
- package/src/lib/generators/project/configs/ProjectPackageConfig.ts +0 -28
- package/src/lib/generators/project/configs/ProjectTypescriptConfig.ts +0 -35
- package/src/lib/manipulators/CreateComponentManipulator.ts +0 -66
- package/src/lib/manipulators/CreateDockerFileManipulator.ts +0 -121
- package/src/lib/manipulators/CreateModuleManipulator.ts +0 -137
- package/src/lib/manipulators/CreatePluginManipulator.ts +0 -71
- package/src/lib/manipulators/CreateProcessManipulator.ts +0 -56
- package/src/lib/manipulators/CreateThreadManipulator.ts +0 -56
- package/src/lib/manipulators/application/ApplicationIndexManipulator.ts +0 -169
- package/src/lib/menus/MainMenu.ts +0 -148
- package/src/lib/menus/initializeMenus/InitializeApplicationProject.ts +0 -84
- package/src/lib/menus/initializeMenus/InitializeComponentProject.ts +0 -84
- package/src/lib/menus/initializeMenus/InitializeModuleProject.ts +0 -84
- package/src/lib/menus/initializeMenus/InitializePluginProject.ts +0 -84
- package/src/lib/menus/manipulateMenus/ManipulateApplicationProject.ts +0 -60
- package/src/lib/menus/manipulateMenus/ManipulateComponentProject.ts +0 -13
- package/src/lib/menus/manipulateMenus/ManipulateModuleProject.ts +0 -49
- package/src/lib/menus/manipulateMenus/ManipulatePluginProject.ts +0 -13
- package/src/tests/generators/GenerateApplication.spec.ts +0 -16
- package/src/tests/generators/GenerateComponent.spec.ts +0 -16
- package/src/tests/generators/GenerateModule.spec.ts +0 -16
- package/src/tests/generators/GeneratePlugin.spec.ts +0 -16
- package/typings.d.ts +0 -4
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
export const ProjectEslintrcConfig = {
|
|
2
|
-
env: {
|
|
3
|
-
browser: true,
|
|
4
|
-
es6: true,
|
|
5
|
-
node: true,
|
|
6
|
-
mocha: true
|
|
7
|
-
},
|
|
8
|
-
extends: [
|
|
9
|
-
'plugin:@typescript-eslint/recommended'
|
|
10
|
-
],
|
|
11
|
-
globals: {
|
|
12
|
-
Atomics: 'readonly',
|
|
13
|
-
SharedArrayBuffer: 'readonly'
|
|
14
|
-
},
|
|
15
|
-
parser: '@typescript-eslint/parser',
|
|
16
|
-
parserOptions: {
|
|
17
|
-
ecmaVersion: 2018,
|
|
18
|
-
sourceType: 'module'
|
|
19
|
-
},
|
|
20
|
-
plugins: [
|
|
21
|
-
'@typescript-eslint'
|
|
22
|
-
],
|
|
23
|
-
rules: {
|
|
24
|
-
quotes: [
|
|
25
|
-
'error',
|
|
26
|
-
'single'
|
|
27
|
-
],
|
|
28
|
-
semi: [
|
|
29
|
-
'error',
|
|
30
|
-
'never'
|
|
31
|
-
],
|
|
32
|
-
'comma-dangle': 'error',
|
|
33
|
-
'prefer-spread': 'off',
|
|
34
|
-
strict: 'off',
|
|
35
|
-
'prefer-rest-params': 'off',
|
|
36
|
-
'no-duplicate-imports': 'error',
|
|
37
|
-
'@typescript-eslint/no-explicit-any': 'off',
|
|
38
|
-
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
39
|
-
'@typescript-eslint/no-namespace': 'off',
|
|
40
|
-
'@typescript-eslint/no-empty-interface': 'off',
|
|
41
|
-
'@typescript-eslint/no-unused-vars': 'off',
|
|
42
|
-
'@typescript-eslint/no-inferrable-types': 'off',
|
|
43
|
-
'@typescript-eslint/no-empty-function': 'off',
|
|
44
|
-
'@typescript-eslint/ban-types': 'off',
|
|
45
|
-
'@typescript-eslint/ban-ts-ignore': 'off'
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export const ProjectPackageConfig: any = {
|
|
2
|
-
name: '',
|
|
3
|
-
version: '0.0.1',
|
|
4
|
-
description: '',
|
|
5
|
-
main: '',
|
|
6
|
-
types: '',
|
|
7
|
-
scripts: {},
|
|
8
|
-
keywords: ['lakutata'],
|
|
9
|
-
author: '',
|
|
10
|
-
license: '',
|
|
11
|
-
dependencies: {},
|
|
12
|
-
devDependencies: {
|
|
13
|
-
'@types/node': '^16.11.7',
|
|
14
|
-
'@typescript-eslint/eslint-plugin': '^4.27.0',
|
|
15
|
-
'@typescript-eslint/parser': '^4.27.0',
|
|
16
|
-
'eslint': '^7.32.0',
|
|
17
|
-
'eslint-config-standard': '^16.0.3',
|
|
18
|
-
'eslint-plugin-import': '^2.25.3',
|
|
19
|
-
'eslint-plugin-node': '^11.1.0',
|
|
20
|
-
'eslint-plugin-promise': '^5.2.0',
|
|
21
|
-
'shx': '^0.3.4',
|
|
22
|
-
'ts-node': '^10.9.1',
|
|
23
|
-
'typescript': '~4.7.4'
|
|
24
|
-
},
|
|
25
|
-
engines: {
|
|
26
|
-
'node': '>=12.22.1'
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export const ProjectTypescriptConfig = {
|
|
2
|
-
compilerOptions: {
|
|
3
|
-
strict: true,
|
|
4
|
-
module: 'CommonJS',
|
|
5
|
-
target: 'ES2017',
|
|
6
|
-
declaration: true,
|
|
7
|
-
sourceMap: true,
|
|
8
|
-
emitDecoratorMetadata: true,
|
|
9
|
-
experimentalDecorators: true,
|
|
10
|
-
removeComments: true,
|
|
11
|
-
allowJs: true,
|
|
12
|
-
pretty: true,
|
|
13
|
-
noUnusedLocals: false,
|
|
14
|
-
noImplicitAny: false,
|
|
15
|
-
noUnusedParameters: false,
|
|
16
|
-
outDir: '',
|
|
17
|
-
rootDir: '',
|
|
18
|
-
moduleResolution: 'Node',
|
|
19
|
-
esModuleInterop: true,
|
|
20
|
-
strictPropertyInitialization: false,
|
|
21
|
-
types: [
|
|
22
|
-
'reflect-metadata',
|
|
23
|
-
'node'
|
|
24
|
-
],
|
|
25
|
-
lib: [
|
|
26
|
-
'ESNext',
|
|
27
|
-
'ES2017',
|
|
28
|
-
'dom'
|
|
29
|
-
]
|
|
30
|
-
},
|
|
31
|
-
exclude: [
|
|
32
|
-
'node_modules',
|
|
33
|
-
'build'
|
|
34
|
-
]
|
|
35
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import {Project, Scope, StructureKind} from 'ts-morph'
|
|
2
|
-
import inquirer from 'inquirer'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 创建应用项目组件
|
|
6
|
-
* @param projectPath
|
|
7
|
-
* @param tsConfigFilePath
|
|
8
|
-
* @param directories
|
|
9
|
-
* @constructor
|
|
10
|
-
*/
|
|
11
|
-
export async function CreateComponentManipulator(projectPath: string, tsConfigFilePath: string, directories: { [name: string]: string }) {
|
|
12
|
-
const project = new Project({tsConfigFilePath: tsConfigFilePath})
|
|
13
|
-
project.addSourceFilesAtPaths(projectPath)
|
|
14
|
-
if (!directories.components) return console.error('项目读取错误: 组件文件夹未找到')
|
|
15
|
-
const componentDir: string = directories.components.toString()
|
|
16
|
-
const createOptions = await inquirer.prompt([{
|
|
17
|
-
type: 'input',
|
|
18
|
-
name: 'className',
|
|
19
|
-
message: '请输入创建的组件类名'
|
|
20
|
-
}])
|
|
21
|
-
if (!createOptions.className) return console.error('组件创建错误: 组件类名不可为空')
|
|
22
|
-
const className: string = createOptions.className
|
|
23
|
-
const componentPath: string = `${componentDir}/${className}.ts`
|
|
24
|
-
let fileExist: boolean
|
|
25
|
-
try {
|
|
26
|
-
fileExist = !!project.getSourceFile(componentPath)
|
|
27
|
-
} catch (e) {
|
|
28
|
-
fileExist = false
|
|
29
|
-
}
|
|
30
|
-
if (fileExist) return console.error('组件创建错误: 已有同名组件存在')
|
|
31
|
-
const file = project.createSourceFile(componentPath)
|
|
32
|
-
file.addImportDeclaration({namedImports: ['Component', 'Configurable'], moduleSpecifier: '@lakutata/core'})
|
|
33
|
-
const componentClass = file.addClass({
|
|
34
|
-
name: className,
|
|
35
|
-
extends: 'Component',
|
|
36
|
-
isExported: true
|
|
37
|
-
})
|
|
38
|
-
componentClass.addMember({
|
|
39
|
-
kind: StructureKind.Property,
|
|
40
|
-
scope: Scope.Protected,
|
|
41
|
-
name: 'configureItem',
|
|
42
|
-
type: 'string',
|
|
43
|
-
docs: [{
|
|
44
|
-
kind: StructureKind.JSDoc,
|
|
45
|
-
description: 'Configurable item example, do not forget add decorator [Configurable()]'
|
|
46
|
-
}],
|
|
47
|
-
isReadonly: true,
|
|
48
|
-
decorators: [{kind: StructureKind.Decorator, name: 'Configurable()'}]
|
|
49
|
-
})
|
|
50
|
-
const initMethod = componentClass.addMethod({
|
|
51
|
-
name: 'initialize',
|
|
52
|
-
isAsync: true,
|
|
53
|
-
returnType: 'Promise<void>',
|
|
54
|
-
scope: Scope.Protected
|
|
55
|
-
})
|
|
56
|
-
initMethod.addStatements(writer => {
|
|
57
|
-
writer.writeLine(`//Initializer for ${className}`)
|
|
58
|
-
writer.writeLine(`//Write your codes here`)
|
|
59
|
-
})
|
|
60
|
-
try {
|
|
61
|
-
await project.save()
|
|
62
|
-
console.info(`组件 ${className} 创建成功`)
|
|
63
|
-
} catch (e) {
|
|
64
|
-
console.error(`组件创建错误: ${(e as Error).message}`)
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import moment from 'moment-timezone'
|
|
4
|
-
import inquirer from 'inquirer'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 生成Dockerfile文件内容
|
|
8
|
-
* @param timezone
|
|
9
|
-
* @param envName
|
|
10
|
-
* @param outDir
|
|
11
|
-
* @param runtime
|
|
12
|
-
* @param entryPoint
|
|
13
|
-
*/
|
|
14
|
-
function generateDockerfileContent(timezone: string, envName: string, outDir: string, runtime: string, entryPoint: string): string {
|
|
15
|
-
const dockerFileContents: string[] = [
|
|
16
|
-
'FROM node:lts-buster',
|
|
17
|
-
'#Set docker timezone',
|
|
18
|
-
`ENV TZ=${timezone}`,
|
|
19
|
-
`ENV NODE_ENV=${envName}`,
|
|
20
|
-
'RUN set -eux',
|
|
21
|
-
'RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime',
|
|
22
|
-
'RUN echo $TZ > /etc/timezone',
|
|
23
|
-
'#Install system level dependencies',
|
|
24
|
-
'RUN npm install -g npm typescript ts-node',
|
|
25
|
-
'#Process project directories',
|
|
26
|
-
'RUN mkdir -p /app',
|
|
27
|
-
'WORKDIR /app',
|
|
28
|
-
'COPY . /app/',
|
|
29
|
-
'RUN rm -rf /app/node_modules',
|
|
30
|
-
`RUN rm -rf ${path.resolve('/app/', outDir)}`,
|
|
31
|
-
'RUN npm install --build-from-source',
|
|
32
|
-
'RUN tsc',
|
|
33
|
-
'#Expose ports',
|
|
34
|
-
'#TODO export ports or remove this line',
|
|
35
|
-
`ENTRYPOINT ${runtime} ${path.resolve('/app/', entryPoint)}`
|
|
36
|
-
]
|
|
37
|
-
let content: string = ''
|
|
38
|
-
dockerFileContents.forEach(line => {
|
|
39
|
-
if (!content) {
|
|
40
|
-
content = line
|
|
41
|
-
} else {
|
|
42
|
-
content = `${content}\n${line}`
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
return content
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export async function CreateDockerFileManipulator(projectPath: string, tsConfigFilePath: string, directories: { [name: string]: string }) {
|
|
49
|
-
try {
|
|
50
|
-
const repositories = await inquirer.prompt([
|
|
51
|
-
{
|
|
52
|
-
type: 'input',
|
|
53
|
-
name: 'production',
|
|
54
|
-
message: '请输入正式环境仓库地址'
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
type: 'input',
|
|
58
|
-
name: 'development',
|
|
59
|
-
message: '请输入测试环境仓库地址'
|
|
60
|
-
}
|
|
61
|
-
])
|
|
62
|
-
const productionRepository: string = repositories.production ? repositories.production : ''
|
|
63
|
-
const developmentRepository: string = repositories.development ? repositories.development : ''
|
|
64
|
-
const timezone = moment.tz.guess()
|
|
65
|
-
const tsConfigJson = JSON.parse(fs.readFileSync(tsConfigFilePath).toString())
|
|
66
|
-
const outDir: string = tsConfigJson?.compilerOptions?.outDir
|
|
67
|
-
if (!outDir) return console.error('项目输出目录设置有误')
|
|
68
|
-
const packageJsonFilePath: string = path.resolve(projectPath, './package.json')
|
|
69
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonFilePath).toString())
|
|
70
|
-
const mainEntry: string = packageJson?.main ? packageJson.main : ''
|
|
71
|
-
if (!mainEntry) return console.error('应用程序主入口设置有误')
|
|
72
|
-
const dockerfiles: { [key: string]: string } = {}
|
|
73
|
-
if (productionRepository) {
|
|
74
|
-
dockerfiles.Dockerfile = generateDockerfileContent(timezone, 'production', outDir, 'node', mainEntry)
|
|
75
|
-
packageJson.scripts.deploy = `lakutata-deploy --dockerfile ./Dockerfile --repository ${productionRepository}`
|
|
76
|
-
}
|
|
77
|
-
if (packageJson?.scripts?.test && developmentRepository) {
|
|
78
|
-
//有测试主入口并且仓库地址被正确配置
|
|
79
|
-
const testScriptString: string = packageJson.scripts.test
|
|
80
|
-
const testScriptParams: string[] = testScriptString.split(' ').reverse()
|
|
81
|
-
let testEntryPoint: string = ''
|
|
82
|
-
let runtime: string = ''
|
|
83
|
-
for (const testScriptParam of testScriptParams) {
|
|
84
|
-
const regExp = /src\//
|
|
85
|
-
if (['.ts', '.js'].includes(path.extname(testScriptParam)) && regExp.test(testScriptParam)) {
|
|
86
|
-
switch (path.extname(testScriptParam)) {
|
|
87
|
-
case '.ts': {
|
|
88
|
-
runtime = 'ts-node'
|
|
89
|
-
}
|
|
90
|
-
break
|
|
91
|
-
case '.js': {
|
|
92
|
-
runtime = 'node'
|
|
93
|
-
}
|
|
94
|
-
break
|
|
95
|
-
default: {
|
|
96
|
-
console.error('不正确的测试主入口扩展名')
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
testEntryPoint = testScriptParam
|
|
100
|
-
break
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (testEntryPoint && runtime) {
|
|
104
|
-
dockerfiles.DockerfileDev = generateDockerfileContent(timezone, 'development', outDir, runtime, testEntryPoint)
|
|
105
|
-
packageJson.scripts['deploy:dev'] = `lakutata-deploy --dockerfile ./DockerfileDev --repository ${developmentRepository}`
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
for (const dockerfileName of Object.keys(dockerfiles)) {
|
|
109
|
-
//生成文件
|
|
110
|
-
fs.writeFileSync(path.resolve(projectPath, dockerfileName), dockerfiles[dockerfileName], {
|
|
111
|
-
encoding: 'utf-8',
|
|
112
|
-
flag: 'w'
|
|
113
|
-
})
|
|
114
|
-
console.info(dockerfileName, '写入成功')
|
|
115
|
-
}
|
|
116
|
-
fs.writeFileSync(packageJsonFilePath, JSON.stringify(packageJson, null, ' '), {encoding: 'utf-8', flag: 'w'})
|
|
117
|
-
console.info('Dockerfile已创建成功')
|
|
118
|
-
} catch (e) {
|
|
119
|
-
console.error(`Dockerfile创建错误: ${(e as Error).message}`)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import {Project, Scope, StructureKind} from 'ts-morph'
|
|
2
|
-
import inquirer from 'inquirer'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 创建应用项目模块
|
|
6
|
-
* @param projectPath
|
|
7
|
-
* @param tsConfigFilePath
|
|
8
|
-
* @param directories
|
|
9
|
-
* @constructor
|
|
10
|
-
*/
|
|
11
|
-
export async function CreateModuleManipulator(projectPath: string, tsConfigFilePath: string, directories: { [name: string]: string }) {
|
|
12
|
-
const project = new Project({tsConfigFilePath: tsConfigFilePath})
|
|
13
|
-
project.addSourceFilesAtPaths(projectPath)
|
|
14
|
-
if (!directories.modules) return console.error('项目读取错误: 模块文件夹未找到')
|
|
15
|
-
const moduleDir: string = directories.modules.toString()
|
|
16
|
-
const createOptions = await inquirer.prompt([{
|
|
17
|
-
type: 'input',
|
|
18
|
-
name: 'className',
|
|
19
|
-
message: '请输入创建的模块类名'
|
|
20
|
-
}])
|
|
21
|
-
if (!createOptions.className) return console.error('模块创建错误: 模块类名不可为空')
|
|
22
|
-
const className: string = createOptions.className
|
|
23
|
-
const modulePath: string = `${moduleDir}/${className}.ts`
|
|
24
|
-
let fileExist: boolean
|
|
25
|
-
try {
|
|
26
|
-
fileExist = !!project.getSourceFile(modulePath)
|
|
27
|
-
} catch (e) {
|
|
28
|
-
fileExist = false
|
|
29
|
-
}
|
|
30
|
-
if (fileExist) return console.error('模块创建错误: 已有同名模块存在')
|
|
31
|
-
const file = project.createSourceFile(modulePath)
|
|
32
|
-
file.addImportDeclaration({
|
|
33
|
-
namedImports: ['Module', 'Configurable', 'IComponentsConfig', 'IModulesConfig', 'TPluginsConfig', 'TProcessesConfig', 'TThreadsConfig', 'TWorkflowsConfig'],
|
|
34
|
-
moduleSpecifier: '@lakutata/core'
|
|
35
|
-
})
|
|
36
|
-
const moduleClass = file.addClass({
|
|
37
|
-
name: className,
|
|
38
|
-
extends: 'Module',
|
|
39
|
-
isExported: true
|
|
40
|
-
})
|
|
41
|
-
moduleClass.addMembers([
|
|
42
|
-
{
|
|
43
|
-
docs: [{
|
|
44
|
-
kind: StructureKind.JSDoc,
|
|
45
|
-
description: 'Module plugins'
|
|
46
|
-
}],
|
|
47
|
-
kind: StructureKind.Property,
|
|
48
|
-
name: 'plugins',
|
|
49
|
-
isReadonly: true,
|
|
50
|
-
scope: Scope.Protected,
|
|
51
|
-
type: 'TPluginsConfig',
|
|
52
|
-
initializer: '[]',
|
|
53
|
-
decorators: [{kind: StructureKind.Decorator, name: 'Configurable()'}]
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
docs: [{
|
|
57
|
-
kind: StructureKind.JSDoc,
|
|
58
|
-
description: 'Module components'
|
|
59
|
-
}],
|
|
60
|
-
kind: StructureKind.Property,
|
|
61
|
-
name: 'components',
|
|
62
|
-
isReadonly: true,
|
|
63
|
-
scope: Scope.Protected,
|
|
64
|
-
type: 'IComponentsConfig',
|
|
65
|
-
initializer: '{}',
|
|
66
|
-
decorators: [{kind: StructureKind.Decorator, name: 'Configurable()'}]
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
docs: [{
|
|
70
|
-
kind: StructureKind.JSDoc,
|
|
71
|
-
description: 'Subset modules'
|
|
72
|
-
}],
|
|
73
|
-
kind: StructureKind.Property,
|
|
74
|
-
name: 'modules',
|
|
75
|
-
isReadonly: true,
|
|
76
|
-
scope: Scope.Protected,
|
|
77
|
-
type: 'IModulesConfig',
|
|
78
|
-
initializer: '{}',
|
|
79
|
-
decorators: [{kind: StructureKind.Decorator, name: 'Configurable()'}]
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
docs: [{
|
|
83
|
-
kind: StructureKind.JSDoc,
|
|
84
|
-
description: 'Module threads'
|
|
85
|
-
}],
|
|
86
|
-
kind: StructureKind.Property,
|
|
87
|
-
name: 'threads',
|
|
88
|
-
isReadonly: true,
|
|
89
|
-
scope: Scope.Protected,
|
|
90
|
-
type: 'TThreadsConfig',
|
|
91
|
-
initializer: '[]',
|
|
92
|
-
decorators: [{kind: StructureKind.Decorator, name: 'Configurable()'}]
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
docs: [{
|
|
96
|
-
kind: StructureKind.JSDoc,
|
|
97
|
-
description: 'Module processes'
|
|
98
|
-
}],
|
|
99
|
-
kind: StructureKind.Property,
|
|
100
|
-
name: 'processes',
|
|
101
|
-
isReadonly: true,
|
|
102
|
-
scope: Scope.Protected,
|
|
103
|
-
type: 'TProcessesConfig',
|
|
104
|
-
initializer: '[]',
|
|
105
|
-
decorators: [{kind: StructureKind.Decorator, name: 'Configurable()'}]
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
docs: [{
|
|
109
|
-
kind: StructureKind.JSDoc,
|
|
110
|
-
description: 'Module workflows'
|
|
111
|
-
}],
|
|
112
|
-
kind: StructureKind.Property,
|
|
113
|
-
name: 'workflows',
|
|
114
|
-
isReadonly: true,
|
|
115
|
-
scope: Scope.Protected,
|
|
116
|
-
type: 'TWorkflowsConfig',
|
|
117
|
-
initializer: '[]',
|
|
118
|
-
decorators: [{kind: StructureKind.Decorator, name: 'Configurable()'}]
|
|
119
|
-
}
|
|
120
|
-
])
|
|
121
|
-
const initMethod = moduleClass.addMethod({
|
|
122
|
-
name: 'initialize',
|
|
123
|
-
isAsync: true,
|
|
124
|
-
returnType: 'Promise<void>',
|
|
125
|
-
scope: Scope.Protected
|
|
126
|
-
})
|
|
127
|
-
initMethod.addStatements(writer => {
|
|
128
|
-
writer.writeLine(`//Initializer for ${className}`)
|
|
129
|
-
writer.writeLine(`//Write your module initialization codes here`)
|
|
130
|
-
})
|
|
131
|
-
try {
|
|
132
|
-
await project.save()
|
|
133
|
-
console.info(`模块 ${className} 创建成功`)
|
|
134
|
-
} catch (e) {
|
|
135
|
-
console.error(`模块创建错误: ${(e as Error).message}`)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {ModuleDeclarationKind, Project, Scope, StructureKind} from 'ts-morph'
|
|
2
|
-
import inquirer from 'inquirer'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 创建应用项目插件
|
|
6
|
-
* @param projectPath
|
|
7
|
-
* @param tsConfigFilePath
|
|
8
|
-
* @param directories
|
|
9
|
-
* @constructor
|
|
10
|
-
*/
|
|
11
|
-
export async function CreatePluginManipulator(projectPath: string, tsConfigFilePath: string, directories: { [name: string]: string }) {
|
|
12
|
-
const project = new Project({tsConfigFilePath: tsConfigFilePath})
|
|
13
|
-
project.addSourceFilesAtPaths(projectPath)
|
|
14
|
-
if (!directories.plugins) return console.error('项目读取错误: 插件文件夹未找到')
|
|
15
|
-
const pluginDir: string = directories.plugins.toString()
|
|
16
|
-
const createOptions = await inquirer.prompt([{
|
|
17
|
-
type: 'input',
|
|
18
|
-
name: 'className',
|
|
19
|
-
message: '请输入创建的插件类名'
|
|
20
|
-
}])
|
|
21
|
-
if (!createOptions.className) return console.error('插件创建错误: 插件类名不可为空')
|
|
22
|
-
const className: string = createOptions.className
|
|
23
|
-
const pluginPath: string = `${pluginDir}/${className}.ts`
|
|
24
|
-
let fileExist: boolean
|
|
25
|
-
try {
|
|
26
|
-
fileExist = !!project.getSourceFile(pluginPath)
|
|
27
|
-
} catch (e) {
|
|
28
|
-
fileExist = false
|
|
29
|
-
}
|
|
30
|
-
if (fileExist) return console.error('插件创建错误: 已有同名插件存在')
|
|
31
|
-
const file = project.createSourceFile(pluginPath)
|
|
32
|
-
file.addImportDeclaration({
|
|
33
|
-
namedImports: ['Plugin', 'Configurable'],
|
|
34
|
-
moduleSpecifier: '@lakutata/core'
|
|
35
|
-
})
|
|
36
|
-
file.addStatements([{
|
|
37
|
-
declarationKind: ModuleDeclarationKind.Module,
|
|
38
|
-
kind: StructureKind.Module,
|
|
39
|
-
hasDeclareKeyword: true,
|
|
40
|
-
name: `'@lakutata/core'`,
|
|
41
|
-
statements: [{
|
|
42
|
-
kind: StructureKind.Interface,
|
|
43
|
-
name: 'Application',
|
|
44
|
-
properties: [{
|
|
45
|
-
name: className,
|
|
46
|
-
type: className
|
|
47
|
-
}]
|
|
48
|
-
}]
|
|
49
|
-
}])
|
|
50
|
-
const pluginClass = file.addClass({
|
|
51
|
-
name: className,
|
|
52
|
-
extends: 'Plugin',
|
|
53
|
-
isExported: true
|
|
54
|
-
})
|
|
55
|
-
const onActivationMethod = pluginClass.addMethod({
|
|
56
|
-
name: 'onActivation',
|
|
57
|
-
isAsync: false,
|
|
58
|
-
returnType: 'void',
|
|
59
|
-
scope: Scope.Protected
|
|
60
|
-
})
|
|
61
|
-
onActivationMethod.addStatements(writer => {
|
|
62
|
-
writer.writeLine('//Codes in here will be executed on plugin activation')
|
|
63
|
-
writer.writeLine('//Plugin is always executed in transient mode')
|
|
64
|
-
})
|
|
65
|
-
try {
|
|
66
|
-
await project.save()
|
|
67
|
-
console.info(`插件 ${className} 创建成功`)
|
|
68
|
-
} catch (e) {
|
|
69
|
-
console.error(`插件创建错误: ${(e as Error).message}`)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import {Project, Scope} from 'ts-morph'
|
|
2
|
-
import inquirer from 'inquirer'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 创建应用项目进程
|
|
6
|
-
* @param projectPath
|
|
7
|
-
* @param tsConfigFilePath
|
|
8
|
-
* @param directories
|
|
9
|
-
* @constructor
|
|
10
|
-
*/
|
|
11
|
-
export async function CreateProcessManipulator(projectPath: string, tsConfigFilePath: string, directories: { [name: string]: string }) {
|
|
12
|
-
const project = new Project({tsConfigFilePath: tsConfigFilePath})
|
|
13
|
-
project.addSourceFilesAtPaths(projectPath)
|
|
14
|
-
if (!directories.processes) return console.error('项目读取错误: 进程文件夹未找到')
|
|
15
|
-
const processDir: string = directories.processes.toString()
|
|
16
|
-
const createOptions = await inquirer.prompt([{
|
|
17
|
-
type: 'input',
|
|
18
|
-
name: 'className',
|
|
19
|
-
message: '请输入创建的进程类名'
|
|
20
|
-
}])
|
|
21
|
-
if (!createOptions.className) return console.error('进程创建错误: 进程类名不可为空')
|
|
22
|
-
const className: string = createOptions.className
|
|
23
|
-
const processPath: string = `${processDir}/${className}.ts`
|
|
24
|
-
let fileExist: boolean
|
|
25
|
-
try {
|
|
26
|
-
fileExist = !!project.getSourceFile(processPath)
|
|
27
|
-
} catch (e) {
|
|
28
|
-
fileExist = false
|
|
29
|
-
}
|
|
30
|
-
if (fileExist) return console.error('进程创建错误: 已有同名进程存在')
|
|
31
|
-
const file = project.createSourceFile(processPath)
|
|
32
|
-
file.addImportDeclaration({
|
|
33
|
-
namedImports: ['Process'],
|
|
34
|
-
moduleSpecifier: '@lakutata/core'
|
|
35
|
-
})
|
|
36
|
-
const processClass = file.addClass({
|
|
37
|
-
name: className,
|
|
38
|
-
extends: 'Process',
|
|
39
|
-
isExported: true
|
|
40
|
-
})
|
|
41
|
-
const initializeMethod = processClass.addMethod({
|
|
42
|
-
name: 'initialize',
|
|
43
|
-
isAsync: true,
|
|
44
|
-
returnType: 'Promise<void>',
|
|
45
|
-
scope: Scope.Protected
|
|
46
|
-
})
|
|
47
|
-
initializeMethod.addStatements(writer => {
|
|
48
|
-
writer.writeLine('//initialize codes for process')
|
|
49
|
-
})
|
|
50
|
-
try {
|
|
51
|
-
await project.save()
|
|
52
|
-
console.info(`进程 ${className} 创建成功`)
|
|
53
|
-
} catch (e) {
|
|
54
|
-
console.error(`进程创建错误: ${(e as Error).message}`)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import {Project, Scope} from 'ts-morph'
|
|
2
|
-
import inquirer from 'inquirer'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 创建应用项目线程
|
|
6
|
-
* @param projectPath
|
|
7
|
-
* @param tsConfigFilePath
|
|
8
|
-
* @param directories
|
|
9
|
-
* @constructor
|
|
10
|
-
*/
|
|
11
|
-
export async function CreateThreadManipulator(projectPath: string, tsConfigFilePath: string, directories: { [name: string]: string }) {
|
|
12
|
-
const project = new Project({tsConfigFilePath: tsConfigFilePath})
|
|
13
|
-
project.addSourceFilesAtPaths(projectPath)
|
|
14
|
-
if (!directories.threads) return console.error('项目读取错误: 线程文件夹未找到')
|
|
15
|
-
const threadDir: string = directories.threads.toString()
|
|
16
|
-
const createOptions = await inquirer.prompt([{
|
|
17
|
-
type: 'input',
|
|
18
|
-
name: 'className',
|
|
19
|
-
message: '请输入创建的线程类名'
|
|
20
|
-
}])
|
|
21
|
-
if (!createOptions.className) return console.error('线程创建错误: 线程类名不可为空')
|
|
22
|
-
const className: string = createOptions.className
|
|
23
|
-
const threadPath: string = `${threadDir}/${className}.ts`
|
|
24
|
-
let fileExist: boolean
|
|
25
|
-
try {
|
|
26
|
-
fileExist = !!project.getSourceFile(threadPath)
|
|
27
|
-
} catch (e) {
|
|
28
|
-
fileExist = false
|
|
29
|
-
}
|
|
30
|
-
if (fileExist) return console.error('线程创建错误: 已有同名线程存在')
|
|
31
|
-
const file = project.createSourceFile(threadPath)
|
|
32
|
-
file.addImportDeclaration({
|
|
33
|
-
namedImports: ['Thread'],
|
|
34
|
-
moduleSpecifier: '@lakutata/core'
|
|
35
|
-
})
|
|
36
|
-
const threadClass = file.addClass({
|
|
37
|
-
name: className,
|
|
38
|
-
extends: 'Thread',
|
|
39
|
-
isExported: true
|
|
40
|
-
})
|
|
41
|
-
const initializeMethod = threadClass.addMethod({
|
|
42
|
-
name: 'initialize',
|
|
43
|
-
isAsync: true,
|
|
44
|
-
returnType: 'Promise<void>',
|
|
45
|
-
scope: Scope.Protected
|
|
46
|
-
})
|
|
47
|
-
initializeMethod.addStatements(writer => {
|
|
48
|
-
writer.writeLine('//initialize codes for thread')
|
|
49
|
-
})
|
|
50
|
-
try {
|
|
51
|
-
await project.save()
|
|
52
|
-
console.info(`线程 ${className} 创建成功`)
|
|
53
|
-
} catch (e) {
|
|
54
|
-
console.error(`线程创建错误: ${(e as Error).message}`)
|
|
55
|
-
}
|
|
56
|
-
}
|