shoplazza-cli 1.0.4 → 1.0.6
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/bin/shoplazza +4 -14
- package/lib/app/api/api.js +93 -0
- package/lib/app/api/request.js +72 -0
- package/lib/app/commands/build.js +74 -53
- package/lib/app/commands/create.js +100 -0
- package/lib/app/commands/deploy.js +39 -210
- package/lib/app/commands/list.js +31 -0
- package/lib/app/commands/serve.js +118 -0
- package/lib/app/commands/versions.js +44 -0
- package/lib/app/index.js +17 -29
- package/lib/app/template/basic-app/.ci/k8s.yaml +4 -0
- package/lib/app/template/basic-app/README.md +84 -0
- package/lib/app/template/basic-app/package.json +15 -0
- package/lib/app/template/basic-app/theme-app/assets/index.css +4 -0
- package/lib/app/template/basic-app/theme-app/blocks/index.liquid +14 -0
- package/lib/app/template/basic-app/theme-app/snippets/index.liquid +8 -0
- package/lib/app/template/basic-app/theme-app.config.json +4 -0
- package/lib/app/template/embed-app/.ci/k8s.yaml +4 -0
- package/lib/app/template/embed-app/README.md +84 -0
- package/lib/app/template/embed-app/package.json +15 -0
- package/lib/app/template/embed-app/theme-app/assets/index.css +4 -0
- package/lib/app/template/embed-app/theme-app/blocks/index.liquid +15 -0
- package/lib/app/template/embed-app/theme-app/locales/ar-SA.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/de-DE.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/en-US.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/es-ES.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/fr-FR.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/id-ID.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/it-IT.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/ja-JP.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/ko-KR.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/nl-NL.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/pl-PL.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/pt-PT.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/ru-RU.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/th-TH.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/zh-CN.json +3 -0
- package/lib/app/template/embed-app/theme-app/locales/zh-TW.json +3 -0
- package/lib/app/template/embed-app/theme-app/snippets/index.liquid +8 -0
- package/lib/app/template/embed-app/theme-app.config.json +4 -0
- package/lib/app/utils/config.js +29 -0
- package/lib/app/utils/index.js +220 -0
- package/lib/checkout/api.js +19 -38
- package/lib/checkout/build/plugin/vite-plugin-transform-extension-html.js +1 -1
- package/lib/checkout/dev/index.js +2 -1
- package/lib/commands/login.js +1 -1
- package/lib/commands/logout.js +1 -1
- package/lib/openAPI/index.js +21 -10
- package/lib/oss.js +102 -0
- package/lib/utils.js +52 -0
- package/package.json +2 -2
- package/lib/app/commands/generate.js +0 -50
- package/lib/app/commands/publish.js +0 -52
- package/lib/app/extensions/index.js +0 -13
- package/lib/app/extensions/theme-app.js +0 -103
- package/lib/app/inquirers/version.js +0 -131
- /package/lib/{app → common}/constants.js +0 -0
- /package/lib/{app → common}/db/partner.js +0 -0
- /package/lib/{app → common}/inquirers/choose-app.js +0 -0
- /package/lib/{app → common}/inquirers/choose-partner.js +0 -0
- /package/lib/{app → common}/log.js +0 -0
- /package/lib/{app → common}/login.js +0 -0
- /package/lib/{app → common}/logout.js +0 -0
package/bin/shoplazza
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
process.noDeprecation = true; // 全局禁用废弃警告
|
|
3
4
|
const { program } = require('commander');
|
|
4
5
|
const updateNotifier = require('update-notifier');
|
|
5
6
|
const Sentry = require('@sentry/node');
|
|
@@ -9,8 +10,7 @@ const report = require('../lib/report');
|
|
|
9
10
|
require('../lib/tracing');
|
|
10
11
|
|
|
11
12
|
const { makeCheckoutCommand } = require('../lib/checkout');
|
|
12
|
-
|
|
13
|
-
const { generateExtension, deployExtension, publishExtension, buildExtension, retry } = require('../lib/app');
|
|
13
|
+
const { initThemeAppCommand } = require('../lib/app');
|
|
14
14
|
|
|
15
15
|
Sentry.init({
|
|
16
16
|
dsn: 'https://89964605acaf4db8839f2d5237396d6c@sentry.shoplazza.com/730',
|
|
@@ -112,21 +112,11 @@ theme
|
|
|
112
112
|
.option('-t, --theme <theme>', 'The ID of the theme that you want to delete.')
|
|
113
113
|
.action(require('../lib/commands/theme/delete'));
|
|
114
114
|
|
|
115
|
-
const app = program.command('app').description('Shoplazza app extensions cli');
|
|
116
|
-
|
|
117
|
-
app.command('generate').command('extension').description('Generate your extension').action(generateExtension);
|
|
118
|
-
app.command('deploy').command('extension').description('Deploy your extension to cdn').action(deployExtension);
|
|
119
|
-
app.command('publish').command('extension').description('Publish your extension').action(publishExtension);
|
|
120
|
-
app.command('build').description('Build your extension').action(buildExtension);
|
|
121
|
-
app
|
|
122
|
-
.command('retry')
|
|
123
|
-
.description('Retry to do some tasks.')
|
|
124
|
-
.option('-p, --partner', 'Retry get and choose your partner list.')
|
|
125
|
-
.option('-a, --app', 'Retry get and choose your app list.')
|
|
126
|
-
.action(retry);
|
|
127
115
|
|
|
128
116
|
// checkout cli
|
|
129
117
|
makeCheckoutCommand(program);
|
|
118
|
+
// theme app cli
|
|
119
|
+
initThemeAppCommand(program);
|
|
130
120
|
|
|
131
121
|
program.parse(process.argv);
|
|
132
122
|
!program.args.length && program.help();
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const { get, post, put, del, patch } = require('./request');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 获取主题列表
|
|
5
|
+
*/
|
|
6
|
+
async function getThemeList() {
|
|
7
|
+
return get('/themes');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 获取店铺私有主题插件列表
|
|
12
|
+
* @returns
|
|
13
|
+
*/
|
|
14
|
+
async function getThemeAppList() {
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
name: '主题插件1',
|
|
18
|
+
version: '1.0.0',
|
|
19
|
+
description: '主题插件1的描述'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: '主题插件2',
|
|
23
|
+
version: '2.0.0',
|
|
24
|
+
description: '主题插件2的描述'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: '主题插件3',
|
|
28
|
+
version: '3.0.0',
|
|
29
|
+
description: '主题插件3的描述'
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
// return get('/theme-extensions');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 创建主题插件
|
|
37
|
+
*/
|
|
38
|
+
async function toCreateThemeApp(data) {
|
|
39
|
+
return put('/theme-extensions', data);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 上传主题插件
|
|
44
|
+
*/
|
|
45
|
+
async function toUploadThemeApp(data) {
|
|
46
|
+
return patch(`theme-extensions/${data.appId}/dev-doctree`, data);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 获取任务状态
|
|
51
|
+
*/
|
|
52
|
+
async function getTaskStatus(data) {
|
|
53
|
+
return get(`/theme-extensions/version-tasks/${data.taskId}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 获取主题插件版本列表
|
|
58
|
+
*/
|
|
59
|
+
async function getThemeAppVersionList(data) {
|
|
60
|
+
return [
|
|
61
|
+
{ version: '1.0.0', date: '2023-01-01', description: 'Initial release' },
|
|
62
|
+
{ version: '1.1.0', date: '2023-02-01', description: 'Added new features and bug fixes' },
|
|
63
|
+
{ version: '1.2.0', date: '2023-03-01', description: 'Fixed bugs and improved performance' },
|
|
64
|
+
{ version: '1.3.0', date: '2023-04-01', description: 'Optimized performance and added new features' },
|
|
65
|
+
{ version: '1.4.0', date: '2023-05-01', description: 'Fixed bugs and improved user experience' }
|
|
66
|
+
];
|
|
67
|
+
// return get(`/theme-extensions/:${data.appId}/versions`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 创建主题插件版本
|
|
72
|
+
*/
|
|
73
|
+
async function toCreateThemeAppVersion(data) {
|
|
74
|
+
return post(`/theme-extensions/version-tasks`, data);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 部署主题插件
|
|
79
|
+
*/
|
|
80
|
+
async function toDeployThemeApp(data) {
|
|
81
|
+
return post(`theme-extensions/publications`, data);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = {
|
|
85
|
+
getThemeList,
|
|
86
|
+
getThemeAppList,
|
|
87
|
+
toCreateThemeApp,
|
|
88
|
+
toUploadThemeApp,
|
|
89
|
+
getThemeAppVersionList,
|
|
90
|
+
toCreateThemeAppVersion,
|
|
91
|
+
toDeployThemeApp,
|
|
92
|
+
getTaskStatus
|
|
93
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const instance = require('../../openAPI/index');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 基础的 API 请求方法
|
|
5
|
+
* @param {string} method 请求方法 (GET, POST, PUT, DELETE)
|
|
6
|
+
* @param {string} url 请求的路径
|
|
7
|
+
* @param {Object} data 请求的数据(适用于 POST、PUT)
|
|
8
|
+
* @param {Object} params 请求的 URL 参数(适用于 GET)
|
|
9
|
+
*/
|
|
10
|
+
async function request({ method, url, data, params }) {
|
|
11
|
+
const response = await instance({
|
|
12
|
+
method,
|
|
13
|
+
url,
|
|
14
|
+
data,
|
|
15
|
+
params
|
|
16
|
+
});
|
|
17
|
+
return response; // 返回请求结果
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* GET 请求封装
|
|
22
|
+
* @param {string} url 请求的路径
|
|
23
|
+
* @param {Object} params 请求的 URL 参数
|
|
24
|
+
*/
|
|
25
|
+
async function get(url, params) {
|
|
26
|
+
return request({ method: 'get', url, params });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* POST 请求封装
|
|
31
|
+
* @param {string} url 请求的路径
|
|
32
|
+
* @param {Object} data 请求的数据
|
|
33
|
+
*/
|
|
34
|
+
async function post(url, data) {
|
|
35
|
+
return request({ method: 'post', url, data });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* PUT 请求封装
|
|
40
|
+
* @param {string} url 请求的路径
|
|
41
|
+
* @param {Object} data 请求的数据
|
|
42
|
+
*/
|
|
43
|
+
async function put(url, data) {
|
|
44
|
+
return request({ method: 'put', url, data });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* DELETE 请求封装
|
|
49
|
+
* @param {string} url 请求的路径
|
|
50
|
+
* @param {Object} params 请求的 URL 参数
|
|
51
|
+
*/
|
|
52
|
+
async function del(url, params) {
|
|
53
|
+
return request({ method: 'delete', url, params });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* PATCH 请求封装
|
|
58
|
+
* @param {string} url 请求的路径
|
|
59
|
+
* @param {Object} data 请求的数据
|
|
60
|
+
*/
|
|
61
|
+
async function patch(url, data) {
|
|
62
|
+
return request({ method: 'patch', url, data });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
module.exports = {
|
|
67
|
+
get,
|
|
68
|
+
post,
|
|
69
|
+
put,
|
|
70
|
+
del,
|
|
71
|
+
patch
|
|
72
|
+
};
|
|
@@ -1,66 +1,87 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
|
-
const
|
|
3
|
-
const fs = require('fs-extra');
|
|
2
|
+
const inquirer = require('inquirer');
|
|
4
3
|
const path = require('path');
|
|
4
|
+
const { getThemeAppConfig, compareVersions } = require('../utils');
|
|
5
|
+
const { getThemeAppVersionList, toCreateThemeAppVersion } = require('../api/api');
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const {
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
);
|
|
26
|
-
await
|
|
7
|
+
async function createNewVersion(appId, version, description) {
|
|
8
|
+
const themeAppPath = path.resolve(WORKSPACE_PATH, 'theme-app');
|
|
9
|
+
const { zipPath, zipName } = await compress(themeAppPath);
|
|
10
|
+
const zipOssUrl = await uploadOss(zipPath, zipName);
|
|
11
|
+
const taskId = await toCreateThemeAppVersion({
|
|
12
|
+
extension_id: appId,
|
|
13
|
+
version,
|
|
14
|
+
description,
|
|
15
|
+
resource_url: zipOssUrl
|
|
16
|
+
});
|
|
17
|
+
while (true) {
|
|
18
|
+
const res = await getTaskStatus({ taskId });
|
|
19
|
+
if (res.data?.task?.state === 1) {
|
|
20
|
+
console.log(chalk.green(`[SUCCESS] Theme app pushed successfully.`));
|
|
21
|
+
break;
|
|
22
|
+
} else if (res.data?.task?.state === 2) {
|
|
23
|
+
console.error(chalk.red(`[ERROR] Theme app push failed: ${res.data?.task?.error_message}`));
|
|
24
|
+
break;
|
|
25
|
+
} else {
|
|
26
|
+
console.log(chalk.yellow(`[WAITING] Theme app push in progress...`));
|
|
27
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
27
28
|
}
|
|
28
|
-
return true;
|
|
29
|
-
} catch (e) {
|
|
30
|
-
console.log(e);
|
|
31
29
|
}
|
|
32
|
-
}
|
|
30
|
+
}
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
/**
|
|
33
|
+
* 交互式命令行
|
|
34
|
+
*/
|
|
35
|
+
async function usePrompt() {
|
|
36
|
+
const versionList = await getThemeAppVersionList();
|
|
37
|
+
const latestVersion = versionList[versionList.length - 1];
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
39
|
+
console.log(
|
|
40
|
+
chalk.cyanBright(`\n🔍 Latest version: `) +
|
|
41
|
+
chalk.yellow(`${latestVersion.version} `) +
|
|
42
|
+
chalk.white(`(${latestVersion.description})`) +
|
|
43
|
+
chalk.gray(` [Released on: ${latestVersion.date}]`)
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
return inquirer.prompt([
|
|
47
|
+
{
|
|
48
|
+
type: 'input',
|
|
49
|
+
name: 'newVersion',
|
|
50
|
+
message: 'Enter the new version number:',
|
|
51
|
+
validate: (newVersion) => {
|
|
52
|
+
if (!/^[0-9]+\.[0-9]+\.[0-9]+$/.test(newVersion)) {
|
|
53
|
+
return chalk.red('❌ Version must follow the format X.Y.Z (e.g., 1.0.0).');
|
|
54
|
+
}
|
|
55
|
+
if (compareVersions(newVersion, latestVersion.version) !== 1) {
|
|
56
|
+
return chalk.red('❌ Version must be greater than the latest version.');
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: 'input',
|
|
63
|
+
name: 'description',
|
|
64
|
+
message: 'Enter the description for this version:',
|
|
65
|
+
validate: (description) => {
|
|
66
|
+
if (!description.trim()) {
|
|
67
|
+
return chalk.red('❌ Description cannot be empty.');
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
]);
|
|
73
|
+
}
|
|
43
74
|
|
|
44
|
-
|
|
45
|
-
const spinner = ora(chalk.cyan('Building your app and generate zip package ...')).start();
|
|
75
|
+
async function build() {
|
|
46
76
|
try {
|
|
47
|
-
const
|
|
48
|
-
await
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
spinner.fail(e.message);
|
|
77
|
+
const { appId } = await getThemeAppConfig();
|
|
78
|
+
const { newVersion, description } = await usePrompt();
|
|
79
|
+
await createNewVersion(appId, newVersion, description);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error(chalk.red(`[ERROR IN BUILD] ${error.message}`));
|
|
53
82
|
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const build = async () => {
|
|
57
|
-
line();
|
|
58
|
-
(await clearManifest()) && (await buildThemeAssets('./assets')) && (await zipApp());
|
|
59
|
-
done();
|
|
60
|
-
line();
|
|
61
|
-
};
|
|
83
|
+
}
|
|
62
84
|
|
|
63
85
|
module.exports = {
|
|
64
|
-
build
|
|
65
|
-
getZipName
|
|
86
|
+
build
|
|
66
87
|
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const inquirer = require('inquirer');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fsExtra = require('fs-extra');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const { WORKSPACE_PATH, THEME_APP_TYPE } = require('../utils/config');
|
|
6
|
+
const { replacePlaceholders, renameFile } = require('../utils');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 交互式命令行
|
|
10
|
+
*/
|
|
11
|
+
async function usePrompt() {
|
|
12
|
+
return await inquirer.prompt([
|
|
13
|
+
{
|
|
14
|
+
type: 'list',
|
|
15
|
+
name: 'themeAppType',
|
|
16
|
+
message: 'Select theme app type:',
|
|
17
|
+
choices: [THEME_APP_TYPE.BASIC_APP.description, THEME_APP_TYPE.EMBEDS_APP.description],
|
|
18
|
+
prefix: '*'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
type: 'input',
|
|
22
|
+
name: 'projectName',
|
|
23
|
+
message: 'Please enter the theme app project name:',
|
|
24
|
+
prefix: '*',
|
|
25
|
+
validate: (projectName) => {
|
|
26
|
+
if (!projectName.trim()) {
|
|
27
|
+
return 'Project name cannot be empty';
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 初始化项目
|
|
37
|
+
*/
|
|
38
|
+
async function initProj(projectPath, projectName) {
|
|
39
|
+
// 替换占位符 key文件相对路径 value替换的内容
|
|
40
|
+
const replacementConfig = {
|
|
41
|
+
'package.json': { projectName },
|
|
42
|
+
'theme-app/blocks/index.liquid': { projectName },
|
|
43
|
+
'theme-app.config.json': { projectName }
|
|
44
|
+
};
|
|
45
|
+
for (const [filePath, replacements] of Object.entries(replacementConfig)) {
|
|
46
|
+
const fullPath = path.resolve(projectPath, filePath);
|
|
47
|
+
await replacePlaceholders(fullPath, replacements);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 重命名文件
|
|
51
|
+
const filesToRename = ['assets/index.css', 'blocks/index.liquid', 'snippets/index.liquid'];
|
|
52
|
+
for (const file of filesToRename) {
|
|
53
|
+
const filePath = path.resolve(projectPath, 'theme-app', file);
|
|
54
|
+
await renameFile(filePath, `${projectName}${file.includes('snippets') ? '_snippet' : ''}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 控制台提示信息
|
|
60
|
+
*/
|
|
61
|
+
function consoleTips(projectName) {
|
|
62
|
+
console.log(chalk.green(`Theme app project "${projectName}" has been successfully created.`));
|
|
63
|
+
console.log(chalk.bold(`To get started:\n`));
|
|
64
|
+
console.log(` ${chalk.cyan(`cd ${projectName}`)}`);
|
|
65
|
+
console.log(` ${chalk.cyan(`npm start`)}\n`);
|
|
66
|
+
console.log(chalk.greenBright(`Happy coding! 🎉🎉🎉`));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 创建项目
|
|
71
|
+
*/
|
|
72
|
+
async function _create(themeAppDescription, projectName) {
|
|
73
|
+
const projectPath = path.resolve(WORKSPACE_PATH, projectName);
|
|
74
|
+
const projectExists = await fsExtra.pathExists(projectPath);
|
|
75
|
+
|
|
76
|
+
if (projectExists) {
|
|
77
|
+
throw new Error(`Project directory "${projectName}" already exists.`);
|
|
78
|
+
}
|
|
79
|
+
await fsExtra.ensureDir(projectPath);
|
|
80
|
+
const templatePath =
|
|
81
|
+
THEME_APP_TYPE.BASIC_APP.description === themeAppDescription
|
|
82
|
+
? THEME_APP_TYPE.BASIC_APP.templatePath
|
|
83
|
+
: THEME_APP_TYPE.EMBEDS_APP.templatePath;
|
|
84
|
+
await fsExtra.copy(templatePath, projectPath);
|
|
85
|
+
await initProj(projectPath, projectName);
|
|
86
|
+
consoleTips(projectName);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function create() {
|
|
90
|
+
try {
|
|
91
|
+
const { themeAppType, projectName } = await usePrompt();
|
|
92
|
+
await _create(themeAppType, projectName);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error(chalk.red(`[ERROR IN CREATE] ${error.message}`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = {
|
|
99
|
+
create
|
|
100
|
+
};
|