shoplazza-cli 1.0.13 → 1.1.2

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 (175) hide show
  1. package/README.md +12 -12
  2. package/bin/shoplazza +5 -3
  3. package/lib/app/api/cli.js +225 -0
  4. package/lib/app/api/openapi.js +121 -0
  5. package/lib/app/api/partnerOpenapi.js +104 -0
  6. package/lib/app/bin/index.js +20 -0
  7. package/lib/app/bin/javy/javy-arm-linux-v5.0.1 +0 -0
  8. package/lib/app/bin/javy/javy-arm-macos-v5.0.1 +0 -0
  9. package/lib/app/bin/javy/javy-x86_64-linux-v5.0.1 +0 -0
  10. package/lib/app/bin/javy/javy-x86_64-macos-v5.0.1 +0 -0
  11. package/lib/app/bin/javy/javy-x86_64-windows-v5.0.1 +0 -0
  12. package/lib/app/commands/config/actions/link.js +189 -0
  13. package/lib/app/commands/config/actions/use.js +40 -0
  14. package/lib/app/commands/config/index.js +25 -0
  15. package/lib/app/commands/config/link.js +11 -0
  16. package/lib/app/commands/config/use.js +11 -0
  17. package/lib/app/commands/deploy/actions/deploy.js +196 -0
  18. package/lib/app/commands/deploy/index.js +11 -0
  19. package/lib/app/commands/dev/actions/dev.js +206 -0
  20. package/lib/app/commands/dev/index.js +11 -0
  21. package/lib/app/commands/generate/actions/extension.js +97 -0
  22. package/lib/app/commands/generate/actions/generateCheckout.js +58 -0
  23. package/lib/app/commands/generate/actions/generateFunction.js +56 -0
  24. package/lib/app/commands/generate/actions/generateTheme.js +128 -0
  25. package/lib/app/commands/generate/extension.js +11 -0
  26. package/lib/app/commands/generate/index.js +22 -0
  27. package/lib/app/commands/index.js +82 -0
  28. package/lib/app/commands/info/actions/info.js +168 -0
  29. package/lib/app/commands/info/index.js +11 -0
  30. package/lib/app/commands/init/actions/init.js +176 -0
  31. package/lib/app/commands/init/index.js +14 -0
  32. package/lib/app/commands/versions/actions/list.js +210 -0
  33. package/lib/app/commands/versions/index.js +22 -0
  34. package/lib/app/commands/versions/list.js +14 -0
  35. package/lib/app/constant/code.js +7 -0
  36. package/lib/app/constant/color.js +18 -0
  37. package/lib/app/constant/extension.js +16 -0
  38. package/lib/app/constant/host.js +23 -0
  39. package/lib/app/constant/sso.js +7 -0
  40. package/lib/app/index.js +4 -25
  41. package/lib/app/services/auth/config.js +33 -0
  42. package/lib/app/services/auth/index.js +9 -0
  43. package/lib/app/services/auth/oauth-server.js +70 -0
  44. package/lib/app/services/auth/partner-token.js +45 -0
  45. package/lib/app/services/auth/sso-token.js +69 -0
  46. package/lib/app/services/auth/store-token.js +100 -0
  47. package/lib/app/services/auth/url-builder.js +23 -0
  48. package/lib/app/services/config/index.js +41 -0
  49. package/lib/app/services/devServer/app.js +76 -0
  50. package/lib/app/services/devServer/index.js +103 -0
  51. package/lib/app/services/devServer/middleware/hmacValidatorMiddleWare.js +20 -0
  52. package/lib/app/services/devServer/middleware/index.js +5 -0
  53. package/lib/app/services/devServer/tunnel/index.js +43 -0
  54. package/lib/app/services/devServer/tunnel/providers/cloudflare.js +364 -0
  55. package/lib/app/services/devServer/tunnel/providers/ngrok.js +70 -0
  56. package/lib/app/services/devServer/utils/index.js +5 -0
  57. package/lib/app/services/devServer/utils/secureCompare.js +5 -0
  58. package/lib/app/services/devServer/views/app.ejs +133 -0
  59. package/lib/app/services/extension-build/buildCheckout.js +47 -0
  60. package/lib/app/services/extension-build/buildFunction.js +57 -0
  61. package/lib/app/services/extension-build/buildTheme.js +100 -0
  62. package/lib/app/services/extension-build/index.js +23 -0
  63. package/lib/app/services/extension-build/plugins/vite-plugin-add-extension-id.js +26 -0
  64. package/lib/app/services/extension-build/plugins/vite-plugin-transform-extension-html.js +207 -0
  65. package/lib/app/services/extension-diff/index.js +132 -0
  66. package/lib/app/services/extension-upsert/index.js +21 -0
  67. package/lib/app/services/extension-upsert/upsertCheckout.js +44 -0
  68. package/lib/app/services/extension-upsert/upsertFunction.js +52 -0
  69. package/lib/app/services/extension-upsert/upsertTheme.js +113 -0
  70. package/lib/app/services/oss/index.js +45 -0
  71. package/lib/app/services/partner/index.js +52 -0
  72. package/lib/app/store/base-store.js +37 -0
  73. package/lib/app/store/config-store.js +55 -0
  74. package/lib/app/store/config.js +21 -0
  75. package/lib/app/store/index.js +14 -0
  76. package/lib/app/store/install-store.js +41 -0
  77. package/lib/app/store/sso-store.js +55 -0
  78. package/lib/app/utils/asyncPool.js +42 -0
  79. package/lib/app/utils/debug/index.js +16 -0
  80. package/lib/app/utils/env.js +24 -0
  81. package/lib/app/utils/error.js +20 -0
  82. package/lib/app/utils/git.js +20 -0
  83. package/lib/app/utils/json.js +27 -0
  84. package/lib/app/utils/path.js +33 -0
  85. package/lib/app/utils/platform.js +37 -0
  86. package/lib/app/utils/request/cli.js +72 -0
  87. package/lib/app/utils/request/debug.js +13 -0
  88. package/lib/app/utils/request/openapi.js +67 -0
  89. package/lib/app/utils/request/partnerOpenapi.js +47 -0
  90. package/lib/app/utils/toml.js +56 -0
  91. package/lib/app/utils/views/message.js +68 -0
  92. package/lib/app/utils/views/select.js +36 -0
  93. package/lib/app/utils/withTempDir.js +55 -0
  94. package/lib/checkout/api.js +2 -0
  95. package/lib/function/bin/javy/javy-arm-macos-v5.0.1 +0 -0
  96. package/lib/oss.js +5 -2
  97. package/lib/theme-extension/index.js +29 -0
  98. package/package.json +12 -1
  99. package/examples/checkout-extension/README.md +0 -19
  100. package/examples/checkout-extension/extension.config.js +0 -4
  101. package/examples/checkout-extension/extensions/add-shipping-desc/extension.json +0 -10
  102. package/examples/checkout-extension/extensions/add-shipping-desc/src/index.js +0 -7
  103. package/examples/checkout-extension/extensions/ext-1/extension.json +0 -10
  104. package/examples/checkout-extension/extensions/ext-1/src/content.html +0 -3
  105. package/examples/checkout-extension/extensions/ext-1/src/index.html +0 -5
  106. package/examples/checkout-extension/extensions/ext-1/src/index.js +0 -11
  107. package/examples/checkout-extension/extensions/ext-1/src/script.html +0 -3
  108. package/examples/checkout-extension/extensions/ext-1/src/style.html +0 -3
  109. package/examples/checkout-extension/extensions/product-list/extension.json +0 -10
  110. package/examples/checkout-extension/extensions/product-list/src/index.js +0 -5
  111. package/examples/checkout-extension/extensions/rewrite-navigate/extension.json +0 -10
  112. package/examples/checkout-extension/extensions/rewrite-navigate/src/content.html +0 -38
  113. package/examples/checkout-extension/extensions/rewrite-navigate/src/index.html +0 -5
  114. package/examples/checkout-extension/extensions/rewrite-navigate/src/index.js +0 -12
  115. package/examples/checkout-extension/extensions/rewrite-navigate/src/script.html +0 -26
  116. package/examples/checkout-extension/extensions/rewrite-navigate/src/style.html +0 -23
  117. package/examples/checkout-extension/package-lock.json +0 -121
  118. package/examples/checkout-extension/package.json +0 -17
  119. /package/lib/{app → theme-extension}/api/index.js +0 -0
  120. /package/lib/{app → theme-extension}/commands/build.js +0 -0
  121. /package/lib/{app → theme-extension}/commands/connect.js +0 -0
  122. /package/lib/{app → theme-extension}/commands/create.js +0 -0
  123. /package/lib/{app → theme-extension}/commands/deploy.js +0 -0
  124. /package/lib/{app → theme-extension}/commands/list.js +0 -0
  125. /package/lib/{app → theme-extension}/commands/release.js +0 -0
  126. /package/lib/{app → theme-extension}/commands/serve.js +0 -0
  127. /package/lib/{app → theme-extension}/commands/versions.js +0 -0
  128. /package/lib/{app → theme-extension}/template/basic-app/README.md +0 -0
  129. /package/lib/{app → theme-extension}/template/basic-app/extension.config.json +0 -0
  130. /package/lib/{app → theme-extension}/template/basic-app/package.json +0 -0
  131. /package/lib/{app → theme-extension}/template/basic-app/theme-app/assets/index.css +0 -0
  132. /package/lib/{app → theme-extension}/template/basic-app/theme-app/assets-manifest.json +0 -0
  133. /package/lib/{app → theme-extension}/template/basic-app/theme-app/blocks/index.liquid +0 -0
  134. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/ar-SA.json +0 -0
  135. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/de-DE.json +0 -0
  136. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/en-US.json +0 -0
  137. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/es-ES.json +0 -0
  138. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/fr-FR.json +0 -0
  139. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/id-ID.json +0 -0
  140. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/it-IT.json +0 -0
  141. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/ja-JP.json +0 -0
  142. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/ko-KR.json +0 -0
  143. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/nl-NL.json +0 -0
  144. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/pl-PL.json +0 -0
  145. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/pt-PT.json +0 -0
  146. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/ru-RU.json +0 -0
  147. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/th-TH.json +0 -0
  148. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/zh-CN.json +0 -0
  149. /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/zh-TW.json +0 -0
  150. /package/lib/{app → theme-extension}/template/basic-app/theme-app/snippets/index.liquid +0 -0
  151. /package/lib/{app → theme-extension}/template/embed-app/README.md +0 -0
  152. /package/lib/{app → theme-extension}/template/embed-app/extension.config.json +0 -0
  153. /package/lib/{app → theme-extension}/template/embed-app/package.json +0 -0
  154. /package/lib/{app → theme-extension}/template/embed-app/theme-app/assets-manifest.json +0 -0
  155. /package/lib/{app → theme-extension}/template/embed-app/theme-app/blocks/index.liquid +0 -0
  156. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/ar-SA.json +0 -0
  157. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/de-DE.json +0 -0
  158. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/en-US.json +0 -0
  159. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/es-ES.json +0 -0
  160. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/fr-FR.json +0 -0
  161. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/id-ID.json +0 -0
  162. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/it-IT.json +0 -0
  163. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/ja-JP.json +0 -0
  164. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/ko-KR.json +0 -0
  165. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/nl-NL.json +0 -0
  166. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/pl-PL.json +0 -0
  167. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/pt-PT.json +0 -0
  168. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/ru-RU.json +0 -0
  169. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/th-TH.json +0 -0
  170. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/zh-CN.json +0 -0
  171. /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/zh-TW.json +0 -0
  172. /package/lib/{app → theme-extension}/template/embed-app/theme-app/snippets/index.liquid +0 -0
  173. /package/lib/{app → theme-extension}/template/embed-app/theme-app/snippets/index_css.liquid +0 -0
  174. /package/lib/{app → theme-extension}/utils/config.js +0 -0
  175. /package/lib/{app → theme-extension}/utils/index.js +0 -0
