@lazycatcloud/lzc-cli 1.2.27 → 1.2.29
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/lib/app/apkshell.js +35 -0
- package/lib/app/index.js +89 -78
- package/lib/app/lpk_build.js +113 -117
- package/lib/app/lpk_create.js +78 -148
- package/lib/app/lpk_create_generator.js +103 -74
- package/lib/app/lpk_debug_bridge.js +61 -73
- package/lib/app/lpk_devshell.js +230 -229
- package/lib/app/lpk_devshell_docker.js +28 -28
- package/lib/app/lpk_installer.js +64 -49
- package/lib/appstore/index.js +29 -29
- package/lib/appstore/login.js +63 -68
- package/lib/appstore/prePublish.js +68 -68
- package/lib/appstore/publish.js +55 -55
- package/lib/box/index.js +25 -25
- package/lib/env.js +18 -18
- package/lib/shellapi.js +55 -58
- package/lib/utils.js +217 -164
- package/package.json +7 -1
- package/scripts/cli.js +56 -56
- package/template/_lpk/manifest.yml.in +8 -8
- package/template/vue/README.md +29 -0
- package/template/vue/index.html +13 -0
- package/template/vue/lzc-build.yml +59 -0
- package/template/vue/lzc-icon.png +0 -0
- package/template/vue/package.json +20 -0
- package/template/vue/public/vite.svg +1 -0
- package/template/vue/src/App.vue +30 -0
- package/template/vue/src/assets/vue.svg +1 -0
- package/template/vue/src/components/HelloWorld.vue +41 -0
- package/template/vue/src/main.ts +5 -0
- package/template/vue/src/style.css +79 -0
- package/template/vue/src/vite-env.d.ts +1 -0
- package/template/vue/tsconfig.app.json +24 -0
- package/template/vue/tsconfig.json +7 -0
- package/template/vue/tsconfig.node.json +22 -0
- package/template/vue/vite.config.ts +7 -0
- package/template/ionic_vue3/package-lock.json +0 -8100
package/lib/utils.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import path from "path"
|
|
2
|
-
import fs from "fs"
|
|
3
|
-
import os from "os"
|
|
4
|
-
import glob from "fast-glob"
|
|
5
|
-
import yaml from "js-yaml"
|
|
6
|
-
import mergeWith from "lodash.mergewith"
|
|
7
|
-
import { dirname } from "path"
|
|
8
|
-
import { fileURLToPath } from "url"
|
|
9
|
-
import ignore from "ignore"
|
|
10
|
-
import { createHash } from "node:crypto"
|
|
11
|
-
import https from "node:https"
|
|
12
|
-
import http from "node:http"
|
|
13
|
-
import zlib from "node:zlib"
|
|
14
|
-
import process from "node:process"
|
|
15
|
-
import { spawnSync } from "node:child_process"
|
|
16
|
-
import logger from "loglevel"
|
|
17
|
-
import * as tar from "tar"
|
|
18
|
-
import dns from "node:dns/promises"
|
|
1
|
+
import path from "path"
|
|
2
|
+
import fs from "fs"
|
|
3
|
+
import os from "os"
|
|
4
|
+
import glob from "fast-glob"
|
|
5
|
+
import yaml from "js-yaml"
|
|
6
|
+
import mergeWith from "lodash.mergewith"
|
|
7
|
+
import { dirname } from "path"
|
|
8
|
+
import { fileURLToPath } from "url"
|
|
9
|
+
import ignore from "ignore"
|
|
10
|
+
import { createHash } from "node:crypto"
|
|
11
|
+
import https from "node:https"
|
|
12
|
+
import http from "node:http"
|
|
13
|
+
import zlib from "node:zlib"
|
|
14
|
+
import process from "node:process"
|
|
15
|
+
import { spawnSync } from "node:child_process"
|
|
16
|
+
import logger from "loglevel"
|
|
17
|
+
import * as tar from "tar"
|
|
18
|
+
import dns from "node:dns/promises"
|
|
19
19
|
|
|
20
20
|
export const envsubstr = async (templateContents, args) => {
|
|
21
|
-
const parse = await importDefault("envsub/js/envsub-parser.js")
|
|
22
|
-
return parse(templateContents, args)
|
|
23
|
-
}
|
|
21
|
+
const parse = await importDefault("envsub/js/envsub-parser.js")
|
|
22
|
+
return parse(templateContents, args)
|
|
23
|
+
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* 确保文件夹存在
|
|
@@ -28,31 +28,70 @@ export const envsubstr = async (templateContents, args) => {
|
|
|
28
28
|
*
|
|
29
29
|
*/
|
|
30
30
|
export function ensureDir(filePath) {
|
|
31
|
-
let dirPath
|
|
31
|
+
let dirPath
|
|
32
32
|
if (filePath.endsWith("/")) {
|
|
33
|
-
dirPath = filePath
|
|
33
|
+
dirPath = filePath
|
|
34
34
|
} else {
|
|
35
|
-
dirPath = path.dirname(filePath)
|
|
35
|
+
dirPath = path.dirname(filePath)
|
|
36
36
|
}
|
|
37
37
|
if (!fs.existsSync(dirPath)) {
|
|
38
|
-
fs.mkdirSync(dirPath, { recursive: true })
|
|
38
|
+
fs.mkdirSync(dirPath, { recursive: true })
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function ensureDirectoryExists(filePath, isRenameOrClear) {
|
|
43
|
+
let result = { isExists: false, renamedFileName: undefined }
|
|
44
|
+
try {
|
|
45
|
+
const stats = fs.statSync(filePath) // 获取文件或目录的状态
|
|
46
|
+
result.isExists = true
|
|
47
|
+
if (isRenameOrClear) {
|
|
48
|
+
if (stats.isDirectory()) {
|
|
49
|
+
const newPath = getUniquePath(filePath)
|
|
50
|
+
result.renamedFileName = path.basename(newPath)
|
|
51
|
+
fs.renameSync(filePath, newPath)
|
|
52
|
+
} else {
|
|
53
|
+
fs.rmSync(filePath)
|
|
54
|
+
}
|
|
55
|
+
fs.mkdirSync(filePath, { recursive: true })
|
|
56
|
+
}
|
|
57
|
+
} catch (err) {
|
|
58
|
+
if (err.code === "ENOENT") {
|
|
59
|
+
fs.mkdirSync(filePath, { recursive: true })
|
|
60
|
+
} else {
|
|
61
|
+
throw `创建文件夹${filePath}错误: ${err}`
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return result
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 如果该路径已存在,则返回带递增数字的路径
|
|
68
|
+
function getUniquePath(basePath) {
|
|
69
|
+
let dirName = path.basename(basePath)
|
|
70
|
+
let dirPath = basePath
|
|
71
|
+
let index = 1
|
|
72
|
+
// 检查是否存在同名目录
|
|
73
|
+
while (fs.existsSync(dirPath)) {
|
|
74
|
+
dirName = `${path.basename(basePath, path.extname(basePath))}_${index}`
|
|
75
|
+
dirPath = path.join(path.dirname(basePath), dirName)
|
|
76
|
+
index++
|
|
39
77
|
}
|
|
78
|
+
return dirPath
|
|
40
79
|
}
|
|
41
80
|
|
|
42
81
|
export async function createTemplateFileCommon(templateFile, outputFile, env) {
|
|
43
82
|
const options = {
|
|
44
83
|
envs: toPair(env),
|
|
45
84
|
syntax: "default",
|
|
46
|
-
protect: false
|
|
47
|
-
}
|
|
85
|
+
protect: false
|
|
86
|
+
}
|
|
48
87
|
const output = await envsubstr(fs.readFileSync(templateFile, "utf-8"), {
|
|
49
|
-
options
|
|
50
|
-
})
|
|
51
|
-
fs.writeFileSync(outputFile, output)
|
|
88
|
+
options
|
|
89
|
+
})
|
|
90
|
+
fs.writeFileSync(outputFile, output)
|
|
52
91
|
}
|
|
53
92
|
|
|
54
93
|
export function loadFromYaml(file) {
|
|
55
|
-
return yaml.load(fs.readFileSync(file, "utf8"))
|
|
94
|
+
return yaml.load(fs.readFileSync(file, "utf8"))
|
|
56
95
|
}
|
|
57
96
|
|
|
58
97
|
export function dumpToYaml(template, target) {
|
|
@@ -60,113 +99,113 @@ export function dumpToYaml(template, target) {
|
|
|
60
99
|
target,
|
|
61
100
|
yaml.dump(template, {
|
|
62
101
|
styles: {
|
|
63
|
-
"!!null": "empty"
|
|
64
|
-
}
|
|
65
|
-
})
|
|
66
|
-
)
|
|
102
|
+
"!!null": "empty" // dump null as ""
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
)
|
|
67
106
|
}
|
|
68
107
|
|
|
69
108
|
export function toPair(object) {
|
|
70
109
|
return Object.keys(object).map((key) => {
|
|
71
|
-
let value = object[key] ? object[key].toString() : ""
|
|
72
|
-
key = key.replace(/-/g, "_")
|
|
110
|
+
let value = object[key] ? object[key].toString() : ""
|
|
111
|
+
key = key.replace(/-/g, "_")
|
|
73
112
|
return {
|
|
74
113
|
name: key,
|
|
75
|
-
value
|
|
76
|
-
}
|
|
77
|
-
})
|
|
114
|
+
value
|
|
115
|
+
}
|
|
116
|
+
})
|
|
78
117
|
}
|
|
79
118
|
|
|
80
119
|
export async function envTemplateFile(templateFile, env) {
|
|
81
|
-
const template = yaml.load(fs.readFileSync(templateFile, "utf8"))
|
|
120
|
+
const template = yaml.load(fs.readFileSync(templateFile, "utf8"))
|
|
82
121
|
const options = {
|
|
83
122
|
envs: toPair(env),
|
|
84
123
|
syntax: "default",
|
|
85
|
-
protect: false
|
|
86
|
-
}
|
|
124
|
+
protect: false
|
|
125
|
+
}
|
|
87
126
|
return await envsubstr(
|
|
88
127
|
yaml.dump(template, {
|
|
89
128
|
styles: {
|
|
90
|
-
"!!null": "empty"
|
|
91
|
-
}
|
|
129
|
+
"!!null": "empty" // dump null as ""
|
|
130
|
+
}
|
|
92
131
|
}),
|
|
93
|
-
{ options }
|
|
94
|
-
)
|
|
132
|
+
{ options }
|
|
133
|
+
)
|
|
95
134
|
}
|
|
96
135
|
|
|
97
136
|
export function mergeYamlInMemory(args) {
|
|
98
137
|
if (args.length == 0) {
|
|
99
|
-
return {}
|
|
138
|
+
return {}
|
|
100
139
|
} else if (args.length == 1) {
|
|
101
|
-
return args[0]
|
|
140
|
+
return args[0]
|
|
102
141
|
}
|
|
103
142
|
return args.reduce((prev, curr) => {
|
|
104
143
|
let result = mergeWith(prev, curr, (objValue, srcValue) => {
|
|
105
144
|
if (Array.isArray(objValue)) {
|
|
106
|
-
return objValue.concat(srcValue)
|
|
145
|
+
return objValue.concat(srcValue)
|
|
107
146
|
}
|
|
108
|
-
})
|
|
109
|
-
return result
|
|
110
|
-
}, {})
|
|
147
|
+
})
|
|
148
|
+
return result
|
|
149
|
+
}, {})
|
|
111
150
|
}
|
|
112
151
|
|
|
113
152
|
export function contextDirname(url = import.meta.url) {
|
|
114
|
-
return dirname(fileURLToPath(url))
|
|
153
|
+
return dirname(fileURLToPath(url))
|
|
115
154
|
}
|
|
116
155
|
|
|
117
156
|
export async function importDefault(pkgPath) {
|
|
118
|
-
let mod = await import(pkgPath)
|
|
119
|
-
return mod.default
|
|
157
|
+
let mod = await import(pkgPath)
|
|
158
|
+
return mod.default
|
|
120
159
|
}
|
|
121
160
|
|
|
122
161
|
export class GitIgnore {
|
|
123
162
|
constructor(root) {
|
|
124
|
-
this.root = root
|
|
125
|
-
this.ignores = []
|
|
163
|
+
this.root = root
|
|
164
|
+
this.ignores = []
|
|
126
165
|
}
|
|
127
166
|
|
|
128
167
|
async collect() {
|
|
129
168
|
const files = await glob(["**/.gitignore"], {
|
|
130
169
|
cwd: this.root,
|
|
131
170
|
dot: true,
|
|
132
|
-
deep: 3
|
|
133
|
-
})
|
|
171
|
+
deep: 3
|
|
172
|
+
})
|
|
134
173
|
|
|
135
|
-
files.forEach((f) => this._add(f))
|
|
174
|
+
files.forEach((f) => this._add(f))
|
|
136
175
|
}
|
|
137
176
|
|
|
138
177
|
_add(ignoreFile) {
|
|
139
|
-
let data = fs.readFileSync(ignoreFile, "utf8")
|
|
140
|
-
let ig = ignore({ allowRelativePaths: true })
|
|
141
|
-
ig.add(data.split("\n"))
|
|
178
|
+
let data = fs.readFileSync(ignoreFile, "utf8")
|
|
179
|
+
let ig = ignore({ allowRelativePaths: true })
|
|
180
|
+
ig.add(data.split("\n"))
|
|
142
181
|
this.ignores.push({
|
|
143
182
|
ig,
|
|
144
|
-
dir: path.dirname(ignoreFile)
|
|
145
|
-
})
|
|
183
|
+
dir: path.dirname(ignoreFile)
|
|
184
|
+
})
|
|
146
185
|
}
|
|
147
186
|
|
|
148
187
|
contain(filepath) {
|
|
149
188
|
return this.ignores.some(({ ig, dir }) => {
|
|
150
189
|
// 去除不应该计算ignore 的文件
|
|
151
190
|
if (!filepath.startsWith(dir)) {
|
|
152
|
-
return false
|
|
191
|
+
return false
|
|
153
192
|
}
|
|
154
193
|
|
|
155
|
-
return ig.ignores(path.relative(dir, filepath))
|
|
156
|
-
})
|
|
194
|
+
return ig.ignores(path.relative(dir, filepath))
|
|
195
|
+
})
|
|
157
196
|
}
|
|
158
197
|
}
|
|
159
198
|
|
|
160
199
|
export function isDirSync(path) {
|
|
161
|
-
let stat = fs.statSync(path)
|
|
162
|
-
return stat.isDirectory()
|
|
200
|
+
let stat = fs.statSync(path)
|
|
201
|
+
return stat.isDirectory()
|
|
163
202
|
}
|
|
164
203
|
|
|
165
204
|
export function isDirExist(path) {
|
|
166
205
|
try {
|
|
167
|
-
return isDirSync(path)
|
|
206
|
+
return isDirSync(path)
|
|
168
207
|
} catch {
|
|
169
|
-
return false
|
|
208
|
+
return false
|
|
170
209
|
}
|
|
171
210
|
}
|
|
172
211
|
|
|
@@ -174,173 +213,182 @@ export function isFileExist(path) {
|
|
|
174
213
|
try {
|
|
175
214
|
fs.accessSync(
|
|
176
215
|
path,
|
|
177
|
-
fs.constants.W_OK | fs.constants.R_OK | fs.constants.F_OK
|
|
178
|
-
)
|
|
179
|
-
return true
|
|
216
|
+
fs.constants.W_OK | fs.constants.R_OK | fs.constants.F_OK
|
|
217
|
+
)
|
|
218
|
+
return true
|
|
180
219
|
} catch {
|
|
181
|
-
return false
|
|
220
|
+
return false
|
|
182
221
|
}
|
|
183
222
|
}
|
|
184
223
|
|
|
185
224
|
export async function sleep(ms) {
|
|
186
225
|
return new Promise((resolve) => {
|
|
187
|
-
setTimeout(resolve, ms)
|
|
188
|
-
})
|
|
226
|
+
setTimeout(resolve, ms)
|
|
227
|
+
})
|
|
189
228
|
}
|
|
190
229
|
|
|
191
230
|
export async function md5String(str) {
|
|
192
|
-
const hash = createHash("md5")
|
|
193
|
-
hash.update(str)
|
|
194
|
-
return hash.digest("hex")
|
|
231
|
+
const hash = createHash("md5")
|
|
232
|
+
hash.update(str)
|
|
233
|
+
return hash.digest("hex")
|
|
195
234
|
}
|
|
196
235
|
|
|
197
236
|
export async function md5File(filepath) {
|
|
198
|
-
const hash = createHash("md5")
|
|
199
|
-
const input = fs.createReadStream(filepath)
|
|
237
|
+
const hash = createHash("md5")
|
|
238
|
+
const input = fs.createReadStream(filepath)
|
|
200
239
|
return new Promise((resolve) => {
|
|
201
240
|
input.on("readable", () => {
|
|
202
|
-
const data = input.read()
|
|
241
|
+
const data = input.read()
|
|
203
242
|
if (data) {
|
|
204
|
-
hash.update(data)
|
|
243
|
+
hash.update(data)
|
|
205
244
|
} else {
|
|
206
|
-
resolve(hash.digest("hex"))
|
|
245
|
+
resolve(hash.digest("hex"))
|
|
207
246
|
}
|
|
208
|
-
})
|
|
209
|
-
})
|
|
247
|
+
})
|
|
248
|
+
})
|
|
210
249
|
}
|
|
211
250
|
|
|
212
251
|
export class Downloader {
|
|
213
252
|
constructor() {}
|
|
214
253
|
|
|
215
254
|
showDownloadingProgress(received, total) {
|
|
216
|
-
let percentage = ((received * 100) / total).toFixed(2)
|
|
217
|
-
process.stdout.write("\r")
|
|
255
|
+
let percentage = ((received * 100) / total).toFixed(2)
|
|
256
|
+
process.stdout.write("\r")
|
|
218
257
|
process.stdout.write(
|
|
219
258
|
percentage +
|
|
220
259
|
"% | " +
|
|
221
260
|
received +
|
|
222
261
|
" bytes downloaded out of " +
|
|
223
262
|
total +
|
|
224
|
-
" bytes."
|
|
225
|
-
)
|
|
263
|
+
" bytes."
|
|
264
|
+
)
|
|
226
265
|
}
|
|
227
266
|
|
|
228
267
|
download(url, savePath, enableGzip = false) {
|
|
229
|
-
let tmpPath = savePath + ".tmp"
|
|
230
|
-
const options = new URL(url)
|
|
231
|
-
let request = url.startsWith("https") ? https.request : http.request
|
|
268
|
+
let tmpPath = savePath + ".tmp"
|
|
269
|
+
const options = new URL(url)
|
|
270
|
+
let request = url.startsWith("https") ? https.request : http.request
|
|
232
271
|
|
|
233
272
|
return new Promise((resolve, reject) => {
|
|
234
273
|
const req = request(options, (res) => {
|
|
235
274
|
if (res.statusCode != 200) {
|
|
236
|
-
reject(`下载 ${url} 失败`)
|
|
237
|
-
return
|
|
275
|
+
reject(`下载 ${url} 失败`)
|
|
276
|
+
return
|
|
238
277
|
}
|
|
239
278
|
|
|
240
|
-
let total = parseInt(res.headers["content-length"])
|
|
241
|
-
let recive = 0
|
|
279
|
+
let total = parseInt(res.headers["content-length"])
|
|
280
|
+
let recive = 0
|
|
242
281
|
res.on("data", (chunk) => {
|
|
243
|
-
recive += chunk.length
|
|
244
|
-
this.showDownloadingProgress(recive, total)
|
|
245
|
-
})
|
|
282
|
+
recive += chunk.length
|
|
283
|
+
this.showDownloadingProgress(recive, total)
|
|
284
|
+
})
|
|
246
285
|
|
|
247
|
-
let outputFile = fs.createWriteStream(tmpPath, { flags: "w+" })
|
|
286
|
+
let outputFile = fs.createWriteStream(tmpPath, { flags: "w+" })
|
|
248
287
|
if (enableGzip) {
|
|
249
|
-
let decoder = zlib.createUnzip()
|
|
250
|
-
res.pipe(decoder).pipe(outputFile)
|
|
288
|
+
let decoder = zlib.createUnzip()
|
|
289
|
+
res.pipe(decoder).pipe(outputFile)
|
|
251
290
|
} else {
|
|
252
|
-
res.pipe(outputFile)
|
|
291
|
+
res.pipe(outputFile)
|
|
253
292
|
}
|
|
254
293
|
|
|
255
|
-
outputFile.on("error", reject)
|
|
294
|
+
outputFile.on("error", reject)
|
|
256
295
|
outputFile.on("finish", () => {
|
|
257
|
-
fs.renameSync(tmpPath, savePath)
|
|
258
|
-
process.stdout.write("\n")
|
|
259
|
-
resolve()
|
|
260
|
-
})
|
|
261
|
-
})
|
|
262
|
-
req.on("error", reject)
|
|
263
|
-
req.end()
|
|
264
|
-
})
|
|
296
|
+
fs.renameSync(tmpPath, savePath)
|
|
297
|
+
process.stdout.write("\n")
|
|
298
|
+
resolve()
|
|
299
|
+
})
|
|
300
|
+
})
|
|
301
|
+
req.on("error", reject)
|
|
302
|
+
req.end()
|
|
303
|
+
})
|
|
265
304
|
}
|
|
266
305
|
}
|
|
267
306
|
|
|
268
307
|
export class FileLocker {
|
|
269
308
|
constructor(id) {
|
|
270
|
-
this.filename = undefined
|
|
271
|
-
this.fd = undefined
|
|
272
|
-
this.id = id
|
|
309
|
+
this.filename = undefined
|
|
310
|
+
this.fd = undefined
|
|
311
|
+
this.id = id
|
|
273
312
|
}
|
|
274
313
|
lock() {
|
|
275
|
-
this.filename = path.resolve(os.tmpdir(), "lzc-cli-file-lock", this.id)
|
|
276
|
-
ensureDir(this.filename)
|
|
314
|
+
this.filename = path.resolve(os.tmpdir(), "lzc-cli-file-lock", this.id)
|
|
315
|
+
ensureDir(this.filename)
|
|
277
316
|
|
|
278
317
|
try {
|
|
279
|
-
this.fd = fs.openSync(this.filename, "wx+")
|
|
318
|
+
this.fd = fs.openSync(this.filename, "wx+")
|
|
280
319
|
} catch (e) {
|
|
281
320
|
if (e.code == "EEXIST" && !this.withOpen(this.filename)) {
|
|
282
|
-
logger.debug("filelock exist open with w+")
|
|
283
|
-
this.fd = fs.openSync(this.filename, "w+")
|
|
321
|
+
logger.debug("filelock exist open with w+")
|
|
322
|
+
this.fd = fs.openSync(this.filename, "w+")
|
|
284
323
|
} else {
|
|
285
|
-
throw e
|
|
324
|
+
throw e
|
|
286
325
|
}
|
|
287
326
|
}
|
|
288
327
|
}
|
|
289
328
|
unlock() {
|
|
290
329
|
if (this.fd) {
|
|
291
|
-
fs.closeSync(this.fd)
|
|
292
|
-
fs.rmSync(this.filename)
|
|
293
|
-
this.fd = undefined
|
|
294
|
-
this.filename = undefined
|
|
330
|
+
fs.closeSync(this.fd)
|
|
331
|
+
fs.rmSync(this.filename)
|
|
332
|
+
this.fd = undefined
|
|
333
|
+
this.filename = undefined
|
|
295
334
|
}
|
|
296
335
|
}
|
|
297
336
|
withOpen(filename) {
|
|
298
|
-
const p = spawnSync("lsof", ["-w", "-t", filename])
|
|
337
|
+
const p = spawnSync("lsof", ["-w", "-t", filename])
|
|
299
338
|
if (p.status === 0) {
|
|
300
|
-
return true
|
|
339
|
+
return true
|
|
301
340
|
} else {
|
|
302
|
-
return false
|
|
341
|
+
return false
|
|
303
342
|
}
|
|
304
343
|
}
|
|
305
344
|
}
|
|
306
345
|
|
|
346
|
+
export function isValidAppId(appId) {
|
|
347
|
+
// 暂时去掉 - 的支持
|
|
348
|
+
// const regex = new RegExp("^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$")
|
|
349
|
+
const regex = new RegExp("^[a-z][a-z0-9]{0,61}[a-zA-Z0-9]$")
|
|
350
|
+
return regex.test(appId)
|
|
351
|
+
}
|
|
352
|
+
|
|
307
353
|
export function isValidPackageName(packageName) {
|
|
308
|
-
|
|
309
|
-
|
|
354
|
+
// 暂时去掉 - 的支持
|
|
355
|
+
// const regex = new RegExp("^(?:[a-z][a-z0-9-]*\\.)+[a-z][a-z0-9-]*$")
|
|
356
|
+
const regex = new RegExp("^(?:[a-z][a-z0-9]*\\.)+[a-z][a-z0-9]*$")
|
|
357
|
+
return regex.test(packageName)
|
|
310
358
|
}
|
|
311
359
|
|
|
312
360
|
export function isUserApp(manifest) {
|
|
313
|
-
return !!manifest["application"]["user_app"]
|
|
361
|
+
return !!manifest["application"]["user_app"]
|
|
314
362
|
}
|
|
315
363
|
|
|
316
364
|
export async function tarContentDir(from, to, cwd = "./") {
|
|
317
365
|
return new Promise((resolve, reject) => {
|
|
318
|
-
const dest = fs.createWriteStream(to)
|
|
366
|
+
const dest = fs.createWriteStream(to)
|
|
319
367
|
tar
|
|
320
368
|
.c(
|
|
321
369
|
{
|
|
322
370
|
cwd: cwd,
|
|
323
371
|
filter: (filePath) => {
|
|
324
|
-
logger.debug(`tar gz ${filePath}`)
|
|
325
|
-
return true
|
|
372
|
+
logger.debug(`tar gz ${filePath}`)
|
|
373
|
+
return true
|
|
326
374
|
},
|
|
327
375
|
sync: true,
|
|
328
376
|
portable: {
|
|
329
377
|
uid: 0,
|
|
330
|
-
gid: 0
|
|
331
|
-
}
|
|
378
|
+
gid: 0
|
|
379
|
+
}
|
|
332
380
|
},
|
|
333
|
-
from
|
|
381
|
+
from
|
|
334
382
|
)
|
|
335
383
|
.pipe(dest)
|
|
336
384
|
.on("close", () => {
|
|
337
|
-
logger.debug(`pack: ${dest.path}`)
|
|
338
|
-
resolve(dest.path)
|
|
385
|
+
logger.debug(`pack: ${dest.path}`)
|
|
386
|
+
resolve(dest.path)
|
|
339
387
|
})
|
|
340
388
|
.on("error", (err) => {
|
|
341
|
-
reject(err)
|
|
342
|
-
})
|
|
343
|
-
})
|
|
389
|
+
reject(err)
|
|
390
|
+
})
|
|
391
|
+
})
|
|
344
392
|
}
|
|
345
393
|
|
|
346
394
|
/**
|
|
@@ -351,7 +399,7 @@ export async function tarContentDir(from, to, cwd = "./") {
|
|
|
351
399
|
*/
|
|
352
400
|
function isPngWithBuffer(buffer) {
|
|
353
401
|
if (!buffer || buffer.length < 8) {
|
|
354
|
-
return false
|
|
402
|
+
return false
|
|
355
403
|
}
|
|
356
404
|
return (
|
|
357
405
|
buffer[0] === 0x89 &&
|
|
@@ -362,38 +410,43 @@ function isPngWithBuffer(buffer) {
|
|
|
362
410
|
buffer[5] === 0x0a &&
|
|
363
411
|
buffer[6] === 0x1a &&
|
|
364
412
|
buffer[7] === 0x0a
|
|
365
|
-
)
|
|
413
|
+
)
|
|
366
414
|
}
|
|
367
415
|
|
|
368
416
|
export function isPngWithFile(filepath) {
|
|
369
|
-
if (!isFileExist(filepath)) return false
|
|
370
|
-
const buf = fs.readFileSync(filepath)
|
|
371
|
-
return isPngWithBuffer(buf)
|
|
417
|
+
if (!isFileExist(filepath)) return false
|
|
418
|
+
const buf = fs.readFileSync(filepath)
|
|
419
|
+
return isPngWithBuffer(buf)
|
|
372
420
|
}
|
|
373
421
|
|
|
374
422
|
export function isDebugMode() {
|
|
375
|
-
return logger.getLevel() <= logger.levels.DEBUG
|
|
423
|
+
return logger.getLevel() <= logger.levels.DEBUG
|
|
376
424
|
}
|
|
377
425
|
|
|
378
426
|
export async function resolveDomain(domain) {
|
|
379
427
|
try {
|
|
380
428
|
// Set machine's dns server as defalut dns server
|
|
381
|
-
dns.setServers(["[fc03:1136:3800::1]"])
|
|
429
|
+
dns.setServers(["[fc03:1136:3800::1]"])
|
|
382
430
|
const [ipv6Addresses, ipv4Addresses] = await Promise.allSettled([
|
|
383
431
|
dns.resolve6(domain),
|
|
384
432
|
dns.resolve4(domain)
|
|
385
|
-
])
|
|
386
|
-
let resolvedAddress
|
|
387
|
-
if (
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
resolvedAddress =
|
|
433
|
+
])
|
|
434
|
+
let resolvedAddress
|
|
435
|
+
if (
|
|
436
|
+
ipv6Addresses.status === "fulfilled" &&
|
|
437
|
+
ipv6Addresses.value.length > 0
|
|
438
|
+
) {
|
|
439
|
+
resolvedAddress = ipv6Addresses.value[0]
|
|
440
|
+
} else if (
|
|
441
|
+
ipv4Addresses.status === "fulfilled" &&
|
|
442
|
+
ipv4Addresses.value.length > 0
|
|
443
|
+
) {
|
|
444
|
+
resolvedAddress = ipv4Addresses.value[0]
|
|
392
445
|
} else {
|
|
393
|
-
throw new Error(`无法解析域名 ${domain}`)
|
|
446
|
+
throw new Error(`无法解析域名 ${domain}`)
|
|
394
447
|
}
|
|
395
|
-
return resolvedAddress
|
|
448
|
+
return resolvedAddress
|
|
396
449
|
} catch (error) {
|
|
397
|
-
throw new Error(`无法解析域名 ${domain}: ${error.message}`)
|
|
450
|
+
throw new Error(`无法解析域名 ${domain}: ${error.message}`)
|
|
398
451
|
}
|
|
399
|
-
}
|
|
452
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazycatcloud/lzc-cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.29",
|
|
4
4
|
"description": "lazycat cloud developer kit",
|
|
5
5
|
"files": [
|
|
6
6
|
"template",
|
|
@@ -44,6 +44,12 @@
|
|
|
44
44
|
"@types/command-exists": "^1.2.3",
|
|
45
45
|
"prettier": "^3.3.3"
|
|
46
46
|
},
|
|
47
|
+
"prettier": {
|
|
48
|
+
"bracketSameLine": true,
|
|
49
|
+
"htmlWhitespaceSensitivity": "ignore",
|
|
50
|
+
"semi": false,
|
|
51
|
+
"trailingComma": "none"
|
|
52
|
+
},
|
|
47
53
|
"publishConfig": {
|
|
48
54
|
"registry": "https://registry.npmjs.org",
|
|
49
55
|
"access": "public"
|