@lazycatcloud/lzc-cli 1.3.11 → 1.3.13
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/changelog.md +24 -0
- package/lib/app/apkshell.js +37 -40
- package/lib/app/index.js +187 -179
- package/lib/app/lpk_build.js +341 -358
- package/lib/app/lpk_create.js +135 -155
- package/lib/app/lpk_create_generator.js +74 -66
- package/lib/app/lpk_devshell.js +444 -533
- package/lib/app/lpk_devshell_docker.js +48 -47
- package/lib/app/lpk_installer.js +119 -123
- package/lib/appstore/index.js +205 -209
- package/lib/appstore/login.js +146 -143
- package/lib/appstore/prePublish.js +101 -100
- package/lib/appstore/publish.js +254 -256
- package/lib/box/index.js +82 -77
- package/lib/config/env.js +2 -2
- package/lib/config/index.js +58 -54
- package/lib/debug_bridge.js +280 -320
- package/lib/docker/index.js +84 -86
- package/lib/i18n/README.md +25 -0
- package/lib/i18n/index.js +37 -0
- package/lib/i18n/locales/en/translation.json +251 -0
- package/lib/i18n/locales/zh/translation.json +251 -0
- package/lib/shellapi.js +122 -146
- package/lib/utils.js +539 -553
- package/package.json +6 -8
- package/scripts/cli.js +81 -77
- package/scripts/lzc-docker-compose.js +34 -33
- package/scripts/lzc-docker.js +34 -33
package/changelog.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.3.13](https://gitee.com/linakesi/lzc-cli/compare/v1.3.12...v1.3.13) (2025-12-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add i18n ([f62c52a](https://gitee.com/linakesi/lzc-cli/commits/f62c52a9b443d2226ffa06d17593f1912b9dc4de))
|
|
9
|
+
* add i18n config ([185418d](https://gitee.com/linakesi/lzc-cli/commits/185418d5e77858d55fca485ff115191c0c95834e))
|
|
10
|
+
* some copywriters provide i18n calls ([54d92f1](https://gitee.com/linakesi/lzc-cli/commits/54d92f17520e6413d735c82d57d3aa3404410add))
|
|
11
|
+
|
|
12
|
+
## [1.3.12](https://gitee.com/linakesi/lzc-cli/compare/v1.3.11...v1.3.12) (2025-10-29)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* ci friendly publish command ([1e7b477](https://gitee.com/linakesi/lzc-cli/commits/1e7b47740f1d9ae15d677a16a97d7cc461814c42))
|
|
18
|
+
* pre publish print error ([55c8326](https://gitee.com/linakesi/lzc-cli/commits/55c832625aa532bab3e0fcf0d7ec09d8235db190))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* add `LZC_CLI_CHECK_DNS_RESOLVE` set check dev tools to use built-in dns resolution ([78ba39e](https://gitee.com/linakesi/lzc-cli/commits/78ba39e6869cbed956141e7ff7812ce3718e41ce))
|
|
24
|
+
* supports config the language key for publish app update logs through `--clang` ([e06eec8](https://gitee.com/linakesi/lzc-cli/commits/e06eec88f11827816ddd4e3a7ccd43b2883a1003))
|
|
25
|
+
* uninstall app add `--delete-data` parameter ([b4378f7](https://gitee.com/linakesi/lzc-cli/commits/b4378f77b528fbb5b5a1c74771ddda9f60f4e49a))
|
|
26
|
+
|
|
3
27
|
## [1.3.11](https://gitee.com/linakesi/lzc-cli/compare/v1.3.10...v1.3.11) (2025-10-10)
|
|
4
28
|
|
|
5
29
|
|
package/lib/app/apkshell.js
CHANGED
|
@@ -1,48 +1,45 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import logger from
|
|
3
|
-
import axios from
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import logger from 'loglevel';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import { t } from '../i18n/index.js';
|
|
4
5
|
|
|
5
6
|
// 创建 Axios 实例
|
|
6
|
-
const api = axios.create()
|
|
7
|
+
const api = axios.create();
|
|
7
8
|
|
|
8
9
|
// 添加响应拦截器
|
|
9
10
|
api.interceptors.response.use(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
)
|
|
11
|
+
(response) => response, // 直接返回响应
|
|
12
|
+
(error) => {
|
|
13
|
+
if (error.response && error.response.status === 304) {
|
|
14
|
+
return Promise.resolve(error.response); // 返回响应以便后续处理
|
|
15
|
+
}
|
|
16
|
+
return Promise.reject(error); // 其他错误继续抛出
|
|
17
|
+
},
|
|
18
|
+
);
|
|
18
19
|
|
|
19
20
|
export async function triggerApk(id, name, iconPath) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
} catch (error) {
|
|
46
|
-
logger.debug(error)
|
|
47
|
-
}
|
|
21
|
+
if (!id) {
|
|
22
|
+
logger.error(t('lzc_cli.lib.app.apkshell.trigger_apk_empty_appid', 'Appid 为必填项!'));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
name = name || t('lzc_cli.lib.app.apkshell.trigger_apk_default_app_name', '懒猫应用');
|
|
26
|
+
try {
|
|
27
|
+
const form = new FormData();
|
|
28
|
+
form.append('app_id', id);
|
|
29
|
+
form.append('app_name', name);
|
|
30
|
+
if (iconPath) {
|
|
31
|
+
form.append('app_icon', new Blob([fs.readFileSync(iconPath)]));
|
|
32
|
+
}
|
|
33
|
+
const resp = await api.post('https://appstore.api.lazycat.cloud/api/trigger_latest_for_app', form, { timeout: 5000 });
|
|
34
|
+
if (resp.status == 304) {
|
|
35
|
+
logger.debug(t('lzc_cli.lib.app.apkshell.trigger_apk_build_tips', `APK构建任务已创建成功,如需使用安卓端,请耐心等待1分钟左右`));
|
|
36
|
+
} else if (resp.status <= 201) {
|
|
37
|
+
logger.info(t('lzc_cli.lib.app.apkshell.trigger_apk_build_ok_tips', `APK构建任务已创建成功,如需使用安卓端,请耐心等待1分钟左右`));
|
|
38
|
+
} else if (resp.status >= 400) {
|
|
39
|
+
logger.debug(t('lzc_cli.lib.app.apkshell.trigger_apk_build_failed', '请求按钮应用出错:'), resp);
|
|
40
|
+
throw t('lzc_cli.lib.app.apkshell.trigger_apk_build_failed_tips', `请求生成应用出错! 使用 --apk=n 停止生成APK`);
|
|
41
|
+
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
logger.debug(error);
|
|
44
|
+
}
|
|
48
45
|
}
|
package/lib/app/index.js
CHANGED
|
@@ -1,192 +1,200 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import lpkCreate from
|
|
3
|
-
import { LpkBuild } from
|
|
4
|
-
import { AppDevShell } from
|
|
5
|
-
import { LpkInstaller, installConfig } from
|
|
6
|
-
import logger from
|
|
7
|
-
import { sleep, checkRsync } from
|
|
8
|
-
import { DebugBridge } from
|
|
9
|
-
import shellApi from
|
|
10
|
-
import { generate } from
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import lpkCreate from './lpk_create.js';
|
|
3
|
+
import { LpkBuild } from './lpk_build.js';
|
|
4
|
+
import { AppDevShell } from './lpk_devshell.js';
|
|
5
|
+
import { LpkInstaller, installConfig } from './lpk_installer.js';
|
|
6
|
+
import logger from 'loglevel';
|
|
7
|
+
import { sleep, checkRsync } from '../utils.js';
|
|
8
|
+
import { DebugBridge } from '../debug_bridge.js';
|
|
9
|
+
import shellApi from '../shellapi.js';
|
|
10
|
+
import { generate } from './lpk_create_generator.js';
|
|
11
|
+
import { t } from '../i18n/index.js';
|
|
11
12
|
|
|
12
13
|
export function lpkProjectCommand(program) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
14
|
+
let subCommands = [
|
|
15
|
+
{
|
|
16
|
+
command: 'init',
|
|
17
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_init_desc', '初始化懒猫云应用(提供最基础的模板)'),
|
|
18
|
+
handler: async () => {
|
|
19
|
+
generate('blank', './');
|
|
20
|
+
logger.info(t('lzc_cli.lib.app.index.lpk_cmd_init_success', '应用初始化完成'));
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
command: 'create <name>',
|
|
25
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_create_desc', '创建懒猫云应用'),
|
|
26
|
+
handler: async ({ name }) => {
|
|
27
|
+
name = String(name);
|
|
28
|
+
await lpkCreate(name);
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
command: 'build [context]',
|
|
33
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_build_desc', '构建'),
|
|
34
|
+
builder: (args) => {
|
|
35
|
+
args.option('o', {
|
|
36
|
+
alias: 'output',
|
|
37
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_build_args_output_desc', '输出文件'),
|
|
38
|
+
type: 'string',
|
|
39
|
+
});
|
|
40
|
+
args.option('f', {
|
|
41
|
+
alias: 'file',
|
|
42
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_build_args_file_desc', '指定构建的lzc-build.yml文件'),
|
|
43
|
+
default: 'lzc-build.yml',
|
|
44
|
+
type: 'string',
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
handler: async ({ context, output, file }) => {
|
|
48
|
+
const lpk = await new LpkBuild(context, file).init();
|
|
49
|
+
// 正常的打包逻辑不需要 devshell
|
|
50
|
+
lpk.onBeforeBuildPackage(async (options) => {
|
|
51
|
+
delete options['devshell'];
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
53
|
+
if (output) {
|
|
54
|
+
options['lpkPath'] = output;
|
|
55
|
+
}
|
|
56
|
+
return options;
|
|
57
|
+
});
|
|
58
|
+
await lpk.exec();
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
command: 'devshell [context]',
|
|
63
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_devshell_desc', '进入盒子的开发环境'),
|
|
64
|
+
builder: (args) => {
|
|
65
|
+
args.option('f', {
|
|
66
|
+
alias: 'force',
|
|
67
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_devshell_args_force_desc', '强制重新构建'),
|
|
68
|
+
type: 'boolean',
|
|
69
|
+
});
|
|
70
|
+
args.option('c', {
|
|
71
|
+
alias: 'config',
|
|
72
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_devshell_args_config_desc', 'devshell配置文件'),
|
|
73
|
+
type: 'string',
|
|
74
|
+
default: 'lzc-build.yml',
|
|
75
|
+
});
|
|
76
|
+
args.option('contentdir', {
|
|
77
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_devshell_args_contentdir_desc', '同时打包 lzc-build.yml 中指定的 contentdir 目录'),
|
|
78
|
+
type: 'boolean',
|
|
79
|
+
});
|
|
80
|
+
args.option('apk', {
|
|
81
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_devshell_args_apk_desc', '是否生成APK(y/n)'),
|
|
82
|
+
type: 'string',
|
|
83
|
+
default: 'y',
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
handler: async ({ context, force, config, contentdir, apk }) => {
|
|
87
|
+
await shellApi.init();
|
|
88
|
+
// 检测 rsync 满足
|
|
89
|
+
await checkRsync();
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
installConfig.apk = apk == 'y';
|
|
92
|
+
const cwd = context ? path.resolve(context) : process.cwd();
|
|
93
|
+
const lpkBuild = await new LpkBuild(cwd, config).init();
|
|
94
|
+
lpkBuild.onBeforeBuildPackage(async (options) => {
|
|
95
|
+
// devshell 正常情况下,不需要执行 buildscript 和 contentdir 字段
|
|
96
|
+
logger.debug("devshell delete 'buildscript' field");
|
|
97
|
+
delete options['buildscript'];
|
|
97
98
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
99
|
+
if (!contentdir) {
|
|
100
|
+
logger.debug("devshell delete 'contentdir' field");
|
|
101
|
+
delete options['contentdir'];
|
|
102
|
+
}
|
|
103
|
+
return options;
|
|
104
|
+
});
|
|
105
|
+
const app = new AppDevShell(cwd, lpkBuild, force, config);
|
|
106
|
+
await app.init();
|
|
107
|
+
await app.build();
|
|
108
|
+
await sleep(2000);
|
|
109
|
+
await app.rsyncShell();
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
];
|
|
113
|
+
program.command({
|
|
114
|
+
command: 'project',
|
|
115
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_project_desc', '项目管理'),
|
|
116
|
+
builder: (args) => {
|
|
117
|
+
args.command(subCommands);
|
|
118
|
+
},
|
|
119
|
+
});
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
export function lpkAppCommand(program) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
123
|
+
let subCommands = [
|
|
124
|
+
{
|
|
125
|
+
command: 'install [pkgPath]',
|
|
126
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_install_desc', '部署应用至设备, pkgPath 可以为路径,或者https://,http://请求地址, 如果不填写,将默认为当前目录下的lpk'),
|
|
127
|
+
builder: (args) => {
|
|
128
|
+
args.option('apk', {
|
|
129
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_index_rags_apk_desc', '是否生成APK(y/n)'),
|
|
130
|
+
type: 'string',
|
|
131
|
+
default: 'y',
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
handler: async ({ pkgPath, apk }) => {
|
|
135
|
+
await shellApi.init();
|
|
136
|
+
installConfig.apk = apk == 'y';
|
|
136
137
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
138
|
+
pkgPath = pkgPath ?? process.cwd();
|
|
139
|
+
const installer = new LpkInstaller();
|
|
140
|
+
await installer.init();
|
|
141
|
+
await installer.install(pkgPath);
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
command: 'uninstall <pkgId>',
|
|
146
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_uninstall_desc', '从设备中卸载某一个应用'),
|
|
147
|
+
builder: (args) => {
|
|
148
|
+
args.option('delete-data', {
|
|
149
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_uninstall_rags_delete_data_desc', '删除应用数据 ⚠️ 警告: 应用数据删除后无法恢复'),
|
|
150
|
+
type: 'boolean',
|
|
151
|
+
default: false,
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
handler: async ({ pkgId, deleteData }) => {
|
|
155
|
+
await shellApi.init();
|
|
148
156
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
const bridge = new DebugBridge();
|
|
158
|
+
await bridge.init();
|
|
159
|
+
await bridge.uninstall(pkgId, deleteData);
|
|
160
|
+
logger.debug(`default lcmd device: ${bridge.boxname} , uninstall the app ${pkgId} finish`);
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
command: 'status <pkgId>',
|
|
165
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_status_desc', '获取某一个应用的状态'),
|
|
166
|
+
handler: async ({ pkgId }) => {
|
|
167
|
+
await shellApi.init();
|
|
160
168
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
169
|
+
const bridge = new DebugBridge();
|
|
170
|
+
await bridge.init();
|
|
171
|
+
const status = await bridge.status(pkgId);
|
|
172
|
+
console.log(status);
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
command: 'log <pkgId>',
|
|
177
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_log_desc', '查看某一个app的日志'),
|
|
178
|
+
builder: (args) => {
|
|
179
|
+
args.option('f', {
|
|
180
|
+
alias: 'follow',
|
|
181
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_log_args_follow_desc', '持续输出'),
|
|
182
|
+
type: 'boolean',
|
|
183
|
+
default: false,
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
handler: async () => {
|
|
187
|
+
await shellApi.init();
|
|
180
188
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
throw 'not yet realized';
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
];
|
|
193
|
+
program.command({
|
|
194
|
+
command: 'app',
|
|
195
|
+
desc: t('lzc_cli.lib.app.index.lpk_cmd_app_desc', '应用管理'),
|
|
196
|
+
builder: async (args) => {
|
|
197
|
+
args.command(subCommands);
|
|
198
|
+
},
|
|
199
|
+
});
|
|
192
200
|
}
|