@@ -0,0 +1,72 @@
1
+ const axios = require('axios');
2
+ const { getSSOAccessToken } = require('../../services/auth');
3
+ const { CODES } = require('../../constant/code');
4
+ const curlirize = require('axios-curlirize');
5
+ const { ssoStore } = require('../../store');
6
+ const chalk = require('chalk');
7
+ const { getPartnerHost } = require('../../services/auth/config');
8
+ const { responseDebug } = require('./debug');
9
+
10
+ const cliClient = axios.create({
11
+ baseURL: `${getPartnerHost()}`,
12
+ headers: {
13
+ 'Content-Type': 'application/json'
14
+ }
15
+ });
16
+
17
+ curlirize(cliClient, () => {});
18
+
19
+ cliClient.interceptors.request.use(
20
+ async (config) => {
21
+ const { access_token } = await getSSOAccessToken();
22
+ config.headers['Cookie'] = `awesomev2=${access_token}`;
23
+ return config;
24
+ },
25
+ (error) => {
26
+ return Promise.reject(error);
27
+ }
28
+ );
29
+
30
+ cliClient.interceptors.response.use(
31
+ (response) => {
32
+ if (typeof response.data === 'string') {
33
+ if (process.env.DEBUG) {
34
+ responseDebug(response);
35
+ }
36
+ // 响应结构体不正确
37
+ throw new Error(`${response.config.url} response data is not a valid JSON`);
38
+ }
39
+
40
+ if (response.data.code === CODES.SUCCESS) {
41
+ return response.data.data;
42
+ }
43
+
44
+ throw new Error(`[${response.config.url}] [${response.status}] ${response?.data?.message}`);
45
+ },
46
+ async (error) => {
47
+ if (!error.response) return Promise.reject(error);
48
+
49
+ if (process.env.DEBUG) {
50
+ responseDebug(error.response);
51
+ }
52
+
53
+ // 自定义重试标记,防止无限循环
54
+ error.config.__isRetry = error.config.__isRetry || false;
55
+
56
+ // 如果 403 且还没重试过
57
+ if (error.response?.status === 403 && !error.config.__isRetry) {
58
+ error.config.__isRetry = true; // 标记为已经重试
59
+ ssoStore.clearSSO();
60
+ // 重新发送请求
61
+ return cliClient(error.config);
62
+ }
63
+
64
+ throw new Error(
65
+ `[${error.response.config?.url}] [${error.response.status}] ${error.response?.data?.message || error.message}`
66
+ );
67
+ }
68
+ );
69
+
70
+ module.exports = {
71
+ cliClient
72
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 打印 response 的 debug 信息
3
+ * @param {import('axios').AxiosResponse} response
4
+ */
5
+ function responseDebug(response) {
6
+ console.log(`=============== DEBUG ${response.config.url} ===============`);
7
+ console.error(response);
8
+ console.log(`=============== DEBUG ${response.config.url} ===============`);
9
+ }
10
+
11
+ module.exports = {
12
+ responseDebug
13
+ };
@@ -0,0 +1,67 @@
1
+ const axios = require('axios');
2
+ const { getStoreAccessToken } = require('../../services/auth');
3
+ const curlirize = require('axios-curlirize');
4
+ const { responseDebug } = require('./debug');
5
+
6
+ // 缓存不同 app_id 的 axios 实例
7
+ const clientCache = new Map();
8
+
9
+ /**
10
+ * 获取或创建指定 app_client_id 的 openapi client
11
+ * @param {string} app_client_id
12
+ * @returns {import('axios').AxiosInstance}
13
+ */
14
+ async function getOpenapiClient(app_client_id, partner_id) {
15
+ if (clientCache.has(app_client_id)) {
16
+ return clientCache.get(app_client_id);
17
+ }
18
+
19
+ const { store_domain, access_token } = await getStoreAccessToken(app_client_id, partner_id);
20
+
21
+ if (!store_domain || !access_token) {
22
+ throw new Error(`storeDomain or accessToken missing for app_client_id: ${app_client_id}`);
23
+ }
24
+
25
+ const client = axios.create({
26
+ baseURL: `https://${store_domain}`,
27
+ headers: { 'Access-Token': access_token },
28
+ 'Content-Type': 'application/json'
29
+ });
30
+
31
+ client.interceptors.request.use((config) => {
32
+ return config;
33
+ });
34
+
35
+ client.interceptors.response.use(
36
+ (response) => {
37
+ if (typeof response.data === 'string') {
38
+ if (process.env.DEBUG) {
39
+ responseDebug(response);
40
+ }
41
+ throw new Error(`${response.config.url} response data is not a valid JSON`);
42
+ }
43
+
44
+ return response.data;
45
+ },
46
+ (error) => {
47
+ if (!error.response) return Promise.reject(error);
48
+
49
+ if (process.env.DEBUG) {
50
+ responseDebug(error.response);
51
+ }
52
+
53
+ throw new Error(
54
+ `[${error.response.config?.url}] [${error.response.status}] ${error.response?.data?.message || error.message}`
55
+ );
56
+ }
57
+ );
58
+
59
+ curlirize(client, () => {});
60
+
61
+ // 缓存下来,避免重复创建
62
+ clientCache.set(app_client_id, client);
63
+
64
+ return client;
65
+ }
66
+
67
+ module.exports = { getOpenapiClient };
@@ -0,0 +1,47 @@
1
+ const axios = require('axios');
2
+ const curlirize = require('axios-curlirize');
3
+ const { getPartnerHost } = require('../../services/auth/config');
4
+ const { responseDebug } = require('./debug');
5
+
6
+ const partnerOpenapiClient = axios.create({
7
+ baseURL: `${getPartnerHost()}`,
8
+ headers: {
9
+ 'Content-Type': 'application/json'
10
+ }
11
+ });
12
+
13
+ curlirize(partnerOpenapiClient, () => {});
14
+
15
+ partnerOpenapiClient.interceptors.request.use(async (config) => {
16
+ // const { store_id } = await getStoreAccessToken(config.headers['app-client-id']);
17
+ // config.headers['store-id'] = store_id;
18
+ return config;
19
+ });
20
+
21
+ partnerOpenapiClient.interceptors.response.use(
22
+ (response) => {
23
+ if (typeof response.data === 'string') {
24
+ if (process.env.DEBUG) {
25
+ responseDebug(response);
26
+ }
27
+ throw new Error(`${response.config.url} response data is not a valid JSON`);
28
+ }
29
+
30
+ return response.data;
31
+ },
32
+ (error) => {
33
+ if (!error.response) return Promise.reject(error);
34
+
35
+ if (process.env.DEBUG) {
36
+ responseDebug(error.response);
37
+ }
38
+
39
+ throw new Error(
40
+ `[${error.response.config?.url}] [${error.response.status}] ${error.response?.data?.message || error.message}`
41
+ );
42
+ }
43
+ );
44
+
45
+ module.exports = {
46
+ partnerOpenapiClient
47
+ };
@@ -0,0 +1,56 @@
1
+ const TOML = require('@iarna/toml');
2
+ const fs = require('fs');
3
+ const glob = require('glob');
4
+
5
+ /**
6
+ * 解析TOML文件
7
+ * @param {string} filePath - 文件路径
8
+ * @returns {Object} - 解析后的对象
9
+ */
10
+ function parseTomlFile(filePath) {
11
+ const content = fs.readFileSync(filePath, 'utf-8');
12
+ return TOML.parse(content);
13
+ }
14
+
15
+ /**
16
+ * 修改TOML配置文件
17
+ * @param {string} filePath - 文件路径
18
+ * @param {function(Object):Object} callback - 修改函数
19
+ */
20
+ async function modifyTomlFile(filePath, callback) {
21
+ const config = parseTomlFile(filePath);
22
+ const result = await callback(config);
23
+ fs.writeFileSync(filePath, TOML.stringify(result), 'utf-8');
24
+ }
25
+
26
+ /**
27
+ * 创建新的TOML配置文件
28
+ * @param {string} filePath - 文件路径
29
+ * @param {function(Object):Object} callback - 修改函数
30
+ */
31
+ async function createTomlConfig(filePath, callback) {
32
+ // 默认配置
33
+ const defaults = {
34
+ client_id: '',
35
+ scopes: 'read_customer write_cart_transform',
36
+ };
37
+ const result = await callback(defaults);
38
+ fs.writeFileSync(filePath, TOML.stringify(result), 'utf-8');
39
+ }
40
+
41
+ /**
42
+ * 获取所有TOML配置文件
43
+ * @param {string} [baseDir=process.cwd()] - 基础目录
44
+ * @returns {string[]} - 配置文件列表
45
+ */
46
+ function getTomlConfigFiles(baseDir = process.cwd()) {
47
+ return glob.sync('shoplazza.app*.toml', { cwd: baseDir });
48
+ }
49
+
50
+
51
+ module.exports = {
52
+ parseTomlFile,
53
+ modifyTomlFile,
54
+ createTomlConfig,
55
+ getTomlConfigFiles
56
+ };
@@ -0,0 +1,68 @@
1
+ const chalk = require('chalk');
2
+ const boxen = require('boxen');
3
+ const { COLORS } = require('../../constant/color');
4
+
5
+ function getBoxenWidth() {
6
+ const width = process.stdout.columns;
7
+ return width > 100 ? 100 : width;
8
+ }
9
+
10
+ // 通用消息渲染函数
11
+ function renderMessage(message, options) {
12
+ console.log(
13
+ boxen(message, {
14
+ width: getBoxenWidth(),
15
+ padding: 1,
16
+ borderStyle: 'round',
17
+ ...options
18
+ })
19
+ );
20
+ }
21
+
22
+ // 标题渲染
23
+ function renderTitle(title) {
24
+ return chalk.hex(COLORS.WHITE)(title);
25
+ }
26
+
27
+ // 错误信息输出
28
+ function errorMessageRender(message) {
29
+ renderMessage(message, {
30
+ title: renderTitle('error'),
31
+ titleAlignment: 'left',
32
+ borderColor: COLORS.RED
33
+ });
34
+ }
35
+
36
+ // 成功信息输出
37
+ function successMessageRender(message) {
38
+ renderMessage(message, {
39
+ title: renderTitle('success'),
40
+ titleAlignment: 'left',
41
+ borderColor: COLORS.GREEN
42
+ });
43
+ }
44
+
45
+ // 提示信息输出
46
+ function infoMessageRender(message) {
47
+ renderMessage(message, {
48
+ title: renderTitle('info'),
49
+ titleAlignment: 'left',
50
+ borderColor: COLORS.GRAY
51
+ });
52
+ }
53
+
54
+ // 警告信息输出
55
+ function warningMessageRender(message) {
56
+ renderMessage(message, {
57
+ title: renderTitle('warning'),
58
+ titleAlignment: 'left',
59
+ borderColor: COLORS.YELLOW
60
+ });
61
+ }
62
+
63
+ module.exports = {
64
+ errorMessageRender,
65
+ successMessageRender,
66
+ infoMessageRender,
67
+ warningMessageRender,
68
+ };
@@ -0,0 +1,36 @@
1
+ const inquirer = require('inquirer');
2
+
3
+ /**
4
+ * 通用:选择列表中的单项
5
+ * @param {Array} list - 数据源数组
6
+ * @param {Object} options - 配置选项
7
+ * @param {string} [options.message='Please select:'] - 选择项的提示
8
+ * @param {boolean} [options.autoPickSingle=true] - 是否只有一项时自动返回
9
+ * @param {Function} [options.formatChoice] - 单项到 { name, value } 的映射函数,默认返回原项
10
+ * @returns {Promise<any|null>}
11
+ */
12
+ async function selectOne(
13
+ list,
14
+ { message = 'Please select:', autoPickSingle = true, formatChoice = (item) => item } = {}
15
+ ) {
16
+ if (!list || list.length === 0) {
17
+ return null;
18
+ }
19
+
20
+ if (autoPickSingle && list.length === 1) {
21
+ return list[0];
22
+ }
23
+
24
+ const { selected } = await inquirer.prompt({
25
+ type: 'list',
26
+ name: 'selected',
27
+ message,
28
+ choices: list.map(formatChoice)
29
+ });
30
+
31
+ return selected;
32
+ }
33
+
34
+ module.exports = {
35
+ selectOne
36
+ };
@@ -0,0 +1,55 @@
1
+ const { mkdtemp, rm } = require('fs/promises');
2
+ const { join } = require('path');
3
+ const { tmpdir } = require('os');
4
+
5
+ /**
6
+ * 创建临时目录
7
+ * @param {string} [prefix='temp-'] - 临时目录前缀
8
+ * @returns {Promise<string>} - 临时目录路径
9
+ */
10
+ async function createTempDir(prefix = 'temp-') {
11
+ const tempDir = await mkdtemp(join(tmpdir(), prefix));
12
+ return tempDir;
13
+ }
14
+
15
+ /**
16
+ * 删除临时目录
17
+ * @param {string} path - 临时目录路径
18
+ * @returns {Promise<void>}
19
+ */
20
+ async function removeTempDir(path) {
21
+ try {
22
+ await rm(path, { recursive: true, force: true });
23
+ } catch (error) {
24
+ console.error(`Failed to remove temporary directory: ${path}`, error);
25
+ throw error;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * 使用临时目录执行操作
31
+ * @param {function(string):Promise<T>} callback - 在临时目录中执行的回调函数
32
+ * @param {string} [prefix='temp-'] - 临时目录前缀
33
+ * @returns {Promise<T>} - 回调函数的返回值
34
+ * @template T
35
+ */
36
+ async function withTempDir(callback, prefix = 'temp-') {
37
+ let tempDir;
38
+ try {
39
+ tempDir = await createTempDir(prefix);
40
+ const result = await callback(tempDir);
41
+ return result;
42
+ } catch (error) {
43
+ throw error;
44
+ } finally {
45
+ if (tempDir) {
46
+ await removeTempDir(tempDir);
47
+ }
48
+ }
49
+ }
50
+
51
+ module.exports = {
52
+ createTempDir,
53
+ removeTempDir,
54
+ withTempDir
55
+ };
@@ -33,6 +33,8 @@ request.interceptors.request.use((config) => {
33
33
  config.headers['Access-Token'] = configJson.token;
34
34
  if (!config.url.startsWith('http')) {
35
35
  config.url = path.join(configJson.store, openAipVersion, config.url);
36
+ // TODO 这里需要处理一下,使用 URL 对象
37
+
36
38
  }
37
39
 
38
40
  if (isDebug()) {
File without changes
package/lib/oss.js CHANGED
@@ -45,8 +45,11 @@ function useOss(accessToken, storeDomain, storeDomainTips) {
45
45
  return response.data;
46
46
  },
47
47
  (error) => {
48
- console.log(error);
49
-
48
+ if (error.response.status === 409) {
49
+ // 文件已存在
50
+ return;
51
+ }
52
+
50
53
  console.error(
51
54
  chalk.red(
52
55
  `[RESPONSE ERROR] ${error.response.status} ${error.response.config.baseURL}${error.response.config.url}`
@@ -0,0 +1,29 @@
1
+ function initThemeAppCommand(_program) {
2
+ const program = _program.command('te').alias('theme_extension').description('Shoplazza theme extension CLI');
3
+
4
+ program.command('create').description('Create a new theme extension').action(require('./commands/create').create);
5
+
6
+ program
7
+ .command('serve')
8
+ .description('Start a local development server for the theme extension')
9
+ .action(require('./commands/serve').serve);
10
+
11
+ program.command('build').description('Build the theme extension for production').action(require('./commands/build').build);
12
+
13
+ program
14
+ .command('versions')
15
+ .description('List all versions of the theme extension')
16
+ .action(require('./commands/versions').versions);
17
+
18
+ program.command('deploy').description('Deploy the theme extension').action(require('./commands/deploy').deploy);
19
+
20
+ program.command('list').description('List all theme extensions').action(require('./commands/list').list);
21
+
22
+ program.command('connect').description('Establish a connection between the theme extension and the shoplazza app').action(require('./commands/connect').connect);
23
+
24
+ program.command('release').description('Release a theme extension version to be applied in the shoplazza app').action(require('./commands/release').release);
25
+ }
26
+
27
+ module.exports = {
28
+ initThemeAppCommand
29
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shoplazza-cli",
3
- "version": "1.0.13",
3
+ "version": "1.1.2",
4
4
  "description": "",
5
5
  "main": "bin/shoplazza",
6
6
  "engines": {
@@ -22,11 +22,14 @@
22
22
  "prettier": "2.6.2"
23
23
  },
24
24
  "dependencies": {
25
+ "@iarna/toml": "^2.2.5",
26
+ "@ngrok/ngrok": "^1.5.2",
25
27
  "@sentry/node": "^6.19.7",
26
28
  "@sentry/tracing": "^6.19.7",
27
29
  "adm-zip": "^0.5.9",
28
30
  "ali-oss": "^6.17.1",
29
31
  "axios": "^1.6.8",
32
+ "axios-curlirize": "^1.3.7",
30
33
  "better-sqlite3": "^11.5.0",
31
34
  "chalk": "^4.1.2",
32
35
  "chokidar": "^3.6.0",
@@ -34,9 +37,13 @@
34
37
  "clean-css": "^5.3.1",
35
38
  "colors": "^1.4.0",
36
39
  "commander": "^9.2.0",
40
+ "conf": "10.2.0",
37
41
  "connect": "^3.7.0",
42
+ "dotenv": "^17.2.1",
38
43
  "download-git-repo": "^3.0.2",
44
+ "ejs": "^3.1.10",
39
45
  "execa": "^5.1.1",
46
+ "express": "^5.1.0",
40
47
  "extension-ui": "^1.0.6",
41
48
  "fancy-log": "~1.3.3",
42
49
  "file-type": "~16.5.0",
@@ -62,6 +69,7 @@
62
69
  "process": "~0.11.10",
63
70
  "semver": "~7.3.5",
64
71
  "serve-static": "^1.15.0",
72
+ "simple-git": "^3.28.0",
65
73
  "spark-md5": "^3.0.2",
66
74
  "table": "^6.9.0",
67
75
  "uglify-js": "^3.17.4",
@@ -70,5 +78,8 @@
70
78
  "vite-plugin-inspect": "^0.7.25",
71
79
  "ws": "^8.17.0",
72
80
  "yargs": "^17.5.0"
81
+ },
82
+ "volta": {
83
+ "node": "22.17.1"
73
84
  }
74
85
  }
@@ -1,19 +0,0 @@
1
- # Chick Extension
2
-
3
- ## Getting started
4
-
5
-
6
- ## init git
7
-
8
- ```
9
- cd `projectDir`
10
- git init
11
- ```
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
@@ -1,4 +0,0 @@
1
- module.exports = {
2
- token: 'aadasd',
3
- store: 'https://perry.stg.myshoplaza.com'
4
- };
@@ -1,10 +0,0 @@
1
- {
2
- "version": "1.0",
3
- "deleteTarget": [],
4
- "placeholder": {},
5
- "templateName": "checkout",
6
- "themeName": "",
7
- "extensionId": "",
8
- "extensionName": "add-shipping-desc",
9
- "extensionDescription": ""
10
- }
@@ -1,7 +0,0 @@
1
- import { extend } from "shoplazza-extension-ui";
2
-
3
- extend({
4
- extensionPoint: "Checkout::ShippingLinesTitle::RenderAfter",
5
- component: `<p class="mb-4">所有物流方式均受到保护。</p>`,
6
- });
7
-
@@ -1,10 +0,0 @@
1
- {
2
- "version": "1.0",
3
- "deleteTarget": [],
4
- "placeholder": {},
5
- "templateName": "checkout",
6
- "themeName": "",
7
- "extensionId": "",
8
- "extensionName": "ext-1",
9
- "extensionDescription": ""
10
- }
@@ -1,3 +0,0 @@
1
- <div>
2
- <h2>hello world</h2>
3
- </div>
@@ -1,5 +0,0 @@
1
- <div>
2
- import './style.html'
3
- import './content.html'
4
- import './script.html'
5
- </div>
@@ -1,11 +0,0 @@
1
- import { extend } from 'shoplazza-extension-ui';
2
- import index from './index.html';
3
-
4
- function App() {
5
- return index;
6
- }
7
-
8
- extend({
9
- extensionPoint: 'Checkout::Navigate::RenderBefore',
10
- component: App()
11
- });
@@ -1,3 +0,0 @@
1
- <ljs-script layout="logic" type="application/javascript">
2
- <!-- js代码 -->
3
- </ljs-script>
@@ -1,3 +0,0 @@
1
- <style>
2
-
3
- </style>
@@ -1,10 +0,0 @@
1
- {
2
- "version": "1.0",
3
- "deleteTarget": [],
4
- "placeholder": {},
5
- "templateName": "checkout",
6
- "themeName": "",
7
- "extensionId": "",
8
- "extensionName": "product-list",
9
- "extensionDescription": ""
10
- }
@@ -1,5 +0,0 @@
1
- const productList = CheckoutAPI.summary.getProductList();
2
-
3
- console.debug('productList', productList);
4
-
5
- // do something, such as report
@@ -1,10 +0,0 @@
1
- {
2
- "version": "1.0",
3
- "deleteTarget": ["navigate"],
4
- "placeholder": {},
5
- "templateName": "checkout",
6
- "themeName": "",
7
- "extensionId": "",
8
- "extensionName": "rewrite-navigate",
9
- "extensionDescription": ""
10
- }