shoplazza-cli 1.0.12 → 1.1.1

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,11 @@
1
+ const { Command } = require('commander');
2
+ const devCommand = new Command('dev');
3
+ const { devAction } = require('./actions/dev');
4
+
5
+ devCommand.option('--path <path>', 'The path to your app directory');
6
+
7
+ devCommand.action(devAction);
8
+
9
+ module.exports = {
10
+ devCommand
11
+ };
@@ -0,0 +1,97 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+ const inquirer = require('inquirer');
4
+
5
+ const { withErrorHandling } = require('../../../utils/error');
6
+ const { EXTENSION_TYPES } = require('../../../constant/extension');
7
+
8
+ const { generateTheme } = require('./generateTheme');
9
+ const { generateCheckout } = require('./generateCheckout');
10
+ const { generateFunction } = require('./generateFunction');
11
+
12
+ const strategies = {
13
+ [EXTENSION_TYPES.THEME]: generateTheme,
14
+ [EXTENSION_TYPES.CHECKOUT]: generateCheckout,
15
+ [EXTENSION_TYPES.FUNCTION]: generateFunction
16
+ };
17
+
18
+ async function selectExtensionType(targetDirectory) {
19
+ // 只允许一个 theme extension
20
+ // const extensionTomlPath = path.join(targetDirectory, 'extensions', '**', 'shoplazza.extension.toml');
21
+ // const extensionTomlPaths = glob.sync(extensionTomlPath);
22
+ // const isExistsThemeExtension = extensionTomlPaths.some((path) => {
23
+ // const toml = parseTomlFile(path);
24
+ // return toml.type === EXTENSION_TYPES.THEME;
25
+ // });
26
+
27
+ // // 创建选项列表
28
+ // const choices = [];
29
+
30
+ // Object.values(EXTENSION_TYPES).forEach((type) => {
31
+ // if (type === EXTENSION_TYPES.THEME && isExistsThemeExtension) {
32
+ // // 使用自定义分隔符替代禁用的选项
33
+ // choices.push(new inquirer.Separator(chalk.gray(`${type} (limit reached)`)));
34
+ // } else {
35
+ // choices.push({
36
+ // name: type,
37
+ // value: type
38
+ // });
39
+ // }
40
+ // });
41
+
42
+ // 允许有多个 theme extension
43
+ const choices = Object.values(EXTENSION_TYPES);
44
+
45
+ const { type } = await inquirer.prompt([
46
+ {
47
+ type: 'list',
48
+ name: 'type',
49
+ message: 'Type of extension?',
50
+ choices: choices
51
+ }
52
+ ]);
53
+
54
+ return type;
55
+ }
56
+
57
+ // 校验项目地址
58
+ async function checkProjectDir(projectDir) {
59
+ // 检查目录是否已存在
60
+ if (fs.existsSync(projectDir)) {
61
+ throw new Error(
62
+ `A directory with this name (${path.basename(projectDir)}) already exists.\nChoose a new name for your extension.`
63
+ );
64
+ }
65
+ }
66
+
67
+ async function extensionAction(options) {
68
+ const { path: argPath = '.' } = options;
69
+ const extensionType = await selectExtensionType(path.resolve(argPath));
70
+
71
+ // 交互获取扩展名称
72
+ const { extensionName } = await inquirer.prompt([
73
+ {
74
+ type: 'input',
75
+ name: 'extensionName',
76
+ message: 'Extension name?',
77
+ validate: (value) => (value.trim() === '' ? 'Extension name is required' : true)
78
+ }
79
+ ]);
80
+
81
+ const targetDirectory = path.resolve(argPath, 'extensions', extensionName);
82
+
83
+ const strategy = strategies[extensionType];
84
+
85
+ if (!strategy) {
86
+ throw new Error(`Unknown extension type: ${extensionType}`);
87
+ }
88
+
89
+ // 校验项目地址
90
+ await checkProjectDir(targetDirectory);
91
+
92
+ await strategy({ targetDirectory });
93
+ }
94
+
95
+ module.exports = {
96
+ extensionAction: withErrorHandling(extensionAction)
97
+ };
@@ -0,0 +1,58 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+ const simpleGit = require('simple-git');
4
+
5
+ const { getTemplateGitRequest } = require('../../../api/cli');
6
+ const { checkGit } = require('../../../utils/git');
7
+ const { withTempDir } = require('../../../utils/withTempDir');
8
+ const { EXTENSION_TYPES } = require('../../../constant/extension');
9
+ const { successMessageRender } = require('../../../utils/views/message');
10
+ const { modifyTomlFile } = require('../../../utils/toml');
11
+ const { modifyJsonFile } = require('../../../utils/json');
12
+
13
+ // 生成结账扩展
14
+ async function generateCheckout(params) {
15
+ const { targetDirectory } = params;
16
+ const extensionName = path.basename(targetDirectory);
17
+
18
+ // 检查 git 是否安装
19
+ checkGit();
20
+
21
+ await withTempDir(async (tempDir) => {
22
+ const { https } = await getTemplateGitRequest('ext_co');
23
+
24
+ const tempDirPath = path.join(tempDir, 'extension');
25
+
26
+ // 克隆项目到本地
27
+ await simpleGit().clone(https, tempDirPath);
28
+
29
+ // 删除 .git 文件夹
30
+ fs.rmSync(path.join(tempDirPath, '.git'), { recursive: true, force: true });
31
+
32
+ // 修改 package.json
33
+ await modifyJsonFile(path.join(tempDirPath, 'package.json'), (config) => {
34
+ return {
35
+ ...config,
36
+ name: extensionName
37
+ };
38
+ });
39
+
40
+ // 修改 shoplazza.extension.toml
41
+ await modifyTomlFile(path.join(tempDirPath, 'shoplazza.extension.toml'), (config) => {
42
+ return {
43
+ ...config,
44
+ name: extensionName,
45
+ type: EXTENSION_TYPES.CHECKOUT
46
+ };
47
+ });
48
+
49
+ // 复制目录到目标位置
50
+ fs.cpSync(tempDirPath, targetDirectory, { recursive: true });
51
+ });
52
+
53
+ successMessageRender(`Your extension was created in extensions/${extensionName}.`);
54
+ }
55
+
56
+ module.exports = {
57
+ generateCheckout
58
+ };
@@ -0,0 +1,56 @@
1
+ const { getTemplateGitRequest } = require('../../../api/cli');
2
+ const { withTempDir } = require('../../../utils/withTempDir');
3
+ const { checkGit } = require('../../../utils/git');
4
+ const simpleGit = require('simple-git');
5
+ const { modifyJsonFile } = require('../../../utils/json');
6
+ const { modifyTomlFile } = require('../../../utils/toml');
7
+ const path = require('path');
8
+ const fs = require('fs');
9
+ const { successMessageRender } = require('../../../utils/views/message');
10
+ const { EXTENSION_TYPES } = require('../../../constant/extension');
11
+
12
+ // 生成功能扩展
13
+ async function generateFunction({ targetDirectory }) {
14
+ const extensionName = path.basename(targetDirectory);
15
+
16
+ // 检查 git 是否安装
17
+ checkGit();
18
+
19
+ await withTempDir(async (tempDir) => {
20
+ const { https } = await getTemplateGitRequest('ext_func');
21
+
22
+ const tempDirPath = path.join(tempDir, 'extension');
23
+
24
+ // 克隆项目到本地
25
+ await simpleGit().clone(https, tempDirPath);
26
+
27
+ // 删除 .git 文件夹
28
+ fs.rmSync(path.join(tempDirPath, '.git'), { recursive: true, force: true });
29
+
30
+ // 修改 package.json
31
+ await modifyJsonFile(path.join(tempDirPath, 'package.json'), (config) => {
32
+ return {
33
+ ...config,
34
+ name: extensionName
35
+ };
36
+ });
37
+
38
+ // 修改 shoplazza.extension.toml
39
+ await modifyTomlFile(path.join(tempDirPath, 'shoplazza.extension.toml'), (config) => {
40
+ return {
41
+ ...config,
42
+ name: extensionName,
43
+ type: EXTENSION_TYPES.FUNCTION
44
+ };
45
+ });
46
+
47
+ // 复制目录到目标位置
48
+ fs.cpSync(tempDirPath, targetDirectory, { recursive: true });
49
+ });
50
+
51
+ successMessageRender(`Your extension was created in extensions/${extensionName}.`);
52
+ }
53
+
54
+ module.exports = {
55
+ generateFunction
56
+ };
@@ -0,0 +1,128 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const inquirer = require('inquirer');
4
+
5
+ const { getTemplateGitRequest } = require('../../../api/cli');
6
+ const { THEME_EXTENSION_TYPES, EXTENSION_TYPES } = require('../../../constant/extension');
7
+ const { successMessageRender } = require('../../../utils/views/message');
8
+ const { withTempDir } = require('../../../utils/withTempDir');
9
+ const { checkGit } = require('../../../utils/git');
10
+ const simpleGit = require('simple-git');
11
+ const { modifyJsonFile } = require('../../../utils/json');
12
+ const { modifyTomlFile } = require('../../../utils/toml');
13
+ // 生成主题扩展
14
+ async function generateTheme({ targetDirectory }) {
15
+ const extensionName = path.basename(targetDirectory);
16
+
17
+ // 选择主题扩展类型
18
+ const { themeExtensionType } = await inquirer.prompt([
19
+ {
20
+ type: 'list',
21
+ name: 'themeExtensionType',
22
+ message: 'Select theme extension type:',
23
+ choices: [
24
+ { name: 'Basic Extension(a card storekeeper decide where it add)', value: THEME_EXTENSION_TYPES.BASIC },
25
+ { name: 'Embed Extension(a card not need add)', value: THEME_EXTENSION_TYPES.EMBED }
26
+ ]
27
+ }
28
+ ]);
29
+
30
+ // 检查 git 是否安装
31
+ checkGit();
32
+
33
+ await withTempDir(async (tempDir) => {
34
+ const { https } = await getTemplateGitRequest('ext_thm');
35
+
36
+ const tempDirPath = path.join(tempDir, 'extension');
37
+
38
+ // 克隆项目到本地
39
+ await simpleGit().clone(https, tempDirPath);
40
+
41
+ // 删除 .git 文件夹
42
+ fs.rmSync(path.join(tempDirPath, '.git'), { recursive: true, force: true });
43
+
44
+ // 修改 package.json
45
+ await modifyJsonFile(path.join(tempDirPath, 'package.json'), (config) => {
46
+ return {
47
+ ...config,
48
+ name: extensionName
49
+ };
50
+ });
51
+
52
+ // 修改 shoplazza.extension.toml
53
+ await modifyTomlFile(path.join(tempDirPath, 'shoplazza.extension.toml'), (config) => {
54
+ return {
55
+ ...config,
56
+ name: extensionName,
57
+ type: EXTENSION_TYPES.THEME
58
+ };
59
+ });
60
+
61
+ // 重命名 文件
62
+ fs.renameSync(
63
+ path.join(tempDirPath, 'blocks', `index-${themeExtensionType}.liquid`),
64
+ path.join(tempDirPath, 'blocks', `${extensionName}.liquid`)
65
+ );
66
+ fs.renameSync(
67
+ path.join(tempDirPath, 'snippets', 'index.liquid'),
68
+ path.join(tempDirPath, 'snippets', `${extensionName}.liquid`)
69
+ );
70
+
71
+ if (themeExtensionType === THEME_EXTENSION_TYPES.EMBED) {
72
+ // embed 重命名 snippets/index_css.liquid
73
+ fs.renameSync(
74
+ path.join(tempDirPath, 'snippets', 'index_css.liquid'),
75
+ path.join(tempDirPath, 'snippets', `${extensionName}_css.liquid`)
76
+ );
77
+
78
+ // embed 删除 assets/**
79
+ fs.rmSync(path.join(tempDirPath, 'assets'), { recursive: true, force: true });
80
+ } else {
81
+ // 删除 snippets/index_css.liquid
82
+ fs.unlinkSync(path.join(tempDirPath, 'snippets', 'index_css.liquid'));
83
+
84
+ // basic 重命名 assets/index.css
85
+ fs.renameSync(
86
+ path.join(tempDirPath, 'assets', 'index.css'),
87
+ path.join(tempDirPath, 'assets', `${extensionName}.css`)
88
+ );
89
+ }
90
+
91
+ // 修改 blocks/index.liquid
92
+ const blocksIndexLiquidPath = path.join(tempDirPath, 'blocks', `${extensionName}.liquid`);
93
+ const blocksIndexLiquidContent = fs.readFileSync(blocksIndexLiquidPath, 'utf-8');
94
+ const newBlocksIndexLiquidContent = blocksIndexLiquidContent.replaceAll('{{projectName}}', extensionName);
95
+ fs.writeFileSync(blocksIndexLiquidPath, newBlocksIndexLiquidContent);
96
+
97
+ // 修改 locales/en-US.json 和 locales/zh-CN.json
98
+ await Promise.all(
99
+ ['en-US.json', 'zh-CN.json'].map(async (locale) => {
100
+ const localesJsonPath = path.join(tempDirPath, 'locales', locale);
101
+ const localesJsonContent = fs.readFileSync(localesJsonPath, 'utf-8');
102
+ const newLocalesJsonContent = localesJsonContent.replaceAll(
103
+ '{{type}}',
104
+ themeExtensionType === THEME_EXTENSION_TYPES.BASIC ? 'BASIC' : 'EMBED'
105
+ );
106
+ fs.writeFileSync(localesJsonPath, newLocalesJsonContent);
107
+ })
108
+ );
109
+
110
+ // 删除 多余的 blocks/index-xxx.liquid
111
+ fs.unlinkSync(
112
+ path.join(
113
+ tempDirPath,
114
+ 'blocks',
115
+ `index-${themeExtensionType === THEME_EXTENSION_TYPES.BASIC ? 'embed' : 'basic'}.liquid`
116
+ )
117
+ );
118
+
119
+ // 复制目录到目标位置
120
+ fs.cpSync(tempDirPath, targetDirectory, { recursive: true });
121
+ });
122
+
123
+ successMessageRender(`Your extension was created in extensions/${extensionName}.`);
124
+ }
125
+
126
+ module.exports = {
127
+ generateTheme
128
+ };
@@ -0,0 +1,11 @@
1
+ const { Command } = require('commander');
2
+ const { extensionAction } = require('./actions/extension');
3
+ const extensionCommand = new Command('extension');
4
+
5
+ extensionCommand.option('--path <path>', 'The path to your app directory');
6
+
7
+ extensionCommand.action(extensionAction);
8
+
9
+ module.exports = {
10
+ extensionCommand
11
+ };
@@ -0,0 +1,22 @@
1
+ const { Command } = require('commander');
2
+ const { extensionCommand } = require('./extension');
3
+ const chalk = require('chalk');
4
+ const generateCommand = new Command('generate');
5
+
6
+ generateCommand.option('--path <path>', 'The path to your app directory');
7
+
8
+ generateCommand.addCommand(extensionCommand);
9
+
10
+ generateCommand.helpInformation = function () {
11
+ return `Generate a new app Extension.
12
+
13
+ ${chalk.bold('USAGE')}
14
+ $ shoplazza app generate COMMAND
15
+
16
+ ${chalk.bold('COMMANDS')}
17
+ app generate extension Generate a new app Extension.`;
18
+ };
19
+
20
+ module.exports = {
21
+ generateCommand
22
+ };
@@ -0,0 +1,82 @@
1
+ const chalk = require('chalk');
2
+ const { Command } = require('commander');
3
+ const { configCommand } = require('./config');
4
+ const { versionsCommand } = require('./versions');
5
+ const { deployCommand } = require('./deploy');
6
+ const { infoCommand } = require('./info');
7
+ const { initCommand } = require('./init');
8
+ const { generateCommand } = require('./generate');
9
+ const { devCommand } = require('./dev');
10
+ const path = require('path');
11
+ const { ssoStore, configStore, installStore } = require('../store');
12
+ const { existsPath } = require('../utils/path');
13
+ const { errorMessageRender } = require('../utils/views/message');
14
+ const { isDebug } = require('../utils/debug');
15
+ const appCommand = new Command('app')
16
+ .description('Build Shoplazza apps.')
17
+ .option('--reset', 'Reset app cache') // 重置 app 的本地缓存
18
+ .addCommand(initCommand)
19
+ .addCommand(infoCommand)
20
+ .addCommand(deployCommand)
21
+ .addCommand(configCommand)
22
+ .addCommand(versionsCommand)
23
+ .addCommand(generateCommand)
24
+ .addCommand(devCommand);
25
+
26
+ // 在 appCommand 执行任何子命令前加载 dotenv
27
+ appCommand.hook('preAction', (thisCommand, actionCommand) => {
28
+ const { path: argPath = '.' } = actionCommand.opts();
29
+
30
+ const { reset: argReset } = thisCommand.opts();
31
+
32
+ const projectDir = path.resolve(process.cwd(), argPath);
33
+
34
+ if (!existsPath(projectDir)) {
35
+ errorMessageRender(`Couldn't find directory ${projectDir}`);
36
+ process.exit(1);
37
+ }
38
+
39
+ require('dotenv').config({
40
+ path: path.join(projectDir, '.env')
41
+ });
42
+
43
+ // 增加环境变量
44
+ process.env.APP_PROJECT_DIR = projectDir;
45
+
46
+ if (isDebug()) {
47
+ // 设置调试模式
48
+ process.env.DEBUG = true;
49
+ }
50
+
51
+ if (argReset) {
52
+ // 清空 app config 缓存
53
+ configStore.clear();
54
+ // 清空 app clientId 对应店铺授权信息
55
+ installStore.clear();
56
+ // 清空 app access_token
57
+ ssoStore.clear();
58
+ }
59
+ });
60
+
61
+ appCommand.helpInformation = function () {
62
+ return `Build Shoplazza app.
63
+
64
+ ${chalk.bold('USAGE')}
65
+ $ shoplazza app COMMAND [options]
66
+
67
+ ${chalk.bold('TOPICS')}
68
+ app config Manage app configuration.
69
+ app generate Generate a new app Extension.
70
+ app versions List deployed versions of your app.
71
+
72
+ ${chalk.bold('COMMANDS')}
73
+ app init Create a new app project.
74
+ app info Print basic information about your app and extensions.
75
+ app dev Run the app.
76
+ app deploy Deploy your Shoplazza app.
77
+ `;
78
+ };
79
+
80
+ module.exports = {
81
+ appCommand
82
+ };
@@ -0,0 +1,168 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+ const glob = require('glob');
4
+ const chalk = require('chalk');
5
+
6
+ const { parseTomlFile } = require('../../../utils/toml');
7
+ const { withErrorHandling } = require('../../../utils/error');
8
+ const { warningMessageRender, infoMessageRender } = require('../../../utils/views/message');
9
+ const { getAppCompleteInfoRequest } = require('../../../api/cli');
10
+ const { getActiveConfigFile } = require('../../../services/config');
11
+
12
+ // 整理 extensions 信息
13
+ function getExtensionInfo(projectDir) {
14
+ const extnesions = glob.sync(path.join(projectDir, 'extensions/**/*.toml'));
15
+
16
+ const extensionsInfo = extnesions.map((extension) => {
17
+ const extensionInfo = parseTomlFile(extension);
18
+ return {
19
+ name: extensionInfo.name,
20
+ type: extensionInfo.type
21
+ };
22
+ });
23
+
24
+ // 获取 extnesions 中 name 最长的长度
25
+ const maxNameLength = Math.max(...extensionsInfo.map((item) => item.name.length));
26
+
27
+ // padEnd 长度
28
+ const result = extensionsInfo.map((item) => {
29
+ return `${item.name.padEnd(maxNameLength)} ${chalk.gray(`(${item.type})`)}`;
30
+ });
31
+
32
+ return result.join('\n');
33
+ }
34
+
35
+ async function infoAction(options) {
36
+ const { path: argPath = '.' } = options;
37
+ // 项目地址
38
+ const projectDir = path.resolve(argPath);
39
+
40
+ // 判断项目是否存在
41
+ if (!fs.existsSync(projectDir)) {
42
+ throw new Error(`Couldn't find directory ${projectDir}`);
43
+ }
44
+
45
+ // 获取当前正在使用的 configFile
46
+ const activeConfigFile = getActiveConfigFile(projectDir);
47
+
48
+ // 判断 configFile 是否存在
49
+ if (!fs.existsSync(path.join(projectDir, activeConfigFile))) {
50
+ // 获取 projectDir 根目录下 所有的 shoplazza.app.*.toml
51
+ const configFiles = glob.sync(path.join(projectDir, 'shoplazza.app.*.toml'));
52
+
53
+ // 如果 configFiles 为空,则抛出错误
54
+ if (configFiles.length === 0) {
55
+ warningMessageRender(
56
+ `No config file found, please use ${chalk.hex('#d079f8')(
57
+ '`shoplazza app config link`'
58
+ )} to create a new config file`
59
+ );
60
+ } else {
61
+ warningMessageRender(
62
+ `No active config file found, please use ${chalk.hex('#d079f8')(
63
+ '`shoplazza app config use`'
64
+ )} to switch to a new config file`
65
+ );
66
+ }
67
+
68
+ process.exit(1);
69
+ }
70
+
71
+ // 获取 configFile 信息
72
+ const configContent = parseTomlFile(path.join(projectDir, activeConfigFile));
73
+
74
+ // 获取 app 相关信息
75
+ const { user, partner, app } = await getAppCompleteInfoRequest(configContent.client_id);
76
+
77
+ // userObj
78
+ const userObj = [
79
+ {
80
+ label: 'Configuration file',
81
+ value: activeConfigFile
82
+ },
83
+ {
84
+ label: 'App name',
85
+ value: app.name
86
+ },
87
+ {
88
+ label: 'App Client ID',
89
+ value: configContent.client_id
90
+ },
91
+ {
92
+ label: 'Access scopes',
93
+ value: configContent.scopes
94
+ },
95
+ {
96
+ label: 'User',
97
+ value: user.shoplazza_account
98
+ }
99
+ ];
100
+
101
+ // your project
102
+ const projectObj = [
103
+ {
104
+ label: 'Root location',
105
+ value: projectDir
106
+ }
107
+ ];
108
+
109
+ // tooling and system
110
+ const toolingObj = [
111
+ {
112
+ label: 'Shoplazza CLI',
113
+ value: `v${require('../../../../../package.json').version}`
114
+ },
115
+ {
116
+ label: 'OS',
117
+ value: `${process.platform}-${process.arch}`
118
+ },
119
+ {
120
+ label: 'Shell',
121
+ value: process.env.SHELL
122
+ },
123
+ {
124
+ label: 'Node',
125
+ value: process.version
126
+ }
127
+ ];
128
+
129
+ const userObjStr = userObj
130
+ .map((item) => {
131
+ return `${chalk.gray(item.label.padEnd(20))} ${item.value || ''}`;
132
+ })
133
+ .join('\n');
134
+
135
+ const projectObjStr = projectObj
136
+ .map((item) => {
137
+ return `${chalk.gray(item.label.padEnd(20))} ${item.value || ''}`;
138
+ })
139
+ .join('\n');
140
+
141
+ const toolingObjStr = toolingObj
142
+ .map((item) => {
143
+ return `${chalk.gray(item.label.padEnd(20))} ${item.value || ''}`;
144
+ })
145
+ .join('\n');
146
+
147
+ // 展示 CURRENT APP CONFIGURATION
148
+ infoMessageRender(`${chalk.bold('CURRENT APP CONFIGURATION')}
149
+
150
+ ${userObjStr}
151
+
152
+ ${chalk.bold('YOUR PROJECT')}
153
+
154
+ ${projectObjStr}
155
+
156
+ ${chalk.bold('DIRECTORY COMPONENTS')}
157
+
158
+ ${getExtensionInfo(projectDir)}
159
+
160
+ ${chalk.bold('TOOLING AND SYSTEM')}
161
+
162
+ ${toolingObjStr}
163
+ `);
164
+ }
165
+
166
+ module.exports = {
167
+ infoAction: withErrorHandling(infoAction)
168
+ };
@@ -0,0 +1,11 @@
1
+ const { Command } = require('commander');
2
+ const { infoAction } = require('./actions/info');
3
+ const infoCommand = new Command('info');
4
+
5
+ infoCommand.option('--path <path>', 'The path to your app directory');
6
+
7
+ infoCommand.action(infoAction);
8
+
9
+ module.exports = {
10
+ infoCommand
11
+ };