@sfmc-bds/bds-tools 0.2.0-beta.0 → 0.2.0-beta.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/dist/check-update.js +11 -11
- package/dist/check-update.js.map +2 -2
- package/dist/cli-pack-manager.js +7 -3
- package/dist/cli-pack-manager.js.map +2 -2
- package/dist/fsx.d.ts +9 -0
- package/dist/fsx.d.ts.map +1 -1
- package/dist/fsx.js +19 -0
- package/dist/fsx.js.map +2 -2
- package/dist/pack-manager.d.ts.map +1 -1
- package/dist/pack-manager.js +4 -3
- package/dist/pack-manager.js.map +2 -2
- package/dist/update-result.d.ts +8 -2
- package/dist/update-result.d.ts.map +1 -1
- package/dist/update-result.js +7 -5
- package/dist/update-result.js.map +2 -2
- package/dist/world-packs.d.ts +65 -3
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +216 -42
- package/dist/world-packs.js.map +2 -2
- package/package.json +1 -1
package/dist/check-update.js
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from "./rollback.js";
|
|
23
23
|
import { ensureEmitServerTelemetry } from "./server-properties.js";
|
|
24
24
|
import { clearTaskbarProgress, isTaskbarSupported, setTaskbarProgress } from "./taskbar.js";
|
|
25
|
-
import { emitUpdateResult } from "./update-result.js";
|
|
25
|
+
import { emitUpdateKv, emitUpdateResult } from "./update-result.js";
|
|
26
26
|
import {
|
|
27
27
|
buildDownloadUrls,
|
|
28
28
|
fetchVersionDetails,
|
|
@@ -140,9 +140,9 @@ async function runUpdate() {
|
|
|
140
140
|
\u5F53\u524D: ${currentVer}
|
|
141
141
|
\u6700\u65B0: ${latestVer}`);
|
|
142
142
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
emitUpdateResult("uptodate");
|
|
143
|
+
emitUpdateKv("CURRENT", currentVer, log);
|
|
144
|
+
emitUpdateKv("LATEST", latestVer, log);
|
|
145
|
+
emitUpdateResult("uptodate", log);
|
|
146
146
|
return 0;
|
|
147
147
|
}
|
|
148
148
|
} catch (e) {
|
|
@@ -157,7 +157,7 @@ async function runUpdate() {
|
|
|
157
157
|
if (qqNotify) {
|
|
158
158
|
await sendText(`\u26A0\uFE0F BDS ${latestVer} \u4E0D\u5728\u517C\u5BB9\u6027\u767D\u540D\u5355\uFF0C\u5DF2\u8DF3\u8FC7\u5347\u7EA7\u3002\u8BF7\u4EBA\u5DE5\u786E\u8BA4\u3002`);
|
|
159
159
|
}
|
|
160
|
-
emitUpdateResult("skipped");
|
|
160
|
+
emitUpdateResult("skipped", log);
|
|
161
161
|
return 2;
|
|
162
162
|
}
|
|
163
163
|
let downloadUrls;
|
|
@@ -174,11 +174,11 @@ async function runUpdate() {
|
|
|
174
174
|
return 1;
|
|
175
175
|
}
|
|
176
176
|
if (checkOnly) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
emitUpdateResult("check-only");
|
|
177
|
+
emitUpdateKv("CURRENT", currentVer, log);
|
|
178
|
+
emitUpdateKv("LATEST", latestVer, log);
|
|
179
|
+
emitUpdateKv("CHANNEL", channel, log);
|
|
180
|
+
emitUpdateKv("URLS", String(downloadUrls.length), log);
|
|
181
|
+
emitUpdateResult("check-only", log);
|
|
182
182
|
return 0;
|
|
183
183
|
}
|
|
184
184
|
log.info(`\u53D1\u73B0\u65B0\u7248\u672C: ${currentVer} \u2192 ${latestVer}`);
|
|
@@ -379,7 +379,7 @@ ${autoRestart ? "\u670D\u52A1\u5668\u5DF2\u91CD\u65B0\u542F\u52A8" : "\u8BF7\u62
|
|
|
379
379
|
);
|
|
380
380
|
}
|
|
381
381
|
log.info(`===== \u66F4\u65B0\u5B8C\u6210 (${(durationMs / 1e3).toFixed(1)}s) =====`);
|
|
382
|
-
emitUpdateResult("deployed");
|
|
382
|
+
emitUpdateResult("deployed", log);
|
|
383
383
|
return 0;
|
|
384
384
|
}
|
|
385
385
|
function isMain() {
|
package/dist/check-update.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/check-update.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * check-update.ts \u2014 BDS \u81EA\u52A8\u66F4\u65B0\u5668 (\u4E3B\u6D41\u7A0B)\n *\n * 1. \u4E34\u65F6 staging \u76EE\u5F55 (mkdtempSync) - \u907F\u514D\u6C61\u67D3\u6570\u636E\u6839\n * 2. \u4E0B\u8F7D/\u89E3\u538B\u5931\u8D25 \u2192 \u81EA\u52A8\u4ECE\u5907\u4EFD\u56DE\u6EDA preserves\n * 3. \u6D41\u5F0F SHA256 \u6821\u9A8C - \u4E0D\u628A 250MB \u6587\u4EF6\u8BFB\u5165\u5185\u5B58\n * 4. \u517C\u5BB9\u7248\u672C\u767D\u540D\u5355 - \u4E0D\u5339\u914D\u5219\u8DF3\u8FC7\u5347\u7EA7\n * 5. QQ \u901A\u77E5\u7EDF\u4E00\u52A0 5s \u8D85\u65F6 - \u6C38\u8FDC\u4E0D\u963B\u585E\u4E3B\u6D41\u7A0B\n * 6. Rollback marker \u843D\u76D8\u5230 <ROOT>/.sfmc/ - \u8DE8\u8FDB\u7A0B / \u8DE8\u91CD\u542F\u53EF\u6062\u590D\n */\n\nimport {\n bindByteProgressToBar,\n createNodeServiceLogger,\n createTerminalProgress,\n} from \"@sfmc-bds/sdk/logs\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { createBdsManager } from \"./bds-manager.js\";\nimport { CHANGELOG_BASE, fetchChangelog } from \"./changelog.js\";\nimport { copyDirSync, emptyDirSync, hashFileAsync, rmSafe } from \"./fsx.js\";\nimport { httpDownload } from \"./http.js\";\nimport { isMainModule } from \"./is-main.js\";\nimport { loadConfig, LOG_PATH, resolvePaths } from \"./paths.js\";\nimport { sendText, sendWithImage } from \"./qqutil.js\";\nimport {\n clearRollbackMarker,\n getDirSize,\n rollbackFromBackup,\n verifyBdsInstall,\n writeRollbackMarker,\n} from \"./rollback.js\";\nimport { ensureEmitServerTelemetry } from \"./server-properties.js\";\nimport { clearTaskbarProgress, isTaskbarSupported, setTaskbarProgress } from \"./taskbar.js\";\nimport { emitUpdateResult } from \"./update-result.js\";\nimport {\n buildDownloadUrls,\n fetchVersionDetails,\n getVersionInfo,\n isVersionCompatible,\n verifyFileHash,\n} from \"./upstream.js\";\nimport { compareVersions, getCurrentVersionAsync, getCurrentVersionSync, saveVersionCache } from \"./version.js\";\nimport { extractZipFileToDir } from \"./zipx.js\";\n\n// \u72EC\u7ACB\u5165\u53E3:source = \"updater\",\u4E0E bds-manager \u7684 \"bds-tools\" \u533A\u5206;\u540C\u843D\u76D8 bds-update.log\nconst log = createNodeServiceLogger({ source: \"updater\", logPath: LOG_PATH });\nconst closeLog = (): void => log.close();\n\nfunction parseArgs(argv: string[]): Record<string, string | boolean> {\n const out: Record<string, string | boolean> = {};\n for (const a of argv) {\n const m = a.match(/^--([\\w-]+)(?:=(.+))?$/);\n if (m) out[m[1]!] = m[2] || true;\n }\n return out;\n}\n\ninterface UpdateContext {\n cfg: ReturnType<typeof loadConfig>;\n channel: \"release\" | \"preview\" | string;\n checkOnly: boolean;\n force: boolean;\n bdsPath: string;\n backupDir: string;\n preserve: string[];\n autoRestart: boolean;\n qqNotify: boolean;\n}\n\nfunction buildContext(): UpdateContext {\n const cfg = loadConfig();\n const args = parseArgs(process.argv.slice(2));\n const { bds_path, backup_dir, preserve } = resolvePaths(cfg);\n const channel = String(args[\"channel\"] || cfg.channel || \"release\");\n return {\n cfg,\n channel,\n checkOnly: !!args[\"check-only\"],\n force: !!args[\"force\"],\n bdsPath: bds_path,\n backupDir: backup_dir,\n preserve,\n autoRestart: !args[\"no-start\"] && cfg.auto_restart !== false,\n qqNotify: !!cfg.qq_notify,\n };\n}\n\nasync function doBackup(\n bdsPath: string,\n backupDir: string,\n preserve: string[]\n): Promise<{ path: string; size: number }> {\n const dateStr = new Date().toISOString().slice(0, 10);\n const dest = path.join(backupDir, dateStr);\n fs.mkdirSync(dest, { recursive: true });\n\n let anyCopied = false;\n for (const item of preserve) {\n const src = path.join(bdsPath, item);\n const target = path.join(dest, item);\n if (!fs.existsSync(src)) continue;\n fs.mkdirSync(path.dirname(target), { recursive: true });\n if (fs.statSync(src).isDirectory()) copyDirSync(src, target);\n else fs.copyFileSync(src, target);\n anyCopied = true;\n log.info(`\u5DF2\u5907\u4EFD: ${item}`);\n }\n\n // \u5373\u4F7F\u5168\u90E8 preserve \u90FD\u8DF3\u8FC7\uFF0C\u4E5F\u8BA9\u76EE\u5F55\u5B58\u5728\u4EE5\u4FBF\u8BB0\u5F55\u65F6\u95F4\u6233\n if (!anyCopied) {\n log.info(`\u6CA1\u6709\u9700\u8981\u5907\u4EFD\u7684\u6587\u4EF6 (preserve \u5217\u8868\u4E3A\u7A7A\u6216\u5168\u90E8\u7F3A\u5931)`);\n }\n return { path: dest, size: getDirSize(dest) };\n}\n\n/** \u5F02\u6B65\u6062\u590D preserves \u4ECE\u5907\u4EFD\u5230 BDS \u8DEF\u5F84 */\nasync function restorePreserves(bdsPath: string, backupDir: string, preserve: string[]): Promise<void> {\n for (const item of preserve) {\n const src = path.join(backupDir, item);\n const dest = path.join(bdsPath, item);\n if (!fs.existsSync(src)) continue;\n try {\n if (fs.statSync(src).isDirectory()) {\n if (fs.existsSync(dest)) emptyDirSync(dest);\n copyDirSync(src, dest);\n } else {\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.copyFileSync(src, dest);\n }\n log.info(`\u5DF2\u6062\u590D: ${item}`);\n } catch (e) {\n log.warn(`\u6062\u590D\u5931\u8D25 ${item}: ${(e as Error).message}`);\n }\n }\n}\n\n/** \u628A zip \u89E3\u538B\u5230 destDir (\u8986\u76D6) \u2014 \u7ECF zipx \u5B89\u5168\u89E3\u538B */\nasync function extractZipToBds(zipPath: string, destDir: string): Promise<void> {\n // \u62BD\u51FA\u5230\u4E34\u65F6\u76EE\u5F55\uFF0C\u907F\u514D\u65E7\u5185\u5BB9\u5E72\u6270\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-extract-\"));\n try {\n await extractZipFileToDir(zipPath, tmpDir);\n // \u628A\u4E34\u65F6\u76EE\u5F55\u91CC\u7684\u5185\u5BB9\u590D\u5236\u5230 BDS \u8DEF\u5F84\n for (const entry of fs.readdirSync(tmpDir)) {\n const srcPath = path.join(tmpDir, entry);\n const destPath = path.join(destDir, entry);\n if (fs.statSync(srcPath).isDirectory()) {\n if (fs.existsSync(destPath)) emptyDirSync(destPath);\n copyDirSync(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n } finally {\n rmSafe(tmpDir);\n }\n}\n\nexport async function runUpdate(): Promise<number> {\n const startTime = Date.now();\n const ctx = buildContext();\n const { cfg, channel, checkOnly, force, bdsPath, backupDir, preserve, autoRestart, qqNotify } = ctx;\n\n log.info(`===== \u5F00\u59CB\u68C0\u67E5\u66F4\u65B0 (${channel}) =====`);\n fs.mkdirSync(bdsPath, { recursive: true });\n fs.mkdirSync(backupDir, { recursive: true });\n\n // 1. \u5F53\u524D\u7248\u672C\n const exePath = path.join(bdsPath, \"bedrock_server.exe\");\n const currentVer = await getCurrentVersionAsync(exePath).catch(() => getCurrentVersionSync(exePath));\n log.info(`\u5F53\u524D\u7248\u672C: ${currentVer}`);\n\n // 2. \u83B7\u53D6\u6700\u65B0\u7248\u672C\n let latestVer: string;\n try {\n const info = await getVersionInfo(cfg, channel);\n latestVer = info.version;\n log.info(`\u6700\u65B0\u7248\u672C: ${latestVer}`);\n const cmp = compareVersions(latestVer, currentVer);\n if (cmp <= 0 && !force) {\n log.info(\"\u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0\");\n if (qqNotify) {\n await sendText(`\u2705 BDS \u5DF2\u662F\u6700\u65B0\u7248\u672C\\n\\n\u5F53\u524D: ${currentVer}\\n\u6700\u65B0: ${latestVer}`);\n }\n console.log(`CURRENT=${currentVer}`);\n console.log(`LATEST=${latestVer}`);\n emitUpdateResult(\"uptodate\");\n return 0;\n }\n } catch (e) {\n log.error(`\u83B7\u53D6\u7248\u672C\u4FE1\u606F\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u65E0\u6CD5\u83B7\u53D6\u7248\u672C\u4FE1\u606F: ${(e as Error).message}`);\n return 1;\n }\n\n // \u517C\u5BB9\u6027\u68C0\u67E5\n if (!force && !isVersionCompatible(cfg, latestVer)) {\n log.warn(`${latestVer} \u4E0D\u5728\u517C\u5BB9\u7248\u672C\u767D\u540D\u5355\u4E2D\uFF0C\u8DF3\u8FC7\u5347\u7EA7`);\n if (qqNotify) {\n await sendText(`\u26A0\uFE0F BDS ${latestVer} \u4E0D\u5728\u517C\u5BB9\u6027\u767D\u540D\u5355\uFF0C\u5DF2\u8DF3\u8FC7\u5347\u7EA7\u3002\u8BF7\u4EBA\u5DE5\u786E\u8BA4\u3002`);\n }\n emitUpdateResult(\"skipped\");\n return 2;\n }\n\n // 3. \u53D6\u4E0B\u8F7D\u94FE\u63A5\n let downloadUrls: string[];\n let hash: { sha1: string; sha256: string };\n try {\n const details = await fetchVersionDetails(cfg, channel, latestVer);\n downloadUrls = buildDownloadUrls(cfg, channel, latestVer, details);\n hash = { sha1: details.sha1, sha256: details.sha256 };\n } catch (e) {\n log.error(`\u83B7\u53D6\u4E0B\u8F7D\u8BE6\u60C5\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u8BE6\u60C5\u83B7\u53D6\u5931\u8D25: ${(e as Error).message}`);\n return 1;\n }\n\n if (checkOnly) {\n console.log(`CURRENT=${currentVer}`);\n console.log(`LATEST=${latestVer}`);\n console.log(`CHANNEL=${channel}`);\n console.log(`URLS=${downloadUrls.length}`);\n emitUpdateResult(\"check-only\");\n return 0;\n }\n\n log.info(`\u53D1\u73B0\u65B0\u7248\u672C: ${currentVer} \u2192 ${latestVer}`);\n\n // 4. QQ \u9884\u544A\n if (qqNotify) {\n await sendText(\n `\uD835\uDC0C\uD835\uDC22\uD835\uDC27\uD835\uDC1E\uD835\uDC1C\uD835\uDC2B\uD835\uDC1A\uD835\uDC1F\uD835\uDC2D \uD835\uDC01\uD835\uDC03\uD835\uDC12 \u66F4\u65B0\u901A\u77E5\\n\\n` +\n `\u68C0\u6D4B\u5230\u65B0\u7248\u672C\uFF01\\n\\n` +\n `\u5F53\u524D: ${currentVer}\\n` +\n `\u6700\u65B0: ${latestVer}\\n` +\n `\u9891\u9053: ${channel === \"preview\" ? \"\u9884\u89C8\u7248\" : \"\u6B63\u5F0F\u7248\"}\\n\\n` +\n `\u670D\u52A1\u5668\u5373\u5C06\u5F00\u59CB\u66F4\u65B0~ \u8BF7\u8010\u5FC3\u7B49\u5F85^(*\uFFE3(oo)\uFFE3)^`\n );\n const cl = await fetchChangelog(channel);\n if (cl) {\n const text = `\uD83D\uDCCB \u66F4\u65B0\u5185\u5BB9\u6982\u8981\\n\\n${cl.text.slice(0, 1500)}\\n\\n\u5B8C\u6574\u65E5\u5FD7: ${CHANGELOG_BASE}`;\n if (cl.imageBase64) await sendWithImage(text, cl.imageBase64);\n else await sendText(text);\n } else {\n await sendText(`\uD83D\uDCCB \u66F4\u65B0\u65E5\u5FD7: ${CHANGELOG_BASE}`);\n }\n }\n\n // 5. \u5907\u4EFD\n let backupInfo: { path: string; size: number };\n try {\n backupInfo = await doBackup(bdsPath, backupDir, preserve);\n log.info(`\u5907\u4EFD\u5B8C\u6210: ${backupInfo.path} (${(backupInfo.size / 1024 / 1024).toFixed(1)} MB)`);\n if (qqNotify) {\n await sendText(`\u2705 \u5907\u4EFD\u5B8C\u6210\\n\\n\u5927\u5C0F: ${(backupInfo.size / 1024 / 1024).toFixed(1)} MB\\n\u4F4D\u7F6E: ${backupInfo.path}`);\n }\n } catch (e) {\n log.error(`\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}\\n\u64CD\u4F5C\u5DF2\u4E2D\u6B62`);\n return 1;\n }\n\n // 6. \u5199\u56DE\u6EDA\u6807\u8BB0 (\u8DE8\u8FDB\u7A0B\u53EF\u6062\u590D)\n writeRollbackMarker({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n\n // 7. \u505C\u670D\n const bds = createBdsManager({ detached: true });\n try {\n log.info(\"\u505C\u6B62 BDS \u670D\u52A1...\");\n await bds.stop();\n log.info(\"BDS \u5DF2\u505C\u6B62\");\n } catch (e) {\n log.warn(`BDS \u505C\u6B62\u5F02\u5E38: ${(e as Error).message}`);\n }\n\n // 8. \u4E0B\u8F7D (\u5168\u90E8\u5931\u8D25\u5219\u56DE\u6EDA)\n // \u7528 mkdtempSync \u521B\u5EFA\u4E34\u65F6 staging \u76EE\u5F55 - \u907F\u514D\u6C61\u67D3 SCRIPT_DIR\n const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-update-\"));\n const zipPath = path.join(stagingDir, `bedrock-server-${latestVer}.zip`);\n let downloaded = false;\n try {\n log.info(`\u5F00\u59CB\u4E0B\u8F7D ${latestVer}...`);\n if (qqNotify) await sendText(`\uD83D\uDCE5 \u6B63\u5728\u4E0B\u8F7D BDS ${latestVer}...`);\n\n let lastErr: Error | null = null;\n const downloadTimeoutMs = (cfg.download_timeout ?? 120) * 1000;\n /* stderr \u88AB pipe \u65F6\u4E0D\u753B bar\uFF1B\u7528\u6587\u672C\u8FDB\u5EA6\u7ED9 sfmc REPL \u7B49\u7236\u8FDB\u7A0B */\n if (isTaskbarSupported() && process.stdout.isTTY) {\n log.info(\"\u68C0\u6D4B\u5230 Windows Terminal,\u4EFB\u52A1\u680F\u8FDB\u5EA6\u5DF2\u542F\u7528 (OSC 9;4)\");\n }\n for (const url of downloadUrls) {\n /* \u6BCF\u6B21\u5C1D\u8BD5\u65B0\u5EFA bar + binder\uFF0C\u907F\u514D\u5931\u8D25\u91CD\u8BD5\u65F6 started \u72B6\u6001\u6B8B\u7559\uFF08LSP\uFF09 */\n const progressBar = createTerminalProgress({\n stream: process.stderr,\n logger: (msg) => log.info(msg.startsWith(\"\u8FDB\u5EA6\") ? `\u4E0B\u8F7D${msg.slice(2)}` : msg),\n format: \"\u4E0B\u8F7D\u8FDB\u5EA6 | {bar} | {percentage}% | {value}/{total} MB | \u901F\u5EA6: {speed}\",\n });\n const onByteProgress = bindByteProgressToBar(progressBar, {\n speedSampleMs: 0,\n onProgress: (dl, total) => {\n const pct = total > 0 ? (dl / total) * 100 : 0;\n setTaskbarProgress(pct);\n },\n });\n try {\n setTaskbarProgress(0);\n await httpDownload(url, zipPath, {\n totalTimeoutMs: Math.max(downloadTimeoutMs, 600_000), // \u4E0D\u5C11\u4E8E 10 \u5206\u949F\n onProgress: onByteProgress,\n });\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5B8C\u6210,\u4EFB\u52A1\u680F\u6536\u5230 100% \u7EFF\u6761\u540E\u6E05\u6389\n setTaskbarProgress(100);\n clearTaskbarProgress();\n downloaded = true;\n lastErr = null;\n break;\n } catch (e) {\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5931\u8D25,\u4EFB\u52A1\u680F\u4EAE\u7EA2\n setTaskbarProgress(100, \"error\");\n clearTaskbarProgress();\n lastErr = e as Error;\n log.warn(`${url} \u4E0D\u53EF\u7528: ${lastErr.message}\uFF0C\u5C1D\u8BD5\u5907\u7528\u5730\u5740...`);\n }\n }\n if (!downloaded && lastErr) throw lastErr;\n\n const zipSizeMB = (fs.statSync(zipPath).size / 1024 / 1024).toFixed(1);\n log.info(`\u4E0B\u8F7D\u5B8C\u6210 (${zipSizeMB} MB)`);\n\n // \u6D41\u5F0F\u54C8\u5E0C\u6821\u9A8C\n if (hash.sha1 || hash.sha256) {\n const algo = hash.sha256 ? \"SHA256\" : \"SHA1\";\n log.info(`\u6821\u9A8C\u6587\u4EF6\u5B8C\u6574\u6027 (${algo})...`);\n const ok = await verifyFileHash(zipPath, hash.sha1, hash.sha256);\n if (!ok) throw new Error(`${algo} \u6821\u9A8C\u4E0D\u901A\u8FC7\uFF0C\u6587\u4EF6\u53EF\u80FD\u635F\u574F`);\n log.info(`${algo} \u6821\u9A8C\u901A\u8FC7`);\n }\n } catch (e) {\n log.error(`\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u81EA\u52A8\u56DE\u6EDA\n rollbackFromBackup({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n rmSafe(stagingDir);\n return 1;\n }\n\n // 9. \u89E3\u538B + \u90E8\u7F72\n try {\n log.info(\"\u89E3\u538B\u4E2D...\");\n // \u5148\u6E05\u7A7A BDS \u76EE\u5F55\n emptyDirSync(bdsPath);\n await extractZipToBds(zipPath, bdsPath);\n log.info(\"\u89E3\u538B\u5B8C\u6210\");\n } catch (e) {\n log.error(`\u89E3\u538B\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u89E3\u538B\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u56DE\u6EDA: \u6E05\u7A7A + \u4ECE\u5907\u4EFD\u6062\u590D preserves\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n } finally {\n rmSafe(zipPath); // \u6E05\u6389 staging zip\n }\n\n // 10. \u5B8C\u6574\u6027\u68C0\u67E5 (\u907F\u514D\u89E3\u538B\u51FA\u7A7A/\u7F3A\u6587\u4EF6\u7684\u75C5\u6001\u5305)\n const verify = verifyBdsInstall(bdsPath, [\n \"bedrock_server.exe\",\n /*\"bedrock_server_symbols.debug\",*/ \"permissions.json\",\n ]);\n if (!verify.ok) {\n log.error(`\u89E3\u538B\u540E\u7684 BDS \u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5931\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u90E8\u7F72\u540E\u7F3A\u5931\u5173\u952E\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n }\n\n // 11. \u6062\u590D preserves (zip \u89E3\u538B\u65F6\u8FD9\u4E9B\u76EE\u5F55\u53EF\u80FD\u88AB\u8986\u76D6)\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n\n // 11b. \u5B89\u88C5\u6536\u5C3E\uFF1A\u56E0 EULA \u5DF2\u540C\u610F\uFF0C\u786E\u4FDD\u9065\u6D4B\u5F00\u5173\uFF08\u5DF2\u6709\u5219\u8DF3\u8FC7\uFF09\n ensureEmitServerTelemetry(bdsPath, log);\n\n // 12. \u5199\u5165\u7248\u672C\u7F13\u5B58\n const newExeHash = await hashFileAsync(exePath, \"sha256\").catch(() => \"\");\n if (newExeHash) {\n saveVersionCache(latestVer, newExeHash);\n log.info(`\u5DF2\u8BB0\u5F55\u7248\u672C ${latestVer} \u7684 SHA256`);\n }\n\n // 13. \u542F\u52A8 BDS\n if (autoRestart) {\n try {\n log.info(\"\u542F\u52A8 BDS...\");\n await bds.start();\n } catch (e) {\n log.error(`\u542F\u52A8\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u542F\u52A8\u5931\u8D25: ${(e as Error).message}\\n\u8BF7\u624B\u52A8\u542F\u52A8 BDS`);\n // \u6CE8\u610F: \u6B64\u65F6 BDS \u5DF2\u7ECF\u90E8\u7F72\u5B8C\u6210\uFF0C\u542F\u52A8\u5931\u8D25 \u2192 \u542F\u52A8\u95EE\u9898\uFF0C\u4E0D\u505A\u6587\u4EF6\u7EA7\u56DE\u6EDA\n rmSafe(stagingDir);\n clearRollbackMarker();\n return 1;\n }\n }\n\n rmSafe(stagingDir);\n clearRollbackMarker();\n\n // 14. QQ \u901A\u77E5\u7ED3\u679C\n const durationMs = Date.now() - startTime;\n if (qqNotify) {\n await sendText(\n `\u2705 BDS \u66F4\u65B0\u5B8C\u6210\\n\\n` +\n `${currentVer} \u2192 ${latestVer}\\n` +\n `\u8017\u65F6: ${(durationMs / 1000).toFixed(1)}s\\n` +\n `${autoRestart ? \"\u670D\u52A1\u5668\u5DF2\u91CD\u65B0\u542F\u52A8\" : \"\u8BF7\u624B\u52A8\u91CD\u542F\u670D\u52A1\u5668\"}`\n );\n }\n log.info(`===== \u66F4\u65B0\u5B8C\u6210 (${(durationMs / 1000).toFixed(1)}s) =====`);\n /* \u673A\u5668\u53EF\u8BFB\u7ED3\u679C\u6807\u8BB0\uFF1A\u4F9B sfmc \u7B49\u76D1\u7763\u5668\u5224\u65AD\u300C\u771F\u6B63\u5B8C\u6210\u90E8\u7F72\u300D\uFF0C\u52FF\u4F9D\u8D56\u672C\u5730\u5316\u65E5\u5FD7\u6587\u6848\u3002 */\n emitUpdateResult(\"deployed\");\n return 0;\n}\n\nfunction isMain(): boolean {\n // sfmc supervisor \u901A\u8FC7 SFMC_SERVICE \u62C9\u8D77\u5B50\u8FDB\u7A0B\u65F6\u4F18\u5148\u5224\u5B9A\n if (process.env.SFMC_SERVICE === \"update\") return true;\n return isMainModule(import.meta.url);\n}\n\nif (isMain()) {\n runUpdate()\n .then((code) => {\n closeLog();\n process.exit(code);\n })\n .catch((e) => {\n log.error(`\u672A\u6355\u83B7\u9519\u8BEF: ${(e as Error).message}`);\n closeLog();\n process.exit(1);\n });\n}\n"],
|
|
5
|
-
"mappings": "AAWA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,wBAAwB;AACjC,SAAS,gBAAgB,sBAAsB;AAC/C,SAAS,aAAa,cAAc,eAAe,cAAc;AACjE,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,YAAY,UAAU,oBAAoB;AACnD,SAAS,UAAU,qBAAqB;AACxC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iCAAiC;AAC1C,SAAS,sBAAsB,oBAAoB,0BAA0B;AAC7E,SAAS,wBAAwB;
|
|
4
|
+
"sourcesContent": ["/**\n * check-update.ts \u2014 BDS \u81EA\u52A8\u66F4\u65B0\u5668 (\u4E3B\u6D41\u7A0B)\n *\n * 1. \u4E34\u65F6 staging \u76EE\u5F55 (mkdtempSync) - \u907F\u514D\u6C61\u67D3\u6570\u636E\u6839\n * 2. \u4E0B\u8F7D/\u89E3\u538B\u5931\u8D25 \u2192 \u81EA\u52A8\u4ECE\u5907\u4EFD\u56DE\u6EDA preserves\n * 3. \u6D41\u5F0F SHA256 \u6821\u9A8C - \u4E0D\u628A 250MB \u6587\u4EF6\u8BFB\u5165\u5185\u5B58\n * 4. \u517C\u5BB9\u7248\u672C\u767D\u540D\u5355 - \u4E0D\u5339\u914D\u5219\u8DF3\u8FC7\u5347\u7EA7\n * 5. QQ \u901A\u77E5\u7EDF\u4E00\u52A0 5s \u8D85\u65F6 - \u6C38\u8FDC\u4E0D\u963B\u585E\u4E3B\u6D41\u7A0B\n * 6. Rollback marker \u843D\u76D8\u5230 <ROOT>/.sfmc/ - \u8DE8\u8FDB\u7A0B / \u8DE8\u91CD\u542F\u53EF\u6062\u590D\n */\n\nimport {\n bindByteProgressToBar,\n createNodeServiceLogger,\n createTerminalProgress,\n} from \"@sfmc-bds/sdk/logs\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { createBdsManager } from \"./bds-manager.js\";\nimport { CHANGELOG_BASE, fetchChangelog } from \"./changelog.js\";\nimport { copyDirSync, emptyDirSync, hashFileAsync, rmSafe } from \"./fsx.js\";\nimport { httpDownload } from \"./http.js\";\nimport { isMainModule } from \"./is-main.js\";\nimport { loadConfig, LOG_PATH, resolvePaths } from \"./paths.js\";\nimport { sendText, sendWithImage } from \"./qqutil.js\";\nimport {\n clearRollbackMarker,\n getDirSize,\n rollbackFromBackup,\n verifyBdsInstall,\n writeRollbackMarker,\n} from \"./rollback.js\";\nimport { ensureEmitServerTelemetry } from \"./server-properties.js\";\nimport { clearTaskbarProgress, isTaskbarSupported, setTaskbarProgress } from \"./taskbar.js\";\nimport { emitUpdateKv, emitUpdateResult } from \"./update-result.js\";\nimport {\n buildDownloadUrls,\n fetchVersionDetails,\n getVersionInfo,\n isVersionCompatible,\n verifyFileHash,\n} from \"./upstream.js\";\nimport { compareVersions, getCurrentVersionAsync, getCurrentVersionSync, saveVersionCache } from \"./version.js\";\nimport { extractZipFileToDir } from \"./zipx.js\";\n\n// \u72EC\u7ACB\u5165\u53E3:source = \"updater\",\u4E0E bds-manager \u7684 \"bds-tools\" \u533A\u5206;\u540C\u843D\u76D8 bds-update.log\nconst log = createNodeServiceLogger({ source: \"updater\", logPath: LOG_PATH });\nconst closeLog = (): void => log.close();\n\nfunction parseArgs(argv: string[]): Record<string, string | boolean> {\n const out: Record<string, string | boolean> = {};\n for (const a of argv) {\n const m = a.match(/^--([\\w-]+)(?:=(.+))?$/);\n if (m) out[m[1]!] = m[2] || true;\n }\n return out;\n}\n\ninterface UpdateContext {\n cfg: ReturnType<typeof loadConfig>;\n channel: \"release\" | \"preview\" | string;\n checkOnly: boolean;\n force: boolean;\n bdsPath: string;\n backupDir: string;\n preserve: string[];\n autoRestart: boolean;\n qqNotify: boolean;\n}\n\nfunction buildContext(): UpdateContext {\n const cfg = loadConfig();\n const args = parseArgs(process.argv.slice(2));\n const { bds_path, backup_dir, preserve } = resolvePaths(cfg);\n const channel = String(args[\"channel\"] || cfg.channel || \"release\");\n return {\n cfg,\n channel,\n checkOnly: !!args[\"check-only\"],\n force: !!args[\"force\"],\n bdsPath: bds_path,\n backupDir: backup_dir,\n preserve,\n autoRestart: !args[\"no-start\"] && cfg.auto_restart !== false,\n qqNotify: !!cfg.qq_notify,\n };\n}\n\nasync function doBackup(\n bdsPath: string,\n backupDir: string,\n preserve: string[]\n): Promise<{ path: string; size: number }> {\n const dateStr = new Date().toISOString().slice(0, 10);\n const dest = path.join(backupDir, dateStr);\n fs.mkdirSync(dest, { recursive: true });\n\n let anyCopied = false;\n for (const item of preserve) {\n const src = path.join(bdsPath, item);\n const target = path.join(dest, item);\n if (!fs.existsSync(src)) continue;\n fs.mkdirSync(path.dirname(target), { recursive: true });\n if (fs.statSync(src).isDirectory()) copyDirSync(src, target);\n else fs.copyFileSync(src, target);\n anyCopied = true;\n log.info(`\u5DF2\u5907\u4EFD: ${item}`);\n }\n\n // \u5373\u4F7F\u5168\u90E8 preserve \u90FD\u8DF3\u8FC7\uFF0C\u4E5F\u8BA9\u76EE\u5F55\u5B58\u5728\u4EE5\u4FBF\u8BB0\u5F55\u65F6\u95F4\u6233\n if (!anyCopied) {\n log.info(`\u6CA1\u6709\u9700\u8981\u5907\u4EFD\u7684\u6587\u4EF6 (preserve \u5217\u8868\u4E3A\u7A7A\u6216\u5168\u90E8\u7F3A\u5931)`);\n }\n return { path: dest, size: getDirSize(dest) };\n}\n\n/** \u5F02\u6B65\u6062\u590D preserves \u4ECE\u5907\u4EFD\u5230 BDS \u8DEF\u5F84 */\nasync function restorePreserves(bdsPath: string, backupDir: string, preserve: string[]): Promise<void> {\n for (const item of preserve) {\n const src = path.join(backupDir, item);\n const dest = path.join(bdsPath, item);\n if (!fs.existsSync(src)) continue;\n try {\n if (fs.statSync(src).isDirectory()) {\n if (fs.existsSync(dest)) emptyDirSync(dest);\n copyDirSync(src, dest);\n } else {\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.copyFileSync(src, dest);\n }\n log.info(`\u5DF2\u6062\u590D: ${item}`);\n } catch (e) {\n log.warn(`\u6062\u590D\u5931\u8D25 ${item}: ${(e as Error).message}`);\n }\n }\n}\n\n/** \u628A zip \u89E3\u538B\u5230 destDir (\u8986\u76D6) \u2014 \u7ECF zipx \u5B89\u5168\u89E3\u538B */\nasync function extractZipToBds(zipPath: string, destDir: string): Promise<void> {\n // \u62BD\u51FA\u5230\u4E34\u65F6\u76EE\u5F55\uFF0C\u907F\u514D\u65E7\u5185\u5BB9\u5E72\u6270\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-extract-\"));\n try {\n await extractZipFileToDir(zipPath, tmpDir);\n // \u628A\u4E34\u65F6\u76EE\u5F55\u91CC\u7684\u5185\u5BB9\u590D\u5236\u5230 BDS \u8DEF\u5F84\n for (const entry of fs.readdirSync(tmpDir)) {\n const srcPath = path.join(tmpDir, entry);\n const destPath = path.join(destDir, entry);\n if (fs.statSync(srcPath).isDirectory()) {\n if (fs.existsSync(destPath)) emptyDirSync(destPath);\n copyDirSync(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n } finally {\n rmSafe(tmpDir);\n }\n}\n\nexport async function runUpdate(): Promise<number> {\n const startTime = Date.now();\n const ctx = buildContext();\n const { cfg, channel, checkOnly, force, bdsPath, backupDir, preserve, autoRestart, qqNotify } = ctx;\n\n log.info(`===== \u5F00\u59CB\u68C0\u67E5\u66F4\u65B0 (${channel}) =====`);\n fs.mkdirSync(bdsPath, { recursive: true });\n fs.mkdirSync(backupDir, { recursive: true });\n\n // 1. \u5F53\u524D\u7248\u672C\n const exePath = path.join(bdsPath, \"bedrock_server.exe\");\n const currentVer = await getCurrentVersionAsync(exePath).catch(() => getCurrentVersionSync(exePath));\n log.info(`\u5F53\u524D\u7248\u672C: ${currentVer}`);\n\n // 2. \u83B7\u53D6\u6700\u65B0\u7248\u672C\n let latestVer: string;\n try {\n const info = await getVersionInfo(cfg, channel);\n latestVer = info.version;\n log.info(`\u6700\u65B0\u7248\u672C: ${latestVer}`);\n const cmp = compareVersions(latestVer, currentVer);\n if (cmp <= 0 && !force) {\n log.info(\"\u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0\");\n if (qqNotify) {\n await sendText(`\u2705 BDS \u5DF2\u662F\u6700\u65B0\u7248\u672C\\n\\n\u5F53\u524D: ${currentVer}\\n\u6700\u65B0: ${latestVer}`);\n }\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateResult(\"uptodate\", log);\n return 0;\n }\n } catch (e) {\n log.error(`\u83B7\u53D6\u7248\u672C\u4FE1\u606F\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u65E0\u6CD5\u83B7\u53D6\u7248\u672C\u4FE1\u606F: ${(e as Error).message}`);\n return 1;\n }\n\n // \u517C\u5BB9\u6027\u68C0\u67E5\n if (!force && !isVersionCompatible(cfg, latestVer)) {\n log.warn(`${latestVer} \u4E0D\u5728\u517C\u5BB9\u7248\u672C\u767D\u540D\u5355\u4E2D\uFF0C\u8DF3\u8FC7\u5347\u7EA7`);\n if (qqNotify) {\n await sendText(`\u26A0\uFE0F BDS ${latestVer} \u4E0D\u5728\u517C\u5BB9\u6027\u767D\u540D\u5355\uFF0C\u5DF2\u8DF3\u8FC7\u5347\u7EA7\u3002\u8BF7\u4EBA\u5DE5\u786E\u8BA4\u3002`);\n }\n emitUpdateResult(\"skipped\", log);\n return 2;\n }\n\n // 3. \u53D6\u4E0B\u8F7D\u94FE\u63A5\n let downloadUrls: string[];\n let hash: { sha1: string; sha256: string };\n try {\n const details = await fetchVersionDetails(cfg, channel, latestVer);\n downloadUrls = buildDownloadUrls(cfg, channel, latestVer, details);\n hash = { sha1: details.sha1, sha256: details.sha256 };\n } catch (e) {\n log.error(`\u83B7\u53D6\u4E0B\u8F7D\u8BE6\u60C5\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u8BE6\u60C5\u83B7\u53D6\u5931\u8D25: ${(e as Error).message}`);\n return 1;\n }\n\n if (checkOnly) {\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateKv(\"CHANNEL\", channel, log);\n emitUpdateKv(\"URLS\", String(downloadUrls.length), log);\n emitUpdateResult(\"check-only\", log);\n return 0;\n }\n\n log.info(`\u53D1\u73B0\u65B0\u7248\u672C: ${currentVer} \u2192 ${latestVer}`);\n\n // 4. QQ \u9884\u544A\n if (qqNotify) {\n await sendText(\n `\uD835\uDC0C\uD835\uDC22\uD835\uDC27\uD835\uDC1E\uD835\uDC1C\uD835\uDC2B\uD835\uDC1A\uD835\uDC1F\uD835\uDC2D \uD835\uDC01\uD835\uDC03\uD835\uDC12 \u66F4\u65B0\u901A\u77E5\\n\\n` +\n `\u68C0\u6D4B\u5230\u65B0\u7248\u672C\uFF01\\n\\n` +\n `\u5F53\u524D: ${currentVer}\\n` +\n `\u6700\u65B0: ${latestVer}\\n` +\n `\u9891\u9053: ${channel === \"preview\" ? \"\u9884\u89C8\u7248\" : \"\u6B63\u5F0F\u7248\"}\\n\\n` +\n `\u670D\u52A1\u5668\u5373\u5C06\u5F00\u59CB\u66F4\u65B0~ \u8BF7\u8010\u5FC3\u7B49\u5F85^(*\uFFE3(oo)\uFFE3)^`\n );\n const cl = await fetchChangelog(channel);\n if (cl) {\n const text = `\uD83D\uDCCB \u66F4\u65B0\u5185\u5BB9\u6982\u8981\\n\\n${cl.text.slice(0, 1500)}\\n\\n\u5B8C\u6574\u65E5\u5FD7: ${CHANGELOG_BASE}`;\n if (cl.imageBase64) await sendWithImage(text, cl.imageBase64);\n else await sendText(text);\n } else {\n await sendText(`\uD83D\uDCCB \u66F4\u65B0\u65E5\u5FD7: ${CHANGELOG_BASE}`);\n }\n }\n\n // 5. \u5907\u4EFD\n let backupInfo: { path: string; size: number };\n try {\n backupInfo = await doBackup(bdsPath, backupDir, preserve);\n log.info(`\u5907\u4EFD\u5B8C\u6210: ${backupInfo.path} (${(backupInfo.size / 1024 / 1024).toFixed(1)} MB)`);\n if (qqNotify) {\n await sendText(`\u2705 \u5907\u4EFD\u5B8C\u6210\\n\\n\u5927\u5C0F: ${(backupInfo.size / 1024 / 1024).toFixed(1)} MB\\n\u4F4D\u7F6E: ${backupInfo.path}`);\n }\n } catch (e) {\n log.error(`\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}\\n\u64CD\u4F5C\u5DF2\u4E2D\u6B62`);\n return 1;\n }\n\n // 6. \u5199\u56DE\u6EDA\u6807\u8BB0 (\u8DE8\u8FDB\u7A0B\u53EF\u6062\u590D)\n writeRollbackMarker({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n\n // 7. \u505C\u670D\n const bds = createBdsManager({ detached: true });\n try {\n log.info(\"\u505C\u6B62 BDS \u670D\u52A1...\");\n await bds.stop();\n log.info(\"BDS \u5DF2\u505C\u6B62\");\n } catch (e) {\n log.warn(`BDS \u505C\u6B62\u5F02\u5E38: ${(e as Error).message}`);\n }\n\n // 8. \u4E0B\u8F7D (\u5168\u90E8\u5931\u8D25\u5219\u56DE\u6EDA)\n // \u7528 mkdtempSync \u521B\u5EFA\u4E34\u65F6 staging \u76EE\u5F55 - \u907F\u514D\u6C61\u67D3 SCRIPT_DIR\n const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-update-\"));\n const zipPath = path.join(stagingDir, `bedrock-server-${latestVer}.zip`);\n let downloaded = false;\n try {\n log.info(`\u5F00\u59CB\u4E0B\u8F7D ${latestVer}...`);\n if (qqNotify) await sendText(`\uD83D\uDCE5 \u6B63\u5728\u4E0B\u8F7D BDS ${latestVer}...`);\n\n let lastErr: Error | null = null;\n const downloadTimeoutMs = (cfg.download_timeout ?? 120) * 1000;\n /* stderr \u88AB pipe \u65F6\u4E0D\u753B bar\uFF1B\u7528\u6587\u672C\u8FDB\u5EA6\u7ED9 sfmc REPL \u7B49\u7236\u8FDB\u7A0B */\n if (isTaskbarSupported() && process.stdout.isTTY) {\n log.info(\"\u68C0\u6D4B\u5230 Windows Terminal,\u4EFB\u52A1\u680F\u8FDB\u5EA6\u5DF2\u542F\u7528 (OSC 9;4)\");\n }\n for (const url of downloadUrls) {\n /* \u6BCF\u6B21\u5C1D\u8BD5\u65B0\u5EFA bar + binder\uFF0C\u907F\u514D\u5931\u8D25\u91CD\u8BD5\u65F6 started \u72B6\u6001\u6B8B\u7559\uFF08LSP\uFF09 */\n const progressBar = createTerminalProgress({\n stream: process.stderr,\n logger: (msg) => log.info(msg.startsWith(\"\u8FDB\u5EA6\") ? `\u4E0B\u8F7D${msg.slice(2)}` : msg),\n format: \"\u4E0B\u8F7D\u8FDB\u5EA6 | {bar} | {percentage}% | {value}/{total} MB | \u901F\u5EA6: {speed}\",\n });\n const onByteProgress = bindByteProgressToBar(progressBar, {\n speedSampleMs: 0,\n onProgress: (dl, total) => {\n const pct = total > 0 ? (dl / total) * 100 : 0;\n setTaskbarProgress(pct);\n },\n });\n try {\n setTaskbarProgress(0);\n await httpDownload(url, zipPath, {\n totalTimeoutMs: Math.max(downloadTimeoutMs, 600_000), // \u4E0D\u5C11\u4E8E 10 \u5206\u949F\n onProgress: onByteProgress,\n });\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5B8C\u6210,\u4EFB\u52A1\u680F\u6536\u5230 100% \u7EFF\u6761\u540E\u6E05\u6389\n setTaskbarProgress(100);\n clearTaskbarProgress();\n downloaded = true;\n lastErr = null;\n break;\n } catch (e) {\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5931\u8D25,\u4EFB\u52A1\u680F\u4EAE\u7EA2\n setTaskbarProgress(100, \"error\");\n clearTaskbarProgress();\n lastErr = e as Error;\n log.warn(`${url} \u4E0D\u53EF\u7528: ${lastErr.message}\uFF0C\u5C1D\u8BD5\u5907\u7528\u5730\u5740...`);\n }\n }\n if (!downloaded && lastErr) throw lastErr;\n\n const zipSizeMB = (fs.statSync(zipPath).size / 1024 / 1024).toFixed(1);\n log.info(`\u4E0B\u8F7D\u5B8C\u6210 (${zipSizeMB} MB)`);\n\n // \u6D41\u5F0F\u54C8\u5E0C\u6821\u9A8C\n if (hash.sha1 || hash.sha256) {\n const algo = hash.sha256 ? \"SHA256\" : \"SHA1\";\n log.info(`\u6821\u9A8C\u6587\u4EF6\u5B8C\u6574\u6027 (${algo})...`);\n const ok = await verifyFileHash(zipPath, hash.sha1, hash.sha256);\n if (!ok) throw new Error(`${algo} \u6821\u9A8C\u4E0D\u901A\u8FC7\uFF0C\u6587\u4EF6\u53EF\u80FD\u635F\u574F`);\n log.info(`${algo} \u6821\u9A8C\u901A\u8FC7`);\n }\n } catch (e) {\n log.error(`\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u81EA\u52A8\u56DE\u6EDA\n rollbackFromBackup({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n rmSafe(stagingDir);\n return 1;\n }\n\n // 9. \u89E3\u538B + \u90E8\u7F72\n try {\n log.info(\"\u89E3\u538B\u4E2D...\");\n // \u5148\u6E05\u7A7A BDS \u76EE\u5F55\n emptyDirSync(bdsPath);\n await extractZipToBds(zipPath, bdsPath);\n log.info(\"\u89E3\u538B\u5B8C\u6210\");\n } catch (e) {\n log.error(`\u89E3\u538B\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u89E3\u538B\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u56DE\u6EDA: \u6E05\u7A7A + \u4ECE\u5907\u4EFD\u6062\u590D preserves\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n } finally {\n rmSafe(zipPath); // \u6E05\u6389 staging zip\n }\n\n // 10. \u5B8C\u6574\u6027\u68C0\u67E5 (\u907F\u514D\u89E3\u538B\u51FA\u7A7A/\u7F3A\u6587\u4EF6\u7684\u75C5\u6001\u5305)\n const verify = verifyBdsInstall(bdsPath, [\n \"bedrock_server.exe\",\n /*\"bedrock_server_symbols.debug\",*/ \"permissions.json\",\n ]);\n if (!verify.ok) {\n log.error(`\u89E3\u538B\u540E\u7684 BDS \u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5931\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u90E8\u7F72\u540E\u7F3A\u5931\u5173\u952E\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n }\n\n // 11. \u6062\u590D preserves (zip \u89E3\u538B\u65F6\u8FD9\u4E9B\u76EE\u5F55\u53EF\u80FD\u88AB\u8986\u76D6)\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n\n // 11b. \u5B89\u88C5\u6536\u5C3E\uFF1A\u56E0 EULA \u5DF2\u540C\u610F\uFF0C\u786E\u4FDD\u9065\u6D4B\u5F00\u5173\uFF08\u5DF2\u6709\u5219\u8DF3\u8FC7\uFF09\n ensureEmitServerTelemetry(bdsPath, log);\n\n // 12. \u5199\u5165\u7248\u672C\u7F13\u5B58\n const newExeHash = await hashFileAsync(exePath, \"sha256\").catch(() => \"\");\n if (newExeHash) {\n saveVersionCache(latestVer, newExeHash);\n log.info(`\u5DF2\u8BB0\u5F55\u7248\u672C ${latestVer} \u7684 SHA256`);\n }\n\n // 13. \u542F\u52A8 BDS\n if (autoRestart) {\n try {\n log.info(\"\u542F\u52A8 BDS...\");\n await bds.start();\n } catch (e) {\n log.error(`\u542F\u52A8\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u542F\u52A8\u5931\u8D25: ${(e as Error).message}\\n\u8BF7\u624B\u52A8\u542F\u52A8 BDS`);\n // \u6CE8\u610F: \u6B64\u65F6 BDS \u5DF2\u7ECF\u90E8\u7F72\u5B8C\u6210\uFF0C\u542F\u52A8\u5931\u8D25 \u2192 \u542F\u52A8\u95EE\u9898\uFF0C\u4E0D\u505A\u6587\u4EF6\u7EA7\u56DE\u6EDA\n rmSafe(stagingDir);\n clearRollbackMarker();\n return 1;\n }\n }\n\n rmSafe(stagingDir);\n clearRollbackMarker();\n\n // 14. QQ \u901A\u77E5\u7ED3\u679C\n const durationMs = Date.now() - startTime;\n if (qqNotify) {\n await sendText(\n `\u2705 BDS \u66F4\u65B0\u5B8C\u6210\\n\\n` +\n `${currentVer} \u2192 ${latestVer}\\n` +\n `\u8017\u65F6: ${(durationMs / 1000).toFixed(1)}s\\n` +\n `${autoRestart ? \"\u670D\u52A1\u5668\u5DF2\u91CD\u65B0\u542F\u52A8\" : \"\u8BF7\u624B\u52A8\u91CD\u542F\u670D\u52A1\u5668\"}`\n );\n }\n log.info(`===== \u66F4\u65B0\u5B8C\u6210 (${(durationMs / 1000).toFixed(1)}s) =====`);\n /* \u673A\u5668\u53EF\u8BFB\u7ED3\u679C\u6807\u8BB0\uFF1A\u4F9B sfmc \u7B49\u76D1\u7763\u5668\u5224\u65AD\u300C\u771F\u6B63\u5B8C\u6210\u90E8\u7F72\u300D\uFF0C\u52FF\u4F9D\u8D56\u672C\u5730\u5316\u65E5\u5FD7\u6587\u6848\u3002 */\n emitUpdateResult(\"deployed\", log);\n return 0;\n}\n\nfunction isMain(): boolean {\n // sfmc supervisor \u901A\u8FC7 SFMC_SERVICE \u62C9\u8D77\u5B50\u8FDB\u7A0B\u65F6\u4F18\u5148\u5224\u5B9A\n if (process.env.SFMC_SERVICE === \"update\") return true;\n return isMainModule(import.meta.url);\n}\n\nif (isMain()) {\n runUpdate()\n .then((code) => {\n closeLog();\n process.exit(code);\n })\n .catch((e) => {\n log.error(`\u672A\u6355\u83B7\u9519\u8BEF: ${(e as Error).message}`);\n closeLog();\n process.exit(1);\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cli-pack-manager.js
CHANGED
|
@@ -227,10 +227,14 @@ async function main() {
|
|
|
227
227
|
}
|
|
228
228
|
{
|
|
229
229
|
const root = need(args, "root");
|
|
230
|
-
const depth = args["max-depth"] ? Number(args["max-depth"]) :
|
|
231
|
-
const
|
|
232
|
-
|
|
230
|
+
const depth = args["max-depth"] ? Number(args["max-depth"]) : 4;
|
|
231
|
+
const resolved = await wp.resolvePackRoots(path.resolve(root), { maxDirDepth: depth });
|
|
232
|
+
try {
|
|
233
|
+
process.stdout.write(`${JSON.stringify(resolved.roots)}
|
|
233
234
|
`);
|
|
235
|
+
} finally {
|
|
236
|
+
resolved.dispose();
|
|
237
|
+
}
|
|
234
238
|
return;
|
|
235
239
|
}
|
|
236
240
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/cli-pack-manager.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * pack-manager CLI \u2014 thin wrapper around the pack-manager pure functions\n * so spawnService can call it as a sub-process.\n *\n * node bds-tools/dist/pack-manager.js assemble-bp --src <dir> --out <dir> --name <name> [--uuid <uuid>] [--module-uuid <uuid>] [--version 1,0,0] [--description \"...\"] [--icon <png>]\n * node bds-tools/dist/pack-manager.js assemble-rp (--modules-dir <dir>|--modules-json <file>) --out <dir> --name <name> [--uuid <uuid>] [--module-uuid <uuid>] [--version 1,0,0] [--description \"...\"]\n * node bds-tools/dist/pack-manager.js deploy --bds-root <dir> --level <name> --bp-src <dir> [--rp-src <dir>] --bp-name <name> [--rp-name <name>] [--clear-rp]\n * node bds-tools/dist/pack-manager.js enable-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid> --version 1,0,0\n * node bds-tools/dist/pack-manager.js disable-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js ensure-permission --bds-root <dir> --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js read-level --bds-root <dir>\n * node bds-tools/dist/pack-manager.js read-manifest --pack-dir <dir>\n * node bds-tools/dist/pack-manager.js has-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js list-packs --worlds-dir <dir> --level <name> --kind behavior|resource\n *\n * The pure-function API lives in pack-manager.ts. This CLI exists so a\n * spawnService child process doesn't have to deal with module resolution \u2014\n * it just gets SFMC_ROOT injected, finds its own dist sibling,\n * and reads JSON flags from argv.\n */\n\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { readLevelName } from \"./pack-manager.js\";\n\nfunction die(msg: string, code = 1): never {\n process.stderr.write(`[pack-manager] ${msg}\\n`);\n process.exit(code);\n}\n\nfunction parseArgs(argv: string[]): { [k: string]: string | undefined } {\n const out: { [k: string]: string | undefined } = {};\n for (let i = 0; i < argv.length; i++) {\n const a = argv[i];\n if (a && a.startsWith(\"--\")) {\n const key = a.slice(2);\n const next = argv[++i];\n /* \u5E03\u5C14\u65D7\u6807(\u65E0\u503C\u6216\u4E0B\u4E00\u53C2\u4E5F\u662F --xxx) */\n if (next === undefined || next.startsWith(\"--\")) {\n out[key] = \"1\";\n if (next !== undefined) i--;\n } else {\n out[key] = next;\n }\n }\n }\n return out;\n}\n\nfunction need(args: { [k: string]: string | undefined }, key: string): string {\n const v = args[key];\n if (!v) die(`--${key} required`);\n return v;\n}\n\nfunction parseVersion(s: string | undefined): [number, number, number] {\n if (!s) return [1, 0, 0];\n const parts = s.split(\",\").map((x) => Number(x.trim()));\n if (parts.length !== 3 || parts.some((n) => !Number.isInteger(n) || (n as number) < 0)) {\n die(`invalid --version (expected \"M,m,p\"): ${s}`);\n }\n return parts as [number, number, number];\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv.slice(2);\n if (argv.length === 0) {\n die(\"usage: pack-manager <verb> [--flags]\");\n }\n const verb = argv[0];\n const args = parseArgs(argv.slice(1));\n\n const mod = await import(\"./pack-manager.js\");\n\n switch (verb) {\n case \"assemble-bp\": {\n const src = need(args, \"src\");\n const out = need(args, \"out\");\n const name = need(args, \"name\");\n const icon = args[\"icon\"];\n await mod.assembleBehaviorPack({\n srcDir: path.resolve(src),\n outDir: path.resolve(out),\n projectName: name,\n version: parseVersion(args[\"version\"]),\n description: args[\"description\"],\n ...(icon ? { iconSrc: path.resolve(icon) } : {}),\n ...(args[\"uuid\"] ? { uuid: args[\"uuid\"] } : {}),\n ...(args[\"module-uuid\"] ? { moduleUuid: args[\"module-uuid\"] } : {}),\n });\n process.stdout.write(`[pack-manager] assembled BP at ${out}\\n`);\n return;\n }\n case \"assemble-rp\": {\n const out = need(args, \"out\");\n const name = need(args, \"name\");\n /* OCP:\u663E\u5F0F map \u4F18\u5148;\u5426\u5219\u56DE\u9000\u626B\u63CF --modules-dir */\n let map: Record<string, string>;\n if (args[\"modules-json\"]) {\n map = mod.loadModuleResourcePackMap(path.resolve(args[\"modules-json\"]));\n } else {\n const modulesDir = need(args, \"modules-dir\");\n map = mod.scanModuleResourcePacks(path.resolve(modulesDir));\n }\n await mod.assembleResourcePack({\n moduleResourceDirs: map,\n outDir: path.resolve(out),\n projectName: name,\n version: parseVersion(args[\"version\"]),\n description: args[\"description\"],\n ...(args[\"uuid\"] ? { uuid: args[\"uuid\"] } : {}),\n ...(args[\"module-uuid\"] ? { moduleUuid: args[\"module-uuid\"] } : {}),\n });\n process.stdout.write(`[pack-manager] assembled RP at ${out} (${Object.keys(map).length} modules)\\n`);\n return;\n }\n case \"deploy\": {\n const bdsRoot = need(args, \"bds-root\");\n const level = need(args, \"level\");\n const bpSrc = need(args, \"bp-src\");\n const bpName = need(args, \"bp-name\");\n const rpSrc = args[\"rp-src\"];\n const rpName = args[\"rp-name\"];\n const clearRp = args[\"clear-rp\"] === \"1\" || args[\"clear-rp\"] === \"true\";\n await mod.deployToBDS({\n bdsRoot: path.resolve(bdsRoot),\n levelName: level,\n behaviorPackSrc: path.resolve(bpSrc),\n ...(rpSrc ? { resourcePackSrc: path.resolve(rpSrc) } : {}),\n bpName,\n ...(rpName ? { rpName } : {}),\n ...(clearRp ? { clearResourcePack: true } : {}),\n });\n process.stdout.write(`[pack-manager] deployed to ${mod.bdsWorldLevelDir(path.resolve(bdsRoot), level)}\\n`);\n return;\n }\n case \"enable-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n await mod.enablePackInWorld({\n worldsDir: path.resolve(worldsDir),\n levelName: level,\n kind,\n packUuid: packId,\n version: parseVersion(args[\"version\"]),\n });\n process.stdout.write(`[pack-manager] enabled ${kind} pack ${packId} in ${level}\\n`);\n return;\n }\n case \"disable-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n await mod.disablePackInWorld({\n worldsDir: path.resolve(worldsDir),\n levelName: level,\n kind,\n packUuid: packId,\n version: parseVersion(args[\"version\"] ?? \"1,0,0\"),\n });\n process.stdout.write(`[pack-manager] disabled ${kind} pack ${packId} in ${level}\\n`);\n return;\n }\n case \"ensure-permission\": {\n const bdsRoot = need(args, \"bds-root\");\n const packId = need(args, \"pack-id\");\n const root = path.resolve(bdsRoot);\n const wrote = await mod.ensureConfigPermission(root, packId);\n const rel = path.relative(root, mod.configPermissionPath(root, packId));\n process.stdout.write(\n wrote ? `[pack-manager] wrote ${rel}\\n` : `[pack-manager] ${rel} already exists \u2014 skipped\\n`\n );\n return;\n }\n case \"read-level\": {\n const root = need(args, \"bds-root\");\n const name = await readLevelName(path.resolve(root));\n process.stdout.write(`${name}\\n`);\n return;\n }\n case \"read-manifest\": {\n const packDir = need(args, \"pack-dir\");\n const header = mod.readPackManifestHeader(path.resolve(packDir));\n if (!header) {\n process.stdout.write(\"null\\n\");\n return;\n }\n process.stdout.write(`${JSON.stringify(header)}\\n`);\n return;\n }\n case \"has-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n const ok = mod.worldPackListHas(path.resolve(worldsDir), level, kind, packId);\n process.stdout.write(ok ? \"1\\n\" : \"0\\n\");\n return;\n }\n case \"list-packs\": {\n /* \u6743\u5A01\u4E16\u754C\u6E05\u5355\u8BFB\u53D6 \u2014 \u8C03\u7528\u65B9\u52FF\u518D\u76F4\u63A5\u89E3\u6790 world_*_packs.json(Demeter/DRY) */\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const list = mod.readWorldPackList(path.resolve(worldsDir), level, kind);\n process.stdout.write(`${JSON.stringify(list)}\\n`);\n return;\n }\n case \"list-installed\":\n case \"bump-version\":\n case \"install-dir\":\n case \"discover-packs\": {\n /* OCP: world-packs \u52A8\u8BCD\u8868\u6269\u5C55\uFF0C\u907F\u514D\u6BCF case \u91CD\u590D dynamic import\uFF08DRY\uFF09 */\n const wp = await import(\"./world-packs.js\");\n if (verb === \"list-installed\") {\n const bdsRoot = need(args, \"bds-root\");\n const level = need(args, \"level\");\n const list = wp.listInstalledWorldPacks(path.resolve(bdsRoot), level);\n process.stdout.write(`${JSON.stringify(list)}\\n`);\n return;\n }\n if (verb === \"bump-version\") {\n const packDir = need(args, \"pack-dir\");\n const next = wp.bumpPackPatchVersion(path.resolve(packDir));\n process.stdout.write(`${JSON.stringify({ version: next })}\\n`);\n return;\n }\n if (verb === \"install-dir\") {\n const src = need(args, \"src\");\n const destParent = need(args, \"dest-parent\");\n const force = !!args[\"force\"];\n const r = await wp.installPackDirectory({\n srcDir: path.resolve(src),\n destParent: path.resolve(destParent),\n force,\n ...(args[\"folder-name\"] ? { folderName: args[\"folder-name\"] } : {}),\n });\n process.stdout.write(`${JSON.stringify(r)}\\n`);\n if (!r.ok && !r.conflict) process.exit(1);\n return;\n }\n {\n const root = need(args, \"root\");\n const depth = args[\"max-depth\"] ? Number(args[\"max-depth\"]) : 2;\n const roots = wp.discoverPackRoots(path.resolve(root), { maxDepth: depth });\n process.stdout.write(`${JSON.stringify(roots)}\\n`);\n return;\n }\n }\n default:\n die(`unknown verb: ${verb}`);\n }\n}\n\nmain().catch((err: unknown) => {\n const msg = err instanceof Error ? (err.stack ?? err.message) : String(err);\n die(msg);\n});\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n/**\n * pack-manager CLI \u2014 thin wrapper around the pack-manager pure functions\n * so spawnService can call it as a sub-process.\n *\n * node bds-tools/dist/pack-manager.js assemble-bp --src <dir> --out <dir> --name <name> [--uuid <uuid>] [--module-uuid <uuid>] [--version 1,0,0] [--description \"...\"] [--icon <png>]\n * node bds-tools/dist/pack-manager.js assemble-rp (--modules-dir <dir>|--modules-json <file>) --out <dir> --name <name> [--uuid <uuid>] [--module-uuid <uuid>] [--version 1,0,0] [--description \"...\"]\n * node bds-tools/dist/pack-manager.js deploy --bds-root <dir> --level <name> --bp-src <dir> [--rp-src <dir>] --bp-name <name> [--rp-name <name>] [--clear-rp]\n * node bds-tools/dist/pack-manager.js enable-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid> --version 1,0,0\n * node bds-tools/dist/pack-manager.js disable-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js ensure-permission --bds-root <dir> --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js read-level --bds-root <dir>\n * node bds-tools/dist/pack-manager.js read-manifest --pack-dir <dir>\n * node bds-tools/dist/pack-manager.js has-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js list-packs --worlds-dir <dir> --level <name> --kind behavior|resource\n *\n * The pure-function API lives in pack-manager.ts. This CLI exists so a\n * spawnService child process doesn't have to deal with module resolution \u2014\n * it just gets SFMC_ROOT injected, finds its own dist sibling,\n * and reads JSON flags from argv.\n */\n\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { readLevelName } from \"./pack-manager.js\";\n\nfunction die(msg: string, code = 1): never {\n process.stderr.write(`[pack-manager] ${msg}\\n`);\n process.exit(code);\n}\n\nfunction parseArgs(argv: string[]): { [k: string]: string | undefined } {\n const out: { [k: string]: string | undefined } = {};\n for (let i = 0; i < argv.length; i++) {\n const a = argv[i];\n if (a && a.startsWith(\"--\")) {\n const key = a.slice(2);\n const next = argv[++i];\n /* \u5E03\u5C14\u65D7\u6807(\u65E0\u503C\u6216\u4E0B\u4E00\u53C2\u4E5F\u662F --xxx) */\n if (next === undefined || next.startsWith(\"--\")) {\n out[key] = \"1\";\n if (next !== undefined) i--;\n } else {\n out[key] = next;\n }\n }\n }\n return out;\n}\n\nfunction need(args: { [k: string]: string | undefined }, key: string): string {\n const v = args[key];\n if (!v) die(`--${key} required`);\n return v;\n}\n\nfunction parseVersion(s: string | undefined): [number, number, number] {\n if (!s) return [1, 0, 0];\n const parts = s.split(\",\").map((x) => Number(x.trim()));\n if (parts.length !== 3 || parts.some((n) => !Number.isInteger(n) || (n as number) < 0)) {\n die(`invalid --version (expected \"M,m,p\"): ${s}`);\n }\n return parts as [number, number, number];\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv.slice(2);\n if (argv.length === 0) {\n die(\"usage: pack-manager <verb> [--flags]\");\n }\n const verb = argv[0];\n const args = parseArgs(argv.slice(1));\n\n const mod = await import(\"./pack-manager.js\");\n\n switch (verb) {\n case \"assemble-bp\": {\n const src = need(args, \"src\");\n const out = need(args, \"out\");\n const name = need(args, \"name\");\n const icon = args[\"icon\"];\n await mod.assembleBehaviorPack({\n srcDir: path.resolve(src),\n outDir: path.resolve(out),\n projectName: name,\n version: parseVersion(args[\"version\"]),\n description: args[\"description\"],\n ...(icon ? { iconSrc: path.resolve(icon) } : {}),\n ...(args[\"uuid\"] ? { uuid: args[\"uuid\"] } : {}),\n ...(args[\"module-uuid\"] ? { moduleUuid: args[\"module-uuid\"] } : {}),\n });\n process.stdout.write(`[pack-manager] assembled BP at ${out}\\n`);\n return;\n }\n case \"assemble-rp\": {\n const out = need(args, \"out\");\n const name = need(args, \"name\");\n /* OCP:\u663E\u5F0F map \u4F18\u5148;\u5426\u5219\u56DE\u9000\u626B\u63CF --modules-dir */\n let map: Record<string, string>;\n if (args[\"modules-json\"]) {\n map = mod.loadModuleResourcePackMap(path.resolve(args[\"modules-json\"]));\n } else {\n const modulesDir = need(args, \"modules-dir\");\n map = mod.scanModuleResourcePacks(path.resolve(modulesDir));\n }\n await mod.assembleResourcePack({\n moduleResourceDirs: map,\n outDir: path.resolve(out),\n projectName: name,\n version: parseVersion(args[\"version\"]),\n description: args[\"description\"],\n ...(args[\"uuid\"] ? { uuid: args[\"uuid\"] } : {}),\n ...(args[\"module-uuid\"] ? { moduleUuid: args[\"module-uuid\"] } : {}),\n });\n process.stdout.write(`[pack-manager] assembled RP at ${out} (${Object.keys(map).length} modules)\\n`);\n return;\n }\n case \"deploy\": {\n const bdsRoot = need(args, \"bds-root\");\n const level = need(args, \"level\");\n const bpSrc = need(args, \"bp-src\");\n const bpName = need(args, \"bp-name\");\n const rpSrc = args[\"rp-src\"];\n const rpName = args[\"rp-name\"];\n const clearRp = args[\"clear-rp\"] === \"1\" || args[\"clear-rp\"] === \"true\";\n await mod.deployToBDS({\n bdsRoot: path.resolve(bdsRoot),\n levelName: level,\n behaviorPackSrc: path.resolve(bpSrc),\n ...(rpSrc ? { resourcePackSrc: path.resolve(rpSrc) } : {}),\n bpName,\n ...(rpName ? { rpName } : {}),\n ...(clearRp ? { clearResourcePack: true } : {}),\n });\n process.stdout.write(`[pack-manager] deployed to ${mod.bdsWorldLevelDir(path.resolve(bdsRoot), level)}\\n`);\n return;\n }\n case \"enable-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n await mod.enablePackInWorld({\n worldsDir: path.resolve(worldsDir),\n levelName: level,\n kind,\n packUuid: packId,\n version: parseVersion(args[\"version\"]),\n });\n process.stdout.write(`[pack-manager] enabled ${kind} pack ${packId} in ${level}\\n`);\n return;\n }\n case \"disable-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n await mod.disablePackInWorld({\n worldsDir: path.resolve(worldsDir),\n levelName: level,\n kind,\n packUuid: packId,\n version: parseVersion(args[\"version\"] ?? \"1,0,0\"),\n });\n process.stdout.write(`[pack-manager] disabled ${kind} pack ${packId} in ${level}\\n`);\n return;\n }\n case \"ensure-permission\": {\n const bdsRoot = need(args, \"bds-root\");\n const packId = need(args, \"pack-id\");\n const root = path.resolve(bdsRoot);\n const wrote = await mod.ensureConfigPermission(root, packId);\n const rel = path.relative(root, mod.configPermissionPath(root, packId));\n process.stdout.write(\n wrote ? `[pack-manager] wrote ${rel}\\n` : `[pack-manager] ${rel} already exists \u2014 skipped\\n`\n );\n return;\n }\n case \"read-level\": {\n const root = need(args, \"bds-root\");\n const name = await readLevelName(path.resolve(root));\n process.stdout.write(`${name}\\n`);\n return;\n }\n case \"read-manifest\": {\n const packDir = need(args, \"pack-dir\");\n const header = mod.readPackManifestHeader(path.resolve(packDir));\n if (!header) {\n process.stdout.write(\"null\\n\");\n return;\n }\n process.stdout.write(`${JSON.stringify(header)}\\n`);\n return;\n }\n case \"has-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n const ok = mod.worldPackListHas(path.resolve(worldsDir), level, kind, packId);\n process.stdout.write(ok ? \"1\\n\" : \"0\\n\");\n return;\n }\n case \"list-packs\": {\n /* \u6743\u5A01\u4E16\u754C\u6E05\u5355\u8BFB\u53D6 \u2014 \u8C03\u7528\u65B9\u52FF\u518D\u76F4\u63A5\u89E3\u6790 world_*_packs.json(Demeter/DRY) */\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const list = mod.readWorldPackList(path.resolve(worldsDir), level, kind);\n process.stdout.write(`${JSON.stringify(list)}\\n`);\n return;\n }\n case \"list-installed\":\n case \"bump-version\":\n case \"install-dir\":\n case \"discover-packs\": {\n /* OCP: world-packs \u52A8\u8BCD\u8868\u6269\u5C55\uFF0C\u907F\u514D\u6BCF case \u91CD\u590D dynamic import\uFF08DRY\uFF09 */\n const wp = await import(\"./world-packs.js\");\n if (verb === \"list-installed\") {\n const bdsRoot = need(args, \"bds-root\");\n const level = need(args, \"level\");\n const list = wp.listInstalledWorldPacks(path.resolve(bdsRoot), level);\n process.stdout.write(`${JSON.stringify(list)}\\n`);\n return;\n }\n if (verb === \"bump-version\") {\n const packDir = need(args, \"pack-dir\");\n const next = wp.bumpPackPatchVersion(path.resolve(packDir));\n process.stdout.write(`${JSON.stringify({ version: next })}\\n`);\n return;\n }\n if (verb === \"install-dir\") {\n const src = need(args, \"src\");\n const destParent = need(args, \"dest-parent\");\n const force = !!args[\"force\"];\n const r = await wp.installPackDirectory({\n srcDir: path.resolve(src),\n destParent: path.resolve(destParent),\n force,\n ...(args[\"folder-name\"] ? { folderName: args[\"folder-name\"] } : {}),\n });\n process.stdout.write(`${JSON.stringify(r)}\\n`);\n if (!r.ok && !r.conflict) process.exit(1);\n return;\n }\n {\n const root = need(args, \"root\");\n const depth = args[\"max-depth\"] ? Number(args[\"max-depth\"]) : 4;\n const resolved = await wp.resolvePackRoots(path.resolve(root), { maxDirDepth: depth });\n try {\n process.stdout.write(`${JSON.stringify(resolved.roots)}\\n`);\n } finally {\n resolved.dispose();\n }\n return;\n }\n }\n default:\n die(`unknown verb: ${verb}`);\n }\n}\n\nmain().catch((err: unknown) => {\n const msg = err instanceof Error ? (err.stack ?? err.message) : String(err);\n die(msg);\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/fsx.d.ts
CHANGED
|
@@ -22,4 +22,13 @@ export declare function emptyDirSync(dir: string): void;
|
|
|
22
22
|
export declare function rmSafe(path: string): void;
|
|
23
23
|
/** 安全写文件 (原子: 写临时文件 → rename) */
|
|
24
24
|
export declare function writeFileSafe(filePath: string, data: string | Buffer): void;
|
|
25
|
+
/**
|
|
26
|
+
* 读 JSON 文件(utf8)。
|
|
27
|
+
* 检测到 UTF-8 BOM 时抛 Utf8BomError(不静默剥离:多为记事本「UTF-8 with BOM」另存,游戏侧也可能异常)。
|
|
28
|
+
*/
|
|
29
|
+
export declare class Utf8BomError extends Error {
|
|
30
|
+
readonly filePath: string;
|
|
31
|
+
constructor(filePath: string);
|
|
32
|
+
}
|
|
33
|
+
export declare function readJsonFile<T = unknown>(filePath: string): T;
|
|
25
34
|
//# sourceMappingURL=fsx.d.ts.map
|
package/dist/fsx.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fsx.d.ts","sourceRoot":"","sources":["../src/fsx.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH;;;GAGG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,GAAG,QAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUzG;AAED,kBAAkB;AAClB,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,GAAG,QAAmB,GAAG,MAAM,CAQzF;AAED,sBAAsB;AACtB,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,kBAAkB;AAClB,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAW3D;AAED,mBAAmB;AACnB,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc3E;AAED,kBAAkB;AAClB,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU9C;AAED,yBAAyB;AACzB,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAY9C;AAED,eAAe;AACf,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzC;AAED,iCAAiC;AACjC,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM3E"}
|
|
1
|
+
{"version":3,"file":"fsx.d.ts","sourceRoot":"","sources":["../src/fsx.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH;;;GAGG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,GAAG,QAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUzG;AAED,kBAAkB;AAClB,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,GAAG,QAAmB,GAAG,MAAM,CAQzF;AAED,sBAAsB;AACtB,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,kBAAkB;AAClB,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAW3D;AAED,mBAAmB;AACnB,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc3E;AAED,kBAAkB;AAClB,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU9C;AAED,yBAAyB;AACzB,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAY9C;AAED,eAAe;AACf,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzC;AAED,iCAAiC;AACjC,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM3E;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,YAAY,QAAQ,EAAE,MAAM,EAM3B;CACF;AAED,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,CAM7D"}
|
package/dist/fsx.js
CHANGED
|
@@ -89,7 +89,25 @@ function writeFileSafe(filePath, data) {
|
|
|
89
89
|
fs.writeFileSync(tmp, data);
|
|
90
90
|
fs.renameSync(tmp, filePath);
|
|
91
91
|
}
|
|
92
|
+
class Utf8BomError extends Error {
|
|
93
|
+
filePath;
|
|
94
|
+
constructor(filePath) {
|
|
95
|
+
super(
|
|
96
|
+
`UTF-8 BOM in ${filePath}: re-save as UTF-8 without BOM (Notepad "UTF-8 with BOM" is not valid for Bedrock packs)`
|
|
97
|
+
);
|
|
98
|
+
this.name = "Utf8BomError";
|
|
99
|
+
this.filePath = filePath;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function readJsonFile(filePath) {
|
|
103
|
+
const text = fs.readFileSync(filePath, "utf8");
|
|
104
|
+
if (text.length > 0 && text.charCodeAt(0) === 65279) {
|
|
105
|
+
throw new Utf8BomError(filePath);
|
|
106
|
+
}
|
|
107
|
+
return JSON.parse(text);
|
|
108
|
+
}
|
|
92
109
|
export {
|
|
110
|
+
Utf8BomError,
|
|
93
111
|
copyDirAsync,
|
|
94
112
|
copyDirSync,
|
|
95
113
|
copyFileAsync,
|
|
@@ -97,6 +115,7 @@ export {
|
|
|
97
115
|
getDirSize,
|
|
98
116
|
hashFileAsync,
|
|
99
117
|
hashFileSync,
|
|
118
|
+
readJsonFile,
|
|
100
119
|
rmSafe,
|
|
101
120
|
writeFileSafe
|
|
102
121
|
};
|
package/dist/fsx.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/fsx.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * fsx.ts \u2014 \u5F02\u6B65/\u6D41\u5F0F\u6587\u4EF6\u64CD\u4F5C (\u907F\u514D\u5927\u6587\u4EF6\u52A0\u8F7D\u8FDB\u5185\u5B58)\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\nimport { pipeline } from \"node:stream/promises\";\n\n/**\n * \u6D41\u5F0F\u8BA1\u7B97\u6587\u4EF6\u54C8\u5E0C (sha1 / sha256)\uFF0C\n * \u7528\u4E8E\u5927\u6587\u4EF6 (\u4F8B\u5982 bedrock_server.exe ~80MB)\uFF0C\u4E0D\u4F1A OOM\u3002\n */\nexport async function hashFileAsync(filePath: string, algo: \"sha1\" | \"sha256\" = \"sha256\"): Promise<string> {\n return new Promise((resolve, reject) => {\n const h = crypto.createHash(algo);\n const stream = fs.createReadStream(filePath);\n stream.on(\"data\", (chunk: Buffer | string) => {\n h.update(typeof chunk === \"string\" ? Buffer.from(chunk) : chunk);\n });\n stream.on(\"end\", () => resolve(h.digest(\"hex\").toLowerCase()));\n stream.on(\"error\", reject);\n });\n}\n\n/** \u540C\u6B65\u7248\u672C\uFF08\u7528\u4E8E\u5C0F\u6587\u4EF6\uFF09 */\nexport function hashFileSync(filePath: string, algo: \"sha1\" | \"sha256\" = \"sha256\"): string {\n try {\n const h = crypto.createHash(algo);\n h.update(fs.readFileSync(filePath));\n return h.digest(\"hex\").toLowerCase();\n } catch {\n return \"\";\n }\n}\n\n/** \u540C\u6B65\u6D41\u5F0F\u62F7\u8D1D\u5355\u6587\u4EF6 (\u590D\u5236\u4E2D) */\nexport async function copyFileAsync(src: string, dest: string): Promise<void> {\n await pipeline(fs.createReadStream(src), fs.createWriteStream(dest));\n}\n\n/** \u540C\u6B65\u76EE\u5F55\u590D\u5236 (\u9012\u5F52) */\nexport function copyDirSync(src: string, dest: string): void {\n fs.mkdirSync(dest, { recursive: true });\n for (const entry of fs.readdirSync(src)) {\n const srcPath = path.join(src, entry);\n const destPath = path.join(dest, entry);\n if (fs.statSync(srcPath).isDirectory()) {\n copyDirSync(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n}\n\n/** \u5F02\u6B65\u76EE\u5F55\u590D\u5236 (\u57FA\u4E8E\u6D41) */\nexport async function copyDirAsync(src: string, dest: string): Promise<void> {\n fs.mkdirSync(dest, { recursive: true });\n await Promise.all(\n fs.readdirSync(src).map(async (entry) => {\n const srcPath = path.join(src, entry);\n const destPath = path.join(dest, entry);\n const stat = fs.statSync(srcPath);\n if (stat.isDirectory()) {\n await copyDirAsync(srcPath, destPath);\n } else {\n await copyFileAsync(srcPath, destPath);\n }\n })\n );\n}\n\n/** \u8BA1\u7B97\u76EE\u5F55\u5927\u5C0F (\u5B57\u8282) */\nexport function getDirSize(dir: string): number {\n let total = 0;\n try {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) total += getDirSize(full);\n else if (entry.isFile()) total += fs.statSync(full).size;\n }\n } catch {}\n return total;\n}\n\n/** \u5F3A\u5236\u6E05\u7A7A\u76EE\u5F55\u5185\u5BB9 (\u4F46\u4FDD\u7559\u76EE\u5F55\u672C\u8EAB) */\nexport function emptyDirSync(dir: string): void {\n if (!fs.existsSync(dir)) return;\n for (const entry of fs.readdirSync(dir)) {\n const full = path.join(dir, entry);\n try {\n const stat = fs.statSync(full);\n if (stat.isDirectory()) fs.rmSync(full, { recursive: true, force: true });\n else fs.unlinkSync(full);\n } catch (e) {\n // \u5FFD\u7565: \u9876\u5C42\u4ECD\u4FDD\u7559\u76EE\u5F55\uFF0C\u5373\u4F7F\u90E8\u5206\u5B50\u9879\u65E0\u6CD5\u5220\u9664\n }\n }\n}\n\n/** \u5B89\u5168\u5220\u9664\u6574\u4E2A\u76EE\u5F55 */\nexport function rmSafe(path: string): void {\n try {\n fs.rmSync(path, { recursive: true, force: true });\n } catch {\n /* ignore */\n }\n}\n\n/** \u5B89\u5168\u5199\u6587\u4EF6 (\u539F\u5B50: \u5199\u4E34\u65F6\u6587\u4EF6 \u2192 rename) */\nexport function writeFileSafe(filePath: string, data: string | Buffer): void {\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n const tmp = `${filePath}.${process.pid}.tmp`;\n fs.writeFileSync(tmp, data);\n fs.renameSync(tmp, filePath);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * fsx.ts \u2014 \u5F02\u6B65/\u6D41\u5F0F\u6587\u4EF6\u64CD\u4F5C (\u907F\u514D\u5927\u6587\u4EF6\u52A0\u8F7D\u8FDB\u5185\u5B58)\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\nimport { pipeline } from \"node:stream/promises\";\n\n/**\n * \u6D41\u5F0F\u8BA1\u7B97\u6587\u4EF6\u54C8\u5E0C (sha1 / sha256)\uFF0C\n * \u7528\u4E8E\u5927\u6587\u4EF6 (\u4F8B\u5982 bedrock_server.exe ~80MB)\uFF0C\u4E0D\u4F1A OOM\u3002\n */\nexport async function hashFileAsync(filePath: string, algo: \"sha1\" | \"sha256\" = \"sha256\"): Promise<string> {\n return new Promise((resolve, reject) => {\n const h = crypto.createHash(algo);\n const stream = fs.createReadStream(filePath);\n stream.on(\"data\", (chunk: Buffer | string) => {\n h.update(typeof chunk === \"string\" ? Buffer.from(chunk) : chunk);\n });\n stream.on(\"end\", () => resolve(h.digest(\"hex\").toLowerCase()));\n stream.on(\"error\", reject);\n });\n}\n\n/** \u540C\u6B65\u7248\u672C\uFF08\u7528\u4E8E\u5C0F\u6587\u4EF6\uFF09 */\nexport function hashFileSync(filePath: string, algo: \"sha1\" | \"sha256\" = \"sha256\"): string {\n try {\n const h = crypto.createHash(algo);\n h.update(fs.readFileSync(filePath));\n return h.digest(\"hex\").toLowerCase();\n } catch {\n return \"\";\n }\n}\n\n/** \u540C\u6B65\u6D41\u5F0F\u62F7\u8D1D\u5355\u6587\u4EF6 (\u590D\u5236\u4E2D) */\nexport async function copyFileAsync(src: string, dest: string): Promise<void> {\n await pipeline(fs.createReadStream(src), fs.createWriteStream(dest));\n}\n\n/** \u540C\u6B65\u76EE\u5F55\u590D\u5236 (\u9012\u5F52) */\nexport function copyDirSync(src: string, dest: string): void {\n fs.mkdirSync(dest, { recursive: true });\n for (const entry of fs.readdirSync(src)) {\n const srcPath = path.join(src, entry);\n const destPath = path.join(dest, entry);\n if (fs.statSync(srcPath).isDirectory()) {\n copyDirSync(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n}\n\n/** \u5F02\u6B65\u76EE\u5F55\u590D\u5236 (\u57FA\u4E8E\u6D41) */\nexport async function copyDirAsync(src: string, dest: string): Promise<void> {\n fs.mkdirSync(dest, { recursive: true });\n await Promise.all(\n fs.readdirSync(src).map(async (entry) => {\n const srcPath = path.join(src, entry);\n const destPath = path.join(dest, entry);\n const stat = fs.statSync(srcPath);\n if (stat.isDirectory()) {\n await copyDirAsync(srcPath, destPath);\n } else {\n await copyFileAsync(srcPath, destPath);\n }\n })\n );\n}\n\n/** \u8BA1\u7B97\u76EE\u5F55\u5927\u5C0F (\u5B57\u8282) */\nexport function getDirSize(dir: string): number {\n let total = 0;\n try {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) total += getDirSize(full);\n else if (entry.isFile()) total += fs.statSync(full).size;\n }\n } catch {}\n return total;\n}\n\n/** \u5F3A\u5236\u6E05\u7A7A\u76EE\u5F55\u5185\u5BB9 (\u4F46\u4FDD\u7559\u76EE\u5F55\u672C\u8EAB) */\nexport function emptyDirSync(dir: string): void {\n if (!fs.existsSync(dir)) return;\n for (const entry of fs.readdirSync(dir)) {\n const full = path.join(dir, entry);\n try {\n const stat = fs.statSync(full);\n if (stat.isDirectory()) fs.rmSync(full, { recursive: true, force: true });\n else fs.unlinkSync(full);\n } catch (e) {\n // \u5FFD\u7565: \u9876\u5C42\u4ECD\u4FDD\u7559\u76EE\u5F55\uFF0C\u5373\u4F7F\u90E8\u5206\u5B50\u9879\u65E0\u6CD5\u5220\u9664\n }\n }\n}\n\n/** \u5B89\u5168\u5220\u9664\u6574\u4E2A\u76EE\u5F55 */\nexport function rmSafe(path: string): void {\n try {\n fs.rmSync(path, { recursive: true, force: true });\n } catch {\n /* ignore */\n }\n}\n\n/** \u5B89\u5168\u5199\u6587\u4EF6 (\u539F\u5B50: \u5199\u4E34\u65F6\u6587\u4EF6 \u2192 rename) */\nexport function writeFileSafe(filePath: string, data: string | Buffer): void {\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n const tmp = `${filePath}.${process.pid}.tmp`;\n fs.writeFileSync(tmp, data);\n fs.renameSync(tmp, filePath);\n}\n\n/**\n * \u8BFB JSON \u6587\u4EF6\uFF08utf8\uFF09\u3002\n * \u68C0\u6D4B\u5230 UTF-8 BOM \u65F6\u629B Utf8BomError\uFF08\u4E0D\u9759\u9ED8\u5265\u79BB\uFF1A\u591A\u4E3A\u8BB0\u4E8B\u672C\u300CUTF-8 with BOM\u300D\u53E6\u5B58\uFF0C\u6E38\u620F\u4FA7\u4E5F\u53EF\u80FD\u5F02\u5E38\uFF09\u3002\n */\nexport class Utf8BomError extends Error {\n readonly filePath: string;\n constructor(filePath: string) {\n super(\n `UTF-8 BOM in ${filePath}: re-save as UTF-8 without BOM (Notepad \"UTF-8 with BOM\" is not valid for Bedrock packs)`\n );\n this.name = \"Utf8BomError\";\n this.filePath = filePath;\n }\n}\n\nexport function readJsonFile<T = unknown>(filePath: string): T {\n const text = fs.readFileSync(filePath, \"utf8\");\n if (text.length > 0 && text.charCodeAt(0) === 0xfeff) {\n throw new Utf8BomError(filePath);\n }\n return JSON.parse(text) as T;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["path"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack-manager.d.ts","sourceRoot":"","sources":["../src/pack-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAAE,YAAY,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"pack-manager.d.ts","sourceRoot":"","sources":["../src/pack-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/pack-manager.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { copyDirAsync, copyFileAsync } from "./fsx.js";
|
|
3
|
+
import { copyDirAsync, copyFileAsync, readJsonFile, Utf8BomError } from "./fsx.js";
|
|
4
4
|
const SFMC_PERMISSIONS = [
|
|
5
5
|
"@minecraft/server",
|
|
6
6
|
"@minecraft/server-ui",
|
|
@@ -124,14 +124,15 @@ function readPackManifestHeader(packDir) {
|
|
|
124
124
|
const file = path.join(packDir, "manifest.json");
|
|
125
125
|
if (!fs.existsSync(file)) return null;
|
|
126
126
|
try {
|
|
127
|
-
const raw =
|
|
127
|
+
const raw = readJsonFile(file);
|
|
128
128
|
const uuid = raw.header?.uuid;
|
|
129
129
|
const ver = raw.header?.version;
|
|
130
130
|
if (typeof uuid !== "string" || !Array.isArray(ver) || ver.length < 3) return null;
|
|
131
131
|
const version = [Number(ver[0]), Number(ver[1]), Number(ver[2])];
|
|
132
132
|
const moduleUuid = raw.modules?.[0]?.uuid;
|
|
133
133
|
return { uuid, version, ...typeof moduleUuid === "string" ? { moduleUuid } : {} };
|
|
134
|
-
} catch {
|
|
134
|
+
} catch (e) {
|
|
135
|
+
if (e instanceof Utf8BomError) throw e;
|
|
135
136
|
return null;
|
|
136
137
|
}
|
|
137
138
|
}
|