@lazycatcloud/lzc-cli 1.3.12 → 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,176 +1,179 @@
1
- import fetch from "node-fetch"
2
- import path from "path"
3
- import url from "url"
4
- import logger from "loglevel"
5
- import env from "../config/env.js"
6
- import inquirer from "inquirer"
7
- import { accountServerUrl } from "./env.js"
1
+ import fetch from 'node-fetch';
2
+ import path from 'path';
3
+ import url from 'url';
4
+ import logger from 'loglevel';
5
+ import env from '../config/env.js';
6
+ import inquirer from 'inquirer';
7
+ import { accountServerUrl } from './env.js';
8
+ import { t } from '../i18n/index.js';
8
9
 
9
10
  function join(...params) {
10
- let x = ""
11
- try {
12
- // fix: url path join failed for windows
13
- const u = new url.URL(params[0])
14
- params.splice(0, 1)
15
- u.pathname = path.posix.join(u.pathname, ...params)
16
- x = u.toString()
17
- } catch (error) {
18
- console.warn(error)
19
- x = path.join(...params)
20
- }
21
- return x
11
+ let x = '';
12
+ try {
13
+ // fix: url path join failed for windows
14
+ const u = new url.URL(params[0]);
15
+ params.splice(0, 1);
16
+ u.pathname = path.posix.join(u.pathname, ...params);
17
+ x = u.toString();
18
+ } catch (error) {
19
+ console.warn(error);
20
+ x = path.join(...params);
21
+ }
22
+ return x;
22
23
  }
23
24
 
24
25
  async function login(username, password) {
25
- return fetch(join(accountServerUrl, "/api/login/signin"), {
26
- method: "POST",
27
- body: new URLSearchParams({
28
- username: username,
29
- password: password
30
- })
31
- })
32
- .then(async (res) => {
33
- let bodyText = await res.text()
34
- try {
35
- let body = JSON.parse(bodyText)
36
- if (body.success) {
37
- return Promise.resolve(body.data)
38
- }
39
- throw body
40
- } catch (error) {
41
- error.responseStatus = res.status
42
- error.responseBody = bodyText
43
- return Promise.reject(error)
44
- }
45
- })
46
- .then((data) => {
47
- env.set({ token: data.token }, true)
48
- logger.info("登录成功!")
49
- })
26
+ return fetch(join(accountServerUrl, '/api/login/signin'), {
27
+ method: 'POST',
28
+ body: new URLSearchParams({
29
+ username: username,
30
+ password: password,
31
+ }),
32
+ })
33
+ .then(async (res) => {
34
+ let bodyText = await res.text();
35
+ try {
36
+ let body = JSON.parse(bodyText);
37
+ if (body.success) {
38
+ return Promise.resolve(body.data);
39
+ }
40
+ throw body;
41
+ } catch (error) {
42
+ error.responseStatus = res.status;
43
+ error.responseBody = bodyText;
44
+ return Promise.reject(error);
45
+ }
46
+ })
47
+ .then((data) => {
48
+ env.set({ token: data.token }, true);
49
+ logger.info(t('lzc_cli.lib.appstore.login.login_success_tips', '登录成功!'));
50
+ });
50
51
  }
51
52
 
52
53
  async function isLogin() {
53
- try {
54
- let token = env.get("token")
55
- if (!token) {
56
- return false
57
- }
58
- return fetch(join(accountServerUrl, "/api/user/current"), {
59
- method: "GET",
60
- headers: {
61
- "X-User-Token": token
62
- }
63
- }).then(async (res) => {
64
- let bodyText = await res.text()
65
- let body = JSON.parse(bodyText)
66
- if (body.success) {
67
- return token
68
- }
69
- logger.debug(body.message)
70
- return false
71
- })
72
- } catch (e) {
73
- logger.trace(e)
74
- return false
75
- }
54
+ try {
55
+ let token = env.get('token');
56
+ if (!token) {
57
+ return false;
58
+ }
59
+ return fetch(join(accountServerUrl, '/api/user/current'), {
60
+ method: 'GET',
61
+ headers: {
62
+ 'X-User-Token': token,
63
+ },
64
+ }).then(async (res) => {
65
+ let bodyText = await res.text();
66
+ let body = JSON.parse(bodyText);
67
+ if (body.success) {
68
+ return token;
69
+ }
70
+ logger.debug(body.message);
71
+ return false;
72
+ });
73
+ } catch (e) {
74
+ logger.trace(e);
75
+ return false;
76
+ }
76
77
  }
77
78
 
