mbler 0.2.4 → 0.2.7-rc.2
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/README.md +48 -41
- package/bin/mbler.js +3 -3
- package/bin/mcx-tsc.js +1 -1
- package/client.d.ts +17 -0
- package/dist/build.d.ts +18 -5
- package/dist/build.esm.mjs +834 -447
- package/dist/build.esm.mjs.map +1 -1
- package/dist/build.js +833 -447
- package/dist/build.js.map +1 -1
- package/dist/index.d.ts +22 -63
- package/dist/index.esm.mjs +665 -851
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.js +655 -839
- package/dist/index.js.map +1 -1
- package/dist/template/mcx/behavior/scripts/app.mcx +8 -5
- package/dist/template/mcx/behavior/scripts/component/ComponentTest.mcx +19 -0
- package/dist/template/mcx/behavior/scripts/config/config.json +5 -0
- package/dist/template/mcx/behavior/scripts/{event$1.mcx → event/event$1.mcx} +2 -3
- package/dist/template/mcx/behavior/scripts/event/event.mcx +10 -0
- package/dist/template/mcx/behavior/scripts/event/test.ts +3 -0
- package/dist/template/mcx/behavior/scripts/index.ts +5 -0
- package/dist/template/ts/behavior/scripts/index.ts +1 -1
- package/package.json +31 -20
- package/dist/template/mcx/behavior/pack_icon.png +0 -0
- package/dist/template/mcx/behavior/scripts/event.mcx +0 -9
- package/dist/template/mcx/behavior/scripts/index.mjs +0 -5
package/dist/index.esm.mjs
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
|
-
import { cwd,
|
|
2
|
-
import
|
|
3
|
-
import fs__default from 'node:fs';
|
|
1
|
+
import { cwd, env, argv } from 'node:process';
|
|
2
|
+
import fs$1 from 'node:fs';
|
|
4
3
|
import * as path from 'node:path';
|
|
5
4
|
import path__default from 'node:path';
|
|
6
5
|
import os, { homedir, tmpdir } from 'node:os';
|
|
7
6
|
import * as fs from 'node:fs/promises';
|
|
8
|
-
import fs__default
|
|
7
|
+
import fs__default, { readFile, writeFile, rm, stat, mkdir } from 'node:fs/promises';
|
|
9
8
|
import * as readline from 'readline';
|
|
10
|
-
import { json } from 'npm-registry-fetch';
|
|
11
9
|
import { spawn } from 'node:child_process';
|
|
12
|
-
import AdmZip from 'adm-zip';
|
|
13
10
|
|
|
14
11
|
const LanguageNames = ['zh', 'en'];
|
|
15
|
-
const cmdList = [
|
|
12
|
+
const cmdList = [
|
|
13
|
+
'c',
|
|
14
|
+
'work',
|
|
15
|
+
'help',
|
|
16
|
+
'h',
|
|
17
|
+
'init',
|
|
18
|
+
'version',
|
|
19
|
+
'build',
|
|
20
|
+
'watch',
|
|
21
|
+
'lang',
|
|
22
|
+
'set-work-dir',
|
|
23
|
+
'publish',
|
|
24
|
+
'unpublish',
|
|
25
|
+
'install',
|
|
26
|
+
'uninstall',
|
|
27
|
+
'login',
|
|
28
|
+
'profile',
|
|
29
|
+
'log',
|
|
30
|
+
'view',
|
|
31
|
+
'config',
|
|
32
|
+
];
|
|
16
33
|
const templateMblerConfig = {
|
|
17
34
|
name: 'demo',
|
|
18
35
|
description: 'demo',
|
|
@@ -29,36 +46,29 @@ const templateMblerConfig = {
|
|
|
29
46
|
},
|
|
30
47
|
build: {
|
|
31
48
|
rollupPlugins: [],
|
|
32
|
-
cache:
|
|
49
|
+
cache: 'auto',
|
|
33
50
|
bundle: true,
|
|
51
|
+
outputDir: 'scripts',
|
|
52
|
+
outputFilename: '',
|
|
34
53
|
onEnd: () => { },
|
|
35
54
|
onStart: () => { },
|
|
36
|
-
onWarn: () => { }
|
|
37
|
-
}
|
|
55
|
+
onWarn: () => { },
|
|
56
|
+
},
|
|
38
57
|
};
|
|
39
58
|
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
cmdList: cmdList,
|
|
44
|
-
templateMblerConfig: templateMblerConfig
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
var MBLERVersion = { commit: `commit 4329ae59e38d365d76d4e90049a1e7bbf6348d84
|
|
48
|
-
Author: Ruanhor <3915264929@qq.com>
|
|
49
|
-
Date: Fri May 1 14:39:53 2026 +0800
|
|
59
|
+
var MBLERVersion = { commit: `commit cf8b9a6e7e38c27c909b1352150a07a8ef36710b
|
|
60
|
+
Author: ruanhor <3915264929@qq.com>
|
|
61
|
+
Date: Mon May 25 22:52:51 2026 +0800
|
|
50
62
|
|
|
51
|
-
fix:
|
|
52
|
-
|
|
53
|
-
Co-authored-by: Copilot <copilot@github.com>
|
|
54
|
-
`, version: "0.2.4" };
|
|
63
|
+
fix: remove unused import
|
|
64
|
+
`, version: "0.2.7-rc.1" };
|
|
55
65
|
|
|
56
66
|
var ZhLang = {
|
|
57
67
|
description: `MBLER
|
|
58
68
|
Minecraft Bedrock Edition
|
|
59
69
|
Addon Bulider In Nodejs
|
|
60
70
|
在基岩版我的世界上的 nodejs 构建工具
|
|
61
|
-
命令 : ${cmdList.join(
|
|
71
|
+
命令 : ${cmdList.join(', ')}
|
|
62
72
|
帮助命令 :
|
|
63
73
|
help
|
|
64
74
|
显示帮助信息
|
|
@@ -67,16 +77,17 @@ Addon Bulider In Nodejs
|
|
|
67
77
|
git https://github.com/RuanhoR/mbler/`,
|
|
68
78
|
help: {
|
|
69
79
|
cmds: cmdList,
|
|
70
|
-
help:
|
|
71
|
-
h:
|
|
72
|
-
work:
|
|
73
|
-
c:
|
|
74
|
-
init:
|
|
75
|
-
build:
|
|
76
|
-
|
|
80
|
+
help: 'mbler [help/h] [?:查看的命令名称]\n - 查看帮助',
|
|
81
|
+
h: '$help',
|
|
82
|
+
work: 'mbler [work/c] [?:相对或绝对路径]\n - 没有输入路径:查询当前工作目录\n - 输入路径:设置工作目录',
|
|
83
|
+
c: '$work',
|
|
84
|
+
init: 'mbler init\n - 初始化当前工作目录,可使用 mbler work 指定工作目录或使用参数一次确定(例: mbler init -in ./)\n - 将会询问选项以完成初始化',
|
|
85
|
+
build: 'mbler build\n - 在工作目录执行构建',
|
|
86
|
+
log: 'mbler log\n - 处理日志文件\n - mbler log point: 得到日志文件路径 \n - mbler log clean: 清除日志',
|
|
87
|
+
watch: 'mbler watch\n - 启动构建并开启监视模式,文件变化会自动重新构建',
|
|
77
88
|
lang: 'mbler lang\n- 无参数:显示当前语言\n- 跟 zh 或 en(如 mbler lang en): 设置语言',
|
|
78
|
-
version:
|
|
79
|
-
'set-work-dir':
|
|
89
|
+
version: 'mbler version - 版本管理命令\n- 无参数:显示当前版本和提交哈希\n- --show=<commit|version>:筛选显示内容\n- <新版本号>:更新package.json和配置文件的版本',
|
|
90
|
+
'set-work-dir': 'mbler set-work-dir <on|off>\n - on: 启用工作目录功能\n - off: 禁用工作目录功能,直接使用 process.cwd()',
|
|
80
91
|
publish: 'mbler publish\n - 将你的附加包发布到 pmnx\n- 参数:\n- -tag: 版本标签名称\n- -build <skip|always>: 是否跳过构建(默认 always)',
|
|
81
92
|
uninstall: 'mbler uninstall @<scope>/<name>@version\n从你的游戏中移除一个包',
|
|
82
93
|
install: 'mbler install @<scope>/<name>@version\n将一个包安装到你的游戏中',
|
|
@@ -84,94 +95,97 @@ git https://github.com/RuanhoR/mbler/`,
|
|
|
84
95
|
login: 'mbler login <?:token>\n使用 token 登录你的 pmnx 账户\n- 如果没有 token,会向你请求',
|
|
85
96
|
profile: 'mbler profile\n显示当前登录账户信息',
|
|
86
97
|
view: 'mbler view @<scope>/<name>\n查看包的版本列表',
|
|
87
|
-
config: 'mbler config get <key>\nmbler config set <key> <value>\nmbler config point <path>\nmbler config point get'
|
|
98
|
+
config: 'mbler config get <key>\nmbler config set <key> <value>\nmbler config point <path>\nmbler config point get',
|
|
88
99
|
},
|
|
89
100
|
init: {
|
|
90
101
|
useUI: '使用UI模块? (y/n): ',
|
|
91
102
|
useGIT: '初始化GIT仓库? (y/n): ',
|
|
92
103
|
name: '项目名称: ',
|
|
93
104
|
welcome: '欢迎使用Mbler初始化向导 语言:中文 mbler 版本: ' + MBLERVersion.version,
|
|
94
|
-
description:
|
|
95
|
-
initDes:
|
|
96
|
-
lang:
|
|
97
|
-
betaApi:
|
|
98
|
-
mcVersion:
|
|
99
|
-
noLanguare:
|
|
100
|
-
noName:
|
|
101
|
-
noMCVersion: "输入的 '支持的mc版本' 格式不对"
|
|
105
|
+
description: '项目描述: ',
|
|
106
|
+
initDes: '初始化依赖? (y/n): ',
|
|
107
|
+
lang: '选择项目语言: ',
|
|
108
|
+
betaApi: '使用Beta Api? (y/n): ',
|
|
109
|
+
mcVersion: '项目使用的mc版本(x.x.x): ',
|
|
110
|
+
noLanguare: '没有输入项目语言,这是必要的',
|
|
111
|
+
noName: '没有项目名称,这是必要的',
|
|
112
|
+
noMCVersion: "输入的 '支持的mc版本' 格式不对",
|
|
102
113
|
},
|
|
103
114
|
default: {
|
|
104
|
-
unexpected:
|
|
105
|
-
youis:
|
|
115
|
+
unexpected: '不正确的命令,',
|
|
116
|
+
youis: '你是否想说: ',
|
|
106
117
|
},
|
|
107
118
|
workdir: {
|
|
108
|
-
set:
|
|
109
|
-
nfound:
|
|
110
|
-
disabled:
|
|
111
|
-
enabled:
|
|
112
|
-
invalidParam:
|
|
119
|
+
set: '[工作目录] 设置为: ',
|
|
120
|
+
nfound: '找不到输入文件夹(无法创建或不是文件夹)',
|
|
121
|
+
disabled: '工作目录功能已禁用,将使用当前目录',
|
|
122
|
+
enabled: '工作目录功能已启用',
|
|
123
|
+
invalidParam: '参数错误,请使用 on 或 off',
|
|
113
124
|
},
|
|
114
125
|
publish: {
|
|
115
|
-
askTip:
|
|
116
|
-
notLoggedIn:
|
|
117
|
-
progress:
|
|
118
|
-
publishFailed:
|
|
119
|
-
publishing:
|
|
120
|
-
building:
|
|
121
|
-
publishToMarket:
|
|
122
|
-
publishSuccess:
|
|
123
|
-
publishResult:
|
|
124
|
-
projectPathNotExist:
|
|
125
|
-
outdirNotFound:
|
|
126
|
-
outdirNotExist:
|
|
127
|
-
readmeNotFound:
|
|
128
|
-
metadataInvalid:
|
|
129
|
-
packageNameInvalid:
|
|
130
|
-
notLoginError:
|
|
131
|
-
tokenMissing:
|
|
132
|
-
unpublishReqFailed:
|
|
133
|
-
createSessionFailed:
|
|
134
|
-
uploadZipFailed:
|
|
135
|
-
packageJsonNotFound:
|
|
136
|
-
noBuildScript:
|
|
137
|
-
buildFailed:
|
|
126
|
+
askTip: '输入MCBE游戏绝对目录 (如 /sdcard/Android/data/com.mojang.minecraftpe/files/games),以进行下一步: ',
|
|
127
|
+
notLoggedIn: '未登录,请先执行 `mbler login <token>`',
|
|
128
|
+
progress: '进度: {progress}%',
|
|
129
|
+
publishFailed: '发布失败: {error}',
|
|
130
|
+
publishing: '正在发布...',
|
|
131
|
+
building: '正在构建项目...',
|
|
132
|
+
publishToMarket: '正在上传到市场...',
|
|
133
|
+
publishSuccess: '发布成功',
|
|
134
|
+
publishResult: '+ {name}@{version} ({tag})',
|
|
135
|
+
projectPathNotExist: '项目路径不存在',
|
|
136
|
+
outdirNotFound: '未找到构建输出目录配置',
|
|
137
|
+
outdirNotExist: '构建输出目录不存在',
|
|
138
|
+
readmeNotFound: '未找到 README 文件',
|
|
139
|
+
metadataInvalid: '元数据无效',
|
|
140
|
+
packageNameInvalid: '包名格式必须是 @scope/name',
|
|
141
|
+
notLoginError: '未登录',
|
|
142
|
+
tokenMissing: '获取 token 失败',
|
|
143
|
+
unpublishReqFailed: '取消发布请求失败',
|
|
144
|
+
createSessionFailed: '创建发布会话失败',
|
|
145
|
+
uploadZipFailed: '上传 zip 文件失败',
|
|
146
|
+
packageJsonNotFound: '未找到 package.json',
|
|
147
|
+
noBuildScript: 'package.json 中未找到 build 脚本',
|
|
148
|
+
buildFailed: '构建失败,退出码: {code}',
|
|
138
149
|
},
|
|
139
150
|
install: {
|
|
140
|
-
failedNoPackageJson:
|
|
141
|
-
failedNoBuildScript:
|
|
142
|
-
installing:
|
|
143
|
-
packageNotFound:
|
|
144
|
-
noVersion:
|
|
145
|
-
usingLatest:
|
|
146
|
-
noValidAddon:
|
|
147
|
-
success:
|
|
148
|
-
failed:
|
|
151
|
+
failedNoPackageJson: '安装失败:工作目录必须包含 package.json',
|
|
152
|
+
failedNoBuildScript: '安装失败:package.json 必须包含 build 脚本',
|
|
153
|
+
installing: '正在安装包 {pkg}...',
|
|
154
|
+
packageNotFound: '未找到包 {pkg}',
|
|
155
|
+
noVersion: '包 {pkg} 没有可用版本',
|
|
156
|
+
usingLatest: '使用最新版本 {version}',
|
|
157
|
+
noValidAddon: '包内未找到有效 addon',
|
|
158
|
+
success: '包 {pkg}@{version} 已安装为 {id}',
|
|
159
|
+
failed: '安装失败: {error}',
|
|
149
160
|
},
|
|
150
161
|
uninstall: {
|
|
151
|
-
success:
|
|
152
|
-
failed:
|
|
162
|
+
success: '包 {pkg}@{version} 卸载成功',
|
|
163
|
+
failed: '卸载失败: {error}',
|
|
153
164
|
},
|
|
154
165
|
unpublish: {
|
|
155
|
-
success:
|
|
156
|
-
failed:
|
|
166
|
+
success: '包 {pkg}@{version} 取消发布成功',
|
|
167
|
+
failed: '取消发布失败: {error}',
|
|
157
168
|
},
|
|
158
169
|
view: {
|
|
159
|
-
usage:
|
|
160
|
-
packageNotFound:
|
|
161
|
-
title:
|
|
162
|
-
versionLine:
|
|
163
|
-
failed:
|
|
170
|
+
usage: 'mbler view @<scope>/<name>',
|
|
171
|
+
packageNotFound: '未找到包 {pkg}',
|
|
172
|
+
title: '包 {pkg} 版本列表:',
|
|
173
|
+
versionLine: '- {version} [{tag}] by {user} at {time}',
|
|
174
|
+
failed: '查看失败: {error}',
|
|
164
175
|
},
|
|
165
176
|
config: {
|
|
166
|
-
usage:
|
|
167
|
-
missingArg:
|
|
168
|
-
getResult:
|
|
169
|
-
setSuccess:
|
|
170
|
-
pointGet:
|
|
171
|
-
pointSetSuccess:
|
|
172
|
-
pointSetFailed:
|
|
173
|
-
failed:
|
|
174
|
-
}
|
|
177
|
+
usage: 'mbler config get <key> | set <key> <value> | point <path> | point get',
|
|
178
|
+
missingArg: '参数不足',
|
|
179
|
+
getResult: '{key} = {value}',
|
|
180
|
+
setSuccess: '已设置 {key} = {value}',
|
|
181
|
+
pointGet: '当前配置文件: {path}',
|
|
182
|
+
pointSetSuccess: '配置文件指向已设置为: {path}',
|
|
183
|
+
pointSetFailed: '配置文件指向设置失败: {error}',
|
|
184
|
+
failed: '配置操作失败: {error}',
|
|
185
|
+
},
|
|
186
|
+
commander: {
|
|
187
|
+
selectTip: '(按 b 确认,n 键选择下一个)',
|
|
188
|
+
},
|
|
175
189
|
};
|
|
176
190
|
|
|
177
191
|
var enLang = {
|
|
@@ -187,10 +201,11 @@ var enLang = {
|
|
|
187
201
|
init: 'mbler init\n - Init current work dir, you can use `mbler work` command or use command param(like be: mbler init -in ./)',
|
|
188
202
|
build: 'mbler build\n - perform a build using the library API',
|
|
189
203
|
b: '$build',
|
|
204
|
+
log: 'mbler log\n - Handler log file\n - mbler log point: Get log file path \n - mbler log clean: Remove Log',
|
|
190
205
|
watch: 'mbler watch\n - run build and enter watch mode; changes will trigger rebuilds',
|
|
191
|
-
lang: 'mbler lang [?:
|
|
206
|
+
lang: 'mbler lang [?:language]\n- No args: show current language\n- language = "zh” | “en": set language',
|
|
192
207
|
version: 'mbler version\n - Version control command\n- No args: Shows version + commit hash\n- --show=<commit|version>: Filters output\n- <new_version>: Updates version in both package.json and config file',
|
|
193
|
-
'set-work-dir':
|
|
208
|
+
'set-work-dir': 'mbler set-work-dir <on|off>\n - on: Enable work dir feature\n - off: Disable work dir feature, use process.cwd() directly',
|
|
194
209
|
publish: 'mbler publish\n - Publish your package to pmnx\n- Params:\n- -tag: version tag name\n- -build <skip|always>: skip or run build before publish (default: always)',
|
|
195
210
|
uninstall: 'mbler uninstall @<scope>/<name>@version\nRemove a package from your game',
|
|
196
211
|
install: 'mbler install @<scope>/<name>@version\nInstall a package to your game',
|
|
@@ -198,21 +213,22 @@ var enLang = {
|
|
|
198
213
|
login: 'mbler login <?:token>\nUse token login your pmnx account',
|
|
199
214
|
profile: 'mbler profile\nShow current logged-in account profile',
|
|
200
215
|
view: 'mbler view @<scope>/<name>\nShow package versions',
|
|
201
|
-
config: 'mbler config get <key>\nmbler config set <key> <value>\nmbler config point <path>\nmbler config point get'
|
|
216
|
+
config: 'mbler config get <key>\nmbler config set <key> <value>\nmbler config point <path>\nmbler config point get',
|
|
202
217
|
},
|
|
203
218
|
init: {
|
|
204
219
|
useUI: 'Use UI? (y/n): ',
|
|
205
220
|
useGIT: 'Initialize GIT repository? (y/n): ',
|
|
206
221
|
name: 'Project name: ',
|
|
207
|
-
description:
|
|
208
|
-
initDes:
|
|
209
|
-
welcome: 'Welcome to use Mbler init wizard! Language: English mbler version: ' +
|
|
210
|
-
|
|
211
|
-
|
|
222
|
+
description: 'Project description: ',
|
|
223
|
+
initDes: 'Initialize dependencies? (y/n): ',
|
|
224
|
+
welcome: 'Welcome to use Mbler init wizard! Language: English mbler version: ' +
|
|
225
|
+
MBLERVersion.version,
|
|
226
|
+
lang: 'Project language: ',
|
|
227
|
+
betaApi: 'use beta api(y/n): ',
|
|
212
228
|
mcVersion: 'Minecraft version(be like: x.x.x): ',
|
|
213
|
-
noLanguare: 'project
|
|
214
|
-
noMCVersion:
|
|
215
|
-
noName:
|
|
229
|
+
noLanguare: 'project language is required',
|
|
230
|
+
noMCVersion: 'project mcVersion format is not right',
|
|
231
|
+
noName: 'project name is required',
|
|
216
232
|
},
|
|
217
233
|
default: {
|
|
218
234
|
unexpected: 'Not found this command,',
|
|
@@ -221,101 +237,105 @@ var enLang = {
|
|
|
221
237
|
workdir: {
|
|
222
238
|
set: '[path to]: ',
|
|
223
239
|
nfound: "not found this dir(can't create or not directory)",
|
|
224
|
-
disabled:
|
|
225
|
-
enabled:
|
|
226
|
-
invalidParam:
|
|
240
|
+
disabled: 'Work dir disabled, will use current directory',
|
|
241
|
+
enabled: 'Work dir enabled',
|
|
242
|
+
invalidParam: 'Invalid parameter, use on or off',
|
|
227
243
|
},
|
|
228
244
|
publish: {
|
|
229
|
-
askTip:
|
|
230
|
-
notLoggedIn:
|
|
231
|
-
progress:
|
|
232
|
-
publishFailed:
|
|
233
|
-
publishing:
|
|
234
|
-
building:
|
|
235
|
-
publishToMarket:
|
|
236
|
-
publishSuccess:
|
|
237
|
-
publishResult:
|
|
238
|
-
projectPathNotExist:
|
|
239
|
-
outdirNotFound:
|
|
240
|
-
outdirNotExist:
|
|
241
|
-
readmeNotFound:
|
|
242
|
-
metadataInvalid:
|
|
243
|
-
packageNameInvalid:
|
|
244
|
-
notLoginError:
|
|
245
|
-
tokenMissing:
|
|
246
|
-
unpublishReqFailed:
|
|
247
|
-
createSessionFailed:
|
|
248
|
-
uploadZipFailed:
|
|
249
|
-
packageJsonNotFound:
|
|
250
|
-
noBuildScript:
|
|
251
|
-
buildFailed:
|
|
245
|
+
askTip: 'Plase input the absolute path of your MCBE game directory (like /sdcard/Android/data/com.mojang.minecraftpe/files/games) for next step: ',
|
|
246
|
+
notLoggedIn: 'Not logged in. Use `mbler login <token>` first.',
|
|
247
|
+
progress: 'Progress: {progress}%',
|
|
248
|
+
publishFailed: 'Publish failed: {error}',
|
|
249
|
+
publishing: 'Publishing...',
|
|
250
|
+
building: 'Building project...',
|
|
251
|
+
publishToMarket: 'Publishing to marketplace...',
|
|
252
|
+
publishSuccess: 'Publish successful',
|
|
253
|
+
publishResult: '+ {name}@{version} ({tag})',
|
|
254
|
+
projectPathNotExist: 'Project path does not exist',
|
|
255
|
+
outdirNotFound: 'Build output directories not found',
|
|
256
|
+
outdirNotExist: 'Build output directories do not exist',
|
|
257
|
+
readmeNotFound: 'README file not found',
|
|
258
|
+
metadataInvalid: 'Invalid metadata',
|
|
259
|
+
packageNameInvalid: 'Package name must be in the format of @scope/name',
|
|
260
|
+
notLoginError: 'Not logged in',
|
|
261
|
+
tokenMissing: 'Failed to get token',
|
|
262
|
+
unpublishReqFailed: 'Failed to unpublish package',
|
|
263
|
+
createSessionFailed: 'Failed to create publish session',
|
|
264
|
+
uploadZipFailed: 'Failed to upload zip file',
|
|
265
|
+
packageJsonNotFound: 'package.json not found',
|
|
266
|
+
noBuildScript: 'No build script found in package.json',
|
|
267
|
+
buildFailed: 'Build failed with code {code}',
|
|
252
268
|
},
|
|
253
269
|
install: {
|
|
254
|
-
failedNoPackageJson:
|
|
255
|
-
failedNoBuildScript:
|
|
256
|
-
installing:
|
|
257
|
-
packageNotFound:
|
|
258
|
-
noVersion:
|
|
259
|
-
usingLatest:
|
|
260
|
-
noValidAddon:
|
|
261
|
-
success:
|
|
262
|
-
failed:
|
|
270
|
+
failedNoPackageJson: 'Install failed: work directory must contain package.json',
|
|
271
|
+
failedNoBuildScript: 'Install failed: package.json must contain a build script',
|
|
272
|
+
installing: 'Installing package {pkg}...',
|
|
273
|
+
packageNotFound: 'Package {pkg} not found',
|
|
274
|
+
noVersion: 'Package {pkg} has no available version',
|
|
275
|
+
usingLatest: 'Using latest version {version}',
|
|
276
|
+
noValidAddon: 'No valid addon found in package',
|
|
277
|
+
success: 'Package {pkg}@{version} installed successfully as {id}',
|
|
278
|
+
failed: 'Install failed: {error}',
|
|
263
279
|
},
|
|
264
280
|
uninstall: {
|
|
265
|
-
success:
|
|
266
|
-
failed:
|
|
281
|
+
success: 'Package {pkg}@{version} uninstalled successfully',
|
|
282
|
+
failed: 'Uninstall failed: {error}',
|
|
267
283
|
},
|
|
268
284
|
unpublish: {
|
|
269
|
-
success:
|
|
270
|
-
failed:
|
|
285
|
+
success: 'Package {pkg}@{version} unpublished successfully',
|
|
286
|
+
failed: 'Unpublish failed: {error}',
|
|
271
287
|
},
|
|
272
288
|
view: {
|
|
273
|
-
usage:
|
|
274
|
-
packageNotFound:
|
|
275
|
-
title:
|
|
276
|
-
versionLine:
|
|
277
|
-
failed:
|
|
289
|
+
usage: 'mbler view @<scope>/<name>',
|
|
290
|
+
packageNotFound: 'Package {pkg} not found',
|
|
291
|
+
title: 'Package {pkg} versions:',
|
|
292
|
+
versionLine: '- {version} [{tag}] by {user} at {time}',
|
|
293
|
+
failed: 'View failed: {error}',
|
|
278
294
|
},
|
|
279
295
|
config: {
|
|
280
|
-
usage:
|
|
281
|
-
missingArg:
|
|
282
|
-
getResult:
|
|
283
|
-
setSuccess:
|
|
284
|
-
pointGet:
|
|
285
|
-
pointSetSuccess:
|
|
286
|
-
pointSetFailed:
|
|
287
|
-
failed:
|
|
288
|
-
}
|
|
296
|
+
usage: 'mbler config get <key> | set <key> <value> | point <path> | point get',
|
|
297
|
+
missingArg: 'Missing argument',
|
|
298
|
+
getResult: '{key} = {value}',
|
|
299
|
+
setSuccess: 'Set {key} = {value}',
|
|
300
|
+
pointGet: 'Current config file: {path}',
|
|
301
|
+
pointSetSuccess: 'Config file pointer set to: {path}',
|
|
302
|
+
pointSetFailed: 'Failed to set config pointer: {error}',
|
|
303
|
+
failed: 'Config command failed: {error}',
|
|
304
|
+
},
|
|
305
|
+
commander: {
|
|
306
|
+
selectTip: '(Press b to confirm, n to select next)',
|
|
307
|
+
},
|
|
289
308
|
};
|
|
290
309
|
|
|
291
|
-
const configPath = path__default.join(homedir(),
|
|
310
|
+
const configPath = path__default.join(homedir(), // ~/.cache/mbler/lang.db: push language config
|
|
311
|
+
'.cache/mbler/lang.db');
|
|
292
312
|
function isLanguareName(language) {
|
|
293
313
|
return LanguageNames.includes(language);
|
|
294
314
|
}
|
|
295
315
|
class Lang {
|
|
296
|
-
currenyLang =
|
|
316
|
+
currenyLang = 'zh';
|
|
297
317
|
init() {
|
|
298
318
|
try {
|
|
299
|
-
const TheyLang =
|
|
319
|
+
const TheyLang = fs$1.readFileSync(configPath, 'utf-8').toString().trim();
|
|
300
320
|
if (isLanguareName(TheyLang)) {
|
|
301
321
|
this.currenyLang = TheyLang;
|
|
302
322
|
}
|
|
303
323
|
else {
|
|
304
|
-
throw new Error(
|
|
324
|
+
throw new Error('[setup lang]: set lang error');
|
|
305
325
|
}
|
|
306
326
|
}
|
|
307
327
|
catch {
|
|
308
|
-
this.currenyLang =
|
|
328
|
+
this.currenyLang = 'zh';
|
|
309
329
|
}
|
|
310
330
|
}
|
|
311
331
|
set(newLang) {
|
|
312
332
|
if (LanguageNames.includes(newLang)) {
|
|
313
|
-
if (!
|
|
314
|
-
|
|
333
|
+
if (!fs$1.existsSync(configPath)) {
|
|
334
|
+
fs$1.mkdirSync(path__default.dirname(configPath), {
|
|
315
335
|
recursive: true,
|
|
316
336
|
});
|
|
317
337
|
}
|
|
318
|
-
|
|
338
|
+
fs$1.writeFileSync(configPath, newLang);
|
|
319
339
|
this.currenyLang = newLang;
|
|
320
340
|
return true;
|
|
321
341
|
}
|
|
@@ -323,7 +343,7 @@ class Lang {
|
|
|
323
343
|
}
|
|
324
344
|
get() {
|
|
325
345
|
try {
|
|
326
|
-
if (this.currenyLang ==
|
|
346
|
+
if (this.currenyLang == 'zh')
|
|
327
347
|
return ZhLang;
|
|
328
348
|
return enLang;
|
|
329
349
|
}
|
|
@@ -333,10 +353,9 @@ class Lang {
|
|
|
333
353
|
}
|
|
334
354
|
}
|
|
335
355
|
const lang = new Lang();
|
|
336
|
-
|
|
356
|
+
const i18n = {};
|
|
337
357
|
function Export(lang) {
|
|
338
358
|
const obj = lang.get();
|
|
339
|
-
// 用原型来让导入后切换语言不需要再次导入,相同引用
|
|
340
359
|
Object.setPrototypeOf(i18n, {
|
|
341
360
|
...obj,
|
|
342
361
|
__internal: {
|
|
@@ -351,47 +370,106 @@ function Export(lang) {
|
|
|
351
370
|
lang.init();
|
|
352
371
|
Export(lang);
|
|
353
372
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
373
|
+
const logFile = path__default.join(os.homedir(), '.cache/mbler/latest.log');
|
|
374
|
+
function _clean(promise) {
|
|
375
|
+
return () => {
|
|
376
|
+
Logger.run = Logger.run.filter((item) => {
|
|
377
|
+
return item !== promise;
|
|
378
|
+
});
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
async function FileExsit$1(file) {
|
|
382
|
+
try {
|
|
383
|
+
const f = await fs__default.stat(file);
|
|
384
|
+
if (f)
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
function writeLog(logContent) {
|
|
393
|
+
async function write() {
|
|
394
|
+
try {
|
|
395
|
+
const dir = path__default.dirname(logFile);
|
|
396
|
+
if (!(await FileExsit$1(dir))) {
|
|
397
|
+
// ensure the directory exists, root-to-leaf
|
|
398
|
+
await fs__default.mkdir(dir, { recursive: true }).catch(() => void 0);
|
|
399
|
+
}
|
|
400
|
+
// if file does not exist, create it (touch)
|
|
401
|
+
if (!(await FileExsit$1(logFile))) {
|
|
402
|
+
await fs__default.writeFile(logFile, '');
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
catch (err) {
|
|
406
|
+
// if we can't prepare the log file, output to stderr but don't crash
|
|
407
|
+
console.error('[logger] unable to prepare log file:', err);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
await fs__default.appendFile(logFile, '\n' + logContent);
|
|
412
|
+
}
|
|
413
|
+
catch (err) {
|
|
414
|
+
console.error('[logger] failed to append to log file:', err);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
const asy = write();
|
|
418
|
+
Logger.run.push(asy.then(_clean(asy)));
|
|
419
|
+
}
|
|
420
|
+
class Logger {
|
|
421
|
+
static LogFile = logFile;
|
|
422
|
+
static run = [];
|
|
423
|
+
static _b(tag, msg, t) {
|
|
424
|
+
const date = new Date();
|
|
425
|
+
const logContent = [
|
|
426
|
+
`${date.toLocaleDateString()} ${date.toLocaleTimeString()}`,
|
|
427
|
+
`[${t} ${tag}]`,
|
|
428
|
+
msg,
|
|
429
|
+
].join(' ');
|
|
430
|
+
writeLog(logContent);
|
|
431
|
+
}
|
|
432
|
+
static w(tag, msg) {
|
|
433
|
+
Logger._b(tag, msg, 'WARN');
|
|
434
|
+
}
|
|
435
|
+
static e(tag, msg) {
|
|
436
|
+
Logger._b(tag, msg, 'ERROR');
|
|
437
|
+
}
|
|
438
|
+
static i(tag, msg) {
|
|
439
|
+
Logger._b(tag, msg, 'INFO');
|
|
440
|
+
}
|
|
441
|
+
static d(tag, msg) {
|
|
442
|
+
Logger._b(tag, msg, 'DEBUG');
|
|
443
|
+
}
|
|
444
|
+
}
|
|
358
445
|
|
|
359
|
-
// 启用 raw mode 和键盘事件(仅在 TTY 环境中)
|
|
360
446
|
if (process.stdin.isTTY) {
|
|
361
447
|
process.stdin.setRawMode(true);
|
|
362
448
|
readline.emitKeypressEvents(process.stdin);
|
|
363
449
|
}
|
|
364
450
|
const promises = [];
|
|
365
451
|
const tasks = [];
|
|
366
|
-
process.on(
|
|
367
|
-
process.stdout.write(
|
|
452
|
+
process.on('exit', (_code) => {
|
|
453
|
+
process.stdout.write('\x1b[?25h');
|
|
368
454
|
});
|
|
369
455
|
const endTasks = [];
|
|
370
456
|
function onEnd(task) {
|
|
371
457
|
endTasks.push(task);
|
|
372
458
|
}
|
|
373
|
-
click(
|
|
459
|
+
click('c', {
|
|
374
460
|
ctrl: true,
|
|
375
461
|
}).then(() => {
|
|
376
462
|
endTasks.forEach((task) => task());
|
|
377
463
|
process.exit(0);
|
|
378
464
|
});
|
|
379
|
-
/**
|
|
380
|
-
* 监听键盘输入并触发对应的 Promise 或任务
|
|
381
|
-
*/
|
|
382
465
|
function handler(name, { ctrl, alt, }, raw) {
|
|
383
|
-
// 查找是否有匹配的 Promise 等待触发
|
|
384
466
|
const find = promises.find((e) => e.name === name && e.ctrl === ctrl && e.alt === alt);
|
|
385
467
|
if (find) {
|
|
386
468
|
find.resolve();
|
|
387
469
|
promises.splice(promises.indexOf(find), 1);
|
|
388
470
|
}
|
|
389
|
-
// 通知所有注册的监听任务
|
|
390
471
|
tasks.forEach((item) => item(name, ctrl, alt, raw));
|
|
391
472
|
}
|
|
392
|
-
/**
|
|
393
|
-
* 模拟等待某个按键被按下,返回一个 Promise
|
|
394
|
-
*/
|
|
395
473
|
function click(name, { ctrl = false, alt = false, }) {
|
|
396
474
|
return new Promise((resolve) => {
|
|
397
475
|
promises.push({
|
|
@@ -402,36 +480,21 @@ function click(name, { ctrl = false, alt = false, }) {
|
|
|
402
480
|
});
|
|
403
481
|
});
|
|
404
482
|
}
|
|
405
|
-
/**
|
|
406
|
-
* 工具类:提供控制台交互功能,比如高亮菜单渲染、交互式选择等
|
|
407
|
-
*/
|
|
408
483
|
class Input {
|
|
409
|
-
/**
|
|
410
|
-
* 渲染一个字符串数组,高亮当前选中的项
|
|
411
|
-
* @param arr 菜单项数组
|
|
412
|
-
* @param index 当前选中索引
|
|
413
|
-
* @returns 格式化后的字符串
|
|
414
|
-
*/
|
|
415
484
|
static render(arr, index) {
|
|
416
485
|
return arr
|
|
417
486
|
.map((item, pindex) => {
|
|
418
487
|
if (pindex === index)
|
|
419
|
-
return
|
|
420
|
-
return
|
|
488
|
+
return '\x1b[1m\x1b[32m' + item + '\x1b[0m'; // 亮绿,高亮
|
|
489
|
+
return '\x1b[1m\x1b[33m' + item + '\x1b[0m'; // 亮黄
|
|
421
490
|
})
|
|
422
|
-
.join(
|
|
491
|
+
.join(' ');
|
|
423
492
|
}
|
|
424
|
-
/**
|
|
425
|
-
* 提供一个交互式菜单选择器
|
|
426
|
-
* @param tip 提示文本
|
|
427
|
-
* @param arr 选项数组
|
|
428
|
-
* @returns 用户选中的选项内容(Promise<string>)
|
|
429
|
-
*/
|
|
430
493
|
static select(tip, arr) {
|
|
431
494
|
let index = 0;
|
|
432
495
|
let win = false;
|
|
433
|
-
console.log(`\x1b[2K\x1b[47m\x1b[1m\x1b[30m${tip}
|
|
434
|
-
console.log(Input.render(arr, index) +
|
|
496
|
+
console.log(`\x1b[2K\x1b[47m\x1b[1m\x1b[30m${tip} ${i18n.commander.selectTip} \x1b[0m\x1b[?25l`);
|
|
497
|
+
console.log(Input.render(arr, index) + '\n\x1b[1A');
|
|
435
498
|
const handlerNext = () => {
|
|
436
499
|
if (win)
|
|
437
500
|
return;
|
|
@@ -439,39 +502,32 @@ class Input {
|
|
|
439
502
|
if (index >= arr.length)
|
|
440
503
|
index = 0;
|
|
441
504
|
console.log(`\x1b[1A${Input.render(arr, index)}\n\x1b[1A`);
|
|
442
|
-
click(
|
|
505
|
+
click('n', {
|
|
443
506
|
ctrl: false,
|
|
444
507
|
alt: false,
|
|
445
508
|
}).then(handlerNext);
|
|
446
509
|
};
|
|
447
510
|
return new Promise((resolve) => {
|
|
448
|
-
|
|
449
|
-
click("n", {
|
|
511
|
+
click('n', {
|
|
450
512
|
ctrl: false,
|
|
451
513
|
alt: false,
|
|
452
514
|
}).then(handlerNext);
|
|
453
|
-
|
|
454
|
-
click("b", {
|
|
515
|
+
click('b', {
|
|
455
516
|
ctrl: false,
|
|
456
517
|
alt: false,
|
|
457
518
|
}).then(() => {
|
|
458
519
|
win = true;
|
|
459
|
-
process.stdout.write(
|
|
520
|
+
process.stdout.write('\x1b[?25h');
|
|
460
521
|
resolve(arr[index]);
|
|
461
522
|
});
|
|
462
523
|
});
|
|
463
524
|
}
|
|
464
|
-
/**
|
|
465
|
-
* 注册一个全局任务,每次按键都会被调用
|
|
466
|
-
* @param task 回调函数
|
|
467
|
-
*/
|
|
468
525
|
static use(task) {
|
|
469
526
|
tasks.push(task);
|
|
470
527
|
}
|
|
471
528
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
const rawKeyName = key?.name || "";
|
|
529
|
+
process.stdin.on('keypress', (str, key) => {
|
|
530
|
+
const rawKeyName = key?.name || '';
|
|
475
531
|
const ctrl = Boolean(key?.ctrl);
|
|
476
532
|
const alt = Boolean(key?.alt);
|
|
477
533
|
handler(rawKeyName, {
|
|
@@ -488,7 +544,7 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
488
544
|
});
|
|
489
545
|
|
|
490
546
|
const BuildConfig = {
|
|
491
|
-
ConfigFile:
|
|
547
|
+
ConfigFile: 'mbler.config.js'};
|
|
492
548
|
|
|
493
549
|
async function FileExsit(file) {
|
|
494
550
|
try {
|
|
@@ -509,7 +565,26 @@ async function ReadProjectMblerConfig(project) {
|
|
|
509
565
|
throw new Error(`[read config]: read config from '${project}' error: Unexpected '${key}'`);
|
|
510
566
|
}
|
|
511
567
|
}
|
|
512
|
-
|
|
568
|
+
const config = {
|
|
569
|
+
...templateMblerConfig,
|
|
570
|
+
...file,
|
|
571
|
+
};
|
|
572
|
+
try {
|
|
573
|
+
const pkgRaw = await fs.readFile(path.join(project, 'package.json'), 'utf-8');
|
|
574
|
+
const pkg = JSON.parse(pkgRaw);
|
|
575
|
+
if (pkg.name)
|
|
576
|
+
config.name = pkg.name;
|
|
577
|
+
if (pkg.version)
|
|
578
|
+
config.version = pkg.version;
|
|
579
|
+
}
|
|
580
|
+
catch {
|
|
581
|
+
// fallback to mbler.config.js or template defaults
|
|
582
|
+
}
|
|
583
|
+
if (!config.name)
|
|
584
|
+
config.name = 'unknown';
|
|
585
|
+
if (!config.version)
|
|
586
|
+
config.version = '0.0.0';
|
|
587
|
+
return config;
|
|
513
588
|
}
|
|
514
589
|
async function readFileAsJson(filePath) {
|
|
515
590
|
try {
|
|
@@ -522,7 +597,7 @@ async function readFileAsJson(filePath) {
|
|
|
522
597
|
throw err;
|
|
523
598
|
}
|
|
524
599
|
else {
|
|
525
|
-
throw new Error(err);
|
|
600
|
+
throw new Error(err, { cause: err });
|
|
526
601
|
}
|
|
527
602
|
}
|
|
528
603
|
}
|
|
@@ -531,7 +606,6 @@ async function readFileAsJson(filePath) {
|
|
|
531
606
|
* Exported here so other modules (for example `build`) do not need
|
|
532
607
|
* to import from `cli`, avoiding a circular dependency.
|
|
533
608
|
*/
|
|
534
|
-
// IO缓冲队列,避免多线程写入冲突
|
|
535
609
|
let outputQueue = [];
|
|
536
610
|
let isFlushing = false;
|
|
537
611
|
async function flushOutputQueue() {
|
|
@@ -550,11 +624,13 @@ async function flushOutputQueue() {
|
|
|
550
624
|
isFlushing = false;
|
|
551
625
|
}
|
|
552
626
|
}
|
|
553
|
-
process.on(
|
|
627
|
+
process.on('exit', flushOutputQueue);
|
|
554
628
|
function showText(text, needNextLine = true) {
|
|
555
|
-
outputQueue.push(text + (needNextLine ? '\n' :
|
|
629
|
+
outputQueue.push(text + (needNextLine ? '\n' : ''));
|
|
556
630
|
if (!isFlushing) {
|
|
557
|
-
Promise.resolve()
|
|
631
|
+
Promise.resolve()
|
|
632
|
+
.then(() => flushOutputQueue())
|
|
633
|
+
.catch(() => {
|
|
558
634
|
outputQueue = [];
|
|
559
635
|
isFlushing = false;
|
|
560
636
|
});
|
|
@@ -631,36 +707,39 @@ const input = (function () {
|
|
|
631
707
|
};
|
|
632
708
|
})();
|
|
633
709
|
function isVaildVersion(version) {
|
|
634
|
-
const split = version.split(
|
|
710
|
+
const split = version.split('-');
|
|
635
711
|
if (!split[0])
|
|
636
712
|
return false;
|
|
637
|
-
if (split[0]
|
|
713
|
+
if (split[0]
|
|
714
|
+
.split('.')
|
|
715
|
+
.map(Number)
|
|
716
|
+
.filter((i) => !Number.isNaN(i)).length !== 3)
|
|
638
717
|
return false;
|
|
639
718
|
return true;
|
|
640
719
|
}
|
|
641
720
|
function runCommand(param, cwd, stdio) {
|
|
642
721
|
let resolve;
|
|
643
|
-
let data =
|
|
644
|
-
const promise = new Promise((r) => resolve =
|
|
722
|
+
let data = '';
|
|
723
|
+
const promise = new Promise((r) => (resolve = (...argv) => {
|
|
724
|
+
Logger.i('Utils: runCommand', `run command: '${param.join(' ')}' return: ${JSON.stringify(argv[0])}`);
|
|
725
|
+
r(...argv);
|
|
726
|
+
}));
|
|
645
727
|
const p = spawn(param[0], param.slice(1), {
|
|
646
728
|
cwd: cwd,
|
|
647
729
|
shell: false,
|
|
648
730
|
stdio: stdio,
|
|
649
|
-
timeout: 1000 * 60 * 10
|
|
650
|
-
});
|
|
651
|
-
p.on("error", (err) => {
|
|
652
|
-
resolve(data + "(code: error)");
|
|
731
|
+
timeout: 1000 * 60 * 10,
|
|
653
732
|
});
|
|
654
|
-
p.
|
|
655
|
-
data
|
|
733
|
+
if (p.stdout) {
|
|
734
|
+
p.stdout.on('data', (chunk) => {
|
|
735
|
+
data += chunk.toString();
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
p.on('error', (_err) => {
|
|
739
|
+
resolve({ code: -1, data });
|
|
656
740
|
});
|
|
657
|
-
p.on(
|
|
658
|
-
|
|
659
|
-
resolve(`${data}(code: ${code})`);
|
|
660
|
-
}
|
|
661
|
-
else {
|
|
662
|
-
resolve(data);
|
|
663
|
-
}
|
|
741
|
+
p.on('close', (code) => {
|
|
742
|
+
resolve({ code, data });
|
|
664
743
|
});
|
|
665
744
|
return promise;
|
|
666
745
|
}
|
|
@@ -674,69 +753,6 @@ async function fileExists(file) {
|
|
|
674
753
|
}
|
|
675
754
|
}
|
|
676
755
|
|
|
677
|
-
const logFile = path__default.join(os.homedir(), ".cache/mbler/latest.log");
|
|
678
|
-
function _clean(promise) {
|
|
679
|
-
return () => {
|
|
680
|
-
Logger.run = Logger.run.filter((item) => {
|
|
681
|
-
return item !== promise;
|
|
682
|
-
});
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
function writeLog(logContent) {
|
|
686
|
-
async function write() {
|
|
687
|
-
try {
|
|
688
|
-
const dir = path__default.dirname(logFile);
|
|
689
|
-
if (!(await FileExsit(dir))) {
|
|
690
|
-
// ensure the directory exists, root-to-leaf
|
|
691
|
-
await fs__default$1.mkdir(dir, { recursive: true }).catch(() => void 0);
|
|
692
|
-
}
|
|
693
|
-
// if file does not exist, create it (touch)
|
|
694
|
-
if (!(await FileExsit(logFile))) {
|
|
695
|
-
await fs__default$1.writeFile(logFile, "");
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
catch (err) {
|
|
699
|
-
// if we can't prepare the log file, output to stderr but don't crash
|
|
700
|
-
console.error("[logger] unable to prepare log file:", err);
|
|
701
|
-
return;
|
|
702
|
-
}
|
|
703
|
-
try {
|
|
704
|
-
await fs__default$1.appendFile(logFile, "\n" + logContent);
|
|
705
|
-
}
|
|
706
|
-
catch (err) {
|
|
707
|
-
console.error("[logger] failed to append to log file:", err);
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
const asy = write();
|
|
711
|
-
Logger.run.push(asy.then(_clean(asy)));
|
|
712
|
-
}
|
|
713
|
-
class Logger {
|
|
714
|
-
// 写入日志池
|
|
715
|
-
static LogFile = logFile;
|
|
716
|
-
static run = [];
|
|
717
|
-
static _b(tag, msg, t) {
|
|
718
|
-
const date = new Date();
|
|
719
|
-
const logContent = [
|
|
720
|
-
`${date.toLocaleDateString()} ${date.toLocaleTimeString()}`,
|
|
721
|
-
`[${t} ${tag}]`,
|
|
722
|
-
msg,
|
|
723
|
-
].join(" ");
|
|
724
|
-
writeLog(logContent);
|
|
725
|
-
}
|
|
726
|
-
static w(tag, msg) {
|
|
727
|
-
Logger._b(tag, msg, "WARN");
|
|
728
|
-
}
|
|
729
|
-
static e(tag, msg) {
|
|
730
|
-
Logger._b(tag, msg, "ERROR");
|
|
731
|
-
}
|
|
732
|
-
static i(tag, msg) {
|
|
733
|
-
Logger._b(tag, msg, "INFO");
|
|
734
|
-
}
|
|
735
|
-
static d(tag, msg) {
|
|
736
|
-
Logger._b(tag, msg, "DEBUG");
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
|
|
740
756
|
async function tryMkdir(point) {
|
|
741
757
|
try {
|
|
742
758
|
await mkdir(point);
|
|
@@ -749,30 +765,29 @@ async function tryMkdir(point) {
|
|
|
749
765
|
class WorkDirManage {
|
|
750
766
|
cacheDir;
|
|
751
767
|
currentWorkPoint = null;
|
|
752
|
-
enabledPath = path__default.join(homedir(),
|
|
753
|
-
constructor(cacheDir = path__default.join(homedir(),
|
|
768
|
+
enabledPath = path__default.join(homedir(), '.cache/mbler/workdir_enabled.db');
|
|
769
|
+
constructor(cacheDir = path__default.join(homedir(), '.cache/mbler/mp.db')) {
|
|
754
770
|
this.cacheDir = cacheDir;
|
|
755
771
|
}
|
|
756
772
|
async isDisabled() {
|
|
757
773
|
try {
|
|
758
|
-
await readFile(this.enabledPath,
|
|
759
|
-
return false;
|
|
774
|
+
await readFile(this.enabledPath, 'utf-8');
|
|
775
|
+
return false;
|
|
760
776
|
}
|
|
761
777
|
catch {
|
|
762
|
-
return true;
|
|
778
|
+
return true;
|
|
763
779
|
}
|
|
764
780
|
}
|
|
765
781
|
async setDisabled(disabled) {
|
|
766
782
|
if (!disabled) {
|
|
767
|
-
|
|
768
|
-
await writeFile(this.enabledPath, "1", { encoding: "utf-8" });
|
|
783
|
+
await writeFile(this.enabledPath, '1', { encoding: 'utf-8' });
|
|
769
784
|
}
|
|
770
785
|
else {
|
|
771
786
|
try {
|
|
772
|
-
await
|
|
787
|
+
await rm(this.enabledPath);
|
|
773
788
|
}
|
|
774
789
|
catch {
|
|
775
|
-
//
|
|
790
|
+
// ignore
|
|
776
791
|
}
|
|
777
792
|
}
|
|
778
793
|
}
|
|
@@ -781,14 +796,14 @@ class WorkDirManage {
|
|
|
781
796
|
try {
|
|
782
797
|
const s = await stat(newPointDir);
|
|
783
798
|
if (!s.isDirectory()) {
|
|
784
|
-
throw new Error(
|
|
799
|
+
throw new Error('Not Dir (0xcvb)');
|
|
785
800
|
}
|
|
786
801
|
}
|
|
787
802
|
catch (err) {
|
|
788
|
-
const
|
|
789
|
-
if (
|
|
803
|
+
const nodeErr = err;
|
|
804
|
+
if (nodeErr.message?.includes('0xcvb'))
|
|
790
805
|
return i18n.workdir.nfound;
|
|
791
|
-
if (code ==
|
|
806
|
+
if (nodeErr.code == 'ENOENT') {
|
|
792
807
|
const res = tryMkdir(newPointDir);
|
|
793
808
|
if (!res) {
|
|
794
809
|
return i18n.workdir.nfound;
|
|
@@ -802,11 +817,13 @@ class WorkDirManage {
|
|
|
802
817
|
return i18n.workdir.nfound;
|
|
803
818
|
}
|
|
804
819
|
await writeFile(this.cacheDir, newPointDir, {
|
|
805
|
-
encoding:
|
|
820
|
+
encoding: 'utf-8',
|
|
806
821
|
});
|
|
807
822
|
}
|
|
808
823
|
catch (err) {
|
|
809
|
-
Logger.e(
|
|
824
|
+
Logger.e('WorkDir', err instanceof Error
|
|
825
|
+
? (err.stack ?? err.message ?? String(err))
|
|
826
|
+
: String(err));
|
|
810
827
|
}
|
|
811
828
|
return i18n.workdir.set + newPointDir;
|
|
812
829
|
}
|
|
@@ -817,7 +834,7 @@ class WorkDirManage {
|
|
|
817
834
|
if (this.currentWorkPoint) {
|
|
818
835
|
return this.currentWorkPoint;
|
|
819
836
|
}
|
|
820
|
-
const file = await readFile(this.cacheDir,
|
|
837
|
+
const file = await readFile(this.cacheDir, 'utf-8').catch((_e) => {
|
|
821
838
|
this.set(cwd());
|
|
822
839
|
return cwd();
|
|
823
840
|
});
|
|
@@ -825,291 +842,17 @@ class WorkDirManage {
|
|
|
825
842
|
}
|
|
826
843
|
}
|
|
827
844
|
|
|
828
|
-
const config = {
|
|
829
|
-
tmpdir: path.join(tmpdir(), ".mbler"),
|
|
830
|
-
mcxVersion: "0.0.2-beta.r7",
|
|
831
|
-
mcxCoreVersion: "0.0.6",
|
|
832
|
-
defaultPmnxBASE: "https://d.pmnx.qzz.io"
|
|
833
|
-
};
|
|
834
|
-
|
|
835
|
-
/**
|
|
836
|
-
* Compare two dotted version strings ("major.minor.patch").
|
|
837
|
-
* Returns negative if a < b, positive if a > b, zero if equal.
|
|
838
|
-
*/
|
|
839
|
-
const exp = (function () {
|
|
840
|
-
const cacheFile = path.join(config.tmpdir, "_sapi_version.json");
|
|
841
|
-
// cacheData is an array of entries keyed by the embedded mc version string
|
|
842
|
-
let cacheData = null;
|
|
843
|
-
/**
|
|
844
|
-
* Pull every published version for a package and reduce it to a mapping
|
|
845
|
-
* from the embedded Minecraft version (e.g. "1.21.60") to the most
|
|
846
|
-
* recent formal/beta release we were able to parse.
|
|
847
|
-
*/
|
|
848
|
-
async function fetchData(pkgName) {
|
|
849
|
-
const data = (await json(`/${pkgName}`));
|
|
850
|
-
const pkgVersions = Object.keys(data.versions);
|
|
851
|
-
const reValue = {};
|
|
852
|
-
// helper to extract the embedded MC version ("yyyy") from a full
|
|
853
|
-
// npm package version string. returns null when the expected pattern
|
|
854
|
-
// cannot be found.
|
|
855
|
-
const mcVersionFrom = (str) => {
|
|
856
|
-
const m = str.match(/-(?:rc|beta)(?:\.[^-.]+)*?\.((?:\d+\.){2}\d+)/);
|
|
857
|
-
return m ? m[1] : null;
|
|
858
|
-
};
|
|
859
|
-
for (const v of pkgVersions) {
|
|
860
|
-
const mcVersion = mcVersionFrom(v);
|
|
861
|
-
if (!mcVersion)
|
|
862
|
-
continue;
|
|
863
|
-
const isStable = /(?:-stable)(?:$|[-.])/.test(v);
|
|
864
|
-
let entry = reValue[mcVersion];
|
|
865
|
-
if (!entry) {
|
|
866
|
-
entry = { formal: "", beta: "", _v: -1 };
|
|
867
|
-
reValue[mcVersion] = entry;
|
|
868
|
-
}
|
|
869
|
-
if (isStable) {
|
|
870
|
-
// pick the lexically greatest stable version string
|
|
871
|
-
if (!entry.formal || v > entry.formal) {
|
|
872
|
-
entry.formal = v;
|
|
873
|
-
}
|
|
874
|
-
entry._v = Infinity;
|
|
875
|
-
}
|
|
876
|
-
else {
|
|
877
|
-
// non-stable release; treat everything else as a beta candidate
|
|
878
|
-
if (!entry.beta || v > entry.beta) {
|
|
879
|
-
entry.beta = v;
|
|
880
|
-
}
|
|
881
|
-
if (entry._v !== Infinity)
|
|
882
|
-
entry._v = 1;
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
return reValue;
|
|
886
|
-
}
|
|
887
|
-
async function refresh() {
|
|
888
|
-
// grab the two packages we care about and merge the keys
|
|
889
|
-
const serverMap = await fetchData("@minecraft/server");
|
|
890
|
-
const uiMap = await fetchData("@minecraft/server-ui");
|
|
891
|
-
const versions = new Set([
|
|
892
|
-
...Object.keys(serverMap),
|
|
893
|
-
...Object.keys(uiMap),
|
|
894
|
-
]);
|
|
895
|
-
const arr = [];
|
|
896
|
-
for (const ver of Array.from(versions)) {
|
|
897
|
-
arr.push({
|
|
898
|
-
version: ver,
|
|
899
|
-
server: serverMap[ver]
|
|
900
|
-
? { formal: serverMap[ver].formal, beta: serverMap[ver].beta }
|
|
901
|
-
: { formal: "", beta: "" },
|
|
902
|
-
"server-ui": uiMap[ver]
|
|
903
|
-
? { formal: uiMap[ver].formal, beta: uiMap[ver].beta }
|
|
904
|
-
: { formal: "", beta: "" },
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
arr.sort((a, b) => compareVersion(a.version, b.version));
|
|
908
|
-
cacheData = arr;
|
|
909
|
-
await fs$1.promises
|
|
910
|
-
.mkdir(config.tmpdir, { recursive: true })
|
|
911
|
-
.catch(() => void 0);
|
|
912
|
-
await fs$1.promises.writeFile(cacheFile, JSON.stringify(arr, null, 2), "utf-8");
|
|
913
|
-
}
|
|
914
|
-
async function generateVersion(module, mcVersion, isBeta) {
|
|
915
|
-
if (!cacheData) {
|
|
916
|
-
try {
|
|
917
|
-
const txt = await fs$1.promises.readFile(cacheFile, "utf-8");
|
|
918
|
-
cacheData = JSON.parse(txt);
|
|
919
|
-
}
|
|
920
|
-
catch {
|
|
921
|
-
await refresh();
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
if (!cacheData) {
|
|
925
|
-
throw new Error("unable to load sapi cache data");
|
|
926
|
-
}
|
|
927
|
-
// try exact match first
|
|
928
|
-
let entry = cacheData.find((e) => e.version === mcVersion);
|
|
929
|
-
if (!entry) {
|
|
930
|
-
// find closest entry less than or equal to requested version
|
|
931
|
-
const sorted = cacheData.slice();
|
|
932
|
-
let candidate = null;
|
|
933
|
-
for (const e of sorted) {
|
|
934
|
-
if (compareVersion(e.version, mcVersion) <= 0) {
|
|
935
|
-
candidate = e;
|
|
936
|
-
}
|
|
937
|
-
else {
|
|
938
|
-
break;
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
if (!candidate) {
|
|
942
|
-
candidate = sorted[0];
|
|
943
|
-
}
|
|
944
|
-
entry = candidate;
|
|
945
|
-
}
|
|
946
|
-
const moduleKey = module === "@minecraft/server" ? "server" : "server-ui";
|
|
947
|
-
const entryModule = entry[moduleKey];
|
|
948
|
-
let result = isBeta ? entryModule.beta : entryModule.formal;
|
|
949
|
-
if (!result) {
|
|
950
|
-
// fall back to whatever is available
|
|
951
|
-
result = entryModule.formal || entryModule.beta;
|
|
952
|
-
}
|
|
953
|
-
const tmp = result.split("-").slice(0, 2);
|
|
954
|
-
tmp[1] = tmp[1].split(".")[0];
|
|
955
|
-
result = tmp.join("-");
|
|
956
|
-
return result || "";
|
|
957
|
-
}
|
|
958
|
-
return {
|
|
959
|
-
refresh,
|
|
960
|
-
generateVersion,
|
|
961
|
-
};
|
|
962
|
-
})();
|
|
963
|
-
|
|
964
|
-
async function isInit(dir) {
|
|
965
|
-
return (await Promise.all([BuildConfig.ConfigFile, 'package.json', 'behavior'].map((item) => {
|
|
966
|
-
return FileExsit(path__default.join(dir, item));
|
|
967
|
-
}))).every((value) => {
|
|
968
|
-
return value;
|
|
969
|
-
});
|
|
970
|
-
}
|
|
971
|
-
async function findTemplatedir() {
|
|
972
|
-
if (await FileExsit(path__default.join(__dirname, '../template')))
|
|
973
|
-
return path__default.join(__dirname, '../template');
|
|
974
|
-
if (await FileExsit(path__default.join(__dirname, './template')))
|
|
975
|
-
return path__default.join(__dirname, './template');
|
|
976
|
-
}
|
|
977
845
|
async function initCommand(cliParam, workdir) {
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
if (await isInit(workdir)) {
|
|
982
|
-
return 0;
|
|
983
|
-
}
|
|
984
|
-
const initOpts = {
|
|
985
|
-
name: cmdParams[0] || (await input(i18n.init.name)),
|
|
986
|
-
description: cmdParams[1] || (await input(i18n.init.description)),
|
|
987
|
-
lang: (cmdParams[2] ||
|
|
988
|
-
(await Input.select(i18n.init.lang, ['ts', 'js', 'mcx']))),
|
|
989
|
-
initDeependencies: await Input.select(i18n.init.initDes, [
|
|
990
|
-
'no',
|
|
991
|
-
'pnpm',
|
|
992
|
-
'npm',
|
|
993
|
-
]),
|
|
994
|
-
useUI: (await input(i18n.init.useUI)) === 'y',
|
|
995
|
-
useGIT: (await input(i18n.init.useGIT)) === 'y',
|
|
996
|
-
useBetaApi: (await input(i18n.init.betaApi)) === 'y',
|
|
997
|
-
mcVersion: await input(i18n.init.mcVersion),
|
|
998
|
-
};
|
|
999
|
-
if (!initOpts.name) {
|
|
1000
|
-
showText(i18n.init.noName);
|
|
1001
|
-
return 1;
|
|
1002
|
-
}
|
|
1003
|
-
if (!initOpts.lang) {
|
|
1004
|
-
showText(i18n.init.noLanguare);
|
|
1005
|
-
return 1;
|
|
1006
|
-
}
|
|
1007
|
-
if (!initOpts.mcVersion || !isVaildVersion(initOpts.mcVersion)) {
|
|
1008
|
-
showText(i18n.init.noMCVersion);
|
|
1009
|
-
return 1;
|
|
1010
|
-
}
|
|
1011
|
-
const mblerConfig = {
|
|
1012
|
-
name: initOpts.name,
|
|
1013
|
-
description: initOpts.description,
|
|
1014
|
-
version: '0.0.0',
|
|
1015
|
-
script: {
|
|
1016
|
-
lang: initOpts.lang,
|
|
1017
|
-
main: 'index.js',
|
|
1018
|
-
ui: initOpts.useUI,
|
|
1019
|
-
UseBeta: initOpts.useBetaApi,
|
|
1020
|
-
},
|
|
1021
|
-
mcVersion: initOpts.mcVersion,
|
|
1022
|
-
minify: false,
|
|
1023
|
-
};
|
|
1024
|
-
const packageJSON = {
|
|
1025
|
-
name: initOpts.name,
|
|
1026
|
-
version: '0.0.0',
|
|
1027
|
-
description: initOpts.description,
|
|
1028
|
-
module: 'module',
|
|
1029
|
-
scripts: {
|
|
1030
|
-
build: 'mcx-tsc && BUILD_MODULE=release mbler build',
|
|
1031
|
-
'dev:build': 'mbler build',
|
|
1032
|
-
install: 'pnpm i -g mbler',
|
|
1033
|
-
watch: 'mbler watch',
|
|
1034
|
-
},
|
|
1035
|
-
devDependencies: {
|
|
1036
|
-
'@minecraft/server': await exp.generateVersion('@minecraft/server', initOpts.mcVersion, initOpts.useBetaApi),
|
|
1037
|
-
},
|
|
1038
|
-
};
|
|
1039
|
-
if (initOpts.useUI) {
|
|
1040
|
-
packageJSON.devDependencies['@minecraft/server-ui'] =
|
|
1041
|
-
await exp.generateVersion('@minecraft/server-ui', initOpts.mcVersion, initOpts.useBetaApi);
|
|
1042
|
-
}
|
|
1043
|
-
const tsconfig = {
|
|
1044
|
-
compilerOptions: {
|
|
1045
|
-
module: 'nodenext',
|
|
1046
|
-
noEmit: true,
|
|
1047
|
-
target: 'esnext',
|
|
1048
|
-
types: ["@mbler/mcx-core/client"],
|
|
1049
|
-
sourceMap: true,
|
|
1050
|
-
declaration: true,
|
|
1051
|
-
declarationMap: false,
|
|
1052
|
-
noUncheckedIndexedAccess: true,
|
|
1053
|
-
exactOptionalPropertyTypes: true,
|
|
1054
|
-
allowJs: true,
|
|
1055
|
-
strict: true,
|
|
1056
|
-
moduleResolution: 'nodenext',
|
|
1057
|
-
verbatimModuleSyntax: false,
|
|
1058
|
-
isolatedModules: true,
|
|
1059
|
-
noUncheckedSideEffectImports: true,
|
|
1060
|
-
moduleDetection: 'force',
|
|
1061
|
-
skipLibCheck: true,
|
|
1062
|
-
},
|
|
1063
|
-
include: ['./behavior/scripts/**/*'],
|
|
1064
|
-
};
|
|
1065
|
-
const mblerConfigPath = path__default.join(workdir, BuildConfig.ConfigFile);
|
|
1066
|
-
const packageJSONPath = path__default.join(workdir, 'package.json');
|
|
1067
|
-
const tsconfigPath = path__default.join(workdir, 'tsconfig.json');
|
|
1068
|
-
if (initOpts.lang == 'mcx') {
|
|
1069
|
-
mblerConfig.script.main = 'index.mjs';
|
|
1070
|
-
packageJSON.devDependencies['@mbler/mcx'] = config.mcxVersion;
|
|
1071
|
-
packageJSON.devDependencies['@mbler/mcx-core'] = config.mcxCoreVersion;
|
|
1072
|
-
}
|
|
1073
|
-
if (initOpts.lang !== 'js') {
|
|
1074
|
-
await writeJSON(tsconfigPath, tsconfig);
|
|
1075
|
-
}
|
|
1076
|
-
await writeJSON(packageJSONPath, packageJSON);
|
|
1077
|
-
const mblerConfigContent = `import { defineConfig } from "mbler";\nexport default ${JSON.stringify(mblerConfig, null, 2)}`;
|
|
1078
|
-
await writeFile(mblerConfigPath, mblerConfigContent);
|
|
1079
|
-
// write template
|
|
1080
|
-
const templatedir = await findTemplatedir();
|
|
1081
|
-
if (!templatedir) {
|
|
1082
|
-
showText("can't find template folder");
|
|
1083
|
-
return 1;
|
|
1084
|
-
}
|
|
1085
|
-
const templateTagerFolder = path__default.join(templatedir, initOpts.lang);
|
|
1086
|
-
if (!(await FileExsit(templateTagerFolder))) {
|
|
1087
|
-
showText("can't resolve template folder");
|
|
1088
|
-
return 1;
|
|
1089
|
-
}
|
|
1090
|
-
const tasks = [];
|
|
1091
|
-
for (const item of await readdir(templateTagerFolder)) {
|
|
1092
|
-
tasks.push(cp(path__default.join(templateTagerFolder, item), path__default.join(workdir, item), {
|
|
1093
|
-
recursive: true,
|
|
1094
|
-
force: true,
|
|
1095
|
-
}));
|
|
846
|
+
const { code } = await runCommand(['pnpm', '--version'], workdir, 'ignore');
|
|
847
|
+
if (code === 0) {
|
|
848
|
+
return ((await runCommand(['pnpm', 'create', 'mbler', '--', workdir, ...process.argv.slice(3)], workdir, 'inherit')).code ?? 1);
|
|
1096
849
|
}
|
|
1097
|
-
await
|
|
1098
|
-
tasks.length = 0;
|
|
1099
|
-
if (initOpts.initDeependencies !== 'no') {
|
|
1100
|
-
tasks.push(runCommand([initOpts.initDeependencies, 'install'], workdir, 'pipe'));
|
|
1101
|
-
}
|
|
1102
|
-
if (initOpts.useGIT) {
|
|
1103
|
-
tasks.push(runCommand(['git', 'init', '-b', 'main'], workdir, 'pipe'));
|
|
1104
|
-
}
|
|
1105
|
-
await Promise.all(tasks);
|
|
1106
|
-
tasks.length = 0;
|
|
1107
|
-
return 0;
|
|
850
|
+
return ((await runCommand(['npm', 'create', 'mbler', '--', workdir, ...process.argv.slice(3)], workdir, 'inherit')).code ?? 1);
|
|
1108
851
|
}
|
|
1109
852
|
|
|
1110
853
|
async function handlerVersion(cliParam, workdir) {
|
|
1111
854
|
if (cliParam.params.length > 1) {
|
|
1112
|
-
if (!await FileExsit(workdir)) {
|
|
855
|
+
if (!(await FileExsit(workdir))) {
|
|
1113
856
|
showText("can't set workdir version, because not exists");
|
|
1114
857
|
return 1;
|
|
1115
858
|
}
|
|
@@ -1118,7 +861,7 @@ async function handlerVersion(cliParam, workdir) {
|
|
|
1118
861
|
showText("can't set version, it is not a vaild version");
|
|
1119
862
|
return 1;
|
|
1120
863
|
}
|
|
1121
|
-
const pkgJSON = await readFileAsJson(path.join(workdir,
|
|
864
|
+
const pkgJSON = await readFileAsJson(path.join(workdir, 'package.json'));
|
|
1122
865
|
const mblerConfigJSON = await readFileAsJson(path.join(workdir, BuildConfig.ConfigFile));
|
|
1123
866
|
mblerConfigJSON.version = pkgJSON.version = version;
|
|
1124
867
|
}
|
|
@@ -1128,15 +871,15 @@ async function handlerVersion(cliParam, workdir) {
|
|
|
1128
871
|
return 0;
|
|
1129
872
|
}
|
|
1130
873
|
function showVersion(cliParam) {
|
|
1131
|
-
let show =
|
|
874
|
+
let show = '';
|
|
1132
875
|
if (Object.getOwnPropertyNames(cliParam.opts).length < 1) {
|
|
1133
876
|
show = `commit: ${MBLERVersion.commit}\nversion: ${MBLERVersion.version}`;
|
|
1134
877
|
}
|
|
1135
878
|
else if (cliParam.opts.show) {
|
|
1136
|
-
if (cliParam.opts.show ==
|
|
879
|
+
if (cliParam.opts.show == 'commit') {
|
|
1137
880
|
show = `commit: ${MBLERVersion.commit}`;
|
|
1138
881
|
}
|
|
1139
|
-
else if (cliParam.opts.show ==
|
|
882
|
+
else if (cliParam.opts.show == 'version') {
|
|
1140
883
|
show = `version: ${MBLERVersion.version}`;
|
|
1141
884
|
}
|
|
1142
885
|
else {
|
|
@@ -1146,56 +889,72 @@ function showVersion(cliParam) {
|
|
|
1146
889
|
showText(show);
|
|
1147
890
|
}
|
|
1148
891
|
|
|
1149
|
-
function langCommand(cliParam,
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
else {
|
|
1155
|
-
i18n.__internal.set(cliParam.params[1]);
|
|
1156
|
-
show = i18n.__internal.class.currenyLang;
|
|
1157
|
-
}
|
|
892
|
+
function langCommand(cliParam, _workdir) {
|
|
893
|
+
const show = cliParam.params.length < 2
|
|
894
|
+
? i18n.__internal.class.currenyLang
|
|
895
|
+
: (i18n.__internal.set(cliParam.params[1]),
|
|
896
|
+
i18n.__internal.class.currenyLang);
|
|
1158
897
|
showText(show);
|
|
1159
898
|
return 0;
|
|
1160
899
|
}
|
|
1161
900
|
|
|
1162
|
-
function
|
|
1163
|
-
const
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
if (!build.outdirs)
|
|
1178
|
-
throw new Error("invalid Build");
|
|
1179
|
-
if (env.BUILD_MODULE !== "release")
|
|
1180
|
-
return;
|
|
1181
|
-
let zip;
|
|
1182
|
-
if (build.module == "all") {
|
|
1183
|
-
zip = await createZipWithMoreFolder([
|
|
1184
|
-
[build.outdirs?.behavior, "behavior"],
|
|
1185
|
-
[build.outdirs?.resources, "resources"]
|
|
1186
|
-
]);
|
|
1187
|
-
}
|
|
1188
|
-
else if (build.module == "behavior") {
|
|
1189
|
-
zip = createFullZip(build.outdirs?.behavior);
|
|
1190
|
-
}
|
|
1191
|
-
else {
|
|
1192
|
-
zip = createFullZip(build.outdirs?.resources);
|
|
901
|
+
function Release() {
|
|
902
|
+
const AdmZip = require('adm-zip');
|
|
903
|
+
function createFullZip(dir) {
|
|
904
|
+
const zip = new AdmZip();
|
|
905
|
+
zip.addLocalFolder(dir);
|
|
906
|
+
return zip;
|
|
907
|
+
}
|
|
908
|
+
async function createZipWithMoreFolder(dir) {
|
|
909
|
+
const zip = new AdmZip();
|
|
910
|
+
for (const folder of dir) {
|
|
911
|
+
await zip.addLocalFolderPromise(folder[0], {
|
|
912
|
+
zipPath: folder[1],
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
return zip;
|
|
1193
916
|
}
|
|
1194
|
-
|
|
917
|
+
return async function generateRelease(build) {
|
|
918
|
+
if (!build.outdirs)
|
|
919
|
+
throw new Error('invalid Build');
|
|
920
|
+
if (env.BUILD_MODULE !== 'release')
|
|
921
|
+
return;
|
|
922
|
+
let zip;
|
|
923
|
+
if (build.module == 'all') {
|
|
924
|
+
zip = await createZipWithMoreFolder([
|
|
925
|
+
[build.outdirs?.behavior, 'behavior'],
|
|
926
|
+
[build.outdirs?.resources, 'resources'],
|
|
927
|
+
]);
|
|
928
|
+
}
|
|
929
|
+
else if (build.module == 'behavior') {
|
|
930
|
+
zip = createFullZip(build.outdirs?.behavior);
|
|
931
|
+
}
|
|
932
|
+
else {
|
|
933
|
+
zip = createFullZip(build.outdirs?.resources);
|
|
934
|
+
}
|
|
935
|
+
await zip.writeZipPromise(build.outdirs?.dist);
|
|
936
|
+
};
|
|
1195
937
|
}
|
|
938
|
+
let releaseEmul = null;
|
|
939
|
+
const generateRelease = (...argv) => {
|
|
940
|
+
if (!releaseEmul)
|
|
941
|
+
releaseEmul = Release();
|
|
942
|
+
return releaseEmul(...argv);
|
|
943
|
+
};
|
|
944
|
+
|
|
945
|
+
const config = {
|
|
946
|
+
tmpdir: path.join(tmpdir(), '.mbler'),
|
|
947
|
+
mcxVersion: '0.0.2-beta.r7',
|
|
948
|
+
mcxCoreVersion: '0.0.6',
|
|
949
|
+
mblerVersion: '0.2.4-rc.4',
|
|
950
|
+
defaultPmnxBASE: 'https://d.pmnx.qzz.io',
|
|
951
|
+
};
|
|
1196
952
|
|
|
1197
953
|
class ConfigManger {
|
|
1198
|
-
|
|
954
|
+
/**
|
|
955
|
+
* @description Mbler Config File Default Point
|
|
956
|
+
*/
|
|
957
|
+
static defaultConfigPoint = path__default.join(homedir(), '.config', '.mbler.config.global.cli.json');
|
|
1199
958
|
static cacheValue = {};
|
|
1200
959
|
static lockPromise = null;
|
|
1201
960
|
static lockResolver = null;
|
|
@@ -1218,9 +977,9 @@ class ConfigManger {
|
|
|
1218
977
|
}
|
|
1219
978
|
}
|
|
1220
979
|
static isCacheValid(configPath) {
|
|
1221
|
-
return this.currentConfigPath === configPath &&
|
|
980
|
+
return (this.currentConfigPath === configPath &&
|
|
1222
981
|
Date.now() - this.lastAccess < this.cacheTTL &&
|
|
1223
|
-
Object.keys(this.cacheValue).length > 0;
|
|
982
|
+
Object.keys(this.cacheValue).length > 0);
|
|
1224
983
|
}
|
|
1225
984
|
static async loadConfigToCache(configPath) {
|
|
1226
985
|
try {
|
|
@@ -1242,13 +1001,13 @@ class ConfigManger {
|
|
|
1242
1001
|
}
|
|
1243
1002
|
}
|
|
1244
1003
|
static async ensureConfigFile(configPath) {
|
|
1245
|
-
if (!await fileExists(configPath)) {
|
|
1004
|
+
if (!(await fileExists(configPath))) {
|
|
1246
1005
|
await writeJSON(configPath, {});
|
|
1247
1006
|
return;
|
|
1248
1007
|
}
|
|
1249
1008
|
try {
|
|
1250
1009
|
const data = await readFileAsJson(configPath);
|
|
1251
|
-
if (!data || typeof data !==
|
|
1010
|
+
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
|
1252
1011
|
await writeJSON(configPath, {});
|
|
1253
1012
|
}
|
|
1254
1013
|
}
|
|
@@ -1270,28 +1029,28 @@ class ConfigManger {
|
|
|
1270
1029
|
}
|
|
1271
1030
|
static async getConfigPoint() {
|
|
1272
1031
|
try {
|
|
1273
|
-
const file = await readFile(path__default.join(config.tmpdir,
|
|
1032
|
+
const file = await readFile(path__default.join(config.tmpdir, '_config_point.json'));
|
|
1274
1033
|
const configPoint = JSON.parse(file.toString());
|
|
1275
1034
|
return configPoint.point;
|
|
1276
1035
|
}
|
|
1277
1036
|
catch {
|
|
1278
|
-
if (!await fileExists(this.defaultConfigPoint)) {
|
|
1037
|
+
if (!(await fileExists(this.defaultConfigPoint))) {
|
|
1279
1038
|
await writeJSON(this.defaultConfigPoint, {});
|
|
1280
1039
|
}
|
|
1281
|
-
await writeJSON(path__default.join(config.tmpdir,
|
|
1040
|
+
await writeJSON(path__default.join(config.tmpdir, '_config_point.json'), {
|
|
1282
1041
|
point: this.defaultConfigPoint,
|
|
1283
|
-
update: new Date()
|
|
1042
|
+
update: new Date(),
|
|
1284
1043
|
});
|
|
1285
1044
|
return this.defaultConfigPoint;
|
|
1286
1045
|
}
|
|
1287
1046
|
}
|
|
1288
1047
|
static async setConfigPoint(point) {
|
|
1289
|
-
if (!await fileExists(point)) {
|
|
1048
|
+
if (!(await fileExists(point))) {
|
|
1290
1049
|
await writeJSON(point, {});
|
|
1291
1050
|
}
|
|
1292
|
-
await writeJSON(path__default.join(config.tmpdir,
|
|
1051
|
+
await writeJSON(path__default.join(config.tmpdir, '_config_point.json'), {
|
|
1293
1052
|
point,
|
|
1294
|
-
update: new Date()
|
|
1053
|
+
update: new Date(),
|
|
1295
1054
|
});
|
|
1296
1055
|
}
|
|
1297
1056
|
static async getKey(key) {
|
|
@@ -1304,7 +1063,7 @@ class ConfigManger {
|
|
|
1304
1063
|
}
|
|
1305
1064
|
return this.cacheValue[key];
|
|
1306
1065
|
}
|
|
1307
|
-
catch (
|
|
1066
|
+
catch (_error) {
|
|
1308
1067
|
return undefined;
|
|
1309
1068
|
}
|
|
1310
1069
|
}
|
|
@@ -1320,13 +1079,14 @@ class ConfigManger {
|
|
|
1320
1079
|
return true;
|
|
1321
1080
|
}
|
|
1322
1081
|
catch (error) {
|
|
1323
|
-
Logger.e('ConfigManger', 'Failed to set key: ' +
|
|
1082
|
+
Logger.e('ConfigManger', 'Failed to set key: ' +
|
|
1083
|
+
(error instanceof Error ? error.message : String(error)));
|
|
1324
1084
|
return false;
|
|
1325
1085
|
}
|
|
1326
1086
|
}
|
|
1327
1087
|
static async init(defaultConfig = {}) {
|
|
1328
1088
|
const configPath = await this.getConfigPoint();
|
|
1329
|
-
if (!await fileExists(configPath)) {
|
|
1089
|
+
if (!(await fileExists(configPath))) {
|
|
1330
1090
|
await writeJSON(configPath, defaultConfig);
|
|
1331
1091
|
}
|
|
1332
1092
|
}
|
|
@@ -1337,20 +1097,22 @@ class TokenManger {
|
|
|
1337
1097
|
static async setToken(newToken) {
|
|
1338
1098
|
const token = newToken.trim();
|
|
1339
1099
|
this.memoryToken = token;
|
|
1340
|
-
const saved = await ConfigManger.setKey(
|
|
1100
|
+
const saved = await ConfigManger.setKey('token', token);
|
|
1341
1101
|
if (!saved) {
|
|
1342
|
-
throw new Error(
|
|
1102
|
+
throw new Error('Failed to store token');
|
|
1343
1103
|
}
|
|
1344
1104
|
this.task = this.requestAPI(token);
|
|
1345
1105
|
await this.task;
|
|
1346
1106
|
}
|
|
1347
|
-
static getToken() {
|
|
1107
|
+
static getToken() {
|
|
1108
|
+
return ConfigManger.getKey('token');
|
|
1109
|
+
}
|
|
1348
1110
|
static isLogin = false;
|
|
1349
1111
|
static task;
|
|
1350
1112
|
static isLoading = true;
|
|
1351
1113
|
static user = null;
|
|
1352
1114
|
static async init() {
|
|
1353
|
-
const token = this.memoryToken || await this.getToken();
|
|
1115
|
+
const token = this.memoryToken || (await this.getToken());
|
|
1354
1116
|
if (token) {
|
|
1355
1117
|
this.task = this.requestAPI(token);
|
|
1356
1118
|
await this.task;
|
|
@@ -1368,17 +1130,17 @@ class TokenManger {
|
|
|
1368
1130
|
this.isLoading = true;
|
|
1369
1131
|
this.isLogin = false;
|
|
1370
1132
|
this.user = null;
|
|
1371
|
-
const token = tokenFromCaller || this.memoryToken || await this.getToken();
|
|
1372
|
-
if (!token || typeof token !==
|
|
1133
|
+
const token = tokenFromCaller || this.memoryToken || (await this.getToken());
|
|
1134
|
+
if (!token || typeof token !== 'string' || token.length < 1) {
|
|
1373
1135
|
this.isLoading = false;
|
|
1374
1136
|
return;
|
|
1375
1137
|
}
|
|
1376
1138
|
try {
|
|
1377
1139
|
const result = await fetch(`${config.defaultPmnxBASE}/token/${token}/verify`, {
|
|
1378
|
-
method:
|
|
1379
|
-
credentials:
|
|
1140
|
+
method: 'GET',
|
|
1141
|
+
credentials: 'omit',
|
|
1380
1142
|
});
|
|
1381
|
-
const body = await result.json().catch(() => ({}));
|
|
1143
|
+
const body = (await result.json().catch(() => ({})));
|
|
1382
1144
|
if (result.ok && body.code === 200 && body.data) {
|
|
1383
1145
|
this.isLogin = true;
|
|
1384
1146
|
this.user = body.data;
|
|
@@ -1397,94 +1159,104 @@ class TokenManger {
|
|
|
1397
1159
|
}
|
|
1398
1160
|
|
|
1399
1161
|
function fmt$6(t, vars) {
|
|
1400
|
-
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ??
|
|
1162
|
+
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? ''));
|
|
1401
1163
|
}
|
|
1402
1164
|
class PublishManger {
|
|
1403
1165
|
static async publish(projectPath, options) {
|
|
1404
1166
|
if (TokenManger.isLoading)
|
|
1405
1167
|
await TokenManger.init();
|
|
1406
|
-
if (!await fileExists(projectPath)) {
|
|
1168
|
+
if (!(await fileExists(projectPath))) {
|
|
1407
1169
|
throw new Error(i18n.publish.projectPathNotExist);
|
|
1408
1170
|
}
|
|
1409
|
-
const { onProgress = (
|
|
1171
|
+
const { onProgress = (_p) => { }, onMessage = (_m) => { }, build, tag, } = options;
|
|
1410
1172
|
onProgress(1);
|
|
1411
1173
|
onMessage(i18n.publish.publishing);
|
|
1412
|
-
if (build ==
|
|
1174
|
+
if (build == 'enable') {
|
|
1413
1175
|
onMessage(i18n.publish.building);
|
|
1414
1176
|
await this.buildProject(projectPath);
|
|
1415
1177
|
onProgress(30);
|
|
1416
1178
|
}
|
|
1417
1179
|
const mblerConfig = await ReadProjectMblerConfig(projectPath);
|
|
1418
|
-
const pkgData = await readFileAsJson(path__default.join(projectPath,
|
|
1419
|
-
const outputPath = path__default.join(config.tmpdir,
|
|
1420
|
-
process.env.BUILD_MODULE =
|
|
1180
|
+
const pkgData = await readFileAsJson(path__default.join(projectPath, 'package.json'));
|
|
1181
|
+
const outputPath = path__default.join(config.tmpdir, 'mbler/0b09/release.zip');
|
|
1182
|
+
process.env.BUILD_MODULE = 'release';
|
|
1421
1183
|
const option = {
|
|
1422
1184
|
outdirs: {
|
|
1423
|
-
behavior: mblerConfig.outdir?.behavior ||
|
|
1424
|
-
|
|
1425
|
-
|
|
1185
|
+
behavior: mblerConfig.outdir?.behavior ||
|
|
1186
|
+
path__default.join(projectPath, 'dist', 'behavior'),
|
|
1187
|
+
resources: mblerConfig.outdir?.resources ||
|
|
1188
|
+
path__default.join(projectPath, 'dist', 'resources'),
|
|
1189
|
+
dist: outputPath,
|
|
1426
1190
|
},
|
|
1427
|
-
module:
|
|
1191
|
+
module: 'all',
|
|
1428
1192
|
};
|
|
1429
1193
|
if (!option.outdirs.behavior || !option.outdirs.resources) {
|
|
1430
1194
|
throw new Error(i18n.publish.outdirNotFound);
|
|
1431
1195
|
}
|
|
1432
|
-
if (!await fileExists(option.outdirs.behavior) ||
|
|
1196
|
+
if (!(await fileExists(option.outdirs.behavior)) ||
|
|
1197
|
+
!(await fileExists(option.outdirs.resources))) {
|
|
1433
1198
|
throw new Error(i18n.publish.outdirNotExist);
|
|
1434
1199
|
}
|
|
1435
1200
|
if (await fileExists(option.outdirs.behavior)) {
|
|
1436
|
-
option.module =
|
|
1201
|
+
option.module = 'behavior';
|
|
1437
1202
|
}
|
|
1438
1203
|
if (await fileExists(option.outdirs.resources)) {
|
|
1439
|
-
if (option.module ==
|
|
1440
|
-
option.module =
|
|
1204
|
+
if (option.module == 'behavior') {
|
|
1205
|
+
option.module = 'all';
|
|
1441
1206
|
}
|
|
1442
1207
|
else {
|
|
1443
|
-
option.module =
|
|
1208
|
+
option.module = 'resources';
|
|
1444
1209
|
}
|
|
1445
1210
|
}
|
|
1446
|
-
let readmePath = path__default.join(projectPath,
|
|
1447
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1448
|
-
readmePath = path__default.join(projectPath,
|
|
1211
|
+
let readmePath = path__default.join(projectPath, 'README.md');
|
|
1212
|
+
if (await fileExists(path__default.join(projectPath, 'README.md'))) {
|
|
1213
|
+
readmePath = path__default.join(projectPath, 'README.md');
|
|
1449
1214
|
}
|
|
1450
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1451
|
-
readmePath = path__default.join(projectPath,
|
|
1215
|
+
if (await fileExists(path__default.join(projectPath, 'readme.md'))) {
|
|
1216
|
+
readmePath = path__default.join(projectPath, 'readme.md');
|
|
1452
1217
|
}
|
|
1453
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1454
|
-
readmePath = path__default.join(projectPath,
|
|
1218
|
+
if (await fileExists(path__default.join(projectPath, 'Readme.md'))) {
|
|
1219
|
+
readmePath = path__default.join(projectPath, 'Readme.md');
|
|
1455
1220
|
}
|
|
1456
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1457
|
-
readmePath = path__default.join(projectPath,
|
|
1221
|
+
if (await fileExists(path__default.join(projectPath, 'README.MD'))) {
|
|
1222
|
+
readmePath = path__default.join(projectPath, 'README.MD');
|
|
1458
1223
|
}
|
|
1459
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1460
|
-
readmePath = path__default.join(projectPath,
|
|
1224
|
+
if (await fileExists(path__default.join(projectPath, 'readme.MD'))) {
|
|
1225
|
+
readmePath = path__default.join(projectPath, 'readme.MD');
|
|
1461
1226
|
}
|
|
1462
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1463
|
-
readmePath = path__default.join(projectPath,
|
|
1227
|
+
if (await fileExists(path__default.join(projectPath, 'Readme.MD'))) {
|
|
1228
|
+
readmePath = path__default.join(projectPath, 'Readme.MD');
|
|
1464
1229
|
}
|
|
1465
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1466
|
-
readmePath = path__default.join(projectPath,
|
|
1230
|
+
if (await fileExists(path__default.join(projectPath, 'README.markdown'))) {
|
|
1231
|
+
readmePath = path__default.join(projectPath, 'README.markdown');
|
|
1467
1232
|
}
|
|
1468
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1469
|
-
readmePath = path__default.join(projectPath,
|
|
1233
|
+
if (await fileExists(path__default.join(projectPath, 'readme.markdown'))) {
|
|
1234
|
+
readmePath = path__default.join(projectPath, 'readme.markdown');
|
|
1470
1235
|
}
|
|
1471
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1472
|
-
readmePath = path__default.join(projectPath,
|
|
1236
|
+
if (await fileExists(path__default.join(projectPath, 'Readme.markdown'))) {
|
|
1237
|
+
readmePath = path__default.join(projectPath, 'Readme.markdown');
|
|
1473
1238
|
}
|
|
1474
|
-
if (await fileExists(path__default.join(projectPath,
|
|
1475
|
-
readmePath = path__default.join(projectPath,
|
|
1239
|
+
if (await fileExists(path__default.join(projectPath, 'README'))) {
|
|
1240
|
+
readmePath = path__default.join(projectPath, 'README');
|
|
1476
1241
|
}
|
|
1477
|
-
if (!await fileExists(readmePath)) {
|
|
1242
|
+
if (!(await fileExists(readmePath))) {
|
|
1478
1243
|
throw new Error(i18n.publish.readmeNotFound);
|
|
1479
1244
|
}
|
|
1480
1245
|
const metadata = {
|
|
1481
|
-
readme: await readFile(readmePath,
|
|
1482
|
-
scope: (mblerConfig.name.split(
|
|
1483
|
-
|
|
1246
|
+
readme: await readFile(readmePath, 'utf-8'),
|
|
1247
|
+
scope: (mblerConfig.name.split('/').length > 1
|
|
1248
|
+
? mblerConfig.name.split('/')[0]
|
|
1249
|
+
: ''),
|
|
1250
|
+
name: mblerConfig.name.split('/').length > 1
|
|
1251
|
+
? (mblerConfig.name.split('/')[1] ?? '')
|
|
1252
|
+
: pkgData.name,
|
|
1484
1253
|
version: mblerConfig.version,
|
|
1485
|
-
version_tag: tag ||
|
|
1254
|
+
version_tag: tag || 'latest',
|
|
1486
1255
|
};
|
|
1487
|
-
if (!metadata.name ||
|
|
1256
|
+
if (!metadata.name ||
|
|
1257
|
+
!metadata.version ||
|
|
1258
|
+
!metadata.readme ||
|
|
1259
|
+
!metadata.scope) {
|
|
1488
1260
|
throw new Error(i18n.publish.metadataInvalid);
|
|
1489
1261
|
}
|
|
1490
1262
|
if (!/^@\w+\/\w+$/.test(mblerConfig.name)) {
|
|
@@ -1498,7 +1270,11 @@ class PublishManger {
|
|
|
1498
1270
|
await PublishManger.publishToMarketplace(outputPath, session);
|
|
1499
1271
|
onProgress(100);
|
|
1500
1272
|
onMessage(i18n.publish.publishSuccess);
|
|
1501
|
-
onMessage(fmt$6(i18n.publish.publishResult, {
|
|
1273
|
+
onMessage(fmt$6(i18n.publish.publishResult, {
|
|
1274
|
+
name: pkgData.name,
|
|
1275
|
+
version: metadata.version,
|
|
1276
|
+
tag: metadata.version_tag,
|
|
1277
|
+
}));
|
|
1502
1278
|
}
|
|
1503
1279
|
static async unpublish(scope, name, version) {
|
|
1504
1280
|
if (TokenManger.isLoading)
|
|
@@ -1509,17 +1285,17 @@ class PublishManger {
|
|
|
1509
1285
|
if (!token)
|
|
1510
1286
|
throw new Error(i18n.publish.tokenMissing);
|
|
1511
1287
|
const response = await fetch(`${config.defaultPmnxBASE}/unpublish/${scope}/${name}/${version}`, {
|
|
1512
|
-
method:
|
|
1288
|
+
method: 'POST',
|
|
1513
1289
|
headers: {
|
|
1514
|
-
|
|
1515
|
-
}
|
|
1290
|
+
Authorization: `Bearer ${token}`,
|
|
1291
|
+
},
|
|
1516
1292
|
});
|
|
1517
1293
|
if (!response.ok) {
|
|
1518
1294
|
throw new Error(i18n.publish.unpublishReqFailed);
|
|
1519
1295
|
}
|
|
1520
|
-
const result = await response.json();
|
|
1296
|
+
const result = (await response.json());
|
|
1521
1297
|
if (result.code !== 200) {
|
|
1522
|
-
throw new Error(`${i18n.publish.unpublishReqFailed}: ${result.data}`);
|
|
1298
|
+
throw new Error(`${i18n.publish.unpublishReqFailed}: ${JSON.stringify(result.data)}`);
|
|
1523
1299
|
}
|
|
1524
1300
|
return true;
|
|
1525
1301
|
}
|
|
@@ -1532,19 +1308,20 @@ class PublishManger {
|
|
|
1532
1308
|
if (!token)
|
|
1533
1309
|
throw new Error(i18n.publish.tokenMissing);
|
|
1534
1310
|
const response = await fetch(`${config.defaultPmnxBASE}/publish/session/${metadata.scope}/${metadata.name}/create`, {
|
|
1535
|
-
method:
|
|
1311
|
+
method: 'POST',
|
|
1536
1312
|
headers: {
|
|
1537
|
-
|
|
1538
|
-
|
|
1313
|
+
'Content-Type': 'application/json',
|
|
1314
|
+
Authorization: `Bearer ${token}`,
|
|
1539
1315
|
},
|
|
1540
|
-
body: JSON.stringify(metadata)
|
|
1316
|
+
body: JSON.stringify(metadata),
|
|
1541
1317
|
});
|
|
1542
|
-
const session = await response.json();
|
|
1318
|
+
const session = (await response.json());
|
|
1543
1319
|
if (!response.ok) {
|
|
1320
|
+
console.log(session);
|
|
1544
1321
|
throw new Error(i18n.publish.createSessionFailed);
|
|
1545
1322
|
}
|
|
1546
1323
|
const sessionKey = session?.data?.sessionKey || session?.data?.sessionId;
|
|
1547
|
-
if (typeof session.data !==
|
|
1324
|
+
if (typeof session.data !== 'object' || typeof sessionKey !== 'string') {
|
|
1548
1325
|
throw new Error(`${i18n.publish.createSessionFailed}: ${response.status} ${response.statusText}: ${session.data}`);
|
|
1549
1326
|
}
|
|
1550
1327
|
return sessionKey;
|
|
@@ -1553,44 +1330,48 @@ class PublishManger {
|
|
|
1553
1330
|
const formData = new FormData();
|
|
1554
1331
|
const fileBit = await readFile(zipPath);
|
|
1555
1332
|
let fileName = path__default.basename(zipPath);
|
|
1556
|
-
if (fileName.endsWith(
|
|
1557
|
-
fileName = fileName.slice(0, -
|
|
1333
|
+
if (fileName.endsWith('.mcaddon')) {
|
|
1334
|
+
fileName = fileName.slice(0, -'.mcaddon'.length) + '.zip';
|
|
1558
1335
|
}
|
|
1559
|
-
formData.append(
|
|
1336
|
+
formData.append('file', new File([fileBit], fileName, { type: 'application/zip' }));
|
|
1560
1337
|
const token = await TokenManger.getToken();
|
|
1561
1338
|
if (!token)
|
|
1562
1339
|
throw new Error(i18n.publish.tokenMissing);
|
|
1563
1340
|
const response = await fetch(`${config.defaultPmnxBASE}/publish/session/${session}/upload`, {
|
|
1564
|
-
method:
|
|
1341
|
+
method: 'POST',
|
|
1565
1342
|
headers: {
|
|
1566
|
-
|
|
1343
|
+
Authorization: `Bearer ${token}`,
|
|
1567
1344
|
},
|
|
1568
|
-
body: formData
|
|
1345
|
+
body: formData,
|
|
1569
1346
|
});
|
|
1570
|
-
const result = await response.json();
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1347
|
+
const result = (await response.json());
|
|
1348
|
+
const responseData = result.data;
|
|
1349
|
+
if (typeof responseData !== 'string' ||
|
|
1350
|
+
!responseData.includes('successfully')) {
|
|
1351
|
+
throw new Error(`${i18n.publish.uploadZipFailed}: ${result.data}` +
|
|
1352
|
+
JSON.stringify({
|
|
1353
|
+
url: `${config.defaultPmnxBASE}/publish/session/${session}/upload`,
|
|
1354
|
+
status: response.status,
|
|
1355
|
+
statusText: response.statusText,
|
|
1356
|
+
body: result,
|
|
1357
|
+
file: zipPath,
|
|
1358
|
+
}, null, 2));
|
|
1579
1359
|
}
|
|
1580
1360
|
return true;
|
|
1581
1361
|
}
|
|
1582
1362
|
static async buildProject(projectPath) {
|
|
1583
|
-
const pkgData = await readFileAsJson(path__default.join(projectPath,
|
|
1363
|
+
const pkgData = await readFileAsJson(path__default.join(projectPath, 'package.json'));
|
|
1584
1364
|
if (!pkgData) {
|
|
1585
1365
|
throw new Error(i18n.publish.packageJsonNotFound);
|
|
1586
1366
|
}
|
|
1587
|
-
|
|
1367
|
+
const scripts = pkgData.scripts;
|
|
1368
|
+
if (!scripts?.build) {
|
|
1588
1369
|
throw new Error(i18n.publish.noBuildScript);
|
|
1589
1370
|
}
|
|
1590
|
-
const pkgManager = pkgData.packageManager ||
|
|
1371
|
+
const pkgManager = pkgData.packageManager || 'npm';
|
|
1591
1372
|
await new Promise((resolve, reject) => {
|
|
1592
|
-
const child = spawn(pkgManager, [
|
|
1593
|
-
child.on(
|
|
1373
|
+
const child = spawn(pkgManager, ['run', 'build'], { cwd: projectPath });
|
|
1374
|
+
child.on('close', (code) => {
|
|
1594
1375
|
if (code === 0) {
|
|
1595
1376
|
resolve(void 0);
|
|
1596
1377
|
}
|
|
@@ -1603,7 +1384,7 @@ class PublishManger {
|
|
|
1603
1384
|
}
|
|
1604
1385
|
|
|
1605
1386
|
function fmt$5(t, vars) {
|
|
1606
|
-
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ??
|
|
1387
|
+
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? ''));
|
|
1607
1388
|
}
|
|
1608
1389
|
function parsePackage$3(pkg) {
|
|
1609
1390
|
const result = /^(@[^/@\s]+)\/([^@\s]+)@(.+)$/.exec(pkg);
|
|
@@ -1615,7 +1396,7 @@ function parsePackage$3(pkg) {
|
|
|
1615
1396
|
version: result[3],
|
|
1616
1397
|
};
|
|
1617
1398
|
}
|
|
1618
|
-
async function unpublishCommand(cliParam,
|
|
1399
|
+
async function unpublishCommand(cliParam, _work) {
|
|
1619
1400
|
const pkg = cliParam.params[1];
|
|
1620
1401
|
if (!pkg) {
|
|
1621
1402
|
showText(i18n.help.unpublish);
|
|
@@ -1628,22 +1409,29 @@ async function unpublishCommand(cliParam, work) {
|
|
|
1628
1409
|
}
|
|
1629
1410
|
try {
|
|
1630
1411
|
await PublishManger.unpublish(parsed.scope, parsed.name, parsed.version);
|
|
1631
|
-
showText(fmt$5(i18n.unpublish.success, {
|
|
1412
|
+
showText(fmt$5(i18n.unpublish.success, {
|
|
1413
|
+
pkg: `${parsed.scope}/${parsed.name}`,
|
|
1414
|
+
version: parsed.version,
|
|
1415
|
+
}));
|
|
1632
1416
|
return 0;
|
|
1633
1417
|
}
|
|
1634
1418
|
catch (error) {
|
|
1635
|
-
showText(fmt$5(i18n.unpublish.failed, {
|
|
1419
|
+
showText(fmt$5(i18n.unpublish.failed, {
|
|
1420
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1421
|
+
}));
|
|
1636
1422
|
return -1;
|
|
1637
1423
|
}
|
|
1638
1424
|
}
|
|
1639
1425
|
|
|
1640
1426
|
function fmt$4(t, vars) {
|
|
1641
|
-
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ??
|
|
1427
|
+
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? ''));
|
|
1642
1428
|
}
|
|
1643
1429
|
async function publishCommand(cliParam, work) {
|
|
1644
|
-
const tag = cliParam.opts.tag ||
|
|
1645
|
-
|
|
1646
|
-
|
|
1430
|
+
const tag = cliParam.opts.tag ||
|
|
1431
|
+
cliParam.params.find((p) => p.startsWith('-tag='))?.split('=')[1] ||
|
|
1432
|
+
'latest';
|
|
1433
|
+
const buildRaw = (cliParam.opts.build || '').trim().toLowerCase();
|
|
1434
|
+
const buildMode = buildRaw === 'skip' ? 'skip' : 'enable';
|
|
1647
1435
|
try {
|
|
1648
1436
|
await TokenManger.waitVeirfy();
|
|
1649
1437
|
if (!TokenManger.isLogin) {
|
|
@@ -1654,7 +1442,7 @@ async function publishCommand(cliParam, work) {
|
|
|
1654
1442
|
build: buildMode,
|
|
1655
1443
|
tag,
|
|
1656
1444
|
onProgress: (progress) => showText(fmt$4(i18n.publish.progress, { progress })),
|
|
1657
|
-
onMessage: (message) => showText(message)
|
|
1445
|
+
onMessage: (message) => showText(message),
|
|
1658
1446
|
});
|
|
1659
1447
|
return 0;
|
|
1660
1448
|
}
|
|
@@ -1667,22 +1455,27 @@ async function publishCommand(cliParam, work) {
|
|
|
1667
1455
|
}
|
|
1668
1456
|
|
|
1669
1457
|
class GamePath {
|
|
1458
|
+
/**
|
|
1459
|
+
* Ask user mcbe game path
|
|
1460
|
+
* @param autoset - Can auto set game path to config
|
|
1461
|
+
* @returns {Promise<string>} - Game Path
|
|
1462
|
+
*/
|
|
1670
1463
|
static async askPath(autoset = true) {
|
|
1671
1464
|
const result = await input(i18n.publish.askTip);
|
|
1672
1465
|
if (!result) {
|
|
1673
|
-
throw new Error(
|
|
1466
|
+
throw new Error('No path provided');
|
|
1674
1467
|
}
|
|
1675
1468
|
if (autoset) {
|
|
1676
|
-
ConfigManger.setKey(
|
|
1469
|
+
ConfigManger.setKey('gamePath', result);
|
|
1677
1470
|
}
|
|
1678
1471
|
return result;
|
|
1679
1472
|
}
|
|
1680
1473
|
static async getPath() {
|
|
1681
|
-
const path = await ConfigManger.getKey(
|
|
1474
|
+
const path = await ConfigManger.getKey('gamePath');
|
|
1682
1475
|
return path || null;
|
|
1683
1476
|
}
|
|
1684
1477
|
static async clearPath() {
|
|
1685
|
-
await ConfigManger.setKey(
|
|
1478
|
+
await ConfigManger.setKey('gamePath', '');
|
|
1686
1479
|
}
|
|
1687
1480
|
static async getPathWithASK() {
|
|
1688
1481
|
let path = await this.getPath();
|
|
@@ -1694,7 +1487,7 @@ class GamePath {
|
|
|
1694
1487
|
}
|
|
1695
1488
|
|
|
1696
1489
|
function fmt$3(t, vars) {
|
|
1697
|
-
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ??
|
|
1490
|
+
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? ''));
|
|
1698
1491
|
}
|
|
1699
1492
|
function parsePackage$2(pkg) {
|
|
1700
1493
|
const result = /^(@[^/@\s]+)\/([^@\s]+)@(.+)$/.exec(pkg);
|
|
@@ -1706,7 +1499,7 @@ function parsePackage$2(pkg) {
|
|
|
1706
1499
|
version: result[3],
|
|
1707
1500
|
};
|
|
1708
1501
|
}
|
|
1709
|
-
async function uninstallCommand(cliParam,
|
|
1502
|
+
async function uninstallCommand(cliParam, _work) {
|
|
1710
1503
|
const pkg = cliParam.params[1];
|
|
1711
1504
|
if (!pkg) {
|
|
1712
1505
|
showText(i18n.help.uninstall);
|
|
@@ -1724,26 +1517,32 @@ async function uninstallCommand(cliParam, work) {
|
|
|
1724
1517
|
}
|
|
1725
1518
|
try {
|
|
1726
1519
|
const id = `${parsed.scope.slice(1)}-${parsed.name}-${parsed.version}`;
|
|
1727
|
-
const behaviorDir = path__default.join(gamePoint,
|
|
1728
|
-
const resourceDir = path__default.join(gamePoint,
|
|
1729
|
-
await fs__default
|
|
1730
|
-
await fs__default
|
|
1520
|
+
const behaviorDir = path__default.join(gamePoint, 'behavior_packs', id);
|
|
1521
|
+
const resourceDir = path__default.join(gamePoint, 'resource_packs', id);
|
|
1522
|
+
await fs__default.rm(behaviorDir, { recursive: true, force: true });
|
|
1523
|
+
await fs__default.rm(resourceDir, { recursive: true, force: true });
|
|
1731
1524
|
// Remove from installed packages
|
|
1732
|
-
const installed = (await ConfigManger.getKey(
|
|
1525
|
+
const installed = (await ConfigManger.getKey('installedPackages')) ||
|
|
1526
|
+
[];
|
|
1733
1527
|
const filtered = installed.filter((pkg) => pkg.id !== id);
|
|
1734
|
-
await ConfigManger.setKey(
|
|
1735
|
-
showText(fmt$3(i18n.uninstall.success, {
|
|
1528
|
+
await ConfigManger.setKey('installedPackages', filtered);
|
|
1529
|
+
showText(fmt$3(i18n.uninstall.success, {
|
|
1530
|
+
pkg: `${parsed.scope}/${parsed.name}`,
|
|
1531
|
+
version: parsed.version,
|
|
1532
|
+
}));
|
|
1736
1533
|
return 0;
|
|
1737
1534
|
}
|
|
1738
1535
|
catch (error) {
|
|
1739
|
-
showText(fmt$3(i18n.uninstall.failed, {
|
|
1536
|
+
showText(fmt$3(i18n.uninstall.failed, {
|
|
1537
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1538
|
+
}));
|
|
1740
1539
|
return -1;
|
|
1741
1540
|
}
|
|
1742
1541
|
}
|
|
1743
1542
|
|
|
1744
1543
|
class InstallManger {
|
|
1745
1544
|
static encodeScope(scope) {
|
|
1746
|
-
return encodeURIComponent(scope.startsWith(
|
|
1545
|
+
return encodeURIComponent(scope.startsWith('@') ? scope : `@${scope}`);
|
|
1747
1546
|
}
|
|
1748
1547
|
static encodePart(v) {
|
|
1749
1548
|
return encodeURIComponent(v);
|
|
@@ -1758,9 +1557,9 @@ class InstallManger {
|
|
|
1758
1557
|
}
|
|
1759
1558
|
static async info(scope, name) {
|
|
1760
1559
|
const response = await fetch(`${config.defaultPmnxBASE}/package/${this.encodeScope(scope)}/${this.encodePart(name)}/info`);
|
|
1761
|
-
const data = await response.json();
|
|
1560
|
+
const data = (await response.json());
|
|
1762
1561
|
if (data.code !== 200) {
|
|
1763
|
-
throw new Error(`Failed to get package info: ${data.data}`);
|
|
1562
|
+
throw new Error(`Failed to get package info: ${JSON.stringify(data.data)}`);
|
|
1764
1563
|
}
|
|
1765
1564
|
return data.data;
|
|
1766
1565
|
}
|
|
@@ -1769,16 +1568,16 @@ class InstallManger {
|
|
|
1769
1568
|
if (!response.ok) {
|
|
1770
1569
|
throw new Error(`Failed to get package version info: ${response.status} ${response.statusText}`);
|
|
1771
1570
|
}
|
|
1772
|
-
const data = await response.json();
|
|
1571
|
+
const data = (await response.json());
|
|
1773
1572
|
if (data.code !== 200) {
|
|
1774
|
-
throw new Error(`Failed to get package version info: ${data.data}`);
|
|
1573
|
+
throw new Error(`Failed to get package version info: ${JSON.stringify(data.data)}`);
|
|
1775
1574
|
}
|
|
1776
1575
|
return data.data;
|
|
1777
1576
|
}
|
|
1778
1577
|
}
|
|
1779
1578
|
|
|
1780
1579
|
function fmt$2(t, vars) {
|
|
1781
|
-
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ??
|
|
1580
|
+
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? ''));
|
|
1782
1581
|
}
|
|
1783
1582
|
function parsePackage$1(pkg) {
|
|
1784
1583
|
const result = /^(@[^/@\s]+)\/([^@\s]+)(?:@(.+))?$/.exec(pkg);
|
|
@@ -1796,11 +1595,11 @@ function parsePackage$1(pkg) {
|
|
|
1796
1595
|
function pickLatestVersion(versions) {
|
|
1797
1596
|
const validVersions = versions.filter(isVaildVersion);
|
|
1798
1597
|
if (validVersions.length > 0) {
|
|
1799
|
-
return validVersions.sort(compareVersion).reverse()[0] ||
|
|
1598
|
+
return validVersions.sort(compareVersion).reverse()[0] || '';
|
|
1800
1599
|
}
|
|
1801
|
-
return versions[0] ||
|
|
1600
|
+
return versions[0] || '';
|
|
1802
1601
|
}
|
|
1803
|
-
async function installCommand(cliParam,
|
|
1602
|
+
async function installCommand(cliParam, _work) {
|
|
1804
1603
|
const pkg = cliParam.params[1];
|
|
1805
1604
|
if (!pkg) {
|
|
1806
1605
|
showText(i18n.help.install);
|
|
@@ -1812,22 +1611,12 @@ async function installCommand(cliParam, work) {
|
|
|
1812
1611
|
return -1;
|
|
1813
1612
|
}
|
|
1814
1613
|
const { scope, name } = parsed;
|
|
1815
|
-
let version = parsed.version ||
|
|
1614
|
+
let version = parsed.version || '';
|
|
1816
1615
|
const gamePoint = await GamePath.getPathWithASK();
|
|
1817
1616
|
if (!gamePoint) {
|
|
1818
1617
|
showText(i18n.help.install);
|
|
1819
1618
|
return -1;
|
|
1820
1619
|
}
|
|
1821
|
-
const packageJsonPath = path__default.join(work, "package.json");
|
|
1822
|
-
if (!await fs__default$1.stat(packageJsonPath).catch(() => null)) {
|
|
1823
|
-
showText(i18n.install.failedNoPackageJson);
|
|
1824
|
-
return -1;
|
|
1825
|
-
}
|
|
1826
|
-
const packageJson = JSON.parse(await fs__default$1.readFile(packageJsonPath, "utf-8"));
|
|
1827
|
-
if (!packageJson.scripts?.build) {
|
|
1828
|
-
showText(i18n.install.failedNoBuildScript);
|
|
1829
|
-
return -1;
|
|
1830
|
-
}
|
|
1831
1620
|
showText(fmt$2(i18n.install.installing, { pkg }));
|
|
1832
1621
|
try {
|
|
1833
1622
|
if (!version) {
|
|
@@ -1838,7 +1627,7 @@ async function installCommand(cliParam, work) {
|
|
|
1838
1627
|
}
|
|
1839
1628
|
const versionCandidates = pkgInfo.versions
|
|
1840
1629
|
.map((item) => item.name)
|
|
1841
|
-
.filter((name) => typeof name ===
|
|
1630
|
+
.filter((name) => typeof name === 'string' && name.length > 0);
|
|
1842
1631
|
version = pickLatestVersion(versionCandidates);
|
|
1843
1632
|
if (!version) {
|
|
1844
1633
|
showText(fmt$2(i18n.install.noVersion, { pkg: `${scope}/${name}` }));
|
|
@@ -1846,26 +1635,33 @@ async function installCommand(cliParam, work) {
|
|
|
1846
1635
|
}
|
|
1847
1636
|
showText(fmt$2(i18n.install.usingLatest, { version }));
|
|
1848
1637
|
}
|
|
1849
|
-
const tmpDir = path__default.join(config.tmpdir,
|
|
1850
|
-
await fs__default
|
|
1851
|
-
await InstallManger.download(scope, name, version, path__default.join(tmpDir,
|
|
1852
|
-
const
|
|
1638
|
+
const tmpDir = path__default.join(config.tmpdir, 'tmp_mbler_install', `${Date.now()}`);
|
|
1639
|
+
await fs__default.mkdir(tmpDir, { recursive: true });
|
|
1640
|
+
await InstallManger.download(scope, name, version, path__default.join(tmpDir, 'package.zip'));
|
|
1641
|
+
const AdmZip = require('adm-zip');
|
|
1642
|
+
const zip = new AdmZip(path__default.join(tmpDir, 'package.zip'));
|
|
1853
1643
|
zip.extractAllTo(tmpDir, true);
|
|
1854
1644
|
async function findAddonRoots(dir) {
|
|
1855
1645
|
const results = [];
|
|
1856
1646
|
async function walk(p) {
|
|
1857
|
-
const entries = await fs__default
|
|
1647
|
+
const entries = await fs__default.readdir(p, { withFileTypes: true });
|
|
1858
1648
|
for (const entry of entries) {
|
|
1859
1649
|
const entryPath = path__default.join(p, entry.name);
|
|
1860
|
-
if (entry.isFile() && entry.name ===
|
|
1650
|
+
if (entry.isFile() && entry.name === 'manifest.json') {
|
|
1861
1651
|
try {
|
|
1862
|
-
const manifest = JSON.parse(await fs__default
|
|
1652
|
+
const manifest = JSON.parse(await fs__default.readFile(entryPath, 'utf-8'));
|
|
1863
1653
|
const type = manifest?.modules?.[0]?.type;
|
|
1864
|
-
if (type ===
|
|
1865
|
-
results.push({
|
|
1654
|
+
if (type === 'data') {
|
|
1655
|
+
results.push({
|
|
1656
|
+
root: path__default.dirname(entryPath),
|
|
1657
|
+
type: 'behavior',
|
|
1658
|
+
});
|
|
1866
1659
|
}
|
|
1867
|
-
else if (type ===
|
|
1868
|
-
results.push({
|
|
1660
|
+
else if (type === 'resources') {
|
|
1661
|
+
results.push({
|
|
1662
|
+
root: path__default.dirname(entryPath),
|
|
1663
|
+
type: 'resource',
|
|
1664
|
+
});
|
|
1869
1665
|
}
|
|
1870
1666
|
}
|
|
1871
1667
|
catch {
|
|
@@ -1885,41 +1681,34 @@ async function installCommand(cliParam, work) {
|
|
|
1885
1681
|
throw new Error(i18n.install.noValidAddon);
|
|
1886
1682
|
}
|
|
1887
1683
|
const id = `${scope.slice(1)}-${name}-${version}`;
|
|
1888
|
-
const installed = (await ConfigManger.getKey(
|
|
1684
|
+
const installed = (await ConfigManger.getKey('installedPackages')) || [];
|
|
1889
1685
|
for (const addon of addons) {
|
|
1890
|
-
const packDir = addon.type ===
|
|
1686
|
+
const packDir = addon.type === 'behavior' ? 'behavior_packs' : 'resource_packs';
|
|
1891
1687
|
const dest = path__default.join(gamePoint, packDir, id);
|
|
1892
|
-
await fs__default
|
|
1893
|
-
await fs__default
|
|
1688
|
+
await fs__default.mkdir(dest, { recursive: true });
|
|
1689
|
+
await fs__default.cp(addon.root, dest, { recursive: true });
|
|
1894
1690
|
installed.push({ id, scope, name, version, type: addon.type });
|
|
1895
1691
|
}
|
|
1896
|
-
await ConfigManger.setKey(
|
|
1897
|
-
await fs__default
|
|
1898
|
-
await new Promise((resolve, reject) => {
|
|
1899
|
-
const child = spawn("pnpm", ["build"], { cwd: work });
|
|
1900
|
-
child.on("close", (code) => {
|
|
1901
|
-
if (code === 0)
|
|
1902
|
-
resolve();
|
|
1903
|
-
else
|
|
1904
|
-
reject(new Error(i18n.publish.buildFailed.replace("{code}", String(code))));
|
|
1905
|
-
});
|
|
1906
|
-
});
|
|
1692
|
+
await ConfigManger.setKey('installedPackages', installed);
|
|
1693
|
+
await fs__default.rm(tmpDir, { recursive: true, force: true });
|
|
1907
1694
|
showText(fmt$2(i18n.install.success, { pkg: `${scope}/${name}`, version, id }));
|
|
1908
1695
|
return 0;
|
|
1909
1696
|
}
|
|
1910
1697
|
catch (error) {
|
|
1911
|
-
showText(fmt$2(i18n.install.failed, {
|
|
1698
|
+
showText(fmt$2(i18n.install.failed, {
|
|
1699
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1700
|
+
}));
|
|
1912
1701
|
return -1;
|
|
1913
1702
|
}
|
|
1914
1703
|
}
|
|
1915
1704
|
|
|
1916
|
-
async function loginCommand(cliParam,
|
|
1705
|
+
async function loginCommand(cliParam, _work) {
|
|
1917
1706
|
let token = cliParam.params[1];
|
|
1918
1707
|
if (!token) {
|
|
1919
|
-
token = await input(
|
|
1708
|
+
token = await input('Token: ', true);
|
|
1920
1709
|
}
|
|
1921
1710
|
if (!token) {
|
|
1922
|
-
showText(
|
|
1711
|
+
showText('Token is required');
|
|
1923
1712
|
return -1;
|
|
1924
1713
|
}
|
|
1925
1714
|
try {
|
|
@@ -1927,14 +1716,14 @@ async function loginCommand(cliParam, work) {
|
|
|
1927
1716
|
await TokenManger.setToken(token.trim());
|
|
1928
1717
|
await TokenManger.waitVeirfy();
|
|
1929
1718
|
if (!TokenManger.isLogin) {
|
|
1930
|
-
if (prevToken && typeof prevToken ===
|
|
1719
|
+
if (prevToken && typeof prevToken === 'string') {
|
|
1931
1720
|
await TokenManger.setToken(prevToken);
|
|
1932
1721
|
await TokenManger.waitVeirfy();
|
|
1933
1722
|
}
|
|
1934
|
-
showText(
|
|
1723
|
+
showText('Login failed: invalid token');
|
|
1935
1724
|
return -1;
|
|
1936
1725
|
}
|
|
1937
|
-
showText(`Login successful: ${TokenManger.user?.name ||
|
|
1726
|
+
showText(`Login successful: ${TokenManger.user?.name || 'unknown user'}`);
|
|
1938
1727
|
return 0;
|
|
1939
1728
|
}
|
|
1940
1729
|
catch (error) {
|
|
@@ -1947,7 +1736,7 @@ async function profileCommand(_, __) {
|
|
|
1947
1736
|
try {
|
|
1948
1737
|
await TokenManger.waitVeirfy();
|
|
1949
1738
|
if (!TokenManger.isLogin || !TokenManger.user) {
|
|
1950
|
-
showText(
|
|
1739
|
+
showText(i18n.publish.notLoggedIn);
|
|
1951
1740
|
return -1;
|
|
1952
1741
|
}
|
|
1953
1742
|
const user = TokenManger.user;
|
|
@@ -1956,7 +1745,7 @@ async function profileCommand(_, __) {
|
|
|
1956
1745
|
showText(`Mail: ${user.mail}`);
|
|
1957
1746
|
showText(`Created: ${user.ctime}`);
|
|
1958
1747
|
if (user.avatar_url) {
|
|
1959
|
-
showText(`Avatar: ${user.avatar_url}`);
|
|
1748
|
+
showText(`Avatar URL: ${user.avatar_url}`);
|
|
1960
1749
|
}
|
|
1961
1750
|
return 0;
|
|
1962
1751
|
}
|
|
@@ -1967,13 +1756,13 @@ async function profileCommand(_, __) {
|
|
|
1967
1756
|
}
|
|
1968
1757
|
|
|
1969
1758
|
function fmt$1(t, vars) {
|
|
1970
|
-
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ??
|
|
1759
|
+
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? ''));
|
|
1971
1760
|
}
|
|
1972
1761
|
function parsePackage(pkg) {
|
|
1973
1762
|
const result = /^(@?[^/@\s]+)\/([^@\s]+)$/.exec(pkg);
|
|
1974
1763
|
if (!result)
|
|
1975
1764
|
return null;
|
|
1976
|
-
const scope = result[1].startsWith(
|
|
1765
|
+
const scope = result[1].startsWith('@') ? result[1] : `@${result[1]}`;
|
|
1977
1766
|
return {
|
|
1978
1767
|
scope,
|
|
1979
1768
|
name: result[2],
|
|
@@ -1999,7 +1788,9 @@ async function viewCommand(cliParam, _) {
|
|
|
1999
1788
|
info = await InstallManger.info(parsed.scope.slice(1), parsed.name);
|
|
2000
1789
|
}
|
|
2001
1790
|
if (!info.versions || info.versions.length === 0) {
|
|
2002
|
-
showText(fmt$1(i18n.view.packageNotFound, {
|
|
1791
|
+
showText(fmt$1(i18n.view.packageNotFound, {
|
|
1792
|
+
pkg: `${parsed.scope}/${parsed.name}`,
|
|
1793
|
+
}));
|
|
2003
1794
|
return -1;
|
|
2004
1795
|
}
|
|
2005
1796
|
showText(fmt$1(i18n.view.title, { pkg: `${parsed.scope}/${parsed.name}` }));
|
|
@@ -2007,7 +1798,7 @@ async function viewCommand(cliParam, _) {
|
|
|
2007
1798
|
showText(fmt$1(i18n.view.versionLine, {
|
|
2008
1799
|
version: v.name,
|
|
2009
1800
|
tag: v.version_tag,
|
|
2010
|
-
user: v.create_user?.name ||
|
|
1801
|
+
user: v.create_user?.name || 'unknown',
|
|
2011
1802
|
time: v.create_time,
|
|
2012
1803
|
}));
|
|
2013
1804
|
}
|
|
@@ -2022,7 +1813,7 @@ async function viewCommand(cliParam, _) {
|
|
|
2022
1813
|
}
|
|
2023
1814
|
|
|
2024
1815
|
function fmt(t, vars) {
|
|
2025
|
-
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ??
|
|
1816
|
+
return t.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? ''));
|
|
2026
1817
|
}
|
|
2027
1818
|
function parseValue(raw) {
|
|
2028
1819
|
const v = raw.trim();
|
|
@@ -2039,7 +1830,7 @@ function parseValue(raw) {
|
|
|
2039
1830
|
}
|
|
2040
1831
|
}
|
|
2041
1832
|
function valueToString(value) {
|
|
2042
|
-
if (value !== null && typeof value ===
|
|
1833
|
+
if (value !== null && typeof value === 'object') {
|
|
2043
1834
|
return JSON.stringify(value);
|
|
2044
1835
|
}
|
|
2045
1836
|
return String(value);
|
|
@@ -2051,7 +1842,7 @@ async function configCommand(cliParam, _) {
|
|
|
2051
1842
|
showText(i18n.config.usage);
|
|
2052
1843
|
return -1;
|
|
2053
1844
|
}
|
|
2054
|
-
if (sub ===
|
|
1845
|
+
if (sub === 'get') {
|
|
2055
1846
|
const key = cliParam.params[2];
|
|
2056
1847
|
if (!key) {
|
|
2057
1848
|
showText(i18n.config.missingArg);
|
|
@@ -2061,9 +1852,9 @@ async function configCommand(cliParam, _) {
|
|
|
2061
1852
|
showText(fmt(i18n.config.getResult, { key, value: valueToString(value) }));
|
|
2062
1853
|
return 0;
|
|
2063
1854
|
}
|
|
2064
|
-
if (sub ===
|
|
1855
|
+
if (sub === 'set') {
|
|
2065
1856
|
const key = cliParam.params[2];
|
|
2066
|
-
const raw = cliParam.params.slice(3).join(
|
|
1857
|
+
const raw = cliParam.params.slice(3).join(' ');
|
|
2067
1858
|
if (!key || raw.length < 1) {
|
|
2068
1859
|
showText(i18n.config.missingArg);
|
|
2069
1860
|
return -1;
|
|
@@ -2071,15 +1862,15 @@ async function configCommand(cliParam, _) {
|
|
|
2071
1862
|
const value = parseValue(raw);
|
|
2072
1863
|
const ok = await ConfigManger.setKey(key, value);
|
|
2073
1864
|
if (!ok) {
|
|
2074
|
-
showText(fmt(i18n.config.failed, { error:
|
|
1865
|
+
showText(fmt(i18n.config.failed, { error: 'write failed' }));
|
|
2075
1866
|
return -1;
|
|
2076
1867
|
}
|
|
2077
1868
|
showText(fmt(i18n.config.setSuccess, { key, value: valueToString(value) }));
|
|
2078
1869
|
return 0;
|
|
2079
1870
|
}
|
|
2080
|
-
if (sub ===
|
|
1871
|
+
if (sub === 'point') {
|
|
2081
1872
|
const next = cliParam.params[2];
|
|
2082
|
-
if (!next || next ===
|
|
1873
|
+
if (!next || next === 'get') {
|
|
2083
1874
|
const point = await ConfigManger.getConfigPoint();
|
|
2084
1875
|
showText(fmt(i18n.config.pointGet, { path: point }));
|
|
2085
1876
|
return 0;
|
|
@@ -2153,7 +1944,6 @@ const main = (function () {
|
|
|
2153
1944
|
}
|
|
2154
1945
|
function getMatchChance(a, b) {
|
|
2155
1946
|
let match = 0;
|
|
2156
|
-
// b = 比较值,a = 待比较值
|
|
2157
1947
|
for (let i = 0; i < b.length; i++) {
|
|
2158
1948
|
if (a[i] == b[i])
|
|
2159
1949
|
match++;
|
|
@@ -2200,15 +1990,15 @@ const main = (function () {
|
|
|
2200
1990
|
max: cur,
|
|
2201
1991
|
index: index,
|
|
2202
1992
|
indices: [],
|
|
2203
|
-
};
|
|
1993
|
+
};
|
|
2204
1994
|
}
|
|
2205
1995
|
else if (cur === acc.max) {
|
|
2206
|
-
acc.indices.push(index);
|
|
1996
|
+
acc.indices.push(index);
|
|
2207
1997
|
return acc;
|
|
2208
1998
|
}
|
|
2209
1999
|
}
|
|
2210
2000
|
catch (err) {
|
|
2211
|
-
Logger.w('matchDefault', err.stack);
|
|
2001
|
+
Logger.w('matchDefault', err.stack || err.message);
|
|
2212
2002
|
}
|
|
2213
2003
|
return acc;
|
|
2214
2004
|
}, {
|
|
@@ -2223,11 +2013,28 @@ const main = (function () {
|
|
|
2223
2013
|
return async function cli() {
|
|
2224
2014
|
const cliParam = parseParam();
|
|
2225
2015
|
const handlerBuild = async (cliParam, workDir) => {
|
|
2226
|
-
const { build } = typeof require ==
|
|
2016
|
+
const { build } = typeof require == 'function'
|
|
2017
|
+
? require('mbler/build')
|
|
2018
|
+
: await import('mbler/build');
|
|
2227
2019
|
return await build(cliParam, workDir);
|
|
2228
2020
|
};
|
|
2021
|
+
const handlerLog = async (cliParam) => {
|
|
2022
|
+
if (cliParam.params[1] == 'point') {
|
|
2023
|
+
showText(Logger.LogFile);
|
|
2024
|
+
}
|
|
2025
|
+
else if (cliParam.params[1] == 'clean') {
|
|
2026
|
+
await rm(Logger.LogFile, {
|
|
2027
|
+
recursive: true,
|
|
2028
|
+
force: true,
|
|
2029
|
+
});
|
|
2030
|
+
}
|
|
2031
|
+
else {
|
|
2032
|
+
showText('Unkown log Command');
|
|
2033
|
+
}
|
|
2034
|
+
return 0;
|
|
2035
|
+
};
|
|
2229
2036
|
const handlerWatch = async (cliParam, workDir) => {
|
|
2230
|
-
const { watch } = require(
|
|
2037
|
+
const { watch } = require('mbler/build');
|
|
2231
2038
|
return await watch(cliParam, workDir);
|
|
2232
2039
|
};
|
|
2233
2040
|
const cmdMap = {
|
|
@@ -2239,6 +2046,7 @@ const main = (function () {
|
|
|
2239
2046
|
watch: handlerWatch,
|
|
2240
2047
|
init: initCommand,
|
|
2241
2048
|
version: handlerVersion,
|
|
2049
|
+
log: handlerLog,
|
|
2242
2050
|
lang: langCommand,
|
|
2243
2051
|
'set-work-dir': handlerSetWorkDirCommand,
|
|
2244
2052
|
unpublish: unpublishCommand,
|
|
@@ -2248,7 +2056,7 @@ const main = (function () {
|
|
|
2248
2056
|
login: loginCommand,
|
|
2249
2057
|
profile: profileCommand,
|
|
2250
2058
|
view: viewCommand,
|
|
2251
|
-
config: configCommand
|
|
2059
|
+
config: configCommand,
|
|
2252
2060
|
};
|
|
2253
2061
|
const cmd = cliParam.params[0];
|
|
2254
2062
|
if (cliParam.opts.cwp) {
|
|
@@ -2267,12 +2075,18 @@ const main = (function () {
|
|
|
2267
2075
|
}
|
|
2268
2076
|
else {
|
|
2269
2077
|
const r = handler(cliParam, await currentWDManage.get());
|
|
2270
|
-
if (r
|
|
2078
|
+
if (typeof r == 'object' && typeof r.then == 'function') {
|
|
2271
2079
|
const code = await r;
|
|
2272
2080
|
process.exit(code);
|
|
2273
2081
|
}
|
|
2274
2082
|
else {
|
|
2275
|
-
|
|
2083
|
+
if (typeof r == 'number') {
|
|
2084
|
+
process.exit(r);
|
|
2085
|
+
}
|
|
2086
|
+
else {
|
|
2087
|
+
showText("Mbler internal Error: can't resolve exit code");
|
|
2088
|
+
process.exit(1);
|
|
2089
|
+
}
|
|
2276
2090
|
}
|
|
2277
2091
|
}
|
|
2278
2092
|
process.exit(0);
|
|
@@ -2288,5 +2102,5 @@ function defineConfig(config) {
|
|
|
2288
2102
|
return config;
|
|
2289
2103
|
}
|
|
2290
2104
|
|
|
2291
|
-
export {
|
|
2105
|
+
export { LanguageNames, main as cli, cmdList, index as commander, defineConfig, i18n, templateMblerConfig };
|
|
2292
2106
|
//# sourceMappingURL=index.esm.mjs.map
|