shoplazza-cli 1.0.6 → 1.0.7

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.
Files changed (61) hide show
  1. package/bin/shoplazza +14 -3
  2. package/lib/app/commands/build.js +53 -74
  3. package/lib/app/commands/deploy.js +210 -39
  4. package/lib/app/commands/generate.js +50 -0
  5. package/lib/app/commands/publish.js +52 -0
  6. package/lib/app/extensions/index.js +13 -0
  7. package/lib/app/extensions/theme-app.js +103 -0
  8. package/lib/app/index.js +29 -17
  9. package/lib/app/inquirers/version.js +131 -0
  10. package/lib/checkout/api.js +34 -11
  11. package/lib/commands/login.js +1 -1
  12. package/lib/commands/logout.js +1 -1
  13. package/lib/openAPI/index.js +10 -21
  14. package/lib/utils.js +0 -52
  15. package/package.json +2 -2
  16. package/lib/app/api/api.js +0 -93
  17. package/lib/app/api/request.js +0 -72
  18. package/lib/app/commands/create.js +0 -100
  19. package/lib/app/commands/list.js +0 -31
  20. package/lib/app/commands/serve.js +0 -118
  21. package/lib/app/commands/versions.js +0 -44
  22. package/lib/app/template/basic-app/.ci/k8s.yaml +0 -4
  23. package/lib/app/template/basic-app/README.md +0 -84
  24. package/lib/app/template/basic-app/package.json +0 -15
  25. package/lib/app/template/basic-app/theme-app/assets/index.css +0 -4
  26. package/lib/app/template/basic-app/theme-app/blocks/index.liquid +0 -14
  27. package/lib/app/template/basic-app/theme-app/snippets/index.liquid +0 -8
  28. package/lib/app/template/basic-app/theme-app.config.json +0 -4
  29. package/lib/app/template/embed-app/.ci/k8s.yaml +0 -4
  30. package/lib/app/template/embed-app/README.md +0 -84
  31. package/lib/app/template/embed-app/package.json +0 -15
  32. package/lib/app/template/embed-app/theme-app/assets/index.css +0 -4
  33. package/lib/app/template/embed-app/theme-app/blocks/index.liquid +0 -15
  34. package/lib/app/template/embed-app/theme-app/locales/ar-SA.json +0 -3
  35. package/lib/app/template/embed-app/theme-app/locales/de-DE.json +0 -3
  36. package/lib/app/template/embed-app/theme-app/locales/en-US.json +0 -3
  37. package/lib/app/template/embed-app/theme-app/locales/es-ES.json +0 -3
  38. package/lib/app/template/embed-app/theme-app/locales/fr-FR.json +0 -3
  39. package/lib/app/template/embed-app/theme-app/locales/id-ID.json +0 -3
  40. package/lib/app/template/embed-app/theme-app/locales/it-IT.json +0 -3
  41. package/lib/app/template/embed-app/theme-app/locales/ja-JP.json +0 -3
  42. package/lib/app/template/embed-app/theme-app/locales/ko-KR.json +0 -3
  43. package/lib/app/template/embed-app/theme-app/locales/nl-NL.json +0 -3
  44. package/lib/app/template/embed-app/theme-app/locales/pl-PL.json +0 -3
  45. package/lib/app/template/embed-app/theme-app/locales/pt-PT.json +0 -3
  46. package/lib/app/template/embed-app/theme-app/locales/ru-RU.json +0 -3
  47. package/lib/app/template/embed-app/theme-app/locales/th-TH.json +0 -3
  48. package/lib/app/template/embed-app/theme-app/locales/zh-CN.json +0 -3
  49. package/lib/app/template/embed-app/theme-app/locales/zh-TW.json +0 -3
  50. package/lib/app/template/embed-app/theme-app/snippets/index.liquid +0 -8
  51. package/lib/app/template/embed-app/theme-app.config.json +0 -4
  52. package/lib/app/utils/config.js +0 -29
  53. package/lib/app/utils/index.js +0 -220
  54. package/lib/oss.js +0 -102
  55. /package/lib/{common → app}/constants.js +0 -0
  56. /package/lib/{common → app}/db/partner.js +0 -0
  57. /package/lib/{common → app}/inquirers/choose-app.js +0 -0
  58. /package/lib/{common → app}/inquirers/choose-partner.js +0 -0
  59. /package/lib/{common → app}/log.js +0 -0
  60. /package/lib/{common → app}/login.js +0 -0
  61. /package/lib/{common → app}/logout.js +0 -0
