shoplazza-cli 1.0.5 → 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 +3 -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 +11 -34
- 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
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Theme Embed App
|
|
2
|
+
|
|
3
|
+
## 概览
|
|
4
|
+
|
|
5
|
+
一个 embed 的主题插件项目
|
|
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 embed 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
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<div id="{{projectName}}" class="container">
|
|
2
|
+
<p>Hello world</p>
|
|
3
|
+
</div>
|
|
4
|
+
{% include "{{projectName}}_snippet" %}
|
|
5
|
+
|
|
6
|
+
{% schema %}
|
|
7
|
+
{
|
|
8
|
+
"name": {
|
|
9
|
+
"en-US": "default name",
|
|
10
|
+
"zh-CN": "默认名称"
|
|
11
|
+
},
|
|
12
|
+
"target":"body",
|
|
13
|
+
"settings": []
|
|
14
|
+
}
|
|
15
|
+
{% endschema %}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { get } = require('../../db/user');
|
|
3
|
+
|
|
4
|
+
const WORKSPACE_PATH = process.cwd();
|
|
5
|
+
|
|
6
|
+
const THEME_APP_PATH = path.resolve(WORKSPACE_PATH, 'theme-app');
|
|
7
|
+
|
|
8
|
+
const STORE_DOMAIN = get('store_domain');
|
|
9
|
+
|
|
10
|
+
const EXCHANGE_TOKEN = get('exchange_token');
|
|
11
|
+
|
|
12
|
+
const THEME_APP_TYPE = {
|
|
13
|
+
BASIC_APP: {
|
|
14
|
+
description: 'basic app(just an basic app)',
|
|
15
|
+
templatePath: path.resolve(__dirname, '../template/basic-app')
|
|
16
|
+
},
|
|
17
|
+
EMBEDS_APP: {
|
|
18
|
+
description: 'embed app(embed in a theme)',
|
|
19
|
+
templatePath: path.resolve(__dirname, '../template/embed-app')
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
module.exports = {
|
|
24
|
+
WORKSPACE_PATH,
|
|
25
|
+
THEME_APP_PATH,
|
|
26
|
+
STORE_DOMAIN,
|
|
27
|
+
EXCHANGE_TOKEN,
|
|
28
|
+
THEME_APP_TYPE,
|
|
29
|
+
};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
const fsExtra = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const AdmZip = require('adm-zip');
|
|
5
|
+
const md5 = require('md5');
|
|
6
|
+
const { table } = require('table');
|
|
7
|
+
const { WORKSPACE_PATH } = require('./config');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 通用的占位符替换函数
|
|
11
|
+
*/
|
|
12
|
+
const replacePlaceholders = async (filePath, replacements) => {
|
|
13
|
+
if (!(await fsExtra.pathExists(filePath))) {
|
|
14
|
+
console.warn(`File "${filePath}" does not exist, skipping replacement.`);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
let content = await fsExtra.readFile(filePath, 'utf-8');
|
|
18
|
+
// 替换占位符
|
|
19
|
+
for (const [placeholder, value] of Object.entries(replacements)) {
|
|
20
|
+
const regex = new RegExp(`\\{\\{${placeholder}\\}\\}`, 'g'); // 匹配占位符格式:{{placeholder}}
|
|
21
|
+
content = content.replace(regex, value);
|
|
22
|
+
}
|
|
23
|
+
// 写回文件
|
|
24
|
+
await fsExtra.writeFile(filePath, content, 'utf-8');
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 重命名指定文件
|
|
29
|
+
* @param {string} filePath - 原始文件的完整路径
|
|
30
|
+
* @param {string} targetName - 新的文件名
|
|
31
|
+
*/
|
|
32
|
+
const renameFile = async (filePath, targetName) => {
|
|
33
|
+
if (!(await fsExtra.pathExists(filePath))) {
|
|
34
|
+
console.warn(`File "${filePath}" does not exist, skipping.`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const targetFilePath = path.resolve(path.dirname(filePath), `${targetName}${path.extname(filePath)}`);
|
|
38
|
+
await fsExtra.rename(filePath, targetFilePath);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 获取themeApp配置(信息)
|
|
43
|
+
* @returns {Promise<string>}
|
|
44
|
+
*/
|
|
45
|
+
async function getThemeAppConfig() {
|
|
46
|
+
const configFilePath = path.join(WORKSPACE_PATH, 'theme-app.config.json');
|
|
47
|
+
if (!(await fsExtra.pathExists(configFilePath))) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`The current workspace is not a valid theme app project, because "${WORKSPACE_PATH}" is missing the required "theme-app.config.json" file.`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return fsExtra.readJson(configFilePath);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 更新themeApp配置(信息)
|
|
57
|
+
* @param {Object} config 待更新的配置信息
|
|
58
|
+
*/
|
|
59
|
+
async function setThemeAppConfig(config) {
|
|
60
|
+
const oldThemeAppConfig = await getThemeAppConfig();
|
|
61
|
+
const newThemeAppConfig = { ...oldThemeAppConfig, ...config };
|
|
62
|
+
await fsExtra.writeJson(configFilePath, newThemeAppConfig, { spaces: 2 });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 计算文件夹内容的哈希值
|
|
67
|
+
* @param {string} dirPath - 文件夹路径
|
|
68
|
+
* @returns {Promise<string>} 返回基于文件夹内容的哈希值
|
|
69
|
+
*/
|
|
70
|
+
async function calculateFolderHash(dirPath) {
|
|
71
|
+
if (!(await fsExtra.pathExists(dirPath))) {
|
|
72
|
+
throw new Error(chalk.red(`Calculate folder hash path does not exist: ${dirPath}`));
|
|
73
|
+
}
|
|
74
|
+
const files = await fsExtra.readdir(dirPath);
|
|
75
|
+
let contentHash = '';
|
|
76
|
+
for (const file of files) {
|
|
77
|
+
const filePath = path.join(dirPath, file);
|
|
78
|
+
const fileStats = await fsExtra.stat(filePath);
|
|
79
|
+
|
|
80
|
+
if (fileStats.isDirectory()) {
|
|
81
|
+
// 如果是目录,递归计算文件夹内容的哈希值
|
|
82
|
+
contentHash += await calculateFolderHash(filePath);
|
|
83
|
+
} else {
|
|
84
|
+
// 如果是文件,读取文件内容并计算哈希
|
|
85
|
+
const fileContent = await fsExtra.readFile(filePath);
|
|
86
|
+
contentHash += md5(fileContent);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return md5(contentHash);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 通用的压缩函数(同目录生成zip压缩文件)
|
|
95
|
+
* @param {string} sourcePath - 需要压缩的目录或文件路径
|
|
96
|
+
* @returns {Promise<Object>} 返回压缩文件的生成路径&压碎文件名
|
|
97
|
+
*/
|
|
98
|
+
async function compress(sourcePath) {
|
|
99
|
+
if (!(await fsExtra.pathExists(sourcePath))) {
|
|
100
|
+
throw new Error(chalk.red(`Compress path does not exist: ${sourcePath}`));
|
|
101
|
+
}
|
|
102
|
+
const sourceName = path.basename(sourcePath);
|
|
103
|
+
const outputDir = path.dirname(sourcePath);
|
|
104
|
+
const sourceHash = await calculateFolderHash(sourcePath);
|
|
105
|
+
const fileName = `${sourceName}-${sourceHash.substring(0, 8)}${Date.now().toString(16).substring(0, 8)}.zip`;
|
|
106
|
+
const outputPath = path.resolve(outputDir, fileName);
|
|
107
|
+
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
const zip = new AdmZip();
|
|
110
|
+
if (fsExtra.statSync(sourcePath).isDirectory()) {
|
|
111
|
+
zip.addLocalFolder(sourcePath, sourceName);
|
|
112
|
+
} else {
|
|
113
|
+
zip.addLocalFile(sourcePath);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
zip.writeZip(outputPath, (err) => {
|
|
117
|
+
if (err) {
|
|
118
|
+
reject(err);
|
|
119
|
+
} else {
|
|
120
|
+
console.log(chalk.green(`Source path compressed successfully. File saved at: ${outputPath}`));
|
|
121
|
+
resolve({
|
|
122
|
+
zipPath: outputPath,
|
|
123
|
+
zipName: fileName
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 比较两个版本号的大小
|
|
132
|
+
* @param {String} version1 版本号1
|
|
133
|
+
* @param {String} version2 版本号2
|
|
134
|
+
* @returns version1 < version2 返回 -1,version1 > version2 返回 1,相等返回 0
|
|
135
|
+
*/
|
|
136
|
+
function compareVersions(version1, version2) {
|
|
137
|
+
const v1 = version1.split('.').map(Number);
|
|
138
|
+
const v2 = version2.split('.').map(Number);
|
|
139
|
+
|
|
140
|
+
for (let i = 0; i < Math.max(v1.length, v2.length); i++) {
|
|
141
|
+
const num1 = v1[i] || 0;
|
|
142
|
+
const num2 = v2[i] || 0;
|
|
143
|
+
|
|
144
|
+
if (num1 < num2) {
|
|
145
|
+
return -1;
|
|
146
|
+
}
|
|
147
|
+
if (num1 > num2) {
|
|
148
|
+
return 1;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return 0;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* 获取文件名及其直接父目录名
|
|
156
|
+
* @param {string} filePath - 文件的绝对路径
|
|
157
|
+
* @returns {{ fileName: string, parentDirName: string }} 返回包含文件名和父目录名的对象
|
|
158
|
+
*/
|
|
159
|
+
async function getFileInfo(filePath) {
|
|
160
|
+
if (!(await fsExtra.pathExists(filePath))) {
|
|
161
|
+
throw new Error(chalk.red(`File path does not exist: ${filePath}`));
|
|
162
|
+
}
|
|
163
|
+
const fileName = path.basename(filePath);
|
|
164
|
+
const parentDirName = path.basename(path.dirname(filePath));
|
|
165
|
+
return { fileName, parentDirName };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 表格配置
|
|
169
|
+
const TABLE_CONFIG = {
|
|
170
|
+
border: {
|
|
171
|
+
topBody: '═',
|
|
172
|
+
topJoin: '╤',
|
|
173
|
+
topLeft: '╔',
|
|
174
|
+
topRight: '╗',
|
|
175
|
+
bottomBody: '═',
|
|
176
|
+
bottomJoin: '╧',
|
|
177
|
+
bottomLeft: '╚',
|
|
178
|
+
bottomRight: '╝',
|
|
179
|
+
bodyLeft: '║',
|
|
180
|
+
bodyRight: '║',
|
|
181
|
+
bodyJoin: '│',
|
|
182
|
+
joinBody: '─',
|
|
183
|
+
joinLeft: '╟',
|
|
184
|
+
joinRight: '╢',
|
|
185
|
+
joinJoin: '┼'
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* 图像化表格渲染数据
|
|
191
|
+
* @param {Array} data - 数据
|
|
192
|
+
* @param {Array} options - 配置项 [{ label:string, filed:string, color?:string}, ...]
|
|
193
|
+
* @example
|
|
194
|
+
* renderTable([{name:'Jack',age:20},{name:'Tom',age:30}],
|
|
195
|
+
* [{label:'姓名',filed:'name',color:''},{label:'年龄',filed:'age',color:''}]
|
|
196
|
+
* )
|
|
197
|
+
*/
|
|
198
|
+
function renderTable(data, options) {
|
|
199
|
+
const header = options.map((item) => chalk.bold(item.label));
|
|
200
|
+
const rows = data.map((item) => options.map((opt) => chalk[opt.color || 'whiteBright'](item[opt.filed])));
|
|
201
|
+
const tableData = [header, ...rows];
|
|
202
|
+
return table(tableData, {
|
|
203
|
+
border: Object.fromEntries(
|
|
204
|
+
Object.entries(TABLE_CONFIG.border).map(([key, val]) => [key, chalk.blueBright.bold(val)])
|
|
205
|
+
)
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
module.exports = {
|
|
212
|
+
replacePlaceholders,
|
|
213
|
+
renameFile,
|
|
214
|
+
getThemeAppConfig,
|
|
215
|
+
setThemeAppConfig,
|
|
216
|
+
compress,
|
|
217
|
+
compareVersions,
|
|
218
|
+
getFileInfo,
|
|
219
|
+
renderTable
|
|
220
|
+
};
|
package/lib/checkout/api.js
CHANGED
|
@@ -8,6 +8,7 @@ const { isDebug } = require('./console');
|
|
|
8
8
|
const { getProjectConfig } = require('./util');
|
|
9
9
|
const chalk = require('chalk');
|
|
10
10
|
const { consoleWarn } = require('./console');
|
|
11
|
+
const { useOss } = require('../oss');
|
|
11
12
|
|
|
12
13
|
const FILE_SIGN_URL = '/checkout_extensions/file/sign';
|
|
13
14
|
const CREATE_URL = '/checkout_extensions/create';
|
|
@@ -19,6 +20,7 @@ const UNDEPLOY_URL = '/checkout_extensions/undeploy';
|
|
|
19
20
|
const PREVIEW_URL = '/checkout_extensions/preview';
|
|
20
21
|
|
|
21
22
|
let configJson = undefined;
|
|
23
|
+
let uploadOss = null;
|
|
22
24
|
|
|
23
25
|
const request = new Axios.create();
|
|
24
26
|
|
|
@@ -64,9 +66,6 @@ request.interceptors.response.use(
|
|
|
64
66
|
if (isDebug()) {
|
|
65
67
|
console.log(`\n<== error ${error.response.status}: ${error.response.config.url}`);
|
|
66
68
|
}
|
|
67
|
-
if (!error.response) {
|
|
68
|
-
throw chalk.red('Network error, please check your connection.');
|
|
69
|
-
}
|
|
70
69
|
if (error.response?.status == 403) {
|
|
71
70
|
return Promise.reject(new Error('Token permission failure'));
|
|
72
71
|
}
|
|
@@ -74,42 +73,20 @@ request.interceptors.response.use(
|
|
|
74
73
|
}
|
|
75
74
|
);
|
|
76
75
|
|
|
77
|
-
async function upload(path, name) {
|
|
78
|
-
const form = new FormData();
|
|
79
|
-
const url = await request(`${FILE_SIGN_URL}?key=${name}`)
|
|
80
|
-
.then((data) => {
|
|
81
|
-
return data.data;
|
|
82
|
-
})
|
|
83
|
-
.then(async (data) => {
|
|
84
|
-
const url = data.write_host;
|
|
85
|
-
form.append('policy', data.policy);
|
|
86
|
-
form.append('OSSAccessKeyId', data.access_id);
|
|
87
|
-
form.append('success_action_status', 200);
|
|
88
|
-
form.append('signature', data.sign);
|
|
89
|
-
form.append('x-oss-forbid-overwrite', 'true');
|
|
90
|
-
form.append('key', name);
|
|
91
|
-
form.append('file', fs.createReadStream(path));
|
|
92
|
-
await request.post(`https:${url}`, form, { headers: form.getHeaders() }).catch((error) => {
|
|
93
|
-
if (error.response?.data.includes('<Code>FileAlreadyExists</Code>')) {
|
|
94
|
-
consoleWarn('The current file already exists, not need to upload.');
|
|
95
|
-
return;
|
|
96
|
-
} else {
|
|
97
|
-
return Promise.reject(error);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
return `${data.read_host}${data.read_host.endsWith('/') ? '' : '/'}${name}`;
|
|
101
|
-
});
|
|
102
|
-
loading('succeed upload').succeed();
|
|
103
|
-
return url;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
76
|
async function uploadFile(dirPath, file) {
|
|
107
|
-
|
|
77
|
+
if (!uploadOss) {
|
|
78
|
+
uploadOss = useOss(
|
|
79
|
+
configJson.token,
|
|
80
|
+
new URL(configJson.store).hostname,
|
|
81
|
+
`✗ No store found. Please check your "extension.config.js" file.`
|
|
82
|
+
).uploadOss;
|
|
83
|
+
}
|
|
84
|
+
return uploadOss(`${dirPath}/${file}`);
|
|
108
85
|
}
|
|
109
86
|
async function uploadDir(dirPath, files) {
|
|
110
87
|
return Promise.all(
|
|
111
88
|
files.map((file) => {
|
|
112
|
-
return
|
|
89
|
+
return uploadOss(`${dirPath}/${file}`);
|
|
113
90
|
})
|
|
114
91
|
);
|
|
115
92
|
}
|
|
@@ -99,7 +99,7 @@ const handleHtmlDeps = (htmlStr, curPath) => {
|
|
|
99
99
|
cachedHtmlStr[importedHtmlAbsolutePath] = handleHtmlDeps(importedHtmlStr, curPath);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
str = str.replace(importReg, cachedHtmlStr[importedHtmlAbsolutePath]);
|
|
102
|
+
str = str.replace(importReg, () => cachedHtmlStr[importedHtmlAbsolutePath]);
|
|
103
103
|
} catch (e) {
|
|
104
104
|
console.error(e);
|
|
105
105
|
}
|
|
@@ -32,10 +32,11 @@ function handleWsConnection(ws) {
|
|
|
32
32
|
console.log(`Received message ${data} from user `);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
let extensionList = [];
|
|
36
36
|
fs.readdirSync(getExtensionsPath()).forEach((ext) => {
|
|
37
37
|
extensionList.push(generateExtensionData(ext));
|
|
38
38
|
});
|
|
39
|
+
extensionList = extensionList.filter((ext) => !ext.resourceUrl.endsWith('undefined'));
|
|
39
40
|
ws.send(JSON.stringify({ event: 'init', data: extensionList }));
|
|
40
41
|
|
|
41
42
|
}
|
package/lib/commands/login.js
CHANGED
|
@@ -8,7 +8,7 @@ const log = require('../log');
|
|
|
8
8
|
const { getShopDetail } = require('../openAPI/api');
|
|
9
9
|
const getCode = require('../auth/getCode');
|
|
10
10
|
const { postAccessToken, getUserInfo, postExchangeToken, postStoreToken } = require('../auth');
|
|
11
|
-
const { loginIntoPartner } = require('../
|
|
11
|
+
const { loginIntoPartner } = require('../common/login');
|
|
12
12
|
|
|
13
13
|
let spinner;
|
|
14
14
|
|
package/lib/commands/logout.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const Sentry = require('@sentry/node');
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
const { empty: emptyUser } = require('../db/user');
|
|
4
|
-
const { logoutPartner } = require('../
|
|
4
|
+
const { logoutPartner } = require('../common/logout');
|
|
5
5
|
const log = require('../log');
|
|
6
6
|
|
|
7
7
|
const logoutStore = () => {
|
package/lib/openAPI/index.js
CHANGED
|
@@ -12,17 +12,23 @@ const openAPI = axios.create({
|
|
|
12
12
|
headers: { 'Access-Token': get('exchange_token') }
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
openAPI.interceptors.request.use(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
openAPI.interceptors.request.use(
|
|
16
|
+
(config) => {
|
|
17
|
+
if (!get('store_domain')) {
|
|
18
|
+
log.error(
|
|
19
|
+
chalk.red(
|
|
20
|
+
`\n✗ No store found. Please run ${chalk.cyan('shoplazza login --store STORE')} to login to a specific store`
|
|
21
|
+
)
|
|
22
|
+
);
|
|
23
|
+
process.exit(-1);
|
|
24
|
+
}
|
|
25
|
+
return config;
|
|
26
|
+
},
|
|
27
|
+
(error) => {
|
|
28
|
+
console.error(chalk.red(`[REQUEST ERROR] ${error.message}`));
|
|
29
|
+
return Promise.reject(error);
|
|
23
30
|
}
|
|
24
|
-
|
|
25
|
-
});
|
|
31
|
+
);
|
|
26
32
|
|
|
27
33
|
openAPI.interceptors.response.use(
|
|
28
34
|
function (response) {
|
|
@@ -39,6 +45,11 @@ openAPI.interceptors.response.use(
|
|
|
39
45
|
return openAPI(error.config);
|
|
40
46
|
});
|
|
41
47
|
}
|
|
48
|
+
error.response && console.error(
|
|
49
|
+
chalk.red(
|
|
50
|
+
`[RESPONSE ERROR] ${error.response.status} ${error.response.config.baseURL}${error.response.config.url}`
|
|
51
|
+
)
|
|
52
|
+
);
|
|
42
53
|
return Promise.reject(error);
|
|
43
54
|
}
|
|
44
55
|
);
|