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
|
@@ -1,218 +1,47 @@
|
|
|
1
|
-
const
|
|
2
|
-
const ora = require('ora');
|
|
1
|
+
const inquirer = require('inquirer');
|
|
3
2
|
const chalk = require('chalk');
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
spinner.succeed(
|
|
31
|
-
chalk.cyan(
|
|
32
|
-
`Success to find your zip: ${chalk.green(`${filename} ${(fileInfo.size / (1024 * 1024)).toFixed(2)}M`)}`
|
|
33
|
-
)
|
|
34
|
-
);
|
|
35
|
-
return path.resolve(process.cwd(), filename);
|
|
36
|
-
} catch (e) {
|
|
37
|
-
spinner.fail(chalk.red('Failed to find your zip, be sure you have built app in root dir!'));
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const getBufferAndMd5 = async (filePath) => {
|
|
42
|
-
const spinner = ora(chalk.cyan('Begin to read zip and generate md5 code ...')).start();
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
return await new Promise((resolve, reject) => {
|
|
46
|
-
const spark = new SparkMD5.ArrayBuffer();
|
|
47
|
-
let buffers = [];
|
|
48
|
-
|
|
49
|
-
const rs = fs.createReadStream(filePath, { autoClose: true });
|
|
50
|
-
rs.on('data', (data) => {
|
|
51
|
-
buffers.push(data);
|
|
52
|
-
spark.append(data);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
rs.on('end', () => {
|
|
56
|
-
const md5 = spark.end();
|
|
57
|
-
const completedBuffer = Buffer.concat(buffers);
|
|
58
|
-
spinner.succeed(chalk.cyan('Success to analyse zip'));
|
|
59
|
-
resolve([completedBuffer, md5 + '.zip']);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
rs.on('error', (err) => {
|
|
63
|
-
reject(err);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
} catch (e) {
|
|
67
|
-
spinner.fail(chalk.red('Failed to analyse zip, please try again!'));
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const getSign = async () => {
|
|
72
|
-
const spinner = ora(chalk.cyan('Waiting get file sign ...')).start();
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
const app = getApp();
|
|
76
|
-
const partnerId = getValue(PARTNER_KEYS.PARTNER_ID);
|
|
77
|
-
const sessionId = getValue(PARTNER_KEYS.SESSION_ID);
|
|
78
|
-
|
|
79
|
-
const url = `${PARNTER_URL}/api/partner/apps/${app.uid}/theme_extensions/file/signv2`;
|
|
80
|
-
const res = await axios.get(url, {
|
|
81
|
-
headers: {
|
|
82
|
-
Cookie: `awesomev2=${sessionId}`,
|
|
83
|
-
'x-shoplazza-partner-id': partnerId
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
spinner.succeed(chalk.cyan('Success to get file sign'));
|
|
87
|
-
return res.data;
|
|
88
|
-
} catch (e) {
|
|
89
|
-
spinner.fail(chalk.red(e.message || e));
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const deployOss = async () => {
|
|
94
|
-
const path = getZipPath();
|
|
95
|
-
if (path) {
|
|
96
|
-
const [buffer, md5] = await getBufferAndMd5(path);
|
|
97
|
-
const signData = await getSign();
|
|
98
|
-
if (!signData) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const spinner = ora(chalk.cyan('Deploying your zip to cdn ...')).start();
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
const formData = new FormData();
|
|
106
|
-
formData.append('policy', signData.policy);
|
|
107
|
-
formData.append('OSSAccessKeyId', signData.access_id);
|
|
108
|
-
formData.append('success_action_status', 200);
|
|
109
|
-
formData.append('signature', signData.sign);
|
|
110
|
-
formData.append('x-oss-forbid-overwrite', 'true');
|
|
111
|
-
formData.append('key', md5);
|
|
112
|
-
formData.append('file', buffer);
|
|
113
|
-
|
|
114
|
-
const url = `https:${signData.write_host}/`;
|
|
115
|
-
const res = await axios.post(url, formData, {
|
|
116
|
-
global: true,
|
|
117
|
-
maxContentLength: 100000000,
|
|
118
|
-
maxBodyLength: 1000000000
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
if (res.status !== 200) {
|
|
122
|
-
throw new Error(`${res.status} ${resstatusText}`);
|
|
123
|
-
}
|
|
124
|
-
spinner.succeed();
|
|
125
|
-
return md5;
|
|
126
|
-
} catch (e) {
|
|
127
|
-
// 409 repeat filename
|
|
128
|
-
if (e?.response?.status === 409) {
|
|
129
|
-
spinner.succeed();
|
|
130
|
-
return md5;
|
|
131
|
-
}
|
|
132
|
-
spinner.fail();
|
|
133
|
-
console.log(chalk.red(e.message || e));
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
const deployPartner = async () => {
|
|
139
|
-
const md5 = await deployOss();
|
|
140
|
-
if (!md5) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const spinner = ora(chalk.cyan('Deploying your zip to PARTNER ...')).start();
|
|
145
|
-
try {
|
|
146
|
-
const app = getApp();
|
|
147
|
-
if (!app) {
|
|
148
|
-
spinner.fail(chalk.red('Please choose your partner first!'));
|
|
149
|
-
return;
|
|
3
|
+
const ora = require('ora');
|
|
4
|
+
const { getThemeAppConfig } = require('../utils');
|
|
5
|
+
const { getThemeAppVersionList, toDeployThemeApp } = require('../api/api');
|
|
6
|
+
|
|
7
|
+
// 调用后端 API 进行部署
|
|
8
|
+
async function deployVersion(appId, version) {
|
|
9
|
+
// await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
10
|
+
await toDeployThemeApp({
|
|
11
|
+
extension_id: appId,
|
|
12
|
+
version,
|
|
13
|
+
type: 'enable'
|
|
14
|
+
});
|
|
15
|
+
console.log(chalk.green(`Version ${version} has been deployed successfully.`));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function usePrompt(versionList) {
|
|
19
|
+
const choices = versionList.map((v) => ({
|
|
20
|
+
name: `${v.version} (${v.date}) - ${v.description}`,
|
|
21
|
+
value: v.version
|
|
22
|
+
}));
|
|
23
|
+
return inquirer.prompt([
|
|
24
|
+
{
|
|
25
|
+
type: 'list',
|
|
26
|
+
name: 'selectedVersion',
|
|
27
|
+
message: 'Select a version to deploy:',
|
|
28
|
+
choices
|
|
150
29
|
}
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
151
32
|
|
|
152
|
-
|
|
153
|
-
const url = `${PARNTER_URL}/api/partner/apps/${app.uid}/theme_extensions`;
|
|
154
|
-
const res = await axios.put(
|
|
155
|
-
url,
|
|
156
|
-
{
|
|
157
|
-
title: getZipName(),
|
|
158
|
-
name: getZipName(),
|
|
159
|
-
file_name: md5
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
headers: {
|
|
163
|
-
cookie: `awesomev2=${getValue(PARTNER_KEYS.SESSION_ID)};`,
|
|
164
|
-
'x-shoplazza-partner-id': partnerId
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
set({ [PARTNER_KEYS.EXTENSION_ID]: res.data.extension_id });
|
|
170
|
-
spinner.succeed();
|
|
171
|
-
return true;
|
|
172
|
-
} catch (e) {
|
|
173
|
-
spinner.fail();
|
|
174
|
-
console.log(e.message || e);
|
|
175
|
-
console.log(chalk.red(JSON.stringify(e.response.data)));
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const createVersion = async (version) => {
|
|
180
|
-
const spinner = ora(chalk.cyan('Creating your version task ...')).start();
|
|
181
|
-
|
|
33
|
+
async function deploy() {
|
|
182
34
|
try {
|
|
183
|
-
const
|
|
184
|
-
const
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
const
|
|
188
|
-
await
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
version
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
headers: {
|
|
195
|
-
cookie: `awesomev2=${getValue(PARTNER_KEYS.SESSION_ID)};`,
|
|
196
|
-
'x-shoplazza-partner-id': partnerId
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
);
|
|
200
|
-
spinner.succeed();
|
|
201
|
-
return true;
|
|
202
|
-
} catch (e) {
|
|
203
|
-
spinner.fail();
|
|
204
|
-
console.log(chalk.red(e.message || e));
|
|
205
|
-
console.log(chalk.red(JSON.stringify(e.response?.data)));
|
|
35
|
+
const { appId } = await getThemeAppConfig();
|
|
36
|
+
const spinner = ora('Fetching version list...').start();
|
|
37
|
+
const versionList = await getThemeAppVersionList();
|
|
38
|
+
spinner.succeed('Version list loaded.');
|
|
39
|
+
const { selectedVersion } = await usePrompt(versionList);
|
|
40
|
+
await deployVersion(appId, selectedVersion);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error(chalk.red(`[ERROR IN DEPLOY] ${error.message}`));
|
|
206
43
|
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const deploy = async () => {
|
|
210
|
-
line();
|
|
211
|
-
ora(chalk.cyan('Deploy Begin')).succeed();
|
|
212
|
-
let version;
|
|
213
|
-
(await deployPartner()) && (version = await inputVersion()) && (await createVersion(version)) && done();
|
|
214
|
-
line();
|
|
215
|
-
};
|
|
44
|
+
}
|
|
216
45
|
|
|
217
46
|
module.exports = {
|
|
218
47
|
deploy
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const ora = require('ora');
|
|
3
|
+
const { getThemeAppConfig, renderTable } = require('../utils');
|
|
4
|
+
const { getThemeAppList } = require('../api/api');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 控制台提示
|
|
8
|
+
*/
|
|
9
|
+
function consoleTips(versionList) {
|
|
10
|
+
console.log(chalk.green('\n📜 Available Theme Apps:'));
|
|
11
|
+
console.log(
|
|
12
|
+
renderTable(versionList, [
|
|
13
|
+
{ label: 'Name', filed: 'name' },
|
|
14
|
+
{ label: 'Version', filed: 'version', color: 'yellowBright' },
|
|
15
|
+
{ label: 'Description', filed: 'description' }
|
|
16
|
+
])
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function list() {
|
|
21
|
+
try {
|
|
22
|
+
const themeAppList = await getThemeAppList();
|
|
23
|
+
consoleTips(themeAppList);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error(chalk.red(`[ERROR IN LIST] ${error.message}`));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
list
|
|
31
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const inquirer = require('inquirer');
|
|
4
|
+
const { STORE_DOMAIN, THEME_APP_PATH, EXCHANGE_TOKEN } = require('../utils/config');
|
|
5
|
+
const { compress, getThemeAppConfig, setThemeAppConfig } = require('../utils');
|
|
6
|
+
const { toCreateThemeApp, toUploadThemeApp, getTaskStatus, getThemeList } = require('../api/api');
|
|
7
|
+
const { initWatcher } = require('../../utils');
|
|
8
|
+
const { useOss } = require('../../oss');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 模拟上传文件到服务器
|
|
12
|
+
*/
|
|
13
|
+
async function uploadFileToServer(filePath) {
|
|
14
|
+
console.log(chalk.blue(`[UPLOAD] ${filePath} - Uploading to server...`));
|
|
15
|
+
// TODO: 替换为实际的上传逻辑(例如调用后端 API 或 WebSocket 通信)
|
|
16
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); // 模拟网络延迟
|
|
17
|
+
console.log(chalk.green(`[SUCCESS] ${filePath} - Uploaded successfully.`));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 控制台提示信息
|
|
22
|
+
*/
|
|
23
|
+
function consoleTips(selectedThemeId, appId) {
|
|
24
|
+
console.log(`\n======================================PREVIEW URLS======================================`);
|
|
25
|
+
console.log(chalk.cyan.bold('🔗 Admin Preview URL:'));
|
|
26
|
+
console.log(
|
|
27
|
+
chalk.blueBright(` https://${STORE_DOMAIN}/admin/card?theme_id=${selectedThemeId}&ext_debug=${appId}\n`)
|
|
28
|
+
);
|
|
29
|
+
console.log(chalk.cyan.bold('🔗 Storefront Preview URL:'));
|
|
30
|
+
console.log(chalk.blueBright(` https://${STORE_DOMAIN}?preview_theme_id=${selectedThemeId}&ext_debug[]=${appId}\n`));
|
|
31
|
+
console.log(`=====================================WATCHER RUNNING=====================================`);
|
|
32
|
+
console.log(chalk.green(`🎉 File watcher is now running!`));
|
|
33
|
+
console.log(chalk.green(`📂 Watching directory:`), chalk.blue(THEME_APP_PATH));
|
|
34
|
+
console.log(chalk.green(`✨ You can make changes to your files, and they will be processed automatically.`));
|
|
35
|
+
console.log(chalk.green(`🚀 Press Ctrl+C to stop.\n`));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 同步本地代码到远程服务器
|
|
40
|
+
*/
|
|
41
|
+
async function syncLocalFiles(appId) {
|
|
42
|
+
const { zipPath, zipName } = await compress(THEME_APP_PATH);
|
|
43
|
+
const { uploadOss } = useOss(
|
|
44
|
+
EXCHANGE_TOKEN,
|
|
45
|
+
STORE_DOMAIN,
|
|
46
|
+
`✗ No store found. Please run ${chalk.cyan('shoplazza login')} to login to a specific store.`
|
|
47
|
+
);
|
|
48
|
+
const zipOssUrl = await uploadOss(zipPath, zipName);
|
|
49
|
+
const res = await toUploadThemeApp({
|
|
50
|
+
extension_id: appId,
|
|
51
|
+
resource_url: zipOssUrl
|
|
52
|
+
});
|
|
53
|
+
const taskId = res.data?.task_id;
|
|
54
|
+
// 轮询查看任务是否完成
|
|
55
|
+
while (true) {
|
|
56
|
+
const res = await getTaskStatus({ taskId });
|
|
57
|
+
if (res.data?.task?.state === 1) {
|
|
58
|
+
console.log(chalk.green(`[SUCCESS] Theme app pushed successfully.`));
|
|
59
|
+
break;
|
|
60
|
+
} else if (res.data?.task?.state === 2) {
|
|
61
|
+
console.error(chalk.red(`[ERROR] Theme app push failed: ${res.data?.task?.error_message}`));
|
|
62
|
+
break;
|
|
63
|
+
} else {
|
|
64
|
+
console.log(chalk.yellow(`[WAITING] Theme app push in progress...`));
|
|
65
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 交互选择预览主题
|
|
72
|
+
*/
|
|
73
|
+
async function usePrompt() {
|
|
74
|
+
const res = await getThemeList();
|
|
75
|
+
const themeList = res.data?.data?.themes || [];
|
|
76
|
+
const { selectedThemeId } = await inquirer.prompt([
|
|
77
|
+
{
|
|
78
|
+
type: 'list',
|
|
79
|
+
name: 'selectedThemeId',
|
|
80
|
+
message: 'Please select a theme to preview:',
|
|
81
|
+
choices: themeList.map((theme) => ({
|
|
82
|
+
name: theme.name,
|
|
83
|
+
value: theme.id
|
|
84
|
+
}))
|
|
85
|
+
}
|
|
86
|
+
]);
|
|
87
|
+
return selectedThemeId;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 创建主题插件
|
|
92
|
+
*/
|
|
93
|
+
async function createThemeApp(appName) {
|
|
94
|
+
const res = await toCreateThemeApp({
|
|
95
|
+
title: appName
|
|
96
|
+
});
|
|
97
|
+
const appId = res.data?.extension_id;
|
|
98
|
+
// QQQ1
|
|
99
|
+
await setThemeAppConfig({ appId });
|
|
100
|
+
return appId;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function serve() {
|
|
104
|
+
try {
|
|
105
|
+
let { appId, appName } = await getThemeAppConfig();
|
|
106
|
+
// if (!appId) {
|
|
107
|
+
// appId = createThemeApp(appName);
|
|
108
|
+
// }
|
|
109
|
+
// await syncLocalFiles(appId);
|
|
110
|
+
const selectedThemeId = await usePrompt();
|
|
111
|
+
initWatcher(THEME_APP_PATH);
|
|
112
|
+
consoleTips(selectedThemeId, appId);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error(chalk.red(`[ERROR IN SERVE] ${error.message}`));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = { serve };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const ora = require('ora');
|
|
3
|
+
const { getThemeAppConfig, renderTable } = require('../utils');
|
|
4
|
+
const { getThemeAppVersionList } = require('../api/api');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 控制台提示
|
|
8
|
+
*/
|
|
9
|
+
function consoleTips(versionList) {
|
|
10
|
+
console.log(chalk.green('\n📜 Available Versions:'));
|
|
11
|
+
console.log(
|
|
12
|
+
renderTable(versionList, [
|
|
13
|
+
{
|
|
14
|
+
label: 'Version',
|
|
15
|
+
filed: 'version',
|
|
16
|
+
color: 'yellowBright'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
label: 'Date',
|
|
20
|
+
filed: 'date',
|
|
21
|
+
color: 'blackBright'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: 'Description',
|
|
25
|
+
filed: 'description',
|
|
26
|
+
color: 'whiteBright'
|
|
27
|
+
}
|
|
28
|
+
])
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function versions() {
|
|
33
|
+
try {
|
|
34
|
+
const { appId } = await getThemeAppConfig();
|
|
35
|
+
const versionList = await getThemeAppVersionList({ appId });
|
|
36
|
+
consoleTips(versionList);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error(chalk.red(`[ERROR IN VERSIONS] ${error.message}`));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = {
|
|
43
|
+
versions
|
|
44
|
+
};
|
package/lib/app/index.js
CHANGED
|
@@ -1,37 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const { deploy } = require('./commands/deploy');
|
|
4
|
-
const { generate } = require('./commands/generate');
|
|
5
|
-
const { publish } = require('./commands/publish');
|
|
6
|
-
const { choosePartner } = require('./inquirers/choose-partner');
|
|
7
|
-
const { chooseApp } = require('./inquirers/choose-app');
|
|
1
|
+
function initThemeAppCommand(_program) {
|
|
2
|
+
const program = _program.command('app').description('Shoplazza app CLI');
|
|
8
3
|
|
|
9
|
-
|
|
10
|
-
(await checkAndLogin()) && (await generate());
|
|
11
|
-
};
|
|
4
|
+
program.command('create').description('Create a new theme app').action(require('./commands/create').create);
|
|
12
5
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
program
|
|
7
|
+
.command('serve')
|
|
8
|
+
.description('Start a local development server for the theme app')
|
|
9
|
+
.action(require('./commands/serve').serve);
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
(await checkAndLogin()) && (await publish());
|
|
19
|
-
};
|
|
11
|
+
program.command('build').description('Build the theme app for production').action(require('./commands/build').build);
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
(
|
|
24
|
-
|
|
13
|
+
program
|
|
14
|
+
.command('versions')
|
|
15
|
+
.description('List all versions of the theme app')
|
|
16
|
+
.action(require('./commands/versions').versions);
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
18
|
+
program.command('deploy').description('Deploy the theme app').action(require('./commands/deploy').deploy);
|
|
19
|
+
|
|
20
|
+
program.command('list').description('List all theme apps').action(require('./commands/list').list);
|
|
21
|
+
}
|
|
30
22
|
|
|
31
23
|
module.exports = {
|
|
32
|
-
|
|
33
|
-
deployExtension,
|
|
34
|
-
publishExtension,
|
|
35
|
-
buildExtension: build,
|
|
36
|
-
retry
|
|
24
|
+
initThemeAppCommand
|
|
37
25
|
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Theme Basic App
|
|
2
|
+
|
|
3
|
+
## 概览
|
|
4
|
+
|
|
5
|
+
一个基础的主题插件项目
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
首先,确保您安装了“Shoplazza CLI”。如果没有,您可以使用以下命令全局安装它:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g shoplazza-cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 可用的脚本
|
|
16
|
+
|
|
17
|
+
### `create`
|
|
18
|
+
|
|
19
|
+
创建主题插件项目模版
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
shoplazza app create
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
进入项目目录后,即可使用以下命令:
|
|
28
|
+
|
|
29
|
+
### `start`
|
|
30
|
+
|
|
31
|
+
启动开发模式
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm start
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
或者
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
shoplazza app serve
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### `build`
|
|
44
|
+
|
|
45
|
+
基于当前的草稿生成对应正式版本的主题插件
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm run build
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
或者
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
shoplazza app build
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `deploy`
|
|
58
|
+
|
|
59
|
+
部署正式版本的主题插件(部署后插件在店铺的主题编辑器的app列表中可见)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm run deploy
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
或者
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
shoplazza app deploy
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### `versions`
|
|
72
|
+
|
|
73
|
+
查询主题插件的历史正式版本列表
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm run versions
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
或者
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
shoplazza app versions
|
|
83
|
+
```
|
|
84
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "theme basic app",
|
|
5
|
+
"main": "null",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "shoplazza app serve",
|
|
8
|
+
"build": "shoplazza app build",
|
|
9
|
+
"deploy": "shoplazza app deploy",
|
|
10
|
+
"versions": "shoplazza app versions"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [],
|
|
13
|
+
"author": "",
|
|
14
|
+
"license": "ISC"
|
|
15
|
+
}
|