@@ -1,220 +0,0 @@
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/oss.js DELETED
@@ -1,102 +0,0 @@
1
- const axios = require('axios');
2
- const fs = require('fs');
3
- const path = require('path');
4
- const FormData = require('form-data');
5
- const chalk = require('chalk');
6
- const loading = require('loading-cli');
7
-
8
- /**
9
- * 获取OSS上传功能,适用于上传文件到店铺的OSS服务器
10
- * @param {string} accessToken - 用于认证的token
11
- * @param {string} storeDomain - 店铺域名
12
- * @param {string} storeDomainTips - 店铺域名为空时的提示信息
13
- * @returns {{ uploadOss: (filePath: string) => Promise<string> }} 返回一个对象,包含上传文件到OSS的函数
14
- * @example
15
- * const { uploadOss } = useOss('your-access-token', 'your-store-domain', 'Store domain is required');
16
- * const ossUrl = await uploadOss('/path/to/file.txt');
17
- * console.log(ossUrl); // 输出文件的 OSS 地址
18
- */
19
- function useOss(accessToken, storeDomain, storeDomainTips) {
20
- const ins = axios.create({
21
- headers: { 'Access-Token': accessToken }
22
- });
23
-
24
- ins.interceptors.request.use(
25
- (config) => {
26
- if (!storeDomain) {
27
- console.error(
28
- // chalk.red(`\n\n`)
29
- chalk.red(`\n${storeDomainTips}\n`)
30
- );
31
- process.exit(-1);
32
- }
33
- if (config.url.startsWith('/checkout_extensions')) {
34
- config.baseURL = `https://${storeDomain}/openapi`;
35
- }
36
- return config;
37
- },
38
- (error) => {
39
- console.error(chalk.red(`[REQUEST ERROR] ${error.message}`));
40
- return Promise.reject(error);
41
- }
42
- );
43
-
44
- ins.interceptors.response.use(
45
- (response) => {
46
- return response.data;
47
- },
48
- (error) => {
49
- console.log(error);
50
-
51
- console.error(
52
- chalk.red(
53
- `[RESPONSE ERROR] ${error.response.status} ${error.response.config.baseURL}${error.response.config.url}`
54
- )
55
- );
56
- return Promise.reject(error);
57
- }
58
- );
59
-
60
- /**
61
- * 上传文件到OSS
62
- * @param {string} filePath - 要上传的文件路径
63
- * @returns {Promise<string>} 返回文件的 OSS 地址
64
- * @throws {Error} 如果上传失败或发生未知错误,抛出错误
65
- * @example
66
- * const ossUrl = await uploadOss('/path/to/file.txt');
67
- * console.log(ossUrl); // 输出文件的 OSS 地址
68
- */
69
- async function uploadOss(filePath) {
70
- console.log(chalk.green('正在上传文件到OSS...',filePath));
71
- let fileName = path.basename(filePath);
72
- const key = 'chick-extension/' + fileName;
73
- const form = new FormData();
74
- const url = await ins.get(`/checkout_extensions/file/sign?key=${key}`).then(async (data) => {
75
- const url = data.write_host;
76
- form.append('policy', data.policy);
77
- form.append('OSSAccessKeyId', data.access_id);
78
- form.append('success_action_status', 200);
79
- form.append('signature', data.sign);
80
- form.append('x-oss-forbid-overwrite', 'true');
81
- form.append('key', key);
82
- form.append('file', fs.createReadStream(filePath));
83
- await ins.post(`https:${url}`, form, { headers: form.getHeaders() }).catch((error) => {
84
- if (error.response?.data.includes('<Code>FileAlreadyExists</Code>')) {
85
- console.log(chalk.yellow('[WARN] The current file already exists, not need to upload.'));
86
- return;
87
- } else {
88
- return Promise.reject(error);
89
- }
90
- });
91
- return `${data.read_host}${data.read_host.endsWith('/') ? '' : '/'}${key}`;
92
- });
93
- loading('succeed upload').succeed();
94
- return url;
95
- }
96
-
97
- return { uploadOss };
98
- }
99
-
100
- module.exports = {
101
- useOss
102
- };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes