@sfmc-bds/cli 0.2.0-beta.9 → 0.2.1
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/LICENSE +663 -0
- package/README.md +4 -5
- package/dist/bds-runtime-version.d.ts +3 -0
- package/dist/bds-runtime-version.d.ts.map +1 -0
- package/dist/bds-runtime-version.js +15 -0
- package/dist/bds-runtime-version.js.map +7 -0
- package/dist/command-surface.d.ts.map +1 -1
- package/dist/command-surface.js +3 -1
- package/dist/command-surface.js.map +2 -2
- package/dist/commands.d.ts +57 -4
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +78 -75
- package/dist/commands.js.map +2 -2
- package/dist/directory-picker.d.ts +27 -0
- package/dist/directory-picker.d.ts.map +1 -0
- package/dist/directory-picker.js +112 -0
- package/dist/directory-picker.js.map +7 -0
- package/dist/i18n/locales/en.d.ts +25 -1
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +25 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
- package/dist/i18n/locales/zh-CN.js +26 -2
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/interactive-prompts.d.ts +1 -2
- package/dist/interactive-prompts.d.ts.map +1 -1
- package/dist/interactive-prompts.js +12 -23
- package/dist/interactive-prompts.js.map +3 -3
- package/dist/llbot-launch.d.ts +3 -3
- package/dist/llbot-launch.js.map +1 -1
- package/dist/log-filter.d.ts +18 -2
- package/dist/log-filter.d.ts.map +1 -1
- package/dist/log-filter.js +54 -4
- package/dist/log-filter.js.map +2 -2
- package/dist/log-translator.d.ts +36 -0
- package/dist/log-translator.d.ts.map +1 -0
- package/dist/log-translator.js +279 -0
- package/dist/log-translator.js.map +7 -0
- package/dist/logs.d.ts +2 -0
- package/dist/logs.d.ts.map +1 -1
- package/dist/logs.js +24 -11
- package/dist/logs.js.map +2 -2
- package/dist/main.js +5 -0
- package/dist/main.js.map +2 -2
- package/dist/module-commands.d.ts.map +1 -1
- package/dist/module-commands.js +34 -13
- package/dist/module-commands.js.map +2 -2
- package/dist/module-fingerprint.d.ts.map +1 -1
- package/dist/module-fingerprint.js +1 -0
- package/dist/module-fingerprint.js.map +2 -2
- package/dist/module-pack-build.d.ts +14 -4
- package/dist/module-pack-build.d.ts.map +1 -1
- package/dist/module-pack-build.js +81 -108
- package/dist/module-pack-build.js.map +2 -2
- package/dist/module-toggle.d.ts +1 -1
- package/dist/module-toggle.d.ts.map +1 -1
- package/dist/module-toggle.js.map +1 -1
- package/dist/pack-lifecycle.d.ts +15 -1
- package/dist/pack-lifecycle.d.ts.map +1 -1
- package/dist/pack-lifecycle.js +242 -15
- package/dist/pack-lifecycle.js.map +2 -2
- package/dist/player-session.d.ts +13 -0
- package/dist/player-session.d.ts.map +1 -0
- package/dist/player-session.js +26 -0
- package/dist/player-session.js.map +7 -0
- package/dist/registry.d.ts +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +4 -1
- package/dist/registry.js.map +2 -2
- package/dist/repl-windows/format-display.d.ts.map +1 -1
- package/dist/repl-windows/format-display.js +5 -1
- package/dist/repl-windows/format-display.js.map +2 -2
- package/dist/repl-windows/host.d.ts +6 -3
- package/dist/repl-windows/host.d.ts.map +1 -1
- package/dist/repl-windows/host.js +12 -6
- package/dist/repl-windows/host.js.map +2 -2
- package/dist/repl-windows/index.d.ts +1 -0
- package/dist/repl-windows/index.d.ts.map +1 -1
- package/dist/repl-windows/index.js +3 -0
- package/dist/repl-windows/index.js.map +2 -2
- package/dist/repl-windows/service-window.d.ts.map +1 -1
- package/dist/repl-windows/service-window.js +1 -0
- package/dist/repl-windows/service-window.js.map +2 -2
- package/dist/repl-windows/sfmc-window.d.ts +7 -0
- package/dist/repl-windows/sfmc-window.d.ts.map +1 -0
- package/dist/repl-windows/sfmc-window.js +28 -0
- package/dist/repl-windows/sfmc-window.js.map +7 -0
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +38 -13
- package/dist/repl.js.map +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +15 -2
- package/dist/runtime.js.map +2 -2
- package/dist/send-target.d.ts +2 -0
- package/dist/send-target.d.ts.map +1 -1
- package/dist/send-target.js +6 -0
- package/dist/send-target.js.map +2 -2
- package/dist/services.d.ts +26 -1
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +179 -45
- package/dist/services.js.map +2 -2
- package/dist/sfmc-modules-root.d.ts.map +1 -1
- package/dist/sfmc-modules-root.js +6 -2
- package/dist/sfmc-modules-root.js.map +2 -2
- package/dist/ui-command.d.ts +6 -0
- package/dist/ui-command.d.ts.map +1 -0
- package/dist/ui-command.js +68 -0
- package/dist/ui-command.js.map +7 -0
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +36 -31
- package/dist/wizard.js.map +2 -2
- package/dist/world-packs.d.ts +2 -0
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +161 -18
- package/dist/world-packs.js.map +2 -2
- package/package.json +22 -15
- package/scripts/module-install/check-modules.mjs +178 -0
- package/scripts/module-install/fetch-module.mjs +1088 -0
- package/scripts/module-install/lib/catalog.mjs +96 -0
- package/scripts/module-install/lib/config-seeding.mjs +128 -0
- package/scripts/module-install/lib/io.mjs +37 -0
- package/scripts/module-install/lib/link-from.mjs +80 -0
- package/scripts/module-install/lib/lock.mjs +78 -0
- package/scripts/module-install/lib/npm-resolver.mjs +55 -0
- package/scripts/module-install/lib/packages.mjs +136 -0
- package/scripts/module-install/lib/paths.mjs +48 -0
- package/scripts/module-install/lib/registry-index.mjs +50 -0
package/dist/pack-lifecycle.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
configPath,
|
|
3
|
+
DEFAULT_DB_CONFIG,
|
|
3
4
|
modulePath,
|
|
4
5
|
readJson,
|
|
5
6
|
writeJson
|
|
@@ -25,7 +26,10 @@ import {
|
|
|
25
26
|
readLevelNameSync,
|
|
26
27
|
readPackManifestHeader,
|
|
27
28
|
readWorldPackList,
|
|
28
|
-
worldPackListHas as pmWorldPackListHas
|
|
29
|
+
worldPackListHas as pmWorldPackListHas,
|
|
30
|
+
BASELINE_BEDROCK_DEPENDENCIES,
|
|
31
|
+
negotiateBedrockDependencies,
|
|
32
|
+
NATIVE_BEDROCK_SCRIPT_MODULES
|
|
29
33
|
} from "@sfmc-bds/bds-tools/pack-manager-lib";
|
|
30
34
|
import { ROOT, PACKAGES_DIR, resolveSdkPackageRoot, getRoot } from "./runtime.js";
|
|
31
35
|
import { c } from "./theme.js";
|
|
@@ -33,7 +37,7 @@ const BP_NAME = "sfmc-modules";
|
|
|
33
37
|
const RP_NAME = "sfmc-modules-rp";
|
|
34
38
|
const DEPLOY_CATALOG_NAME = "sfmc-deploy-catalog.json";
|
|
35
39
|
const DEFAULT_PACK_VERSION = [1, 0, 0];
|
|
36
|
-
function createSdkResolvePlugin(sdkRoot) {
|
|
40
|
+
function createSdkResolvePlugin(sdkRoot, dbPort) {
|
|
37
41
|
const pkg = JSON.parse(readFileSync(path.join(sdkRoot, "package.json"), "utf8"));
|
|
38
42
|
const exportsMap = pkg.exports ?? {};
|
|
39
43
|
function resolveExportSubpath(subpath) {
|
|
@@ -48,9 +52,59 @@ function createSdkResolvePlugin(sdkRoot) {
|
|
|
48
52
|
return {
|
|
49
53
|
name: "sfmc-sdk-resolve",
|
|
50
54
|
setup(build) {
|
|
55
|
+
build.onResolve({ filter: /^sfmc:host$/ }, () => ({
|
|
56
|
+
path: "sfmc:host",
|
|
57
|
+
namespace: "sfmc-host"
|
|
58
|
+
}));
|
|
59
|
+
build.onLoad({ filter: /.*/, namespace: "sfmc-host" }, () => ({
|
|
60
|
+
contents: [
|
|
61
|
+
'import { installHostBootstrap } from "@sfmc-bds/sdk/module-loader/install";',
|
|
62
|
+
`installHostBootstrap({ dbServerUrl: ${JSON.stringify(`http://127.0.0.1:${dbPort}`)} });`
|
|
63
|
+
].join("\n"),
|
|
64
|
+
loader: "ts"
|
|
65
|
+
}));
|
|
51
66
|
build.onResolve({ filter: /^@sfmc(?:-bds)?\/sdk(?:\/|$)/ }, (args) => {
|
|
52
67
|
const normalized = args.path.replace(/^@sfmc\/sdk/, "@sfmc-bds/sdk");
|
|
53
68
|
const sub = normalized === "@sfmc-bds/sdk" ? "" : normalized.slice("@sfmc-bds/sdk/".length);
|
|
69
|
+
const importerNorm = (args.importer || "").replace(/\\/g, "/");
|
|
70
|
+
const sapiIdx = importerNorm.indexOf("/sapi/");
|
|
71
|
+
if (sapiIdx !== -1 && !importerNorm.includes("@sfmc-sdk") && !importerNorm.includes("@sfmc/sdk")) {
|
|
72
|
+
const sapiDir = importerNorm.slice(0, sapiIdx + "/sapi".length);
|
|
73
|
+
const manifestFile = path.join(sapiDir, "manifest.json");
|
|
74
|
+
let logicalId = "";
|
|
75
|
+
let configKey = "";
|
|
76
|
+
if (existsSync(manifestFile)) {
|
|
77
|
+
try {
|
|
78
|
+
const man = JSON.parse(readFileSync(manifestFile, "utf8"));
|
|
79
|
+
if (man.id) logicalId = man.id;
|
|
80
|
+
if (man.configKey) configKey = man.configKey;
|
|
81
|
+
} catch {
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (!logicalId) {
|
|
85
|
+
const rootDir = importerNorm.slice(0, sapiIdx);
|
|
86
|
+
logicalId = path.basename(rootDir).replace(/^sfmc-module-/, "");
|
|
87
|
+
configKey = logicalId;
|
|
88
|
+
}
|
|
89
|
+
if (sub === "sapi/db") {
|
|
90
|
+
return {
|
|
91
|
+
path: `sfmc-scoped:db?mod=${encodeURIComponent(logicalId)}`,
|
|
92
|
+
namespace: "sfmc-scoped-db"
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (sub === "sapi/config") {
|
|
96
|
+
return {
|
|
97
|
+
path: `sfmc-scoped:config?cfg=${encodeURIComponent(configKey)}`,
|
|
98
|
+
namespace: "sfmc-scoped-config"
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (sub === "sapi/service") {
|
|
102
|
+
return {
|
|
103
|
+
path: `sfmc-scoped:service?mod=${encodeURIComponent(logicalId)}`,
|
|
104
|
+
namespace: "sfmc-scoped-service"
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
54
108
|
const resolved = resolveExportSubpath(sub);
|
|
55
109
|
if (!resolved) {
|
|
56
110
|
return {
|
|
@@ -61,7 +115,64 @@ function createSdkResolvePlugin(sdkRoot) {
|
|
|
61
115
|
]
|
|
62
116
|
};
|
|
63
117
|
}
|
|
64
|
-
return { path: resolved };
|
|
118
|
+
return { path: resolved, namespace: "file" };
|
|
119
|
+
});
|
|
120
|
+
build.onLoad({ filter: /.*/, namespace: "sfmc-scoped-db" }, (args) => {
|
|
121
|
+
const u = new URL(args.path);
|
|
122
|
+
const mod = u.searchParams.get("mod") || "";
|
|
123
|
+
return {
|
|
124
|
+
contents: [
|
|
125
|
+
'import { getDbClient } from "@sfmc-bds/sdk/sapi/db";',
|
|
126
|
+
'export * from "@sfmc-bds/sdk/sapi/db";',
|
|
127
|
+
"export const db = new Proxy({}, {",
|
|
128
|
+
" get(_t, prop) {",
|
|
129
|
+
` const c = getDbClient(${JSON.stringify(mod)});`,
|
|
130
|
+
" const val = (c as any)[prop];",
|
|
131
|
+
' return typeof val === "function" ? val.bind(c) : val;',
|
|
132
|
+
" }",
|
|
133
|
+
"});"
|
|
134
|
+
].join("\n"),
|
|
135
|
+
loader: "ts",
|
|
136
|
+
resolveDir: sdkRoot
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
build.onLoad({ filter: /.*/, namespace: "sfmc-scoped-config" }, (args) => {
|
|
140
|
+
const u = new URL(args.path);
|
|
141
|
+
const cfg = u.searchParams.get("cfg") || "";
|
|
142
|
+
return {
|
|
143
|
+
contents: [
|
|
144
|
+
'import { getConfigClient } from "@sfmc-bds/sdk/sapi/config";',
|
|
145
|
+
'export * from "@sfmc-bds/sdk/sapi/config";',
|
|
146
|
+
"export const config = new Proxy({}, {",
|
|
147
|
+
" get(_t, prop) {",
|
|
148
|
+
` const c = getConfigClient(${JSON.stringify(cfg)});`,
|
|
149
|
+
" const val = (c as any)[prop];",
|
|
150
|
+
' return typeof val === "function" ? val.bind(c) : val;',
|
|
151
|
+
" }",
|
|
152
|
+
"});"
|
|
153
|
+
].join("\n"),
|
|
154
|
+
loader: "ts",
|
|
155
|
+
resolveDir: sdkRoot
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
build.onLoad({ filter: /.*/, namespace: "sfmc-scoped-service" }, (args) => {
|
|
159
|
+
const u = new URL(args.path);
|
|
160
|
+
const mod = u.searchParams.get("mod") || "";
|
|
161
|
+
return {
|
|
162
|
+
contents: [
|
|
163
|
+
'import { getServiceClient } from "@sfmc-bds/sdk/sapi/service";',
|
|
164
|
+
'export * from "@sfmc-bds/sdk/sapi/service";',
|
|
165
|
+
"export const service = new Proxy({}, {",
|
|
166
|
+
" get(_t, prop) {",
|
|
167
|
+
` const c = getServiceClient(${JSON.stringify(mod)});`,
|
|
168
|
+
" const val = (c as any)[prop];",
|
|
169
|
+
' return typeof val === "function" ? val.bind(c) : val;',
|
|
170
|
+
" }",
|
|
171
|
+
"});"
|
|
172
|
+
].join("\n"),
|
|
173
|
+
loader: "ts",
|
|
174
|
+
resolveDir: sdkRoot
|
|
175
|
+
};
|
|
65
176
|
});
|
|
66
177
|
}
|
|
67
178
|
};
|
|
@@ -90,12 +201,21 @@ function lockPath() {
|
|
|
90
201
|
function catalogPath() {
|
|
91
202
|
return modulePath(path.join(ROOT, "modules"), "catalog.json");
|
|
92
203
|
}
|
|
204
|
+
function configuredDbPort(root) {
|
|
205
|
+
const configured = readJson(configPath(root, "db_config.json"));
|
|
206
|
+
const port = configured?.db_port ?? DEFAULT_DB_CONFIG.db_port ?? 3001;
|
|
207
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
208
|
+
throw new Error(`configs/db_config.json: db_port \u5FC5\u987B\u662F 1\u201365535 \u7684\u6574\u6570 (\u5F53\u524D ${port})`);
|
|
209
|
+
}
|
|
210
|
+
return port;
|
|
211
|
+
}
|
|
93
212
|
function resolveBdsContext(root = getRoot()) {
|
|
94
213
|
const cfg = readJson(configPath(root, "bds_updater.json")) ?? {};
|
|
95
|
-
const
|
|
96
|
-
if (!
|
|
214
|
+
const rawBds = cfg.bds_path;
|
|
215
|
+
if (!rawBds) {
|
|
97
216
|
throw new Error("bds_path not configured. Run `sfmc init` first.");
|
|
98
217
|
}
|
|
218
|
+
const bdsRoot = path.isAbsolute(rawBds) ? rawBds : path.resolve(root, rawBds);
|
|
99
219
|
return { bdsRoot, levelName: readLevelNameSync(bdsRoot) };
|
|
100
220
|
}
|
|
101
221
|
function deployedBpDir(bdsRoot, levelName) {
|
|
@@ -124,11 +244,71 @@ function collectDeployedPackUuids(bdsRoot, levelName) {
|
|
|
124
244
|
if (liveRp?.uuid) rp.add(liveRp.uuid);
|
|
125
245
|
return { bp, rp };
|
|
126
246
|
}
|
|
247
|
+
async function extractModuleBedrockDependencies(modPath) {
|
|
248
|
+
const deps = [];
|
|
249
|
+
const seen = /* @__PURE__ */ new Set();
|
|
250
|
+
const manifestPath = path.join(modPath, "sapi", "manifest.json");
|
|
251
|
+
if (existsSync(manifestPath)) {
|
|
252
|
+
try {
|
|
253
|
+
const raw = JSON.parse(await fs.readFile(manifestPath, "utf8"));
|
|
254
|
+
if (Array.isArray(raw.dependencies)) {
|
|
255
|
+
for (const d of raw.dependencies) {
|
|
256
|
+
if (d && typeof d === "object" && typeof d.module_name === "string" && d.module_name.startsWith("@minecraft/") && NATIVE_BEDROCK_SCRIPT_MODULES.has(d.module_name)) {
|
|
257
|
+
const modName = d.module_name;
|
|
258
|
+
const ver = String(d.version ?? "1.0.0");
|
|
259
|
+
const uuid = typeof d.uuid === "string" ? d.uuid : void 0;
|
|
260
|
+
deps.push({ module_name: modName, version: ver, ...uuid ? { uuid } : {} });
|
|
261
|
+
seen.add(modName);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
} else if (raw.dependencies && typeof raw.dependencies === "object") {
|
|
265
|
+
for (const [modName, ver] of Object.entries(raw.dependencies)) {
|
|
266
|
+
if (modName.startsWith("@minecraft/") && !seen.has(modName) && NATIVE_BEDROCK_SCRIPT_MODULES.has(modName)) {
|
|
267
|
+
deps.push({ module_name: modName, version: String(ver ?? "1.0.0") });
|
|
268
|
+
seen.add(modName);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (raw.minecraft && typeof raw.minecraft === "object") {
|
|
273
|
+
const mc = raw.minecraft;
|
|
274
|
+
const mcDeps = Array.isArray(mc.dependencies) ? mc.dependencies : mc;
|
|
275
|
+
if (typeof mcDeps === "object" && !Array.isArray(mcDeps)) {
|
|
276
|
+
for (const [modName, ver] of Object.entries(mcDeps)) {
|
|
277
|
+
if (modName.startsWith("@minecraft/") && !seen.has(modName) && NATIVE_BEDROCK_SCRIPT_MODULES.has(modName)) {
|
|
278
|
+
deps.push({ module_name: modName, version: String(ver ?? "1.0.0") });
|
|
279
|
+
seen.add(modName);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
} catch {
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const pkgPath = path.join(modPath, "package.json");
|
|
288
|
+
if (existsSync(pkgPath)) {
|
|
289
|
+
try {
|
|
290
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, "utf8"));
|
|
291
|
+
const candidateMap = {
|
|
292
|
+
...pkg.devDependencies ?? {},
|
|
293
|
+
...pkg.dependencies ?? {},
|
|
294
|
+
...pkg.peerDependencies ?? {}
|
|
295
|
+
};
|
|
296
|
+
for (const [modName, ver] of Object.entries(candidateMap)) {
|
|
297
|
+
if (modName.startsWith("@minecraft/") && !seen.has(modName) && NATIVE_BEDROCK_SCRIPT_MODULES.has(modName)) {
|
|
298
|
+
deps.push({ module_name: modName, version: ver });
|
|
299
|
+
seen.add(modName);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
} catch {
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return deps;
|
|
306
|
+
}
|
|
127
307
|
async function scanLocalModules() {
|
|
128
308
|
const dir = packagesDir();
|
|
129
309
|
if (!existsSync(dir)) return [];
|
|
130
310
|
const lock = readJson(lockPath()) ?? { version: 1, modules: {} };
|
|
131
|
-
const cat = readJson(catalogPath()) ?? {};
|
|
311
|
+
const cat = readJson(catalogPath()) ?? { version: 1, modules: [] };
|
|
132
312
|
const defaults = /* @__PURE__ */ new Map();
|
|
133
313
|
if (Array.isArray(cat.modules)) {
|
|
134
314
|
for (const m of cat.modules) {
|
|
@@ -166,6 +346,7 @@ async function scanLocalModules() {
|
|
|
166
346
|
const hasResourcePack = existsSync(path.join(modPath, "resource_pack"));
|
|
167
347
|
const fingerprint = await dirFingerprint(modPath);
|
|
168
348
|
const enabled = isModuleEnabled(logicalId, lock, defaults);
|
|
349
|
+
const declaredDependencies = await extractModuleBedrockDependencies(modPath);
|
|
169
350
|
out.push({
|
|
170
351
|
folderId,
|
|
171
352
|
logicalId,
|
|
@@ -174,7 +355,8 @@ async function scanLocalModules() {
|
|
|
174
355
|
hasSapi,
|
|
175
356
|
hasResourcePack,
|
|
176
357
|
fingerprint,
|
|
177
|
-
entryPath: hasSapi ? entryPath : null
|
|
358
|
+
entryPath: hasSapi ? entryPath : null,
|
|
359
|
+
declaredDependencies
|
|
178
360
|
});
|
|
179
361
|
}
|
|
180
362
|
out.sort((a, b) => a.folderId.localeCompare(b.folderId));
|
|
@@ -207,8 +389,26 @@ async function computeDesiredCatalog(opts) {
|
|
|
207
389
|
rpVersion = opts?.rpVersion ?? localRp?.version ?? DEFAULT_PACK_VERSION;
|
|
208
390
|
rpModuleUuid = opts?.rpModuleUuid ?? localRp?.moduleUuid;
|
|
209
391
|
}
|
|
392
|
+
let sdkVersion;
|
|
393
|
+
try {
|
|
394
|
+
const sdkRoot = resolveSdkPackageRoot();
|
|
395
|
+
const pkg = JSON.parse(readFileSync(path.join(sdkRoot, "package.json"), "utf8"));
|
|
396
|
+
sdkVersion = pkg.version;
|
|
397
|
+
} catch {
|
|
398
|
+
}
|
|
399
|
+
const enabledModuleReqs = mods.filter((m) => m.enabled && m.declaredDependencies.length > 0).map((m) => ({ folderId: m.folderId, dependencies: m.declaredDependencies }));
|
|
400
|
+
const negotiated = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, enabledModuleReqs);
|
|
401
|
+
if (negotiated.promotions.length > 0) {
|
|
402
|
+
for (const p of negotiated.promotions) {
|
|
403
|
+
packLog(
|
|
404
|
+
`promoted ${p.moduleName} ${p.from} -> ${p.to} (requested by: ${p.requestedBy.join(", ")})`,
|
|
405
|
+
"info"
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
210
409
|
return {
|
|
211
410
|
schemaVersion: 1,
|
|
411
|
+
dbPort: configuredDbPort(getRoot()),
|
|
212
412
|
bpUuid,
|
|
213
413
|
rpUuid,
|
|
214
414
|
bpVersion,
|
|
@@ -216,6 +416,8 @@ async function computeDesiredCatalog(opts) {
|
|
|
216
416
|
...bpModuleUuid ? { bpModuleUuid } : {},
|
|
217
417
|
...rpModuleUuid ? { rpModuleUuid } : {},
|
|
218
418
|
generatedAt: Date.now(),
|
|
419
|
+
...sdkVersion ? { sdkVersion } : {},
|
|
420
|
+
dependencies: negotiated.dependencies,
|
|
219
421
|
modules
|
|
220
422
|
};
|
|
221
423
|
}
|
|
@@ -229,8 +431,20 @@ function readDeployedCatalog(bdsRoot, levelName) {
|
|
|
229
431
|
}
|
|
230
432
|
}
|
|
231
433
|
function catalogsEqual(a, b) {
|
|
434
|
+
if (a.dbPort !== b.dbPort) return false;
|
|
232
435
|
if (a.bpUuid !== b.bpUuid) return false;
|
|
233
436
|
if ((a.rpUuid ?? null) !== (b.rpUuid ?? null)) return false;
|
|
437
|
+
if ((a.sdkVersion ?? null) !== (b.sdkVersion ?? null)) return false;
|
|
438
|
+
const depsA = a.dependencies ?? [];
|
|
439
|
+
const depsB = b.dependencies ?? [];
|
|
440
|
+
if (depsA.length !== depsB.length) return false;
|
|
441
|
+
for (let i = 0; i < depsA.length; i++) {
|
|
442
|
+
const da = depsA[i];
|
|
443
|
+
const db = depsB[i];
|
|
444
|
+
if (!da || !db || da.module_name !== db.module_name || da.version !== db.version) {
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
234
448
|
const aKeys = Object.keys(a.modules).sort();
|
|
235
449
|
const bKeys = Object.keys(b.modules).sort();
|
|
236
450
|
if (aKeys.length !== bKeys.length) return false;
|
|
@@ -270,19 +484,23 @@ async function buildPacks(desired) {
|
|
|
270
484
|
const sdkRoot = resolveSdkPackageRoot();
|
|
271
485
|
packLog(`SDK root: ${sdkRoot}`);
|
|
272
486
|
await build({
|
|
273
|
-
|
|
487
|
+
stdin: {
|
|
488
|
+
contents: [
|
|
489
|
+
'import "sfmc:host";',
|
|
490
|
+
...entries.map((e) => `import ${JSON.stringify(path.resolve(e).replace(/\\/g, "/"))};`)
|
|
491
|
+
].join("\n"),
|
|
492
|
+
resolveDir: ROOT,
|
|
493
|
+
sourcefile: "bootstrap.ts",
|
|
494
|
+
loader: "ts"
|
|
495
|
+
},
|
|
274
496
|
outfile: outFile,
|
|
275
497
|
bundle: true,
|
|
276
498
|
platform: "neutral",
|
|
277
499
|
format: "esm",
|
|
278
500
|
target: "es2022",
|
|
279
501
|
logLevel: "warning",
|
|
280
|
-
sourcemap:
|
|
502
|
+
sourcemap: true,
|
|
281
503
|
external: ["@minecraft/*"],
|
|
282
|
-
// BDS host 启动:与 module-loader barrel 分离(DIP),须在模块 register 之前执行
|
|
283
|
-
banner: {
|
|
284
|
-
js: 'import { installHostBootstrap } from "@sfmc-bds/sdk/module-loader/install";\ninstallHostBootstrap();\n'
|
|
285
|
-
},
|
|
286
504
|
// 避免读取模块内残缺的 extends(如 ../../../sdk/@sfmc-sdk/tsconfig.json)
|
|
287
505
|
tsconfigRaw: JSON.stringify({
|
|
288
506
|
compilerOptions: {
|
|
@@ -293,7 +511,7 @@ async function buildPacks(desired) {
|
|
|
293
511
|
skipLibCheck: true
|
|
294
512
|
}
|
|
295
513
|
}),
|
|
296
|
-
plugins: [createSdkResolvePlugin(sdkRoot)]
|
|
514
|
+
plugins: [createSdkResolvePlugin(sdkRoot, catalog.dbPort)]
|
|
297
515
|
});
|
|
298
516
|
packLog(`esbuild bundled ${entries.length} entr(y/ies)`, "success");
|
|
299
517
|
}
|
|
@@ -305,7 +523,8 @@ async function buildPacks(desired) {
|
|
|
305
523
|
version: catalog.bpVersion,
|
|
306
524
|
description: "ScriptsForMinecraftServer aggregated behavior pack",
|
|
307
525
|
uuid: catalog.bpUuid,
|
|
308
|
-
...catalog.bpModuleUuid ? { moduleUuid: catalog.bpModuleUuid } : {}
|
|
526
|
+
...catalog.bpModuleUuid ? { moduleUuid: catalog.bpModuleUuid } : {},
|
|
527
|
+
...catalog.dependencies ? { dependencies: catalog.dependencies } : {}
|
|
309
528
|
});
|
|
310
529
|
} catch (e) {
|
|
311
530
|
throw new Error(`assemble-bp failed: ${e.message}`);
|
|
@@ -431,6 +650,10 @@ function formatPackLoadInfo(catalog, rebuilt) {
|
|
|
431
650
|
catalog.rpUuid ? ` RP ${catalog.rpUuid} v${(catalog.rpVersion ?? DEFAULT_PACK_VERSION).join(".")}` : ` RP (none)`,
|
|
432
651
|
` modules: ${enabled.length} enabled / ${disabled.length} disabled / ${mods.length} installed`
|
|
433
652
|
];
|
|
653
|
+
if (catalog.dependencies && catalog.dependencies.length > 0) {
|
|
654
|
+
const depStr = catalog.dependencies.map((d) => `${d.module_name}@${d.version}`).join(" ");
|
|
655
|
+
lines.push(` dependencies: ${depStr}`);
|
|
656
|
+
}
|
|
434
657
|
for (const [folderId, m] of enabled.sort((a, b) => a[0].localeCompare(b[0]))) {
|
|
435
658
|
lines.push(` \u25CF ${folderId} (${m.logicalId}) ${m.version}${m.hasResourcePack ? " +rp" : ""}`);
|
|
436
659
|
}
|
|
@@ -474,6 +697,8 @@ async function ensurePacksReady() {
|
|
|
474
697
|
if (deployed.rpUuid && !worldPackListHas(bdsRoot, levelName, "resource", deployed.rpUuid)) {
|
|
475
698
|
needRebuild = true;
|
|
476
699
|
}
|
|
700
|
+
const deployedMainJs = path.join(deployedBpDir(bdsRoot, levelName), "scripts", "main.js");
|
|
701
|
+
if (!existsSync(deployedMainJs)) needRebuild = true;
|
|
477
702
|
if (!hasConfigPermission(bdsRoot, deployed.bpUuid)) {
|
|
478
703
|
try {
|
|
479
704
|
const wrote = await ensureConfigPermission(bdsRoot, deployed.bpUuid);
|
|
@@ -630,11 +855,13 @@ export {
|
|
|
630
855
|
cmdPackList,
|
|
631
856
|
cmdPackStatus,
|
|
632
857
|
computeDesiredCatalog,
|
|
858
|
+
createSdkResolvePlugin,
|
|
633
859
|
deployPacks,
|
|
634
860
|
deployedBpDir,
|
|
635
861
|
deployedCatalogPath,
|
|
636
862
|
deployedRpDir,
|
|
637
863
|
ensurePacksReady,
|
|
864
|
+
extractModuleBedrockDependencies,
|
|
638
865
|
formatPackLoadInfo,
|
|
639
866
|
readDeployedCatalog,
|
|
640
867
|
resolveBdsContext,
|