@lazycatcloud/lzc-cli 1.2.27 → 1.2.28

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.
Files changed (37) hide show
  1. package/lib/app/apkshell.js +37 -0
  2. package/lib/app/index.js +74 -74
  3. package/lib/app/lpk_build.js +113 -117
  4. package/lib/app/lpk_create.js +78 -148
  5. package/lib/app/lpk_create_generator.js +101 -74
  6. package/lib/app/lpk_debug_bridge.js +65 -62
  7. package/lib/app/lpk_devshell.js +227 -228
  8. package/lib/app/lpk_devshell_docker.js +28 -28
  9. package/lib/app/lpk_installer.js +59 -49
  10. package/lib/appstore/index.js +29 -29
  11. package/lib/appstore/login.js +64 -64
  12. package/lib/appstore/prePublish.js +68 -68
  13. package/lib/appstore/publish.js +55 -55
  14. package/lib/box/index.js +25 -25
  15. package/lib/env.js +18 -18
  16. package/lib/shellapi.js +55 -58
  17. package/lib/utils.js +217 -164
  18. package/package.json +7 -1
  19. package/scripts/cli.js +56 -56
  20. package/template/_lpk/manifest.yml.in +8 -8
  21. package/template/vue/README.md +29 -0
  22. package/template/vue/index.html +13 -0
  23. package/template/vue/lzc-build.yml +59 -0
  24. package/template/vue/lzc-icon.png +0 -0
  25. package/template/vue/package.json +20 -0
  26. package/template/vue/public/vite.svg +1 -0
  27. package/template/vue/src/App.vue +30 -0
  28. package/template/vue/src/assets/vue.svg +1 -0
  29. package/template/vue/src/components/HelloWorld.vue +41 -0
  30. package/template/vue/src/main.ts +5 -0
  31. package/template/vue/src/style.css +79 -0
  32. package/template/vue/src/vite-env.d.ts +1 -0
  33. package/template/vue/tsconfig.app.json +24 -0
  34. package/template/vue/tsconfig.json +7 -0
  35. package/template/vue/tsconfig.node.json +22 -0
  36. package/template/vue/vite.config.ts +7 -0
  37. package/template/ionic_vue3/package-lock.json +0 -8100
@@ -1,23 +1,23 @@
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 { spawnSync } from "node:child_process";
7
- import path from "node:path";
8
- import { isFileExist, isPngWithFile } from "../utils.js";
9
- import env from "../env.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 { spawnSync } from "node:child_process"
7
+ import path from "node:path"
8
+ import { isFileExist, isPngWithFile } from "../utils.js"
9
+ import env from "../env.js"
10
10
 
11
11
  async function askChangeLog() {
12
- const noEmpty = (value) => value != "";
12
+ const noEmpty = (value) => value != ""
13
13
  return await inquirer.prompt([
14
14
  {
15
15
  name: "changelog",
16
16
  type: "editor",
17
17
  message: "填写 changelog 内容",
18
- validate: noEmpty,
19
- },
20
- ]);
18
+ validate: noEmpty
19
+ }
20
+ ])
21
21
  }
22
22
 
23
23
  async function askGroup(choices) {
@@ -27,88 +27,88 @@ async function askGroup(choices) {
27
27
  name: "type",
28
28
  message: "选择内测组",
29
29
  type: "list",
30
- choices,
31
- },
30
+ choices
31
+ }
32
32
  ])
33
- )["type"];
33
+ )["type"]
34
34
  }
35
35
 
36
36
  export class PrePublish {
37
37
  constructor(baseUrl = "https://testflight.lazycat.cloud/api") {
38
- this.baseUrl = baseUrl;
38
+ this.baseUrl = baseUrl
39
39
  }
40
40
 
41
41
  /**
42
42
  * @param {string} raw
43
43
  */
44
44
  isJSON(raw) {
45
- const ml = raw.length;
46
- if (ml <= 1) return false;
47
- return raw[0] == "{" && raw[ml - 1] == "}";
45
+ const ml = raw.length
46
+ if (ml <= 1) return false
47
+ return raw[0] == "{" && raw[ml - 1] == "}"
48
48
  }
49
49
 
50
50
  preCheck(pkgPath) {
51
- const tempDir = fs.mkdtempSync(".lzc-cli-publish");
51
+ const tempDir = fs.mkdtempSync(".lzc-cli-publish")
52
52
  try {
53
- spawnSync("unzip", ["-d", tempDir, pkgPath]);
53
+ spawnSync("unzip", ["-d", tempDir, pkgPath])
54
54
  if (isFileExist(path.join(tempDir, "devshell"))) {
55
55
  logger.error(
56
56
  "不能发布一个devshell的版本,请重新使用 `lzc-cli project build` 构建"
57
- );
58
- return false;
57
+ )
58
+ return false
59
59
  }
60
- const tempIcon = path.join(tempDir, "icon.png");
60
+ const tempIcon = path.join(tempDir, "icon.png")
61
61
  if (!isFileExist(tempIcon) || !isPngWithFile(tempIcon)) {
62
- logger.error("icon 必须是 png 格式");
63
- return false;
62
+ logger.error("icon 必须是 png 格式")
63
+ return false
64
64
  }
65
- return true;
65
+ return true
66
66
  } finally {
67
- fs.rmSync(tempDir, { recursive: true });
67
+ fs.rmSync(tempDir, { recursive: true })
68
68
  }
69
69
  }
70
70
 
71
71
  async getDict() {
72
- const url = this.baseUrl + "/groups/dict";
73
- const token = env.get("token");
72
+ const url = this.baseUrl + "/groups/dict"
73
+ const token = env.get("token")
74
74
  const res = await request(url, {
75
75
  method: "GET",
76
76
  headers: {
77
- Authorization: `Bearer ${token}`,
78
- },
79
- });
80
- const text = (await res.text()).trim();
77
+ Authorization: `Bearer ${token}`
78
+ }
79
+ })
80
+ const text = (await res.text()).trim()
81
81
  if (!this.isJSON(text)) {
82
- logger.error(`parse error: dict resp text not is json`);
83
- return;
82
+ logger.error(`parse error: dict resp text not is json`)
83
+ return
84
84
  }
85
- const respJson = await JSON.parse(text);
86
- return respJson.data || [];
85
+ const respJson = await JSON.parse(text)
86
+ return respJson.data || []
87
87
  }
88
88
 
89
89
  async upload(groupId, changelog, pkgPath) {
90
- const form = new FormData();
91
- form.append("type", "Lpk");
92
- form.append("changelog", changelog);
93
- form.append("file", fs.createReadStream(pkgPath));
90
+ const form = new FormData()
91
+ form.append("type", "Lpk")
92
+ form.append("changelog", changelog)
93
+ form.append("file", fs.createReadStream(pkgPath))
94
94
 
95
- const url = this.baseUrl + `/group/${groupId}/upload`;
96
- const token = env.get("token");
95
+ const url = this.baseUrl + `/group/${groupId}/upload`
96
+ const token = env.get("token")
97
97
  const res = await request(url, {
98
98
  method: "POST",
99
99
  body: form,
100
100
  headers: {
101
- Authorization: `Bearer ${token}`,
102
- },
103
- });
104
- const text = (await res.text()).trim();
101
+ Authorization: `Bearer ${token}`
102
+ }
103
+ })
104
+ const text = (await res.text()).trim()
105
105
  if (!this.isJSON(text)) {
106
- logger.error(`parse error: upload resp text not is json`);
107
- return;
106
+ logger.error(`parse error: upload resp text not is json`)
107
+ return
108
108
  }
109
- const respJson = await JSON.parse(text);
110
- logger.debug("upload lpk response", respJson);
111
- return respJson;
109
+ const respJson = await JSON.parse(text)
110
+ logger.debug("upload lpk response", respJson)
111
+ return respJson
112
112
  }
113
113
 
114
114
  /**
@@ -116,30 +116,30 @@ export class PrePublish {
116
116
  * @param {string} changelog
117
117
  */
118
118
  async publish(pkgPath, changelog, gid) {
119
- if (!this.preCheck(pkgPath)) return;
119
+ if (!this.preCheck(pkgPath)) return
120
120
 
121
- await autoLogin();
121
+ await autoLogin()
122
122
 
123
123
  if (!gid) {
124
- const groups = await this.getDict();
125
- const groupName = await askGroup(groups.map((it) => it.name));
126
- gid = groups.find((it) => it.name == groupName)?.id;
124
+ const groups = await this.getDict()
125
+ const groupName = await askGroup(groups.map((it) => it.name))
126
+ gid = groups.find((it) => it.name == groupName)?.id
127
127
  }
128
128
  if (!gid) {
129
- logger.error("请选择内测组");
130
- return;
129
+ logger.error("请选择内测组")
130
+ return
131
131
  }
132
132
  if (!changelog) {
133
- const answer = await askChangeLog();
134
- changelog = answer.changelog;
133
+ const answer = await askChangeLog()
134
+ changelog = answer.changelog
135
135
  }
136
- changelog = changelog.trim(); // clean space ^:)
137
- logger.info("正在提交内测...");
138
- const resp = await this.upload(gid, changelog, pkgPath);
136
+ changelog = changelog.trim() // clean space ^:)
137
+ logger.info("正在提交内测...")
138
+ const resp = await this.upload(gid, changelog, pkgPath)
139
139
  if (resp.success) {
140
- logger.info("应用提交成功! 请在内测工具中查看");
140
+ logger.info("应用提交成功! 请在内测工具中查看")
141
141
  } else {
142
- logger.error(`应用提交失败: ${resp.msg}`);
142
+ logger.error(`应用提交失败: ${resp.msg}`)
143
143
  }
144
144
  }
145
145
  }
@@ -1,56 +1,56 @@
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 { spawnSync } from "node:child_process";
7
- import path from "node:path";
8
- import { isFileExist, isPngWithFile } from "../utils.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 { spawnSync } from "node:child_process"
7
+ import path from "node:path"
8
+ import { isFileExist, isPngWithFile } from "../utils.js"
9
9
 
10
10
  async function askChangeLog() {
11
- const noEmpty = (value) => value != "";
11
+ const noEmpty = (value) => value != ""
12
12
  return await inquirer.prompt([
13
13
  {
14
14
  name: "changelog",
15
15
  type: "editor",
16
16
  message: "填写 changelog 内容",
17
- validate: noEmpty,
18
- },
19
- ]);
17
+ validate: noEmpty
18
+ }
19
+ ])
20
20
  }
21
21
 
22
22
  export class Publish {
23
23
  constructor(baseUrl = "https://developer.lazycat.cloud/api/v2/developer") {
24
- this.baseUrl = baseUrl;
24
+ this.baseUrl = baseUrl
25
25
  }
26
26
 
27
27
  /**
28
28
  * @param {string} raw
29
29
  */
30
30
  isJSON(raw) {
31
- const ml = raw.length;
32
- if (ml <= 1) return false;
33
- return raw[0] == "{" && raw[ml - 1] == "}";
31
+ const ml = raw.length
32
+ if (ml <= 1) return false
33
+ return raw[0] == "{" && raw[ml - 1] == "}"
34
34
  }
35
35
 
36
36
  preCheck(pkgPath) {
37
- const tempDir = fs.mkdtempSync(".lzc-cli-publish");
37
+ const tempDir = fs.mkdtempSync(".lzc-cli-publish")
38
38
  try {
39
- spawnSync("unzip", ["-d", tempDir, pkgPath]);
39
+ spawnSync("unzip", ["-d", tempDir, pkgPath])
40
40
  if (isFileExist(path.join(tempDir, "devshell"))) {
41
41
  logger.error(
42
42
  "不能发布一个devshell的版本,请重新使用 `lzc-cli project build` 构建"
43
- );
44
- return false;
43
+ )
44
+ return false
45
45
  }
46
- const tempIcon = path.join(tempDir, "icon.png");
46
+ const tempIcon = path.join(tempDir, "icon.png")
47
47
  if (!isFileExist(tempIcon) || !isPngWithFile(tempIcon)) {
48
- logger.error("icon 必须是 png 格式");
49
- return false;
48
+ logger.error("icon 必须是 png 格式")
49
+ return false
50
50
  }
51
- return true;
51
+ return true
52
52
  } finally {
53
- fs.rmSync(tempDir, { recursive: true });
53
+ fs.rmSync(tempDir, { recursive: true })
54
54
  }
55
55
  }
56
56
 
@@ -59,37 +59,37 @@ export class Publish {
59
59
  * @param {string} changelog
60
60
  */
61
61
  async publish(pkgPath, changelog) {
62
- if (!this.preCheck(pkgPath)) return;
62
+ if (!this.preCheck(pkgPath)) return
63
63
 
64
- await autoLogin();
64
+ await autoLogin()
65
65
 
66
66
  if (!changelog) {
67
- const answer = await askChangeLog();
68
- changelog = answer.changelog;
67
+ const answer = await askChangeLog()
68
+ changelog = answer.changelog
69
69
  }
70
- changelog = changelog.trim(); // clean space ^:)
70
+ changelog = changelog.trim() // clean space ^:)
71
71
 
72
- logger.info("正在提交审核...");
73
- const form = new FormData();
74
- form.append("file", fs.createReadStream(pkgPath));
72
+ logger.info("正在提交审核...")
73
+ const form = new FormData()
74
+ form.append("file", fs.createReadStream(pkgPath))
75
75
 
76
- const uploadURL = this.baseUrl + "/upload_lpk";
77
- logger.debug("upload url is", uploadURL);
76
+ const uploadURL = this.baseUrl + "/upload_lpk"
77
+ logger.debug("upload url is", uploadURL)
78
78
 
79
79
  const res = await request(uploadURL, {
80
80
  method: "POST",
81
- body: form,
82
- });
83
- const text = (await res.text()).trim();
81
+ body: form
82
+ })
83
+ const text = (await res.text()).trim()
84
84
  if (!this.isJSON(text)) {
85
- logger.info("upload lpk fail", text);
86
- return;
85
+ logger.info("upload lpk fail", text)
86
+ return
87
87
  }
88
- const lpkInfo = await JSON.parse(text);
89
- logger.debug("upload lpk response", lpkInfo);
88
+ const lpkInfo = await JSON.parse(text)
89
+ logger.debug("upload lpk response", lpkInfo)
90
90
 
91
- const sendURL = this.baseUrl + `/apps/${lpkInfo.package}/reviews`;
92
- logger.debug("publish url is", sendURL);
91
+ const sendURL = this.baseUrl + `/apps/${lpkInfo.package}/reviews`
92
+ logger.debug("publish url is", sendURL)
93
93
 
94
94
  const formData = {
95
95
  changelog,
@@ -97,24 +97,24 @@ export class Publish {
97
97
  iconPath: lpkInfo.iconPath,
98
98
  pkgPath: lpkInfo.url,
99
99
  supportPC: lpkInfo.supportPC,
100
- supportMobile: lpkInfo.supportMobile,
101
- };
100
+ supportMobile: lpkInfo.supportMobile
101
+ }
102
102
 
103
- logger.debug("form data is", formData);
103
+ logger.debug("form data is", formData)
104
104
 
105
105
  return request(sendURL, {
106
106
  method: "POST",
107
- body: JSON.stringify(formData),
107
+ body: JSON.stringify(formData)
108
108
  }).then(async (res) => {
109
109
  if (res.status >= 400) {
110
- logger.error("发布应用出错,错误状态码为: ", res.status);
111
- logger.error(await res.text());
112
- return;
110
+ logger.error("发布应用出错,错误状态码为: ", res.status)
111
+ logger.error(await res.text())
112
+ return
113
113
  }
114
114
 
115
- logger.info("应用提交成功! 请等待审核结果");
116
- logger.debug("publish response", await res.text());
117
- return;
118
- });
115
+ logger.info("应用提交成功! 请等待审核结果")
116
+ logger.debug("publish response", await res.text())
117
+ return
118
+ })
119
119
  }
120
120
  }
package/lib/box/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import shellapi from "../shellapi.js";
1
+ import shellapi from "../shellapi.js"
2
2
 
3
3
  export function boxCommand(box) {
4
4
  let subCommands = [
@@ -6,17 +6,17 @@ export function boxCommand(box) {
6
6
  command: "switch <boxname>",
7
7
  desc: "设置默认的盒子",
8
8
  handler: async ({ boxname }) => {
9
- await shellapi.init();
10
- await shellapi.setDefaultBox(boxname);
11
- },
9
+ await shellapi.init()
10
+ await shellapi.setDefaultBox(boxname)
11
+ }
12
12
  },
13
13
  {
14
14
  command: "default",
15
15
  desc: "输出当前默认的盒子名",
16
16
  handler: async () => {
17
- await shellapi.init();
18
- console.log(shellapi.boxname);
19
- },
17
+ await shellapi.init()
18
+ console.log(shellapi.boxname)
19
+ }
20
20
  },
21
21
  {
22
22
  command: "list",
@@ -25,19 +25,19 @@ export function boxCommand(box) {
25
25
  args.option("v", {
26
26
  alias: "verbose",
27
27
  describe: "查看详细输出",
28
- type: "boolean",
29
- });
28
+ type: "boolean"
29
+ })
30
30
  },
31
31
  handler: async ({ verbose }) => {
32
- await shellapi.init();
33
- const boxes = await shellapi.boxList();
32
+ await shellapi.init()
33
+ const boxes = await shellapi.boxList()
34
34
  if (boxes.length === 0) {
35
- console.log("没有找到任何盒子,赶紧添加一个吧!");
36
- return;
35
+ console.log("没有找到任何盒子,赶紧添加一个吧!")
36
+ return
37
37
  }
38
38
  if (verbose) {
39
- console.log(JSON.stringify(boxes, undefined, "\t"));
40
- return;
39
+ console.log(JSON.stringify(boxes, undefined, "\t"))
40
+ return
41
41
  }
42
42
 
43
43
  const list = boxes.map((b) => {
@@ -46,18 +46,18 @@ export function boxCommand(box) {
46
46
  状态: b.status,
47
47
  登录用户: b.login_user,
48
48
  是否管理员: b.is_admin_login ? "✔" : "✖",
49
- 是否默认盒子: b.is_default_box ? "✔" : "✖",
50
- };
51
- });
52
- console.table(list);
53
- },
54
- },
55
- ];
49
+ 是否默认盒子: b.is_default_box ? "✔" : "✖"
50
+ }
51
+ })
52
+ console.table(list)
53
+ }
54
+ }
55
+ ]
56
56
  box.command({
57
57
  command: "box",
58
58
  desc: "盒子管理",
59
59
  builder: (args) => {
60
- args.command(subCommands);
61
- },
62
- });
60
+ args.command(subCommands)
61
+ }
62
+ })
63
63
  }
package/lib/env.js CHANGED
@@ -1,47 +1,47 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import { ensureDir } from "./utils.js";
4
- import logger from "loglevel";
5
- import os from "node:os";
1
+ import path from "path"
2
+ import fs from "fs"
3
+ import { ensureDir } from "./utils.js"
4
+ import logger from "loglevel"
5
+ import os from "node:os"
6
6
 
7
7
  export const GLOBAL_CONFIG_DIR = path.join(
8
8
  os.homedir(),
9
9
  "/.config/lazycat/box-config.json"
10
- );
10
+ )
11
11
 
12
12
  class Env {
13
13
  constructor() {
14
- this.allEnv = {};
15
- this.globalEnvPath = GLOBAL_CONFIG_DIR;
16
- ensureDir(this.globalEnvPath);
14
+ this.allEnv = {}
15
+ this.globalEnvPath = GLOBAL_CONFIG_DIR
16
+ ensureDir(this.globalEnvPath)
17
17
 
18
- this._loadGlobalEnv();
18
+ this._loadGlobalEnv()
19
19
  }
20
20
 
21
21
  has(key) {
22
- return Object.keys(this.allEnv).indexOf(key) > -1;
22
+ return Object.keys(this.allEnv).indexOf(key) > -1
23
23
  }
24
24
 
25
25
  get(key) {
26
- return this.allEnv[key];
26
+ return this.allEnv[key]
27
27
  }
28
28
 
29
29
  set(pairs) {
30
- Object.assign(this.allEnv, pairs);
30
+ Object.assign(this.allEnv, pairs)
31
31
  fs.writeFileSync(
32
32
  this.globalEnvPath,
33
33
  JSON.stringify(this.allEnv, null, " ")
34
- );
34
+ )
35
35
  }
36
36
 
37
37
  _loadGlobalEnv() {
38
38
  try {
39
- this.allEnv = JSON.parse(fs.readFileSync(this.globalEnvPath));
39
+ this.allEnv = JSON.parse(fs.readFileSync(this.globalEnvPath))
40
40
  } catch (e) {
41
- logger.debug("global env fail to fetch ", e.message);
42
- this.allEnv = {};
41
+ logger.debug("global env fail to fetch ", e.message)
42
+ this.allEnv = {}
43
43
  }
44
44
  }
45
45
  }
46
46
 
47
- export default new Env();
47
+ export default new Env()