78
79
  async function askUserInfo() {
79
- const noEmpty = (value) => value != ""
80
- return await inquirer.prompt([
81
- {
82
- type: "input",
83
- name: "username",
84
- message: "请输入登录用户名",
85
- validate: noEmpty
86
- },
87
- {
88
- type: "password",
89
- mask: "*",
90
- name: "password",
91
- message: "请输入登录密码",
92
- validate: noEmpty
93
- }
94
- ])
80
+ const noEmpty = (value) => value != '';
81
+ return await inquirer.prompt([
82
+ {
83
+ type: 'input',
84
+ name: 'username',
85
+ message: t('lzc_cli.lib.login.ask_user_info_username_prompt', '请输入登录用户名'),
86
+ validate: noEmpty,
87
+ },
88
+ {
89
+ type: 'password',
90
+ mask: '*',
91
+ name: 'password',
92
+ message: t('lzc_cli.lib.login.ask_user_info_password_prompt', '请输入登录密码'),
93
+ validate: noEmpty,
94
+ },
95
+ ]);
95
96
  }
96
97
 
97
98
  async function interactiveLogin() {
98
- try {
99
- let info = await askUserInfo()
100
- await login(info.username, info.password)
101
- } catch (e) {
102
- logger.debug("login error: ", e)
103
- if (e?.errorCode == 0 || e?.message == "密码错误") {
104
- logger.error("帐号或者密码错误,请重新输入!")
105
- } else {
106
- logger.error(`登录失败,${e?.message ?? e}`)
107
- }
108
- return interactiveLogin()
109
- }
99
+ try {
100
+ let info = await askUserInfo();
101
+ await login(info.username, info.password);
102
+ } catch (e) {
103
+ logger.debug('login error: ', e);
104
+ if (e?.errorCode == 0 || e?.message == '密码错误') {
105
+ logger.error(t('lzc_cli.lib.login.interactive_login_user_passwd_error_tips', '帐号或者密码错误,请重新输入!'));
106
+ } else {
107
+ logger.error(
108
+ t('lzc_cli.lib.login.interactive_login_fail_tips', `登录失败,{{message}}`, {
109
+ message: e?.message ?? e,
110
+ }),
111
+ );
112
+ }
113
+ return interactiveLogin();
114
+ }
110
115
  }
111
116
 
112
117
  function tipsFirstLogin() {
113
- let token = env.get("token")
114
- if (!token) {
115
- // 还没登录过的用户提示用户前往 https://developer.lazycat.cloud/manage 注册开发者账号
116
- logger.info(
117
- "请登录懒猫微服社区账号,账号注册以及开发者权限申请地址: https://developer.lazycat.cloud/manage"
118
- )
119
- }
118
+ let token = env.get('token');
119
+ if (!token) {
120
+ // 还没登录过的用户提示用户前往 https://developer.lazycat.cloud/manage 注册开发者账号
121
+ logger.info(t('lzc_cli.lib.login.tips_first_login_tips', '请登录懒猫微服社区账号,账号注册以及开发者权限申请地址: https://developer.lazycat.cloud/manage'));
122
+ }
120
123
  }
121
124
 
122
125
  export async function reLogin() {
123
- let token = await isLogin()
124
- if (token) {
125
- const questions = [
126
- {
127
- name: "relogin",
128
- type: "input",
129
- default: "n",
130
- message: "检测到已经登录,是否重新登录(y/n):"
131
- }
132
- ]
133
- const answers = await inquirer.prompt(questions)
134
- if (answers.relogin.toLowerCase() === "n") {
135
- logger.info(`token: ${token}`)
136
- return
137
- }
138
- } else {
139
- tipsFirstLogin()
140
- }
141
- await interactiveLogin()
126
+ let token = await isLogin();
127
+ if (token) {
128
+ const questions = [
129
+ {
130
+ name: 'relogin',
131
+ type: 'input',
132
+ default: 'n',
133
+ message: t('lzc_cli.lib.login.re_login_message_prompt', '检测到已经登录,是否重新登录(y/n):'),
134
+ },
135
+ ];
136
+ const answers = await inquirer.prompt(questions);
137
+ if (answers.relogin.toLowerCase() === 'n') {
138
+ logger.info(`token: ${token}`);
139
+ return;
140
+ }
141
+ } else {
142
+ tipsFirstLogin();
143
+ }
144
+ await interactiveLogin();
142
145
  }
143
146
 
144
147
  export async function autoLogin() {
145
- let token = await isLogin()
146
- if (token) {
147
- logger.debug("appstore 已经登录")
148
- return
149
- } else {
150
- tipsFirstLogin()
151
- }
148
+ let token = await isLogin();
149
+ if (token) {
150
+ logger.debug(t('lzc_cli.lib.login.auto_login_success', 'appstore 已经登录'));
151
+ return;
152
+ } else {
153
+ tipsFirstLogin();
154
+ }
152
155
 
153
- logger.debug("token错误,尝试自动登录")
154
- await interactiveLogin()
156
+ logger.debug(t('lzc_cli.lib.login.auto_login_interactive_login', 'token错误,尝试自动登录'));
157
+ await interactiveLogin();
155
158
  }
156
159
 
157
160
  export async function request(url, options = {}) {
158
- await autoLogin()
161
+ await autoLogin();
159
162
 
160
- const token = env.get("token")
163
+ const token = env.get('token');
161
164
 
162
- let headers = {
163
- "X-User-Token": token,
164
- cookie: `userToken=${token}`
165
- }
166
- if (options.headers) {
167
- headers = Object.assign({}, options.headers, headers)
168
- }
165
+ let headers = {
166
+ 'X-User-Token': token,
167
+ cookie: `userToken=${token}`,
168
+ };
169
+ if (options.headers) {
170
+ headers = Object.assign({}, options.headers, headers);
171
+ }
169
172
 
170
- // logger.debug("token", token)
173
+ // logger.debug("token", token)
171
174
 
172
- options = Object.assign({}, options, { headers })
173
- logger.trace(`fetch ${url}`, options)
175
+ options = Object.assign({}, options, { headers });
176
+ logger.trace(`fetch ${url}`, options);
174
177
 
175
- return fetch(url, options)
178
+ return fetch(url, options);
176
179
  }
@@ -1,115 +1,116 @@
1
- import { request, autoLogin } from "./login.js"
2
- import logger from "loglevel"
3
- import FormData from "form-data"
4
- import fs from "node:fs"
5
- import inquirer from "inquirer"
6
- import path from "node:path"
7
- import { isFileExist, isPngWithFile, unzipSync } from "../utils.js"
8
- import env from "../config/env.js"
9
- import { Publish } from "./publish.js"
1
+ import { request, autoLogin } from './login.js';
2
+ import logger from 'loglevel';
3
+ import FormData from 'form-data';
4
+ import fs from 'node:fs';
5
+ import inquirer from 'inquirer';
6
+ // import path from 'node:path';
7
+ // import { isFileExist, isPngWithFile, unzipSync } from "../utils.js"
8
+ import env from '../config/env.js';
9
+ import { t } from '../i18n/index.js';
10
+ import { Publish } from './publish.js';
10
11
 
11
12
  async function askChangeLog() {
12
- const noEmpty = (value) => value != ""
13
- return await inquirer.prompt([
14
- {
15
- name: "changelog",
16
- type: "editor",
17
- message: "填写 changelog 内容",
18
- validate: noEmpty
19
- }
20
- ])
13
+ const noEmpty = (value) => value != '';
14
+ return await inquirer.prompt([
15
+ {
16
+ name: 'changelog',
17
+ type: 'editor',
18
+ message: t('lzc_cli.lib.pre_publish.ask_changelog_prompt', '填写 changelog 内容'),
19
+ validate: noEmpty,
20
+ },
21
+ ]);
21
22
  }
22
23
 
23
24
  async function askGroup(choices) {
24
- return (
25
- await inquirer.prompt([
26
- {
27
- name: "type",
28
- message: "选择内测组",
29
- type: "list",
30
- choices
31
- }
32
- ])
33
- )["type"]
25
+ return (
26
+ await inquirer.prompt([
27
+ {
28
+ name: 'type',
29
+ message: t('lzc_cli.lib.pre_publish.ask_group_prompt', '选择内测组'),
30
+ type: 'list',
31
+ choices,
32
+ },
33
+ ])
34
+ )['type'];
34
35
  }
35
36
 
