shoplazza-cli 1.0.13 → 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.
- package/README.md +12 -12
- package/bin/shoplazza +5 -3
- package/lib/app/api/cli.js +225 -0
- package/lib/app/api/openapi.js +121 -0
- package/lib/app/api/partnerOpenapi.js +104 -0
- package/lib/app/bin/index.js +20 -0
- package/lib/app/bin/javy/javy-arm-linux-v5.0.1 +0 -0
- package/lib/app/bin/javy/javy-arm-macos-v5.0.1 +0 -0
- package/lib/app/bin/javy/javy-x86_64-linux-v5.0.1 +0 -0
- package/lib/app/bin/javy/javy-x86_64-macos-v5.0.1 +0 -0
- package/lib/app/bin/javy/javy-x86_64-windows-v5.0.1 +0 -0
- package/lib/app/commands/config/actions/link.js +189 -0
- package/lib/app/commands/config/actions/use.js +40 -0
- package/lib/app/commands/config/index.js +25 -0
- package/lib/app/commands/config/link.js +11 -0
- package/lib/app/commands/config/use.js +11 -0
- package/lib/app/commands/deploy/actions/deploy.js +196 -0
- package/lib/app/commands/deploy/index.js +11 -0
- package/lib/app/commands/dev/actions/dev.js +206 -0
- package/lib/app/commands/dev/index.js +11 -0
- package/lib/app/commands/generate/actions/extension.js +97 -0
- package/lib/app/commands/generate/actions/generateCheckout.js +58 -0
- package/lib/app/commands/generate/actions/generateFunction.js +56 -0
- package/lib/app/commands/generate/actions/generateTheme.js +128 -0
- package/lib/app/commands/generate/extension.js +11 -0
- package/lib/app/commands/generate/index.js +22 -0
- package/lib/app/commands/index.js +82 -0
- package/lib/app/commands/info/actions/info.js +168 -0
- package/lib/app/commands/info/index.js +11 -0
- package/lib/app/commands/init/actions/init.js +176 -0
- package/lib/app/commands/init/index.js +14 -0
- package/lib/app/commands/versions/actions/list.js +210 -0
- package/lib/app/commands/versions/index.js +22 -0
- package/lib/app/commands/versions/list.js +14 -0
- package/lib/app/constant/code.js +7 -0
- package/lib/app/constant/color.js +18 -0
- package/lib/app/constant/extension.js +16 -0
- package/lib/app/constant/host.js +23 -0
- package/lib/app/constant/sso.js +7 -0
- package/lib/app/index.js +4 -25
- package/lib/app/services/auth/config.js +33 -0
- package/lib/app/services/auth/index.js +9 -0
- package/lib/app/services/auth/oauth-server.js +70 -0
- package/lib/app/services/auth/partner-token.js +45 -0
- package/lib/app/services/auth/sso-token.js +69 -0
- package/lib/app/services/auth/store-token.js +100 -0
- package/lib/app/services/auth/url-builder.js +23 -0
- package/lib/app/services/config/index.js +41 -0
- package/lib/app/services/devServer/app.js +76 -0
- package/lib/app/services/devServer/index.js +103 -0
- package/lib/app/services/devServer/middleware/hmacValidatorMiddleWare.js +20 -0
- package/lib/app/services/devServer/middleware/index.js +5 -0
- package/lib/app/services/devServer/tunnel/index.js +43 -0
- package/lib/app/services/devServer/tunnel/providers/cloudflare.js +364 -0
- package/lib/app/services/devServer/tunnel/providers/ngrok.js +70 -0
- package/lib/app/services/devServer/utils/index.js +5 -0
- package/lib/app/services/devServer/utils/secureCompare.js +5 -0
- package/lib/app/services/devServer/views/app.ejs +133 -0
- package/lib/app/services/extension-build/buildCheckout.js +47 -0
- package/lib/app/services/extension-build/buildFunction.js +57 -0
- package/lib/app/services/extension-build/buildTheme.js +100 -0
- package/lib/app/services/extension-build/index.js +23 -0
- package/lib/app/services/extension-build/plugins/vite-plugin-add-extension-id.js +26 -0
- package/lib/app/services/extension-build/plugins/vite-plugin-transform-extension-html.js +207 -0
- package/lib/app/services/extension-diff/index.js +132 -0
- package/lib/app/services/extension-upsert/index.js +21 -0
- package/lib/app/services/extension-upsert/upsertCheckout.js +44 -0
- package/lib/app/services/extension-upsert/upsertFunction.js +52 -0
- package/lib/app/services/extension-upsert/upsertTheme.js +113 -0
- package/lib/app/services/oss/index.js +45 -0
- package/lib/app/services/partner/index.js +52 -0
- package/lib/app/store/base-store.js +37 -0
- package/lib/app/store/config-store.js +55 -0
- package/lib/app/store/config.js +21 -0
- package/lib/app/store/index.js +14 -0
- package/lib/app/store/install-store.js +41 -0
- package/lib/app/store/sso-store.js +55 -0
- package/lib/app/utils/asyncPool.js +42 -0
- package/lib/app/utils/debug/index.js +16 -0
- package/lib/app/utils/env.js +24 -0
- package/lib/app/utils/error.js +20 -0
- package/lib/app/utils/git.js +20 -0
- package/lib/app/utils/json.js +27 -0
- package/lib/app/utils/path.js +33 -0
- package/lib/app/utils/platform.js +37 -0
- package/lib/app/utils/request/cli.js +72 -0
- package/lib/app/utils/request/debug.js +13 -0
- package/lib/app/utils/request/openapi.js +67 -0
- package/lib/app/utils/request/partnerOpenapi.js +47 -0
- package/lib/app/utils/toml.js +56 -0
- package/lib/app/utils/views/message.js +68 -0
- package/lib/app/utils/views/select.js +36 -0
- package/lib/app/utils/withTempDir.js +55 -0
- package/lib/checkout/api.js +2 -0
- package/lib/function/bin/javy/javy-arm-macos-v5.0.1 +0 -0
- package/lib/oss.js +5 -2
- package/lib/theme-extension/index.js +29 -0
- package/lib/utils/config.js +1 -1
- package/package.json +12 -1
- package/examples/checkout-extension/README.md +0 -19
- package/examples/checkout-extension/extension.config.js +0 -4
- package/examples/checkout-extension/extensions/add-shipping-desc/extension.json +0 -10
- package/examples/checkout-extension/extensions/add-shipping-desc/src/index.js +0 -7
- package/examples/checkout-extension/extensions/ext-1/extension.json +0 -10
- package/examples/checkout-extension/extensions/ext-1/src/content.html +0 -3
- package/examples/checkout-extension/extensions/ext-1/src/index.html +0 -5
- package/examples/checkout-extension/extensions/ext-1/src/index.js +0 -11
- package/examples/checkout-extension/extensions/ext-1/src/script.html +0 -3
- package/examples/checkout-extension/extensions/ext-1/src/style.html +0 -3
- package/examples/checkout-extension/extensions/product-list/extension.json +0 -10
- package/examples/checkout-extension/extensions/product-list/src/index.js +0 -5
- package/examples/checkout-extension/extensions/rewrite-navigate/extension.json +0 -10
- package/examples/checkout-extension/extensions/rewrite-navigate/src/content.html +0 -38
- package/examples/checkout-extension/extensions/rewrite-navigate/src/index.html +0 -5
- package/examples/checkout-extension/extensions/rewrite-navigate/src/index.js +0 -12
- package/examples/checkout-extension/extensions/rewrite-navigate/src/script.html +0 -26
- package/examples/checkout-extension/extensions/rewrite-navigate/src/style.html +0 -23
- package/examples/checkout-extension/package-lock.json +0 -121
- package/examples/checkout-extension/package.json +0 -17
- /package/lib/{app → theme-extension}/api/index.js +0 -0
- /package/lib/{app → theme-extension}/commands/build.js +0 -0
- /package/lib/{app → theme-extension}/commands/connect.js +0 -0
- /package/lib/{app → theme-extension}/commands/create.js +0 -0
- /package/lib/{app → theme-extension}/commands/deploy.js +0 -0
- /package/lib/{app → theme-extension}/commands/list.js +0 -0
- /package/lib/{app → theme-extension}/commands/release.js +0 -0
- /package/lib/{app → theme-extension}/commands/serve.js +0 -0
- /package/lib/{app → theme-extension}/commands/versions.js +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/README.md +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/extension.config.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/package.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/assets/index.css +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/assets-manifest.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/blocks/index.liquid +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/ar-SA.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/de-DE.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/en-US.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/es-ES.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/fr-FR.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/id-ID.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/it-IT.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/ja-JP.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/ko-KR.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/nl-NL.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/pl-PL.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/pt-PT.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/ru-RU.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/th-TH.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/zh-CN.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/locales/zh-TW.json +0 -0
- /package/lib/{app → theme-extension}/template/basic-app/theme-app/snippets/index.liquid +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/README.md +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/extension.config.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/package.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/assets-manifest.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/blocks/index.liquid +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/ar-SA.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/de-DE.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/en-US.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/es-ES.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/fr-FR.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/id-ID.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/it-IT.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/ja-JP.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/ko-KR.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/nl-NL.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/pl-PL.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/pt-PT.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/ru-RU.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/th-TH.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/zh-CN.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/locales/zh-TW.json +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/snippets/index.liquid +0 -0
- /package/lib/{app → theme-extension}/template/embed-app/theme-app/snippets/index_css.liquid +0 -0
- /package/lib/{app → theme-extension}/utils/config.js +0 -0
- /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
|
+
};
|