@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.
@@ -1,219 +1,215 @@
1
- import { Publish } from "./publish.js"
2
- import logger from "loglevel"
3
- import { PrePublish } from "./prePublish.js"
4
- import { reLogin, request } from "./login.js"
5
- import fs from "node:fs"
6
- import { sleep } from "../utils.js"
7
- import { appStoreServerUrl } from "./env.js"
1
+ import { Publish } from './publish.js';
2
+ import logger from 'loglevel';
3
+ import { PrePublish } from './prePublish.js';
4
+ import { reLogin, request } from './login.js';
5
+ import fs from 'node:fs';
6
+ import { sleep } from '../utils.js';
7
+ import { t } from '../i18n/index.js';
8
+ import { appStoreServerUrl } from './env.js';
8
9
 
9
10
  export function appstoreCommand(program) {
10
- let subCommands = [
11
- {
12
- command: "login",
13
- desc: "登录",
14
- handler: async () => {
15
- await reLogin()
16
- }
17
- },
18
- {
19
- command: "pre-publish <pkgPath>",
20
- desc: "发布到内测",
21
- builder: (args) => {
22
- args.option("c", {
23
- alias: "changelog",
24
- describe: "更改日志",
25
- type: "string"
26
- })
27
- args.option("F", {
28
- alias: "file",
29
- describe: "更改日志文件",
30
- type: "string"
31
- })
32
- args.option("G", {
33
- alias: "gid",
34
- describe: "内测组ID",
35
- type: "string"
36
- })
37
- },
38
- handler: async ({ pkgPath, changelog, file, gid }) => {
39
- const p = new PrePublish()
40
- if (!changelog && file) {
41
- changelog = fs.readFileSync(file, "utf8")
42
- }
43
- await p.publish(pkgPath, changelog, gid)
44
- }
45
- },
46
- {
47
- command: "publish <pkgPath>",
48
- desc: "发布到商店",
49
- builder: (args) => {
50
- args.option("c", {
51
- alias: "changelog",
52
- describe: "更改日志",
53
- type: "string"
54
- })
55
- args.option("F", {
56
- alias: "file",
57
- describe: "更改日志文件",
58
- type: "string"
59
- })
60
- },
61
- handler: async ({ pkgPath, changelog, file }) => {
62
- const locale = program.locale()
63
- const p = new Publish()
64
- if (!changelog && file) {
65
- changelog = fs.readFileSync(file, "utf8")
66
- }
67
- await p.publish(pkgPath, changelog, locale)
68
- }
69
- },
70
- {
71
- command: "copy-image <img>",
72
- desc: `复制镜像至懒猫微服官方源`,
73
- builder: (yargs) => {
74
- yargs.option("arch", {
75
- describe: "image arch 'amd64', 'arm64'",
76
- default: "amd64",
77
- type: "string"
78
- })
79
- // 出于 CI 目的增加控制是否打印进度选项
80
- yargs.option("trace-level", {
81
- describe: "trace level 'verbose', 'quiet'",
82
- default: "verbose",
83
- type: "string"
84
- })
85
- return yargs
86
- },
87
- handler: async ({ img: imageName, arch: platform, traceLevel }) => {
88
- const uploadUrl = `${appStoreServerUrl}/api/v3/developer/app/docker/image/push/v3/copy?image=${imageName}&platform=${platform}`
89
- const progressUrl = `${appStoreServerUrl}/api/v3/developer/app/docker/image/push/v3/progress?image=${imageName}&platform=${platform}`
11
+ let subCommands = [
12
+ {
13
+ command: 'login',
14
+ desc: t('lzc_cli.lib.appstore.index.login_cmd_desc', '登录'),
15
+ handler: async () => {
16
+ await reLogin();
17
+ },
18
+ },
19
+ {
20
+ command: 'pre-publish <pkgPath>',
21
+ desc: t('lzc_cli.lib.appstore.index.pre_publish_cmd_desc', '发布到内测'),
22
+ builder: (args) => {
23
+ args.option('c', {
24
+ alias: 'changelog',
25
+ describe: t('lzc_cli.lib.appstore.index.pre_publish_cmd_changelog_desc', '更改日志'),
26
+ type: 'string',
27
+ });
28
+ args.option('F', {
29
+ alias: 'file',
30
+ describe: t('lzc_cli.lib.appstore.index.pre_publish_cmd_changelog_file_desc', '更改日志文件'),
31
+ type: 'string',
32
+ });
33
+ args.option('G', {
34
+ alias: 'gid',
35
+ describe: t('lzc_cli.lib.appstore.index.pre_publish_cmd_gid_desc', '内测组ID'),
36
+ type: 'string',
37
+ });
38
+ },
39
+ handler: async ({ pkgPath, changelog, file, gid }) => {
40
+ const p = new PrePublish();
41
+ if (!changelog && file) {
42
+ changelog = fs.readFileSync(file, 'utf8');
43
+ }
44
+ await p.publish(pkgPath, changelog, gid);
45
+ },
46
+ },
47
+ {
48
+ command: 'publish <pkgPath>',
49
+ desc: t('lzc_cli.lib.appstore.index.publish_cmd_desc', '发布到商店'),
50
+ builder: (args) => {
51
+ args.option('c', {
52
+ alias: 'changelog',
53
+ describe: t('lzc_cli.lib.appstore.index.publish_cmd_changelog_desc', '更新日志'),
54
+ type: 'string',
55
+ });
56
+ args.option('clang', {
57
+ alias: 'changelog-locale',
58
+ describe: t('lzc_cli.lib.appstore.index.publish_cmd_changelog_lang_desc', '更新日志语言标识,默认通过当前 shell 语言环境识别'),
59
+ type: 'string',
60
+ });
61
+ args.option('F', {
62
+ alias: 'file',
63
+ describe: t('lzc_cli.lib.appstore.index.publish_cmd_changelog_file_desc', '更新日志文件'),
64
+ type: 'string',
65
+ });
66
+ },
67
+ handler: async ({ pkgPath, changelog, changelogLocale, file }) => {
68
+ const locale = changelogLocale ?? program.locale();
69
+ const p = new Publish();
70
+ if (!changelog && file) {
71
+ changelog = fs.readFileSync(file, 'utf8');
72
+ }
73
+ await p.publish(pkgPath, changelog, locale);
74
+ },
75
+ },
76
+ {
77
+ command: 'copy-image <img>',
78
+ desc: t('lzc_cli.lib.appstore.index.copy_image_cmd_desc', `复制镜像至懒猫微服官方源`),
79
+ builder: (yargs) => {
80
+ yargs.option('arch', {
81
+ describe: "image arch 'amd64', 'arm64'",
82
+ default: 'amd64',
83
+ type: 'string',
84
+ });
85
+ // 出于 CI 目的增加控制是否打印进度选项
86
+ yargs.option('trace-level', {
87
+ describe: "trace level 'verbose', 'quiet'",
88
+ default: 'verbose',
89
+ type: 'string',
90
+ });
91
+ return yargs;
92
+ },
93
+ handler: async ({ img: imageName, arch: platform, traceLevel }) => {
94
+ const uploadUrl = `${appStoreServerUrl}/api/v3/developer/app/docker/image/push/v3/copy?image=${imageName}&platform=${platform}`;
95
+ const progressUrl = `${appStoreServerUrl}/api/v3/developer/app/docker/image/push/v3/progress?image=${imageName}&platform=${platform}`;
90
96
 
91
- const useCI = traceLevel === "quiet"
92
- const _logger = logger
93
- _logger.setLevel(useCI ? _logger.levels.ERROR : _logger.levels.INFO)
97
+ const useCI = traceLevel === 'quiet';
98
+ const _logger = logger;
99
+ _logger.setLevel(useCI ? _logger.levels.ERROR : _logger.levels.INFO);
94
100
 
95
- _logger.info(
96
- `Waiting ... ( copy ${imageName} (${platform}) to lazycat offical registry)`
97
- )
98
- try {
99
- const resp = await request(uploadUrl)
100
- if (resp.ok) {
101
- _logger.info("uploading")
102
- } else {
103
- _logger.error("error: ", resp, await resp.text())
104
- return
105
- }
106
- sleep(1000)
107
- let prevLineCount = 0 // 新增:记录上次输出行数
108
- let layers = []
101
+ _logger.info(`Waiting ... ( copy ${imageName} (${platform}) to lazycat offical registry)`);
102
+ try {
103
+ const resp = await request(uploadUrl);
104
+ if (resp.ok) {
105
+ _logger.info('uploading');
106
+ } else {
107
+ _logger.error('error: ', resp, await resp.text());
108
+ return;
109
+ }
110
+ sleep(1000);
111
+ let prevLineCount = 0; // 新增:记录上次输出行数
112
+ let layers = [];
109
113
 
110
- let refreshProgress = (lys) => {
111
- if (useCI) {
112
- // 日志级别为 quiet 时不输出进度(用于 CI 目的)
113
- return
114
- }
115
- // 关键修改:动态回退多行
116
- process.stdout.write("\x1B[?25l") // 隐藏光标
117
- if (prevLineCount > 0) {
118
- process.stdout.write(`\x1B[${prevLineCount}A`) // 移动光标到之前输出的起始行
119
- }
114
+ let refreshProgress = (lys) => {
115
+ if (useCI) {
116
+ // 日志级别为 quiet 时不输出进度(用于 CI 目的)
117
+ return;
118
+ }
119
+ // 关键修改:动态回退多行
120
+ process.stdout.write('\x1B[?25l'); // 隐藏光标
121
+ if (prevLineCount > 0) {
122
+ process.stdout.write(`\x1B[${prevLineCount}A`); // 移动光标到之前输出的起始行
123
+ }
120
124
 
121
- // 构建多行进度字符串
122
- let output = []
123
- ;(lys || []).forEach((v) => {
124
- const progressBar =
125
- "#".repeat(v.progress) + " ".repeat(100 - v.progress)
126
- output.push(
127
- `${v.hash.substring(0, 8)}: [${progressBar}] ${v.progress}%`
128
- )
129
- })
125
+ // 构建多行进度字符串
126
+ let output = [];
127
+ (lys || []).forEach((v) => {
128
+ const progressBar = '#'.repeat(v.progress) + ' '.repeat(100 - v.progress);
129
+ output.push(`${v.hash.substring(0, 8)}: [${progressBar}] ${v.progress}%`);
130
+ });
130
131
 
131
- // 清除旧行并写入新内容
132
- output.forEach((line) => {
133
- process.stdout.write("\x1B[2K") // 清除当前行
134
- process.stdout.write(line + "\n")
135
- })
136
- prevLineCount = output.length // 记录本次输出行数
137
- process.stdout.write("\x1B[?25h") // 恢复光标显示
138
- }
132
+ // 清除旧行并写入新内容
133
+ output.forEach((line) => {
134
+ process.stdout.write('\x1B[2K'); // 清除当前行
135
+ process.stdout.write(line + '\n');
136
+ });
137
+ prevLineCount = output.length; // 记录本次输出行数
138
+ process.stdout.write('\x1B[?25h'); // 恢复光标显示
139
+ };
139
140
 
140
- for (;;) {
141
- const pgsResp = await request(progressUrl)
142
- if (pgsResp.ok) {
143
- const pgs = JSON.parse(await pgsResp.text())
144
- if (pgs.finished) {
145
- ;(layers ? layers : [])?.forEach((v) => {
146
- v.progress = 100
147
- })
148
- if (pgs.errmsg) {
149
- throw Error(
150
- `failed to copyimage ${imageName} err: ${pgs.errmsg}`
151
- )
152
- }
153
- if (!useCI) {
154
- refreshProgress(layers)
155
- process.stdout.write("\n")
156
- _logger.info("uploaded: ", pgs.lzc_image)
157
- } else {
158
- // 日志级别为 quiet 时仅输出结果(用于 CI 目的)
159
- console.log(pgs.lzc_image)
160
- }
161
- break
162
- }
163
- layers = pgs?.layers
164
- refreshProgress(layers)
165
- await sleep(1000)
166
- } else {
167
- throw Error(`error: ${await resp.text()}`)
168
- }
169
- }
170
- } catch (err) {
171
- _logger.error(err?.message ?? "unknown exception")
172
- }
173
- }
174
- },
175
- {
176
- command: "my-images",
177
- desc: "查看已上传镜像列表",
178
- handler: async () => {
179
- const url = `${appStoreServerUrl}/api/v3/developer/app/docker/image/push/v3/myimages`
180
- try {
181
- const resp = await request(url)
182
- if (resp.ok) {
183
- const ilist = JSON.parse(await resp.text())
184
- ilist.sort((a, b) => {
185
- return (
186
- new Date(b.UpdatedAt).getTime() -
187
- new Date(a.UpdatedAt).getTime()
188
- )
189
- })
190
- const tableItems = []
191
- ilist?.forEach((v) => {
192
- if (v.errmsg) {
193
- return
194
- }
195
- tableItems.push({
196
- "Source Image": v.source_image,
197
- "Lazycat Image": v.lzc_image,
198
- "Updated At": new Date(v.UpdatedAt).toLocaleString()
199
- })
200
- })
201
- console.table(tableItems)
202
- } else {
203
- logger.error("error: ", await resp.text())
204
- }
205
- } catch (err) {
206
- console.error(err)
207
- }
208
- }
209
- }
210
- ]
141
+ for (;;) {
142
+ const pgsResp = await request(progressUrl);
143
+ if (pgsResp.ok) {
144
+ const pgs = JSON.parse(await pgsResp.text());
145
+ if (pgs.finished) {
146
+ (layers ? layers : [])?.forEach((v) => {
147
+ v.progress = 100;
148
+ });
149
+ if (pgs.errmsg) {
150
+ throw Error(`failed to copyimage ${imageName} err: ${pgs.errmsg}`);
151
+ }
152
+ if (!useCI) {
153
+ refreshProgress(layers);
154
+ process.stdout.write('\n');
155
+ _logger.info('uploaded: ', pgs.lzc_image);
156
+ } else {
157
+ // 日志级别为 quiet 时仅输出结果(用于 CI 目的)
158
+ console.log(pgs.lzc_image);
159
+ }
160
+ break;
161
+ }
162
+ layers = pgs?.layers;
163
+ refreshProgress(layers);
164
+ await sleep(1000);
165
+ } else {
166
+ throw Error(`error: ${await resp.text()}`);
167
+ }
168
+ }
169
+ } catch (err) {
170
+ _logger.error(err?.message ?? 'unknown exception');
171
+ }
172
+ },
173
+ },
174
+ {
175
+ command: 'my-images',
176
+ desc: t('lzc_cli.lib.appstore.index.my_images_cmd_desc', '查看已上传镜像列表'),
177
+ handler: async () => {
178
+ const url = `${appStoreServerUrl}/api/v3/developer/app/docker/image/push/v3/myimages`;
179
+ try {
180
+ const resp = await request(url);
181
+ if (resp.ok) {
182
+ const ilist = JSON.parse(await resp.text());
183
+ ilist.sort((a, b) => {
184
+ return new Date(b.UpdatedAt).getTime() - new Date(a.UpdatedAt).getTime();
185
+ });
186
+ const tableItems = [];
187
+ ilist?.forEach((v) => {
188
+ if (v.errmsg) {
189
+ return;
190
+ }
191
+ tableItems.push({
192
+ 'Source Image': v.source_image,
193
+ 'Lazycat Image': v.lzc_image,
194
+ 'Updated At': new Date(v.UpdatedAt).toLocaleString(),
195
+ });
196
+ });
197
+ console.table(tableItems);
198
+ } else {
199
+ logger.error('error: ', await resp.text());
200
+ }
201
+ } catch (err) {
202
+ console.error(err);
203
+ }
204
+ },
205
+ },
206
+ ];
211
207
 
212
- program.command({
213
- command: "appstore",
214
- desc: "应用商店",
215
- builder: (args) => {
216
- args.command(subCommands)
217
- }
218
- })
208
+ program.command({
209
+ command: 'appstore',
210
+ desc: t('lzc_cli.lib.appstore.index.appstore_cmd_desc', '应用商店'),
211
+ builder: (args) => {
212
+ args.command(subCommands);
213
+ },
214
+ });
219
215
  }