36
37
  export class PrePublish {
37
- constructor(baseUrl = "https://testflight.lazycat.cloud/api") {
38
- this.baseUrl = baseUrl
39
- }
38
+ constructor(baseUrl = 'https://testflight.lazycat.cloud/api') {
39
+ this.baseUrl = baseUrl;
40
+ }
40
41
 
41
- async getDict() {
42
- const url = this.baseUrl + "/groups/dict"
43
- const token = env.get("token")
44
- const res = await request(url, {
45
- method: "GET",
46
- headers: {
47
- Authorization: `Bearer ${token}`
48
- }
49
- })
50
- const text = (await res.text()).trim()
51
- if (!Publish.isJSON(text)) {
52
- logger.error(`parse error: dict resp text not is json`)
53
- return
54
- }
55
- const respJson = await JSON.parse(text)
56
- return respJson.data || []
57
- }
42
+ async getDict() {
43
+ const url = this.baseUrl + '/groups/dict';
44
+ const token = env.get('token');
45
+ const res = await request(url, {
46
+ method: 'GET',
47
+ headers: {
48
+ Authorization: `Bearer ${token}`,
49
+ },
50
+ });
51
+ const text = (await res.text()).trim();
52
+ if (!Publish.isJSON(text)) {
53
+ logger.error(`parse error: dict resp text not is json`);
54
+ return;
55
+ }
56
+ const respJson = await JSON.parse(text);
57
+ return respJson.data || [];
58
+ }
58
59
 
59
- async upload(groupId, changelog, pkgPath) {
60
- const form = new FormData()
61
- form.append("type", "Lpk")
62
- form.append("changelog", changelog)
63
- form.append("file", fs.createReadStream(pkgPath))
60
+ async upload(groupId, changelog, pkgPath) {
61
+ const form = new FormData();
62
+ form.append('type', 'Lpk');
63
+ form.append('changelog', changelog);
64
+ form.append('file', fs.createReadStream(pkgPath));
64
65
 
65
- const url = this.baseUrl + `/group/${groupId}/upload`
66
- const token = env.get("token")
67
- const res = await request(url, {
68
- method: "POST",
69
- body: form,
70
- headers: {
71
- Authorization: `Bearer ${token}`
72
- }
73
- })
74
- const text = (await res.text()).trim()
75
- if (!Publish.isJSON(text)) {
76
- logger.error(`parse error: upload resp text not is json`, text)
77
- return
78
- }
79
- const respJson = await JSON.parse(text)
80
- logger.debug("upload lpk response", respJson)
81
- return respJson
82
- }
66
+ const url = this.baseUrl + `/group/${groupId}/upload`;
67
+ const token = env.get('token');
68
+ const res = await request(url, {
69
+ method: 'POST',
70
+ body: form,
71
+ headers: {
72
+ Authorization: `Bearer ${token}`,
73
+ },
74
+ });
75
+ const text = (await res.text()).trim();
76
+ if (!Publish.isJSON(text)) {
77
+ logger.error(`parse error: upload resp text not is json`, text);
78
+ return;
79
+ }
80
+ const respJson = await JSON.parse(text);
81
+ logger.debug('upload lpk response', respJson);
82
+ return respJson;
83
+ }
83
84
 
84
- /**
85
- * @param {string} pkgPath
86
- * @param {string} changelog
87
- */
88
- async publish(pkgPath, changelog, gid) {
89
- if (!Publish.preCheck(pkgPath)) return
85
+ /**
86
+ * @param {string} pkgPath
87
+ * @param {string} changelog
88
+ */
89
+ async publish(pkgPath, changelog, gid) {
90
+ if (!Publish.preCheck(pkgPath)) return;
90
91
 
91
- await autoLogin()
92
+ await autoLogin();
92
93
 
93
- if (!gid) {
94
- const groups = await this.getDict()
95
- const groupName = await askGroup(groups.map((it) => it.name))
96
- gid = groups.find((it) => it.name == groupName)?.id
97
- }
98
- if (!gid) {
99
- logger.error("请选择内测组")
100
- return
101
- }
102
- if (!changelog) {
103
- const answer = await askChangeLog()
104
- changelog = answer.changelog
105
- }
106
- changelog = changelog.trim() // clean space ^:)
107
- logger.info("正在提交内测...")
108
- const resp = await this.upload(gid, changelog, pkgPath)
109
- if (resp.success) {
110
- logger.info("应用提交成功! 请在内测工具中查看")
111
- } else {
112
- logger.error(`应用提交失败: ${resp.msg}`)
113
- }
114
- }
94
+ if (!gid) {
95
+ const groups = await this.getDict();
96
+ const groupName = await askGroup(groups.map((it) => it.name));
97
+ gid = groups.find((it) => it.name == groupName)?.id;
98
+ }
99
+ if (!gid) {
100
+ logger.error(t('lzc_cli.lib.pre_publish.publish_gid_not_exist_tips', '请选择内测组'));
101
+ return;
102
+ }
103
+ if (!changelog) {
104
+ const answer = await askChangeLog();
105
+ changelog = answer.changelog;
106
+ }
107
+ changelog = changelog.trim(); // clean space ^:)
108
+ logger.info(t('lzc_cli.lib.pre_publish.publish_pending_tips', '正在提交内测...'));
109
+ const resp = await this.upload(gid, changelog, pkgPath);
110
+ if (resp.success) {
111
+ logger.info(t('lzc_cli.lib.pre_publish.publish_done_tips', '应用提交成功! 请在内测工具中查看'));
112
+ } else {
113
+ logger.error(t('lzc_cli.lib.pre_publish.publish_fail_tips', `应用提交失败: {{message}}`, { message: resp.msg }));
114
+ }
115
+ }
115
116
  }