@lazycatcloud/lzc-cli 1.3.15 → 1.3.17
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 +33 -19
- package/lib/app/index.js +7 -1
- package/lib/app/lpk_installer.js +5 -5
- package/lib/appstore/publish.js +54 -15
- package/lib/debug_bridge.js +65 -22
- package/lib/i18n/locales/en/translation.json +7 -2
- package/lib/i18n/locales/zh/translation.json +6 -1
- package/package.json +89 -89
package/changelog.md
CHANGED
|
@@ -1,55 +1,69 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [1.3.
|
|
3
|
+
## [1.3.17](https://gitee.com/linakesi/lzc-cli/compare/v1.3.15...v1.3.17) (2026-03-03)
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
### Bug Fixes
|
|
7
7
|
|
|
8
|
-
*
|
|
8
|
+
* dealing with the error prompt of creating a new app ([6069b28](https://gitee.com/linakesi/lzc-cli/commits/6069b282027c7a6ddbcde45a0ff26156e6745030))
|
|
9
|
+
* playground site url ([5afd2ec](https://gitee.com/linakesi/lzc-cli/commits/5afd2ec5edd8aee51579add5daed3ccaabc4650f))
|
|
10
|
+
* submit the app file size ([7dffe90](https://gitee.com/linakesi/lzc-cli/commits/7dffe90b4a18f6f4b8afd8ace23c836d7fba17a7))
|
|
9
11
|
|
|
10
|
-
## [1.3.
|
|
12
|
+
## [1.3.16](https://gitee.com/linakesi/lzc-cli/compare/v1.3.13...v1.3.16) (2026-02-28)
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- dealing with the i18n difference escape problem ([2b98cdf](https://gitee.com/linakesi/lzc-cli/commits/2b98cdf0573a1537bee409079d6160da1b7cd80b))
|
|
17
|
+
- disable i18next support notice output ([f433c88](https://gitee.com/linakesi/lzc-cli/commits/f433c88e9a2434c9cff303c088fa39d33bf59309))
|
|
18
|
+
- playground site url ([5afd2ec](https://gitee.com/linakesi/lzc-cli/commits/5afd2ec5edd8aee51579add5daed3ccaabc4650f))
|
|
11
19
|
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
- cmd publish add `changelog-files` option ([17d95c6](https://gitee.com/linakesi/lzc-cli/commits/17d95c6fa761f25af234946dedd3d6a0503ba962))
|
|
23
|
+
|
|
24
|
+
## [1.3.15](https://gitee.com/linakesi/lzc-cli/compare/v1.3.14...v1.3.15) (2026-02-26)
|
|
12
25
|
|
|
13
26
|
### Bug Fixes
|
|
14
27
|
|
|
15
|
-
|
|
28
|
+
- disable i18next support notice output ([f433c88](https://gitee.com/linakesi/lzc-cli/commits/f433c88e9a2434c9cff303c088fa39d33bf59309))
|
|
16
29
|
|
|
30
|
+
## [1.3.14](https://gitee.com/linakesi/lzc-cli/compare/v1.3.13...v1.3.14) (2025-12-17)
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
- dealing with the i18n difference escape problem ([2b98cdf](https://gitee.com/linakesi/lzc-cli/commits/2b98cdf0573a1537bee409079d6160da1b7cd80b))
|
|
17
35
|
|
|
18
36
|
### Features
|
|
19
37
|
|
|
20
|
-
|
|
38
|
+
- cmd publish add `changelog-files` option ([17d95c6](https://gitee.com/linakesi/lzc-cli/commits/17d95c6fa761f25af234946dedd3d6a0503ba962))
|
|
21
39
|
|
|
22
40
|
## [1.3.13](https://gitee.com/linakesi/lzc-cli/compare/v1.3.12...v1.3.13) (2025-12-10)
|
|
23
41
|
|
|
24
|
-
|
|
25
42
|
### Features
|
|
26
43
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
44
|
+
- add i18n ([f62c52a](https://gitee.com/linakesi/lzc-cli/commits/f62c52a9b443d2226ffa06d17593f1912b9dc4de))
|
|
45
|
+
- add i18n config ([185418d](https://gitee.com/linakesi/lzc-cli/commits/185418d5e77858d55fca485ff115191c0c95834e))
|
|
46
|
+
- some copywriters provide i18n calls ([54d92f1](https://gitee.com/linakesi/lzc-cli/commits/54d92f17520e6413d735c82d57d3aa3404410add))
|
|
30
47
|
|
|
31
48
|
## [1.3.12](https://gitee.com/linakesi/lzc-cli/compare/v1.3.11...v1.3.12) (2025-10-29)
|
|
32
49
|
|
|
33
|
-
|
|
34
50
|
### Bug Fixes
|
|
35
51
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
52
|
+
- ci friendly publish command ([1e7b477](https://gitee.com/linakesi/lzc-cli/commits/1e7b47740f1d9ae15d677a16a97d7cc461814c42))
|
|
53
|
+
- pre publish print error ([55c8326](https://gitee.com/linakesi/lzc-cli/commits/55c832625aa532bab3e0fcf0d7ec09d8235db190))
|
|
39
54
|
|
|
40
55
|
### Features
|
|
41
56
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
57
|
+
- 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))
|
|
58
|
+
- supports config the language key for publish app update logs through `--clang` ([e06eec8](https://gitee.com/linakesi/lzc-cli/commits/e06eec88f11827816ddd4e3a7ccd43b2883a1003))
|
|
59
|
+
- uninstall app add `--delete-data` parameter ([b4378f7](https://gitee.com/linakesi/lzc-cli/commits/b4378f77b528fbb5b5a1c74771ddda9f60f4e49a))
|
|
45
60
|
|
|
46
61
|
## [1.3.11](https://gitee.com/linakesi/lzc-cli/compare/v1.3.10...v1.3.11) (2025-10-10)
|
|
47
62
|
|
|
48
|
-
|
|
49
63
|
### Features
|
|
50
64
|
|
|
51
|
-
|
|
52
|
-
|
|
65
|
+
- support setting token through environment variables ([4a25f84](https://gitee.com/linakesi/lzc-cli/commits/4a25f84fe4df938cb3d85f6391e27772dae5b071))
|
|
66
|
+
- the copy-image command adds the `trace-level` parameter ([cd4d4c3](https://gitee.com/linakesi/lzc-cli/commits/cd4d4c351d4bd43bffcfe5f67087c6bffd65d3f4))
|
|
53
67
|
|
|
54
68
|
## [1.3.10](https://gitee.com/linakesi/lzc-cli/compare/v0.0.8...v1.3.10) (2025-08-15)
|
|
55
69
|
|
package/lib/app/index.js
CHANGED
|
@@ -130,10 +130,16 @@ export function lpkAppCommand(program) {
|
|
|
130
130
|
type: 'string',
|
|
131
131
|
default: 'y',
|
|
132
132
|
});
|
|
133
|
+
args.option('ssh-private-key', {
|
|
134
|
+
alias: 'ssh-key',
|
|
135
|
+
describe: t('lzc_cli.lib.app.index.lpk_cmd_install_args_ssh_private_key_desc', '指定安装时用于连接设备的 SSH 私钥路径(兼容别名: --ssh-key)'),
|
|
136
|
+
type: 'string',
|
|
137
|
+
});
|
|
133
138
|
},
|
|
134
|
-
handler: async ({ pkgPath, apk }) => {
|
|
139
|
+
handler: async ({ pkgPath, apk, sshPrivateKey }) => {
|
|
135
140
|
await shellApi.init();
|
|
136
141
|
installConfig.apk = apk == 'y';
|
|
142
|
+
installConfig.sshPrivateKey = sshPrivateKey ? path.resolve(sshPrivateKey) : '';
|
|
137
143
|
|
|
138
144
|
pkgPath = pkgPath ?? process.cwd();
|
|
139
145
|
const installer = new LpkInstaller();
|
package/lib/app/lpk_installer.js
CHANGED
|
@@ -7,7 +7,7 @@ import shellapi from '../shellapi.js';
|
|
|
7
7
|
import { t } from '../i18n/index.js';
|
|
8
8
|
import { triggerApk } from './apkshell.js';
|
|
9
9
|
|
|
10
|
-
export const installConfig = { apk: true };
|
|
10
|
+
export const installConfig = { apk: true, sshPrivateKey: '' };
|
|
11
11
|
// 从一个目录中找出修改时间最新的包
|
|
12
12
|
function findOnceLpkByDir(dir = process.cwd()) {
|
|
13
13
|
const pkg = fs
|
|
@@ -26,9 +26,9 @@ function findOnceLpkByDir(dir = process.cwd()) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export class LpkInstaller {
|
|
29
|
-
constructor() {
|
|
29
|
+
constructor() {}
|
|
30
30
|
|
|
31
|
-
async init() {
|
|
31
|
+
async init() {}
|
|
32
32
|
|
|
33
33
|
// deploy 构建和安装
|
|
34
34
|
async deploy(builder) {
|
|
@@ -116,7 +116,7 @@ export class LpkInstaller {
|
|
|
116
116
|
|
|
117
117
|
try {
|
|
118
118
|
const bridge = new DebugBridge();
|
|
119
|
-
await bridge.init();
|
|
119
|
+
await bridge.init(installConfig.sshPrivateKey);
|
|
120
120
|
logger.info(t('lzc_cli.lib.app.lpk_installer.install_from_file_start_tips', '开始安装应用'));
|
|
121
121
|
await bridge.install(pkgPath, manifest ? manifest['package'] : '');
|
|
122
122
|
logger.info('\n');
|
|
@@ -126,7 +126,7 @@ export class LpkInstaller {
|
|
|
126
126
|
t('lzc_cli.lib.app.lpk_installer.install_from_file_done_tips', `👉 请在浏览器中访问 https://{{ subdomain }}.{{ boxname }}.heiyu.space`, {
|
|
127
127
|
subdomain: manifest['application']['subdomain'],
|
|
128
128
|
boxname: shellapi.boxname,
|
|
129
|
-
interpolation: { escapeValue: false }
|
|
129
|
+
interpolation: { escapeValue: false },
|
|
130
130
|
}),
|
|
131
131
|
);
|
|
132
132
|
logger.info(t('lzc_cli.lib.app.lpk_installer.install_from_file_login_tips', `👉 并使用微服的用户名和密码登录`));
|
package/lib/appstore/publish.js
CHANGED
|
@@ -107,15 +107,33 @@ async function askPublishAppInfo(baseUrl, manifest, locale) {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
async function askWhetherCreateLPK(baseUrl, manifest, locale) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
110
|
+
try {
|
|
111
|
+
// 是否允许创建应用预检请求
|
|
112
|
+
const _options = await request(`${baseUrl}/app/create`, {
|
|
113
|
+
method: 'OPTIONS',
|
|
114
|
+
});
|
|
115
|
+
logger.debug('create app preflight:', { url: _options.url, ok: _options.ok, status: _options.status });
|
|
116
|
+
if (!_options.ok || _options.status < 199 || _options.status > 299) {
|
|
117
|
+
throw undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 要求输入应用信息
|
|
121
|
+
const answers = await inquirer.prompt([
|
|
122
|
+
{
|
|
123
|
+
name: 'continue',
|
|
124
|
+
type: 'input',
|
|
125
|
+
message: t(
|
|
126
|
+
'lzc_cli.lib.publish.ask_whether_create_lpk_continue_prompt',
|
|
127
|
+
'检测到您当前的应用,还没有在懒猫微服中创建,是否使用当前的安装包中的信息进行创建? [y/n]',
|
|
128
|
+
),
|
|
129
|
+
default: 'y',
|
|
130
|
+
},
|
|
131
|
+
]);
|
|
132
|
+
if (answers.continue.toLowerCase() != 'y') {
|
|
133
|
+
throw undefined;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// 发送创建应用请求
|
|
119
137
|
const appInfo = await askPublishAppInfo(baseUrl, manifest, locale);
|
|
120
138
|
const crateAppRes = await request(`${baseUrl}/app/create`, {
|
|
121
139
|
method: 'POST',
|
|
@@ -127,9 +145,28 @@ async function askWhetherCreateLPK(baseUrl, manifest, locale) {
|
|
|
127
145
|
source_author: appInfo.author,
|
|
128
146
|
}),
|
|
129
147
|
});
|
|
130
|
-
logger.debug('create app res:
|
|
131
|
-
|
|
132
|
-
|
|
148
|
+
logger.debug('create app res:', await crateAppRes.text());
|
|
149
|
+
if (!crateAppRes.ok) {
|
|
150
|
+
const data = await crateAppRes.json();
|
|
151
|
+
throw new Error(data?.message || `status:${crateAppRes.status} statusText:${crateAppRes.statusText}`);
|
|
152
|
+
}
|
|
153
|
+
logger.info(
|
|
154
|
+
t('lzc_cli.lib.publish.ask_whether_create_lpk_success_tips', `创建 {{ package }} 应用成功!`, {
|
|
155
|
+
package: manifest['package'],
|
|
156
|
+
interpolation: { escapeValue: false },
|
|
157
|
+
}),
|
|
158
|
+
);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (error) {
|
|
161
|
+
logger.debug('create app failed: ', error.message ?? 'unknown');
|
|
162
|
+
logger.error(
|
|
163
|
+
t('lzc_cli.lib.publish.ask_whether_create_lpk_failed_tips', `创建 {{ package }} 应用失败!`, {
|
|
164
|
+
package: manifest['package'],
|
|
165
|
+
interpolation: { escapeValue: false },
|
|
166
|
+
}),
|
|
167
|
+
error.message || '',
|
|
168
|
+
);
|
|
169
|
+
}
|
|
133
170
|
logger.info(
|
|
134
171
|
t(
|
|
135
172
|
'lzc_cli.lib.publish.ask_whether_create_lpk_fail_tips',
|
|
@@ -212,7 +249,7 @@ export class Publish {
|
|
|
212
249
|
|
|
213
250
|
const { manifest, appIdExisted } = await this.checkAppIdExist(pkgPath);
|
|
214
251
|
if (!appIdExisted) {
|
|
215
|
-
await askWhetherCreateLPK(this.baseUrl, manifest,
|
|
252
|
+
await askWhetherCreateLPK(this.baseUrl, manifest, currentLocale);
|
|
216
253
|
}
|
|
217
254
|
|
|
218
255
|
await autoLogin();
|
|
@@ -239,7 +276,7 @@ export class Publish {
|
|
|
239
276
|
logger.error(
|
|
240
277
|
t('lzc_cli.lib.publish.publish_lpk_fail_tips', `LPK 文件上传失败,err: {{ message }}`, {
|
|
241
278
|
message: lpkInfo?.message ?? lpkInfo,
|
|
242
|
-
interpolation: { escapeValue: false }
|
|
279
|
+
interpolation: { escapeValue: false },
|
|
243
280
|
}),
|
|
244
281
|
);
|
|
245
282
|
throw new Error(lpkInfo?.message ?? lpkInfo);
|
|
@@ -253,7 +290,7 @@ export class Publish {
|
|
|
253
290
|
|
|
254
291
|
// changelogs 本地化
|
|
255
292
|
const langKey = getLanguageForLocale(currentLocale);
|
|
256
|
-
changelogs[langKey] = changelog
|
|
293
|
+
changelogs[langKey] = changelog;
|
|
257
294
|
}
|
|
258
295
|
logger.debug('publish changelogs is', changelogs);
|
|
259
296
|
|
|
@@ -270,6 +307,8 @@ export class Publish {
|
|
|
270
307
|
pkg_path: lpkInfo.url,
|
|
271
308
|
unsupported_platforms: lpkInfo.unsupportedPlatforms,
|
|
272
309
|
min_os_version: lpkInfo.minOsVersion,
|
|
310
|
+
lpk_size: lpkInfo.lpkSize,
|
|
311
|
+
image_size: lpkInfo.imageSize,
|
|
273
312
|
changelogs,
|
|
274
313
|
},
|
|
275
314
|
};
|
package/lib/debug_bridge.js
CHANGED
|
@@ -28,9 +28,11 @@ export class DebugBridge {
|
|
|
28
28
|
this.boxname = shellApi.boxname;
|
|
29
29
|
this.domain = `dev.${this.boxname}.heiyu.space`;
|
|
30
30
|
this.checkUseResolve = !!process.env[`${_SYSTEM_ENV_PREFIX}_CHECK_DNS_RESOLVE`];
|
|
31
|
+
this.sshPrivateKeyPath = '';
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
async init() {
|
|
34
|
+
async init(sshPrivateKeyPath = '') {
|
|
35
|
+
this.setSshPrivateKey(sshPrivateKeyPath);
|
|
34
36
|
await this.checkDevTools();
|
|
35
37
|
if (!(await this.canPublicKey())) {
|
|
36
38
|
// 如果不能 ssh public key 登录则提示授权申请,否则后面可能会出现 rsync 询问密码的问题
|
|
@@ -38,13 +40,45 @@ export class DebugBridge {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
setSshPrivateKey(sshPrivateKeyPath = '') {
|
|
44
|
+
this.sshPrivateKeyPath = '';
|
|
45
|
+
if (!sshPrivateKeyPath) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (!fs.existsSync(sshPrivateKeyPath)) {
|
|
49
|
+
throw t('lzc_cli.lib.debug_bridge.ssh_private_key_not_exist_fail', '指定的 ssh 私钥不存在: {{ sshPrivateKeyPath }}', {
|
|
50
|
+
sshPrivateKeyPath,
|
|
51
|
+
interpolation: { escapeValue: false },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const keyStat = fs.statSync(sshPrivateKeyPath);
|
|
55
|
+
if (!keyStat.isFile()) {
|
|
56
|
+
throw t('lzc_cli.lib.debug_bridge.ssh_private_key_not_file_fail', '指定的 ssh 私钥路径不是文件: {{ sshPrivateKeyPath }}', {
|
|
57
|
+
sshPrivateKeyPath,
|
|
58
|
+
interpolation: { escapeValue: false },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
this.sshPrivateKeyPath = sshPrivateKeyPath;
|
|
62
|
+
logger.info(
|
|
63
|
+
t('lzc_cli.lib.debug_bridge.ssh_private_key_in_use_tips', '当前使用 --ssh-private-key: {{ sshPrivateKeyPath }}', {
|
|
64
|
+
sshPrivateKeyPath,
|
|
65
|
+
interpolation: { escapeValue: false },
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
buildSshCmdArgs(...args) {
|
|
71
|
+
const identityArg = this.sshPrivateKeyPath ? [`-i "${this.sshPrivateKeyPath}"`] : [];
|
|
72
|
+
return sshCmdArgs(...identityArg, ...args);
|
|
73
|
+
}
|
|
74
|
+
|
|
41
75
|
async checkDevTools() {
|
|
42
76
|
let domain = this.domain;
|
|
43
77
|
if (this.checkUseResolve) {
|
|
44
78
|
try {
|
|
45
79
|
const _ipv6 = await resolveDomain(this.domain, true);
|
|
46
80
|
domain = `[${_ipv6}]`;
|
|
47
|
-
} catch {
|
|
81
|
+
} catch {}
|
|
48
82
|
}
|
|
49
83
|
const url = `https://${domain}/bannerfile`;
|
|
50
84
|
return new Promise((resolve, reject) => {
|
|
@@ -87,21 +121,21 @@ export class DebugBridge {
|
|
|
87
121
|
ssh.status == 0
|
|
88
122
|
? resolve(ssh.stdout)
|
|
89
123
|
: reject(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
124
|
+
t('lzc_cli.lib.debug_bridge.common_exec_fail', `执行命令 {{ cmd }} {{ args }} 出错\n{{ stdout }}\n{{ stderr }}`, {
|
|
125
|
+
cmd,
|
|
126
|
+
args: args.join(' '),
|
|
127
|
+
stdout: ssh.stdout ?? '',
|
|
128
|
+
stdout: ssh.stderr ?? '',
|
|
129
|
+
interpolation: { escapeValue: false },
|
|
130
|
+
}),
|
|
131
|
+
);
|
|
98
132
|
});
|
|
99
133
|
}
|
|
100
134
|
|
|
101
135
|
async install(lpkPath, pkgId) {
|
|
102
136
|
const stream = fs.createReadStream(lpkPath);
|
|
103
137
|
const resolvedIp = await resolveDomain(this.domain);
|
|
104
|
-
const ssh = spawn(sshBinary(), [...
|
|
138
|
+
const ssh = spawn(sshBinary(), [...this.buildSshCmdArgs(`box@${resolvedIp}`), `install --uid ${this.uid}`, pkgId ? `--pkgId ${pkgId}` : ''], {
|
|
105
139
|
shell: true,
|
|
106
140
|
stdio: ['pipe', 'inherit', 'inherit'],
|
|
107
141
|
});
|
|
@@ -115,7 +149,7 @@ export class DebugBridge {
|
|
|
115
149
|
|
|
116
150
|
async canPublicKey() {
|
|
117
151
|
try {
|
|
118
|
-
await this.common(sshBinary(), [...
|
|
152
|
+
await this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`)]);
|
|
119
153
|
return true;
|
|
120
154
|
} catch (err) {
|
|
121
155
|
logger.debug('canPublicKey error: ', err);
|
|
@@ -146,7 +180,7 @@ export class DebugBridge {
|
|
|
146
180
|
boxname: this.boxname,
|
|
147
181
|
domain: this.domain,
|
|
148
182
|
pk,
|
|
149
|
-
interpolation: { escapeValue: false }
|
|
183
|
+
interpolation: { escapeValue: false },
|
|
150
184
|
},
|
|
151
185
|
),
|
|
152
186
|
);
|
|
@@ -154,21 +188,21 @@ export class DebugBridge {
|
|
|
154
188
|
}
|
|
155
189
|
|
|
156
190
|
async status(appId) {
|
|
157
|
-
return this.common(sshBinary(), [...
|
|
191
|
+
return this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `status --uid ${this.uid}`, appId]);
|
|
158
192
|
}
|
|
159
193
|
|
|
160
194
|
async isDevshell(appId) {
|
|
161
195
|
await this.backendVersion020();
|
|
162
|
-
const stdout = await this.common(sshBinary(), [...
|
|
196
|
+
const stdout = await this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `isDevshellV2 --uid ${this.uid}`, appId]);
|
|
163
197
|
return stdout == 'true';
|
|
164
198
|
}
|
|
165
199
|
|
|
166
200
|
async resume(appId) {
|
|
167
|
-
return this.common(sshBinary(), [...
|
|
201
|
+
return this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `resume --uid ${this.uid}`, appId]);
|
|
168
202
|
}
|
|
169
203
|
|
|
170
204
|
async version() {
|
|
171
|
-
const output = await this.common(sshBinary(), [...
|
|
205
|
+
const output = await this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `version`]);
|
|
172
206
|
logger.debug(`backend version:\n${output}`);
|
|
173
207
|
try {
|
|
174
208
|
const data = JSON.parse(output);
|
|
@@ -179,7 +213,7 @@ export class DebugBridge {
|
|
|
179
213
|
}
|
|
180
214
|
|
|
181
215
|
async uninstall(appId, deleteAppData = false) {
|
|
182
|
-
return this.common(sshBinary(), [...
|
|
216
|
+
return this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `uninstall --uid ${this.uid}`, deleteAppData ? '--delete-data' : '', appId]);
|
|
183
217
|
}
|
|
184
218
|
|
|
185
219
|
async devshell(appId, isUserApp, onconnect = null) {
|
|
@@ -199,7 +233,16 @@ export class DebugBridge {
|
|
|
199
233
|
|
|
200
234
|
const stream = spawn(
|
|
201
235
|
sshBinary(),
|
|
202
|
-
[
|
|
236
|
+
[
|
|
237
|
+
...this.buildSshCmdArgs(`box@${resolvedIp}`),
|
|
238
|
+
'-t',
|
|
239
|
+
'devshell',
|
|
240
|
+
`--uid ${this.uid}`,
|
|
241
|
+
isUserApp ? '--userapp' : '',
|
|
242
|
+
appId,
|
|
243
|
+
'/bin/sh',
|
|
244
|
+
'/lzcapp/pkg/content/devshell/exec.sh',
|
|
245
|
+
],
|
|
203
246
|
{
|
|
204
247
|
shell: true,
|
|
205
248
|
stdio: 'inherit',
|
|
@@ -224,7 +267,7 @@ export class DebugBridge {
|
|
|
224
267
|
const resolvedIp = await resolveDomain(this.domain);
|
|
225
268
|
const stream = fs.createReadStream(contextTar);
|
|
226
269
|
|
|
227
|
-
const buildStream = spawn(sshBinary(), [...
|
|
270
|
+
const buildStream = spawn(sshBinary(), [...this.buildSshCmdArgs(`box@${resolvedIp}`), `build --tag ${tag}`], {
|
|
228
271
|
shell: true,
|
|
229
272
|
stdio: ['pipe', 'inherit', 'inherit'],
|
|
230
273
|
});
|
|
@@ -244,7 +287,7 @@ export class DebugBridge {
|
|
|
244
287
|
await this.backendVersion020();
|
|
245
288
|
|
|
246
289
|
const resolvedIp = await resolveDomain(this.domain);
|
|
247
|
-
const stream = spawn(sshBinary(), [...
|
|
290
|
+
const stream = spawn(sshBinary(), [...this.buildSshCmdArgs(`box@${resolvedIp}`), '-t', 'lzc-docker', ...argv], {
|
|
248
291
|
shell: true,
|
|
249
292
|
stdio: 'inherit',
|
|
250
293
|
});
|
|
@@ -259,7 +302,7 @@ export class DebugBridge {
|
|
|
259
302
|
await this.backendVersion020();
|
|
260
303
|
|
|
261
304
|
const resolvedIp = await resolveDomain(this.domain);
|
|
262
|
-
const stream = spawn(sshBinary(), [...
|
|
305
|
+
const stream = spawn(sshBinary(), [...this.buildSshCmdArgs(`box@${resolvedIp}`), '-t', 'lzc-docker-compose', ...argv], {
|
|
263
306
|
shell: true,
|
|
264
307
|
stdio: 'inherit',
|
|
265
308
|
});
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"lpk_cmd_devshell_args_force_desc": "force rebuild",
|
|
23
23
|
"lpk_cmd_devshell_desc": "Enter the development environment of the box",
|
|
24
24
|
"lpk_cmd_index_rags_apk_desc": "Whether to generate APK(y/n)",
|
|
25
|
+
"lpk_cmd_install_args_ssh_private_key_desc": "Specify the SSH private key path used to connect to the device (compatible alias: --ssh-key)",
|
|
25
26
|
"lpk_cmd_init_desc": "Initialize Lazycat Cloud application (providing the most basic template)",
|
|
26
27
|
"lpk_cmd_init_success": "Application initialization completed",
|
|
27
28
|
"lpk_cmd_install_desc": "Deploy the application to the device. pkgPath can be a path, or https://, http:// request address. If not filled in, it will default to lpk in the current directory.",
|
|
@@ -158,7 +159,10 @@
|
|
|
158
159
|
"common_start_log": "Execute command {{cmd}} {{args}}",
|
|
159
160
|
"install_fail": "install failed",
|
|
160
161
|
"ssh_apply_grant_not_credible_tips": "The public key of your current machine has not been added to the trust list of Microservice ({{boxname}}). Please use the Microservice administrator account to visit the following address in the browser to automatically add the public key you selected to the trust list. (All operations are only performed in your LCMD, and no data, including this development machine, will be leaked outside your LCMD)\n\n-> https://{{domain}}/auth?key={{pk}}",
|
|
161
|
-
"ssh_apply_grant_not_exist_tips": "It is detected that your current environment has not added the ssh public key to the ‘Lazy Cat Developer Tools’. Please select the type of public key you need to add."
|
|
162
|
+
"ssh_apply_grant_not_exist_tips": "It is detected that your current environment has not added the ssh public key to the ‘Lazy Cat Developer Tools’. Please select the type of public key you need to add.",
|
|
163
|
+
"ssh_private_key_in_use_tips": "Using --ssh-private-key: {{sshPrivateKeyPath}}",
|
|
164
|
+
"ssh_private_key_not_exist_fail": "The specified SSH private key does not exist: {{sshPrivateKeyPath}}",
|
|
165
|
+
"ssh_private_key_not_file_fail": "The specified SSH private key path is not a file: {{sshPrivateKeyPath}}"
|
|
162
166
|
},
|
|
163
167
|
"docker": {
|
|
164
168
|
"index": {
|
|
@@ -193,6 +197,7 @@
|
|
|
193
197
|
"ask_publish_app_info_package_validate": "The application bundle identifier does not comply with the specification. It is recommended to use reverse domain name notation.",
|
|
194
198
|
"ask_publish_app_info_source_prompt": "Please enter the application source (original applications are optional):",
|
|
195
199
|
"ask_whether_create_lpk_continue_prompt": "It is detected that your current application has not been created in Lazycat LCMD. Do you want to use the information in the current installation package to create it? [y/n]",
|
|
200
|
+
"ask_whether_create_lpk_failed_tips": "Failed to create {{package}} application!",
|
|
196
201
|
"ask_whether_create_lpk_fail_tips": "The application you currently want to publish has not been created in the 'Developer Center of Lazy Mao Microservice'. Please follow the steps below to create it:\n\n1. Open the browser https://developer.lazycat.cloud/manage\n2. Log in to your developer account\n3. After logging in successfully, you can view the applications in your account and manage your applications.\n4. Click 'Add' and fill in the information based on your application.\n5. After filling in, click Create\n6. After successful creation, you can publish the application through 'lzc-cli appstore publish'",
|
|
197
202
|
"ask_whether_create_lpk_success_tips": "Created {{package}} application successfully!",
|
|
198
203
|
"check_app_id_exist_fail_tips": "Check whether there is an error in the application. The error status code is:",
|
|
@@ -249,4 +254,4 @@
|
|
|
249
254
|
}
|
|
250
255
|
}
|
|
251
256
|
}
|
|
252
|
-
}
|
|
257
|
+
}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"lpk_cmd_index_rags_apk_desc": "是否生成APK(y/n)",
|
|
25
25
|
"lpk_cmd_init_desc": "初始化懒猫云应用(提供最基础的模板)",
|
|
26
26
|
"lpk_cmd_init_success": "应用初始化完成",
|
|
27
|
+
"lpk_cmd_install_args_ssh_private_key_desc": "指定安装时用于连接设备的 SSH 私钥路径(兼容别名: --ssh-key)",
|
|
27
28
|
"lpk_cmd_install_desc": "部署应用至设备, pkgPath 可以为路径,或者https://,http://请求地址, 如果不填写,将默认为当前目录下的lpk",
|
|
28
29
|
"lpk_cmd_log_args_follow_desc": "持续输出",
|
|
29
30
|
"lpk_cmd_log_desc": "查看某一个app的日志",
|
|
@@ -158,7 +159,10 @@
|
|
|
158
159
|
"common_start_log": "执行命令 {{ cmd }} {{ args }}",
|
|
159
160
|
"install_fail": "install 失败",
|
|
160
161
|
"ssh_apply_grant_not_credible_tips": "您当前机器的公钥未添加到微服({{ boxname }})的信任列表中,请使用微服管理员账号在浏览器中访问以下地址,将您选择的公钥自动添加到信任列表中。(所有操作均只在您微服中进行,包括本开发机在内的任何数据不会泄漏到您的微服之外)\n\n-> https://{{ domain }}/auth?key={{ pk }}\n",
|
|
161
|
-
"ssh_apply_grant_not_exist_tips": "检测到您当前的环境还没有添加 ssh 公钥到 ‘懒猫开发者工具’ 中,请选择您需要添加的公钥类型"
|
|
162
|
+
"ssh_apply_grant_not_exist_tips": "检测到您当前的环境还没有添加 ssh 公钥到 ‘懒猫开发者工具’ 中,请选择您需要添加的公钥类型",
|
|
163
|
+
"ssh_private_key_in_use_tips": "当前使用 --ssh-private-key: {{ sshPrivateKeyPath }}",
|
|
164
|
+
"ssh_private_key_not_exist_fail": "指定的 ssh 私钥不存在: {{ sshPrivateKeyPath }}",
|
|
165
|
+
"ssh_private_key_not_file_fail": "指定的 ssh 私钥路径不是文件: {{ sshPrivateKeyPath }}"
|
|
162
166
|
},
|
|
163
167
|
"docker": {
|
|
164
168
|
"index": {
|
|
@@ -194,6 +198,7 @@
|
|
|
194
198
|
"ask_publish_app_info_source_prompt": "请输入应用来源(原创应用可不填):",
|
|
195
199
|
"ask_whether_create_lpk_continue_prompt": "检测到您当前的应用,还没有在懒猫微服中创建,是否使用当前的安装包中的信息进行创建? [y/n]",
|
|
196
200
|
"ask_whether_create_lpk_fail_tips": "当前想发布的应用没有在 '懒猫微服的开发者中心' 创建,请按照以下步骤创建:\n\n1. 浏览器打开 https://developer.lazycat.cloud/manage\n2. 登录您的开发者帐号\n3. 登录成功后,您可以查看到您帐号中的应用,同时您也可以对您的应用进行管理\n4. 点击 '新增',根据您的应用信息进行填写\n5. 填写完成后,点击创建即可\n6. 创建成功后,您可以通过 'lzc-cli appstore publish' 来发布应用了\n",
|
|
201
|
+
"ask_whether_create_lpk_failed_tips": "创建 {{ package }} 应用失败!",
|
|
197
202
|
"ask_whether_create_lpk_success_tips": "创建 {{ package }} 应用成功!",
|
|
198
203
|
"check_app_id_exist_fail_tips": "检测应用是否存在出错, 错误状态码为: ",
|
|
199
204
|
"pre_check_fail_tips": "不能发布一个devshell的版本,请重新使用 `lzc-cli project build` 构建",
|
package/package.json
CHANGED
|
@@ -1,91 +1,91 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
51
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
2
|
+
"name": "@lazycatcloud/lzc-cli",
|
|
3
|
+
"version": "1.3.17",
|
|
4
|
+
"description": "lazycat cloud developer kit",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"release": "release-it patch",
|
|
7
|
+
"prepublishOnly": "node check-changelog.js",
|
|
8
|
+
"i18n:parser": "i18next-cli extract -c i18next.config.js --sync-all && prettier -w ./lib/i18n/locales"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"template",
|
|
12
|
+
"scripts",
|
|
13
|
+
"lib",
|
|
14
|
+
"changelog.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"lzc-cli": "scripts/cli.js",
|
|
21
|
+
"lzc-docker": "scripts/lzc-docker.js",
|
|
22
|
+
"lzc-docker-compose": "scripts/lzc-docker-compose.js"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"keywords": [
|
|
26
|
+
"lazycat cloud sdk"
|
|
27
|
+
],
|
|
28
|
+
"author": "zac zeng",
|
|
29
|
+
"license": "ISC",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@balena/dockerignore": "^1.0.2",
|
|
32
|
+
"@grpc/grpc-js": "^1.11.1",
|
|
33
|
+
"@grpc/proto-loader": "^0.7.13",
|
|
34
|
+
"@lazycatcloud/sdk": "^0.1.423",
|
|
35
|
+
"adm-zip": "^0.5.16",
|
|
36
|
+
"archiver": "^7.0.1",
|
|
37
|
+
"axios": "^1.7.7",
|
|
38
|
+
"chalk": "^5.3.0",
|
|
39
|
+
"chokidar": "^3.6.0",
|
|
40
|
+
"command-exists": "^1.2.9",
|
|
41
|
+
"cross-spawn": "^7.0.3",
|
|
42
|
+
"dockerfile-ast": "^0.6.1",
|
|
43
|
+
"envsub": "^4.1.0",
|
|
44
|
+
"fast-glob": "^3.3.2",
|
|
45
|
+
"form-data": "^4.0.0",
|
|
46
|
+
"i18next": "^25.7.1",
|
|
47
|
+
"i18next-fs-backend": "^2.6.1",
|
|
48
|
+
"ignore": "^5.3.2",
|
|
49
|
+
"inquirer": "^10.1.8",
|
|
50
|
+
"isbinaryfile": "^5.0.2",
|
|
51
|
+
"js-yaml": "^4.1.0",
|
|
52
|
+
"lodash": "^4.17.23",
|
|
53
|
+
"lodash.debounce": "^4.0.8",
|
|
54
|
+
"lodash.merge": "^4.6.2",
|
|
55
|
+
"lodash.mergewith": "^4.6.2",
|
|
56
|
+
"loglevel": "^1.9.1",
|
|
57
|
+
"node-fetch": "^3.3.2",
|
|
58
|
+
"semver": "^7.6.3",
|
|
59
|
+
"tar": "^7.4.3",
|
|
60
|
+
"yargs": "^17.7.2"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@release-it/conventional-changelog": "^10.0.1",
|
|
64
|
+
"@types/command-exists": "^1.2.3",
|
|
65
|
+
"i18next-cli": "^1.32.0",
|
|
66
|
+
"prettier": "^3.3.3",
|
|
67
|
+
"release-it": "^19.0.4"
|
|
68
|
+
},
|
|
69
|
+
"release-it": {
|
|
70
|
+
"git": {
|
|
71
|
+
"requireCleanWorkingDir": false,
|
|
72
|
+
"commitMessage": "chore: release v${version}",
|
|
73
|
+
"commit": true,
|
|
74
|
+
"tag": true,
|
|
75
|
+
"push": false
|
|
76
|
+
},
|
|
77
|
+
"npm": {
|
|
78
|
+
"publish": false
|
|
79
|
+
},
|
|
80
|
+
"plugins": {
|
|
81
|
+
"@release-it/conventional-changelog": {
|
|
82
|
+
"preset": "angular",
|
|
83
|
+
"infile": "changelog.md"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"publishConfig": {
|
|
88
|
+
"registry": "https://registry.npmjs.org",
|
|
89
|
+
"access": "public"
|
|
90
|
+
}
|
|
91
91
|
}
|