@sfmc-bds/bds-tools 0.1.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.
Files changed (73) hide show
  1. package/dist/bds-manager.d.ts.map +1 -1
  2. package/dist/bds-manager.js +236 -263
  3. package/dist/bds-manager.js.map +7 -1
  4. package/dist/changelog.js +39 -50
  5. package/dist/changelog.js.map +7 -1
  6. package/dist/check-update.d.ts +2 -2
  7. package/dist/check-update.d.ts.map +1 -1
  8. package/dist/check-update.js +361 -401
  9. package/dist/check-update.js.map +7 -1
  10. package/dist/cli-pack-manager.d.ts +10 -6
  11. package/dist/cli-pack-manager.d.ts.map +1 -1
  12. package/dist/cli-pack-manager.js +229 -134
  13. package/dist/cli-pack-manager.js.map +7 -1
  14. package/dist/fsx.d.ts +9 -0
  15. package/dist/fsx.d.ts.map +1 -1
  16. package/dist/fsx.js +105 -100
  17. package/dist/fsx.js.map +7 -1
  18. package/dist/http.d.ts.map +1 -1
  19. package/dist/http.js +166 -185
  20. package/dist/http.js.map +7 -1
  21. package/dist/is-main.d.ts +17 -0
  22. package/dist/is-main.d.ts.map +1 -0
  23. package/dist/is-main.js +32 -0
  24. package/dist/is-main.js.map +7 -0
  25. package/dist/log.d.ts +2 -4
  26. package/dist/log.d.ts.map +1 -1
  27. package/dist/log.js +12 -19
  28. package/dist/log.js.map +7 -1
  29. package/dist/logger.js +6 -10
  30. package/dist/logger.js.map +7 -1
  31. package/dist/pack-manager.d.ts +88 -24
  32. package/dist/pack-manager.d.ts.map +1 -1
  33. package/dist/pack-manager.js +282 -246
  34. package/dist/pack-manager.js.map +7 -1
  35. package/dist/paths.d.ts +8 -3
  36. package/dist/paths.d.ts.map +1 -1
  37. package/dist/paths.js +53 -39
  38. package/dist/paths.js.map +7 -1
  39. package/dist/qqutil.d.ts.map +1 -1
  40. package/dist/qqutil.js +90 -87
  41. package/dist/qqutil.js.map +7 -1
  42. package/dist/recovery.js +26 -37
  43. package/dist/recovery.js.map +7 -1
  44. package/dist/rollback.d.ts +1 -1
  45. package/dist/rollback.js +55 -74
  46. package/dist/rollback.js.map +7 -1
  47. package/dist/server-properties.d.ts +12 -0
  48. package/dist/server-properties.d.ts.map +1 -0
  49. package/dist/server-properties.js +28 -0
  50. package/dist/server-properties.js.map +7 -0
  51. package/dist/taskbar.d.ts +2 -0
  52. package/dist/taskbar.d.ts.map +1 -1
  53. package/dist/taskbar.js +51 -82
  54. package/dist/taskbar.js.map +7 -1
  55. package/dist/types.js +1 -5
  56. package/dist/types.js.map +7 -1
  57. package/dist/update-result.d.ts +18 -0
  58. package/dist/update-result.d.ts.map +1 -0
  59. package/dist/update-result.js +17 -0
  60. package/dist/update-result.js.map +7 -0
  61. package/dist/upstream.js +94 -108
  62. package/dist/upstream.js.map +7 -1
  63. package/dist/version.js +63 -81
  64. package/dist/version.js.map +7 -1
  65. package/dist/world-packs.d.ts +174 -0
  66. package/dist/world-packs.d.ts.map +1 -0
  67. package/dist/world-packs.js +509 -0
  68. package/dist/world-packs.js.map +7 -0
  69. package/dist/zipx.d.ts +10 -0
  70. package/dist/zipx.d.ts.map +1 -0
  71. package/dist/zipx.js +48 -0
  72. package/dist/zipx.js.map +7 -0
  73. package/package.json +17 -6
@@ -1 +1,7 @@
1
- {"version":3,"file":"rollback.js","sourceRoot":"","sources":["../src/rollback.ts"],"names":[],"mappings":"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"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/rollback.ts"],
4
+ "sourcesContent": ["/**\n * rollback.ts \u2014 \u56DE\u6EDA\u652F\u6301\n *\n * \u5728\u66F4\u65B0\u5F00\u59CB\u524D\u8BB0\u5F55: \u5F53\u524D BDS \u76EE\u5F55 + \u5907\u4EFD\u76EE\u5F55\u3002\n * \u4E3B\u6D41\u7A0B\u4EFB\u610F\u9636\u6BB5\u5931\u8D25\u65F6\uFF0C\u5C1D\u8BD5\u53CD\u5411\u6062\u590D preserves \u5230 BDS_PATH\uFF0C\n * \u7136\u540E\u4ECE\u5907\u4EFD\u91CD\u65B0\u653E\u56DE preserve \u5185\u5BB9\uFF0C\u6062\u590D\u65E7\u914D\u7F6E\u3002\n *\n * \u6301\u4E45\u5316: <SFMC_ROOT>/.sfmc/last_update_rollback.json \u7528\u4E8E\u8DE8\u8FDB\u7A0B\u8BB0\u5F55\u3002\n */\n\nimport { readJson, writeJson } from \"@sfmc-bds/sdk/node/config\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ROLLBACK_MARKER } from \"./paths.js\";\nimport { copyDirSync, getDirSize, emptyDirSync } from \"./fsx.js\";\nimport { log } from \"./log.js\";\n\nexport interface RollbackMarker {\n timestamp: number;\n bds_path: string;\n backup_dir: string;\n preserve: string[];\n previous_version: string;\n}\n\n/** \u5728\u5907\u4EFD\u5B8C\u6210\u540E\u8C03\u7528: \u8BB0\u5F55\u5FEB\u7167\u6307\u793A\u7B26\u3002 */\nexport function writeRollbackMarker(marker: RollbackMarker): void {\n try {\n writeJson(ROLLBACK_MARKER, marker);\n log.info(`[\u56DE\u6EDA] \u5DF2\u8BB0\u5F55\u56DE\u6EDA\u6807\u8BB0 -> ${ROLLBACK_MARKER}`);\n } catch (e) {\n log.warn(`[\u56DE\u6EDA] \u65E0\u6CD5\u5199\u5165\u6807\u8BB0: ${(e as Error).message}`);\n }\n}\n\nexport function clearRollbackMarker(): void {\n try {\n if (fs.existsSync(ROLLBACK_MARKER)) fs.unlinkSync(ROLLBACK_MARKER);\n } catch {\n /* ignore */\n }\n}\n\nexport function readRollbackMarker(): RollbackMarker | null {\n return readJson<RollbackMarker>(ROLLBACK_MARKER) ?? null;\n}\n\n/**\n * \u7D27\u6025\u56DE\u6EDA: \u628A preserve \u9879\u4ECE backup_dir \u62F7\u56DE bds_path\u3002\n * \u7528\u6CD5: \u5728 catch \u5206\u652F\u8C03\u7528\uFF0C\u5982\u679C\u4E3B\u6D41\u7A0B\u5931\u8D25\u5BFC\u81F4 BDS \u76EE\u5F55\u7834\u574F\u3002\n */\nexport function rollbackFromBackup(marker: RollbackMarker): { ok: boolean; reason?: string } {\n const { bds_path, backup_dir, preserve } = marker;\n if (!fs.existsSync(backup_dir)) {\n return { ok: false, reason: `\u5907\u4EFD\u76EE\u5F55\u4E0D\u5B58\u5728: ${backup_dir}` };\n }\n log.warn(`[\u56DE\u6EDA] \u5F00\u59CB\u6062\u590D ${preserve.length} \u9879\u5230 ${bds_path}`);\n for (const item of preserve) {\n const src = path.join(backup_dir, item);\n const dest = path.join(bds_path, item);\n if (!fs.existsSync(src)) {\n log.warn(`[\u56DE\u6EDA] \u8DF3\u8FC7 (\u5907\u4EFD\u4E2D\u4E0D\u5B58\u5728): ${item}`);\n continue;\n }\n try {\n // \u5148\u786E\u4FDD\u76EE\u6807\u76EE\u5F55\u5B58\u5728 (BDS \u76EE\u5F55\u53EF\u80FD\u5DF2\u88AB\u89E3\u538B\u8986\u76D6\u4E3A\u7A7A)\n const destDir = path.dirname(dest);\n if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });\n if (fs.statSync(src).isDirectory()) {\n // \u5148\u5220\u9664\u76EE\u6807\uFF0C\u518D\u590D\u5236\u76EE\u5F55\n if (fs.existsSync(dest)) emptyDirSync(dest);\n copyDirSync(src, dest);\n } else {\n fs.copyFileSync(src, dest);\n }\n log.info(`[\u56DE\u6EDA] \u5DF2\u6062\u590D: ${item}`);\n } catch (e) {\n log.warn(`[\u56DE\u6EDA] \u6062\u590D\u5931\u8D25 ${item}: ${(e as Error).message}`);\n }\n }\n return { ok: true };\n}\n\n/** \u68C0\u67E5 BDS_PATH \u4E2D\u5173\u952E\u6587\u4EF6\u662F\u5426\u90FD\u8FD8\u5728 (\u66F4\u65B0\u540E\u5B8C\u6574\u6027 sanity check) */\nexport function verifyBdsInstall(bds_path: string, expected: string[]): { ok: boolean; missing: string[] } {\n const missing: string[] = [];\n for (const f of expected) {\n if (!fs.existsSync(path.join(bds_path, f))) missing.push(f);\n }\n return { ok: missing.length === 0, missing };\n}\n\nexport { getDirSize };\n"],
5
+ "mappings": "AAUA,SAAS,UAAU,iBAAiB;AACpC,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,uBAAuB;AAChC,SAAS,aAAa,YAAY,oBAAoB;AACtD,SAAS,WAAW;AAWb,SAAS,oBAAoB,QAA8B;AAChE,MAAI;AACF,cAAU,iBAAiB,MAAM;AACjC,QAAI,KAAK,gEAAmB,eAAe,EAAE;AAAA,EAC/C,SAAS,GAAG;AACV,QAAI,KAAK,wDAAiB,EAAY,OAAO,EAAE;AAAA,EACjD;AACF;AAEO,SAAS,sBAA4B;AAC1C,MAAI;AACF,QAAI,GAAG,WAAW,eAAe,EAAG,IAAG,WAAW,eAAe;AAAA,EACnE,QAAQ;AAAA,EAER;AACF;AAEO,SAAS,qBAA4C;AAC1D,SAAO,SAAyB,eAAe,KAAK;AACtD;AAMO,SAAS,mBAAmB,QAA0D;AAC3F,QAAM,EAAE,UAAU,YAAY,SAAS,IAAI;AAC3C,MAAI,CAAC,GAAG,WAAW,UAAU,GAAG;AAC9B,WAAO,EAAE,IAAI,OAAO,QAAQ,+CAAY,UAAU,GAAG;AAAA,EACvD;AACA,MAAI,KAAK,2CAAa,SAAS,MAAM,iBAAO,QAAQ,EAAE;AACtD,aAAW,QAAQ,UAAU;AAC3B,UAAM,MAAM,KAAK,KAAK,YAAY,IAAI;AACtC,UAAM,OAAO,KAAK,KAAK,UAAU,IAAI;AACrC,QAAI,CAAC,GAAG,WAAW,GAAG,GAAG;AACvB,UAAI,KAAK,uEAAqB,IAAI,EAAE;AACpC;AAAA,IACF;AACA,QAAI;AAEF,YAAM,UAAU,KAAK,QAAQ,IAAI;AACjC,UAAI,CAAC,GAAG,WAAW,OAAO,EAAG,IAAG,UAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACtE,UAAI,GAAG,SAAS,GAAG,EAAE,YAAY,GAAG;AAElC,YAAI,GAAG,WAAW,IAAI,EAAG,cAAa,IAAI;AAC1C,oBAAY,KAAK,IAAI;AAAA,MACvB,OAAO;AACL,WAAG,aAAa,KAAK,IAAI;AAAA,MAC3B;AACA,UAAI,KAAK,sCAAa,IAAI,EAAE;AAAA,IAC9B,SAAS,GAAG;AACV,UAAI,KAAK,2CAAa,IAAI,KAAM,EAAY,OAAO,EAAE;AAAA,IACvD;AAAA,EACF;AACA,SAAO,EAAE,IAAI,KAAK;AACpB;AAGO,SAAS,iBAAiB,UAAkB,UAAwD;AACzG,QAAM,UAAoB,CAAC;AAC3B,aAAW,KAAK,UAAU;AACxB,QAAI,CAAC,GAAG,WAAW,KAAK,KAAK,UAAU,CAAC,CAAC,EAAG,SAAQ,KAAK,CAAC;AAAA,EAC5D;AACA,SAAO,EAAE,IAAI,QAAQ,WAAW,GAAG,QAAQ;AAC7C;",
6
+ "names": []
7
+ }
@@ -0,0 +1,12 @@
1
+ export declare const EMIT_SERVER_TELEMETRY_KEY = "emit-server-telemetry";
2
+ export declare const EMIT_SERVER_TELEMETRY_LINE = "emit-server-telemetry=true";
3
+ export type ServerPropertiesLogger = {
4
+ info: (msg: string) => void;
5
+ };
6
+ /**
7
+ * 若 `<bdsRoot>/server.properties` 中尚无 emit-server-telemetry,则追加 `=true`。
8
+ * 已有该键(任意值)则跳过。文件不存在时跳过(BDS 尚未解压)。
9
+ * @returns true = 本次新追加;false = 跳过
10
+ */
11
+ export declare function ensureEmitServerTelemetry(bdsRoot: string, logger?: ServerPropertiesLogger): boolean;
12
+ //# sourceMappingURL=server-properties.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-properties.d.ts","sourceRoot":"","sources":["../src/server-properties.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AACjE,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAEvE,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,sBAAsB,GAC9B,OAAO,CAmBT"}
@@ -0,0 +1,28 @@
1
+ import fs from "node:fs";
2
+ import { serverPropertiesPath } from "./pack-manager.js";
3
+ const EMIT_SERVER_TELEMETRY_KEY = "emit-server-telemetry";
4
+ const EMIT_SERVER_TELEMETRY_LINE = "emit-server-telemetry=true";
5
+ function ensureEmitServerTelemetry(bdsRoot, logger) {
6
+ const file = serverPropertiesPath(bdsRoot);
7
+ if (!fs.existsSync(file)) return false;
8
+ let text = fs.readFileSync(file, "utf8");
9
+ if (/^\s*emit-server-telemetry\s*=/im.test(text)) {
10
+ return false;
11
+ }
12
+ if (text.length > 0 && !text.endsWith("\n")) {
13
+ text += "\n";
14
+ }
15
+ text += `${EMIT_SERVER_TELEMETRY_LINE}
16
+ `;
17
+ fs.writeFileSync(file, text, "utf8");
18
+ logger?.info(
19
+ "\u5DF2\u5411 server.properties \u8FFD\u52A0 emit-server-telemetry=true\uFF08\u56E0\u60A8\u5DF2\u540C\u610F Mojang EULA\uFF0C\u6309\u534F\u8BAE\u542F\u7528\u670D\u52A1\u5668\u9065\u6D4B\uFF09"
20
+ );
21
+ return true;
22
+ }
23
+ export {
24
+ EMIT_SERVER_TELEMETRY_KEY,
25
+ EMIT_SERVER_TELEMETRY_LINE,
26
+ ensureEmitServerTelemetry
27
+ };
28
+ //# sourceMappingURL=server-properties.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/server-properties.ts"],
4
+ "sourcesContent": ["/**\n * server.properties \u8F85\u52A9\uFF1A\u5B89\u88C5/\u542F\u52A8\u65F6\u786E\u4FDD emit-server-telemetry=true\n */\nimport fs from \"node:fs\";\nimport { serverPropertiesPath } from \"./pack-manager.js\";\n\nexport const EMIT_SERVER_TELEMETRY_KEY = \"emit-server-telemetry\";\nexport const EMIT_SERVER_TELEMETRY_LINE = \"emit-server-telemetry=true\";\n\nexport type ServerPropertiesLogger = {\n info: (msg: string) => void;\n};\n\n/**\n * \u82E5 `<bdsRoot>/server.properties` \u4E2D\u5C1A\u65E0 emit-server-telemetry\uFF0C\u5219\u8FFD\u52A0 `=true`\u3002\n * \u5DF2\u6709\u8BE5\u952E\uFF08\u4EFB\u610F\u503C\uFF09\u5219\u8DF3\u8FC7\u3002\u6587\u4EF6\u4E0D\u5B58\u5728\u65F6\u8DF3\u8FC7\uFF08BDS \u5C1A\u672A\u89E3\u538B\uFF09\u3002\n * @returns true = \u672C\u6B21\u65B0\u8FFD\u52A0\uFF1Bfalse = \u8DF3\u8FC7\n */\nexport function ensureEmitServerTelemetry(\n bdsRoot: string,\n logger?: ServerPropertiesLogger\n): boolean {\n const file = serverPropertiesPath(bdsRoot);\n if (!fs.existsSync(file)) return false;\n\n let text = fs.readFileSync(file, \"utf8\");\n if (/^\\s*emit-server-telemetry\\s*=/im.test(text)) {\n return false;\n }\n\n if (text.length > 0 && !text.endsWith(\"\\n\")) {\n text += \"\\n\";\n }\n text += `${EMIT_SERVER_TELEMETRY_LINE}\\n`;\n fs.writeFileSync(file, text, \"utf8\");\n\n logger?.info(\n \"\u5DF2\u5411 server.properties \u8FFD\u52A0 emit-server-telemetry=true\uFF08\u56E0\u60A8\u5DF2\u540C\u610F Mojang EULA\uFF0C\u6309\u534F\u8BAE\u542F\u7528\u670D\u52A1\u5668\u9065\u6D4B\uFF09\"\n );\n return true;\n}\n"],
5
+ "mappings": "AAGA,OAAO,QAAQ;AACf,SAAS,4BAA4B;AAE9B,MAAM,4BAA4B;AAClC,MAAM,6BAA6B;AAWnC,SAAS,0BACd,SACA,QACS;AACT,QAAM,OAAO,qBAAqB,OAAO;AACzC,MAAI,CAAC,GAAG,WAAW,IAAI,EAAG,QAAO;AAEjC,MAAI,OAAO,GAAG,aAAa,MAAM,MAAM;AACvC,MAAI,kCAAkC,KAAK,IAAI,GAAG;AAChD,WAAO;AAAA,EACT;AAEA,MAAI,KAAK,SAAS,KAAK,CAAC,KAAK,SAAS,IAAI,GAAG;AAC3C,YAAQ;AAAA,EACV;AACA,UAAQ,GAAG,0BAA0B;AAAA;AACrC,KAAG,cAAc,MAAM,MAAM,MAAM;AAEnC,UAAQ;AAAA,IACN;AAAA,EACF;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }
package/dist/taskbar.d.ts CHANGED
@@ -27,6 +27,8 @@
27
27
  * clearTaskbarProgress(); // 隐藏
28
28
  */
29
29
  type ProgressState = "normal" | "error" | "indeterminate";
30
+ /** 从日志文本剥离 WT 任务栏 OSC 9;4(与写入侧同一权威,供父进程 DRY)。 */
31
+ export declare function stripTaskbarOsc(s: string): string;
30
32
  /**
31
33
  * 设置任务栏进度。
32
34
  * - normal: 绿色 (pct 0-100)
@@ -1 +1 @@
1
- {"version":3,"file":"taskbar.d.ts","sourceRoot":"","sources":["../src/taskbar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,KAAK,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,eAAe,CAAC;AA2B1D;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,aAAwB,GAAG,IAAI,CAmBrF;AAED,yBAAyB;AACzB,wBAAgB,oBAAoB,IAAI,IAAI,CAM3C;AAED,8CAA8C;AAC9C,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C"}
1
+ {"version":3,"file":"taskbar.d.ts","sourceRoot":"","sources":["../src/taskbar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,KAAK,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,eAAe,CAAC;AAmC1D,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,aAAwB,GAAG,IAAI,CAmBrF;AAED,yBAAyB;AACzB,wBAAgB,oBAAoB,IAAI,IAAI,CAM3C;AAED,8CAA8C;AAC9C,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C"}
package/dist/taskbar.js CHANGED
@@ -1,94 +1,63 @@
1
- /**
2
- * taskbar.ts — Windows Terminal 任务栏进度 (OSC 9;4)
3
- *
4
- * 通过 OSC 9;4 转义序列直接驱动 Windows Terminal 任务栏图标上的进度条。
5
- * 不需要 native 绑定(ffi / ITaskbarList3),但**仅 Windows Terminal 支持**。
6
- * cmd.exe / PowerShell ISE 等老终端会忽略该序列,本模块在不支持的终端
7
- * 上静默 no-op。
8
- *
9
- * 兼容性:
10
- * - Windows Terminal ✅
11
- * - ConEmu / Cmder ⚠️ 部分
12
- * - cmd.exe / ISE ❌(不解析 OSC)
13
- *
14
- * 检测方式:WT_SESSION 或 TERM_PROGRAM === "Windows Terminal"。
15
- *
16
- * 序列格式(Windows Terminal 私有):
17
- * \x1b]9;4;0;\x07 清除(隐藏)
18
- * \x1b]9;4;1;<pct>\x07 正常(绿,pct 0-100)
19
- * \x1b]9;4;2;<pct>\x07 错误(红,pct 0-100)
20
- * \x1b]9;4;3;\x07 不确定(动画条纹)
21
- *
22
- * 幂等:相同 state+pct 不重复输出,避免刷屏。
23
- *
24
- * 用法:
25
- * setTaskbarProgress(50); // 50% 绿
26
- * setTaskbarProgress(100, "error"); // 100% 红
27
- * clearTaskbarProgress(); // 隐藏
28
- */
29
1
  function detect() {
30
- if (process.platform !== "win32")
31
- return false;
32
- if (process.env["WT_SESSION"])
33
- return true;
34
- if (process.env["TERM_PROGRAM"] === "Windows Terminal")
35
- return true;
36
- return false;
2
+ if (process.platform !== "win32") return false;
3
+ if (process.env["WT_SESSION"]) return true;
4
+ if (process.env["TERM_PROGRAM"] === "Windows Terminal") return true;
5
+ return false;
37
6
  }
38
7
  let supported = detect();
39
8
  let active = false;
40
9
  let lastPct = -1;
41
10
  let lastState = 0;
42
11
  function stateCode(s) {
43
- switch (s) {
44
- case "clear":
45
- return 0;
46
- case "normal":
47
- return 1;
48
- case "error":
49
- return 2;
50
- case "indeterminate":
51
- return 3;
52
- }
12
+ switch (s) {
13
+ case "clear":
14
+ return 0;
15
+ case "normal":
16
+ return 1;
17
+ case "error":
18
+ return 2;
19
+ case "indeterminate":
20
+ return 3;
21
+ }
53
22
  }
54
- /**
55
- * 设置任务栏进度。
56
- * - normal: 绿色 (pct 0-100)
57
- * - error: 红色 (pct 0-100)
58
- * - indeterminate: 动画条纹(pct 忽略)
59
- */
60
- export function setTaskbarProgress(pct, state = "normal") {
61
- if (!supported)
62
- return;
63
- if (state === "indeterminate") {
64
- if (lastState === 3)
65
- return; // 已在 indeterminate,不再重发
66
- process.stdout.write("\x1b]9;4;3\x07");
67
- lastState = 3;
68
- lastPct = -1;
69
- active = true;
70
- return;
71
- }
72
- const p = Math.max(0, Math.min(100, Math.round(pct)));
73
- const sc = stateCode(state);
74
- if (lastState === sc && lastPct === p)
75
- return; // 无变化,跳过
76
- process.stdout.write(`\x1b]9;4;${sc};${p}\x07`);
77
- lastPct = p;
78
- lastState = sc;
79
- active = true;
23
+ function canWriteOsc() {
24
+ return supported && !!process.stdout.isTTY;
25
+ }
26
+ function stripTaskbarOsc(s) {
27
+ return s.replace(/\x1b\]9;4[^\x07\x1b]*(?:\x07|\x1b\\)/g, "");
80
28
  }
81
- /** 清除任务栏进度(隐藏进度条)。幂等。 */
82
- export function clearTaskbarProgress() {
83
- if (!supported || !active)
84
- return;
85
- process.stdout.write("\x1b]9;4;0\x07");
29
+ function setTaskbarProgress(pct, state = "normal") {
30
+ if (!canWriteOsc()) return;
31
+ if (state === "indeterminate") {
32
+ if (lastState === 3) return;
33
+ process.stdout.write("\x1B]9;4;3\x07");
34
+ lastState = 3;
86
35
  lastPct = -1;
87
- lastState = 0;
88
- active = false;
36
+ active = true;
37
+ return;
38
+ }
39
+ const p = Math.max(0, Math.min(100, Math.round(pct)));
40
+ const sc = stateCode(state);
41
+ if (lastState === sc && lastPct === p) return;
42
+ process.stdout.write(`\x1B]9;4;${sc};${p}\x07`);
43
+ lastPct = p;
44
+ lastState = sc;
45
+ active = true;
46
+ }
47
+ function clearTaskbarProgress() {
48
+ if (!canWriteOsc() || !active) return;
49
+ process.stdout.write("\x1B]9;4;0\x07");
50
+ lastPct = -1;
51
+ lastState = 0;
52
+ active = false;
89
53
  }
90
- /** 模块是否启用(Windows Terminal 探测结果)。供日志 / 调试。 */
91
- export function isTaskbarSupported() {
92
- return supported;
54
+ function isTaskbarSupported() {
55
+ return supported;
93
56
  }
94
- //# sourceMappingURL=taskbar.js.map
57
+ export {
58
+ clearTaskbarProgress,
59
+ isTaskbarSupported,
60
+ setTaskbarProgress,
61
+ stripTaskbarOsc
62
+ };
63
+ //# sourceMappingURL=taskbar.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"taskbar.js","sourceRoot":"","sources":["../src/taskbar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,SAAS,MAAM;IACb,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,kBAAkB;QAAE,OAAO,IAAI,CAAC;IACpE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,IAAI,SAAS,GAAG,MAAM,EAAE,CAAC;AACzB,IAAI,MAAM,GAAG,KAAK,CAAC;AACnB,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;AACjB,IAAI,SAAS,GAAkB,CAAC,CAAC;AAEjC,SAAS,SAAS,CAAC,CAA0B;IAC3C,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,OAAO;YACV,OAAO,CAAC,CAAC;QACX,KAAK,QAAQ;YACX,OAAO,CAAC,CAAC;QACX,KAAK,OAAO;YACV,OAAO,CAAC,CAAC;QACX,KAAK,eAAe;YAClB,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,QAAuB,QAAQ;IAC7E,IAAI,CAAC,SAAS;QAAE,OAAO;IAEvB,IAAI,KAAK,KAAK,eAAe,EAAE,CAAC;QAC9B,IAAI,SAAS,KAAK,CAAC;YAAE,OAAO,CAAC,wBAAwB;QACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACvC,SAAS,GAAG,CAAC,CAAC;QACd,OAAO,GAAG,CAAC,CAAC,CAAC;QACb,MAAM,GAAG,IAAI,CAAC;QACd,OAAO;IACT,CAAC;IAED,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,SAAS,KAAK,EAAE,IAAI,OAAO,KAAK,CAAC;QAAE,OAAO,CAAC,SAAS;IACxD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAChD,OAAO,GAAG,CAAC,CAAC;IACZ,SAAS,GAAG,EAAE,CAAC;IACf,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM;QAAE,OAAO;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACvC,OAAO,GAAG,CAAC,CAAC,CAAC;IACb,SAAS,GAAG,CAAC,CAAC;IACd,MAAM,GAAG,KAAK,CAAC;AACjB,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,kBAAkB;IAChC,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/taskbar.ts"],
4
+ "sourcesContent": ["/**\n * taskbar.ts \u2014 Windows Terminal \u4EFB\u52A1\u680F\u8FDB\u5EA6 (OSC 9;4)\n *\n * \u901A\u8FC7 OSC 9;4 \u8F6C\u4E49\u5E8F\u5217\u76F4\u63A5\u9A71\u52A8 Windows Terminal \u4EFB\u52A1\u680F\u56FE\u6807\u4E0A\u7684\u8FDB\u5EA6\u6761\u3002\n * \u4E0D\u9700\u8981 native \u7ED1\u5B9A(ffi / ITaskbarList3),\u4F46**\u4EC5 Windows Terminal \u652F\u6301**\u3002\n * cmd.exe / PowerShell ISE \u7B49\u8001\u7EC8\u7AEF\u4F1A\u5FFD\u7565\u8BE5\u5E8F\u5217,\u672C\u6A21\u5757\u5728\u4E0D\u652F\u6301\u7684\u7EC8\u7AEF\n * \u4E0A\u9759\u9ED8 no-op\u3002\n *\n * \u517C\u5BB9\u6027:\n * - Windows Terminal \u2705\n * - ConEmu / Cmder \u26A0\uFE0F \u90E8\u5206\n * - cmd.exe / ISE \u274C(\u4E0D\u89E3\u6790 OSC)\n *\n * \u68C0\u6D4B\u65B9\u5F0F:WT_SESSION \u6216 TERM_PROGRAM === \"Windows Terminal\"\u3002\n *\n * \u5E8F\u5217\u683C\u5F0F(Windows Terminal \u79C1\u6709):\n * \\x1b]9;4;0;\\x07 \u6E05\u9664(\u9690\u85CF)\n * \\x1b]9;4;1;<pct>\\x07 \u6B63\u5E38(\u7EFF,pct 0-100)\n * \\x1b]9;4;2;<pct>\\x07 \u9519\u8BEF(\u7EA2,pct 0-100)\n * \\x1b]9;4;3;\\x07 \u4E0D\u786E\u5B9A(\u52A8\u753B\u6761\u7EB9)\n *\n * \u5E42\u7B49:\u76F8\u540C state+pct \u4E0D\u91CD\u590D\u8F93\u51FA,\u907F\u514D\u5237\u5C4F\u3002\n *\n * \u7528\u6CD5:\n * setTaskbarProgress(50); // 50% \u7EFF\n * setTaskbarProgress(100, \"error\"); // 100% \u7EA2\n * clearTaskbarProgress(); // \u9690\u85CF\n */\n\ntype ProgressState = \"normal\" | \"error\" | \"indeterminate\";\n\nfunction detect(): boolean {\n if (process.platform !== \"win32\") return false;\n if (process.env[\"WT_SESSION\"]) return true;\n if (process.env[\"TERM_PROGRAM\"] === \"Windows Terminal\") return true;\n return false;\n}\n\nlet supported = detect();\nlet active = false;\nlet lastPct = -1;\nlet lastState: 0 | 1 | 2 | 3 = 0;\n\nfunction stateCode(s: ProgressState | \"clear\"): 0 | 1 | 2 | 3 {\n switch (s) {\n case \"clear\":\n return 0;\n case \"normal\":\n return 1;\n case \"error\":\n return 2;\n case \"indeterminate\":\n return 3;\n }\n}\n\n/**\n * stdout \u88AB pipe\uFF08\u5982 sfmc REPL \u6355\u83B7\u5B50\u8FDB\u7A0B\u8F93\u51FA\uFF09\u65F6\u4E0D\u5E94\u5199 OSC\uFF1A\n * \u7EC8\u7AEF\u4E0D\u4F1A\u89E3\u6790\uFF0C\u7236\u8FDB\u7A0B\u5374\u4F1A\u628A\u5E8F\u5217\u5F53\u6210\u300C\u7A7A\u767D\u65E5\u5FD7\u884C\u300D\u5237\u5C4F\u3002\n */\nfunction canWriteOsc(): boolean {\n return supported && !!process.stdout.isTTY;\n}\n\n/** \u4ECE\u65E5\u5FD7\u6587\u672C\u5265\u79BB WT \u4EFB\u52A1\u680F OSC 9;4\uFF08\u4E0E\u5199\u5165\u4FA7\u540C\u4E00\u6743\u5A01\uFF0C\u4F9B\u7236\u8FDB\u7A0B DRY\uFF09\u3002 */\nexport function stripTaskbarOsc(s: string): string {\n return s.replace(/\\x1b\\]9;4[^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)/g, \"\");\n}\n\n/**\n * \u8BBE\u7F6E\u4EFB\u52A1\u680F\u8FDB\u5EA6\u3002\n * - normal: \u7EFF\u8272 (pct 0-100)\n * - error: \u7EA2\u8272 (pct 0-100)\n * - indeterminate: \u52A8\u753B\u6761\u7EB9(pct \u5FFD\u7565)\n */\nexport function setTaskbarProgress(pct: number, state: ProgressState = \"normal\"): void {\n if (!canWriteOsc()) return;\n\n if (state === \"indeterminate\") {\n if (lastState === 3) return; // \u5DF2\u5728 indeterminate,\u4E0D\u518D\u91CD\u53D1\n process.stdout.write(\"\\x1b]9;4;3\\x07\");\n lastState = 3;\n lastPct = -1;\n active = true;\n return;\n }\n\n const p = Math.max(0, Math.min(100, Math.round(pct)));\n const sc = stateCode(state);\n if (lastState === sc && lastPct === p) return; // \u65E0\u53D8\u5316,\u8DF3\u8FC7\n process.stdout.write(`\\x1b]9;4;${sc};${p}\\x07`);\n lastPct = p;\n lastState = sc;\n active = true;\n}\n\n/** \u6E05\u9664\u4EFB\u52A1\u680F\u8FDB\u5EA6(\u9690\u85CF\u8FDB\u5EA6\u6761)\u3002\u5E42\u7B49\u3002 */\nexport function clearTaskbarProgress(): void {\n if (!canWriteOsc() || !active) return;\n process.stdout.write(\"\\x1b]9;4;0\\x07\");\n lastPct = -1;\n lastState = 0;\n active = false;\n}\n\n/** \u6A21\u5757\u662F\u5426\u542F\u7528(Windows Terminal \u63A2\u6D4B\u7ED3\u679C)\u3002\u4F9B\u65E5\u5FD7 / \u8C03\u8BD5\u3002 */\nexport function isTaskbarSupported(): boolean {\n return supported;\n}\n"],
5
+ "mappings": "AA+BA,SAAS,SAAkB;AACzB,MAAI,QAAQ,aAAa,QAAS,QAAO;AACzC,MAAI,QAAQ,IAAI,YAAY,EAAG,QAAO;AACtC,MAAI,QAAQ,IAAI,cAAc,MAAM,mBAAoB,QAAO;AAC/D,SAAO;AACT;AAEA,IAAI,YAAY,OAAO;AACvB,IAAI,SAAS;AACb,IAAI,UAAU;AACd,IAAI,YAA2B;AAE/B,SAAS,UAAU,GAA2C;AAC5D,UAAQ,GAAG;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAMA,SAAS,cAAuB;AAC9B,SAAO,aAAa,CAAC,CAAC,QAAQ,OAAO;AACvC;AAGO,SAAS,gBAAgB,GAAmB;AACjD,SAAO,EAAE,QAAQ,yCAAyC,EAAE;AAC9D;AAQO,SAAS,mBAAmB,KAAa,QAAuB,UAAgB;AACrF,MAAI,CAAC,YAAY,EAAG;AAEpB,MAAI,UAAU,iBAAiB;AAC7B,QAAI,cAAc,EAAG;AACrB,YAAQ,OAAO,MAAM,gBAAgB;AACrC,gBAAY;AACZ,cAAU;AACV,aAAS;AACT;AAAA,EACF;AAEA,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG,CAAC,CAAC;AACpD,QAAM,KAAK,UAAU,KAAK;AAC1B,MAAI,cAAc,MAAM,YAAY,EAAG;AACvC,UAAQ,OAAO,MAAM,YAAY,EAAE,IAAI,CAAC,MAAM;AAC9C,YAAU;AACV,cAAY;AACZ,WAAS;AACX;AAGO,SAAS,uBAA6B;AAC3C,MAAI,CAAC,YAAY,KAAK,CAAC,OAAQ;AAC/B,UAAQ,OAAO,MAAM,gBAAgB;AACrC,YAAU;AACV,cAAY;AACZ,WAAS;AACX;AAGO,SAAS,qBAA8B;AAC5C,SAAO;AACT;",
6
+ "names": []
7
+ }
package/dist/types.js CHANGED
@@ -1,5 +1 @@
1
- /**
2
- * types.ts — BDSTools 共享类型
3
- */
4
- export {};
5
- //# sourceMappingURL=types.js.map
1
+ //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1,7 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * update-result.ts — BDS updater ↔ sfmc 监督器机器可读结果契约(DRY / DIP)
3
+ *
4
+ * 勿依赖本地化日志文案判断「是否真正部署」;一律解析本标记。
5
+ * 写出走统一 Logger(bare stdout),避免 console.log 旁路。
6
+ */
7
+ import type { Logger } from "@sfmc-bds/sdk/logs";
8
+ export declare const UPDATE_RESULT_PREFIX = "SFMC_UPDATE_RESULT=";
9
+ export type UpdateResultKind = "uptodate" | "skipped" | "check-only" | "deployed";
10
+ type InfoLogger = Pick<Logger, "info">;
11
+ /** 向 logger 打印机器标记(bare stdout 下仍为可解析纯文本)。 */
12
+ export declare function emitUpdateResult(kind: UpdateResultKind, log: InfoLogger): void;
13
+ /** KEY=value 机器行(CURRENT/LATEST/CHANNEL/URLS 等) */
14
+ export declare function emitUpdateKv(key: string, value: string, log: InfoLogger): void;
15
+ /** 从 updater 合并输出中解析是否完成部署。 */
16
+ export declare function didUpdateDeploy(out: string): boolean;
17
+ export {};
18
+ //# sourceMappingURL=update-result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-result.d.ts","sourceRoot":"","sources":["../src/update-result.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,eAAO,MAAM,oBAAoB,wBAAwB,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,CAAC;AAElF,KAAK,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEvC,8CAA8C;AAC9C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAE9E;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAE9E;AAED,+BAA+B;AAC/B,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD"}
@@ -0,0 +1,17 @@
1
+ const UPDATE_RESULT_PREFIX = "SFMC_UPDATE_RESULT=";
2
+ function emitUpdateResult(kind, log) {
3
+ log.info(`${UPDATE_RESULT_PREFIX}${kind}`);
4
+ }
5
+ function emitUpdateKv(key, value, log) {
6
+ log.info(`${key}=${value}`);
7
+ }
8
+ function didUpdateDeploy(out) {
9
+ return new RegExp(`(?:^|\\n)${UPDATE_RESULT_PREFIX}deployed(?:\\r?\\n|$)`).test(out);
10
+ }
11
+ export {
12
+ UPDATE_RESULT_PREFIX,
13
+ didUpdateDeploy,
14
+ emitUpdateKv,
15
+ emitUpdateResult
16
+ };
17
+ //# sourceMappingURL=update-result.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/update-result.ts"],
4
+ "sourcesContent": ["/**\n * update-result.ts \u2014 BDS updater \u2194 sfmc \u76D1\u7763\u5668\u673A\u5668\u53EF\u8BFB\u7ED3\u679C\u5951\u7EA6\uFF08DRY / DIP\uFF09\n *\n * \u52FF\u4F9D\u8D56\u672C\u5730\u5316\u65E5\u5FD7\u6587\u6848\u5224\u65AD\u300C\u662F\u5426\u771F\u6B63\u90E8\u7F72\u300D\uFF1B\u4E00\u5F8B\u89E3\u6790\u672C\u6807\u8BB0\u3002\n * \u5199\u51FA\u8D70\u7EDF\u4E00 Logger\uFF08bare stdout\uFF09\uFF0C\u907F\u514D console.log \u65C1\u8DEF\u3002\n */\nimport type { Logger } from \"@sfmc-bds/sdk/logs\";\n\nexport const UPDATE_RESULT_PREFIX = \"SFMC_UPDATE_RESULT=\";\n\nexport type UpdateResultKind = \"uptodate\" | \"skipped\" | \"check-only\" | \"deployed\";\n\ntype InfoLogger = Pick<Logger, \"info\">;\n\n/** \u5411 logger \u6253\u5370\u673A\u5668\u6807\u8BB0\uFF08bare stdout \u4E0B\u4ECD\u4E3A\u53EF\u89E3\u6790\u7EAF\u6587\u672C\uFF09\u3002 */\nexport function emitUpdateResult(kind: UpdateResultKind, log: InfoLogger): void {\n log.info(`${UPDATE_RESULT_PREFIX}${kind}`);\n}\n\n/** KEY=value \u673A\u5668\u884C\uFF08CURRENT/LATEST/CHANNEL/URLS \u7B49\uFF09 */\nexport function emitUpdateKv(key: string, value: string, log: InfoLogger): void {\n log.info(`${key}=${value}`);\n}\n\n/** \u4ECE updater \u5408\u5E76\u8F93\u51FA\u4E2D\u89E3\u6790\u662F\u5426\u5B8C\u6210\u90E8\u7F72\u3002 */\nexport function didUpdateDeploy(out: string): boolean {\n return new RegExp(`(?:^|\\\\n)${UPDATE_RESULT_PREFIX}deployed(?:\\\\r?\\\\n|$)`).test(out);\n}\n"],
5
+ "mappings": "AAQO,MAAM,uBAAuB;AAO7B,SAAS,iBAAiB,MAAwB,KAAuB;AAC9E,MAAI,KAAK,GAAG,oBAAoB,GAAG,IAAI,EAAE;AAC3C;AAGO,SAAS,aAAa,KAAa,OAAe,KAAuB;AAC9E,MAAI,KAAK,GAAG,GAAG,IAAI,KAAK,EAAE;AAC5B;AAGO,SAAS,gBAAgB,KAAsB;AACpD,SAAO,IAAI,OAAO,YAAY,oBAAoB,uBAAuB,EAAE,KAAK,GAAG;AACrF;",
6
+ "names": []
7
+ }
package/dist/upstream.js CHANGED
@@ -1,11 +1,3 @@
1
- /**
2
- * upstream.ts — 版本源 / 下载源 / 哈希校验
3
- *
4
- * 改进:
5
- * - 3 次重试 + 指数退避
6
- * - sha1 / sha256 同时校验
7
- * - 流式校验 + 边下边校验
8
- */
9
1
  import crypto from "node:crypto";
10
2
  import fs from "node:fs";
11
3
  import { fetchJsonWithFallback } from "./http.js";
@@ -14,113 +6,107 @@ import { toVer3 } from "./version.js";
14
6
  const DEFAULT_VERSIONS_API = "https://raw.githubusercontent.com/Bedrock-OSS/BDS-Versions/main/versions.json";
15
7
  const DEFAULT_VERSIONS_MIRROR = "https://cdn.jsdelivr.net/gh/Bedrock-OSS/BDS-Versions@main/versions.json";
16
8
  function resolveTemplate(tpl, vars) {
17
- let s = tpl;
18
- for (const [k, v] of Object.entries(vars)) {
19
- s = s.replace(new RegExp(`\\{${k}\\}`, "g"), v);
20
- }
21
- return s;
9
+ let s = tpl;
10
+ for (const [k, v] of Object.entries(vars)) {
11
+ s = s.replace(new RegExp(`\\{${k}\\}`, "g"), v);
12
+ }
13
+ return s;
22
14
  }
23
- /** 获取最新版本号 ( cdn_root),3 次重试 */
24
- export async function getVersionInfo(cfg, channel) {
25
- const api = cfg.version_versions || process.env["BDS_VERSIONS_API"] || DEFAULT_VERSIONS_API;
26
- const mirror = cfg.version_versions_mirror || process.env["BDS_VERSIONS_MIRROR"] || DEFAULT_VERSIONS_MIRROR;
27
- const sources = [api, mirror].filter(Boolean);
28
- const versionMode = cfg.version_mode || "bedrock-oss";
29
- let lastErr;
30
- for (let attempt = 1; attempt <= 3; attempt++) {
31
- try {
32
- const json = await fetchJsonWithFallback(sources);
33
- let ver;
34
- if (versionMode === "endstone") {
35
- const entry = channel === "preview" ? json.preview : json.release;
36
- ver = entry?.latest;
37
- }
38
- else {
39
- const platform = json.windows || json.linux;
40
- ver = channel === "preview" ? platform?.preview : platform?.stable;
41
- }
42
- if (!ver)
43
- throw new Error("未找到最新版本号");
44
- return { version: ver, cdnRoot: json.cdn_root ?? "" };
45
- }
46
- catch (e) {
47
- lastErr = e;
48
- if (attempt < 3) {
49
- const wait = attempt * 3000;
50
- log.warn(`版本号获取失败 (${attempt}/3): ${e.message},${wait / 1000}s 后重试...`);
51
- await new Promise((r) => setTimeout(r, wait));
52
- }
53
- }
15
+ async function getVersionInfo(cfg, channel) {
16
+ const api = cfg.version_versions || process.env["BDS_VERSIONS_API"] || DEFAULT_VERSIONS_API;
17
+ const mirror = cfg.version_versions_mirror || process.env["BDS_VERSIONS_MIRROR"] || DEFAULT_VERSIONS_MIRROR;
18
+ const sources = [api, mirror].filter(Boolean);
19
+ const versionMode = cfg.version_mode || "bedrock-oss";
20
+ let lastErr;
21
+ for (let attempt = 1; attempt <= 3; attempt++) {
22
+ try {
23
+ const json = await fetchJsonWithFallback(sources);
24
+ let ver;
25
+ if (versionMode === "endstone") {
26
+ const entry = channel === "preview" ? json.preview : json.release;
27
+ ver = entry?.latest;
28
+ } else {
29
+ const platform = json.windows || json.linux;
30
+ ver = channel === "preview" ? platform?.preview : platform?.stable;
31
+ }
32
+ if (!ver) throw new Error("\u672A\u627E\u5230\u6700\u65B0\u7248\u672C\u53F7");
33
+ return { version: ver, cdnRoot: json.cdn_root ?? "" };
34
+ } catch (e) {
35
+ lastErr = e;
36
+ if (attempt < 3) {
37
+ const wait = attempt * 3e3;
38
+ log.warn(`\u7248\u672C\u53F7\u83B7\u53D6\u5931\u8D25 (${attempt}/3): ${e.message}\uFF0C${wait / 1e3}s \u540E\u91CD\u8BD5...`);
39
+ await new Promise((r) => setTimeout(r, wait));
40
+ }
54
41
  }
55
- throw lastErr instanceof Error ? lastErr : new Error("版本号获取失败");
42
+ }
43
+ throw lastErr instanceof Error ? lastErr : new Error("\u7248\u672C\u53F7\u83B7\u53D6\u5931\u8D25");
56
44
  }
57
- /** 获取 per-version 的下载链接 + 哈希 (fallback GitHub → jsdelivr) */
58
- export async function fetchVersionDetails(cfg, channel, version) {
59
- const platform = channel === "preview" ? "windows_preview" : "windows";
60
- const ch = channel === "preview" ? "preview" : "release";
61
- const vars = { version, ver3: toVer3(version), platform, channel: ch };
62
- const detailsTpl = cfg.version_details || "https://raw.githubusercontent.com/Bedrock-OSS/BDS-Versions/main/{platform}/{version}.json";
63
- const mirrorTpl = cfg.version_details_mirror || "https://cdn.jsdelivr.net/gh/Bedrock-OSS/BDS-Versions@main/{platform}/{version}.json";
64
- const sources = [detailsTpl, mirrorTpl].filter(Boolean).map((t) => resolveTemplate(t, vars));
65
- const json = await fetchJsonWithFallback(sources);
66
- const mode = cfg.version_mode || "bedrock-oss";
67
- if (mode === "endstone") {
68
- const bw = json.binary?.windows;
69
- return {
70
- downloadUrl: bw?.url ?? "",
71
- sha1: "",
72
- sha256: bw?.sha256 ?? "",
73
- size: bw?.size_in_bytes ?? 0,
74
- };
75
- }
45
+ async function fetchVersionDetails(cfg, channel, version) {
46
+ const platform = channel === "preview" ? "windows_preview" : "windows";
47
+ const ch = channel === "preview" ? "preview" : "release";
48
+ const vars = { version, ver3: toVer3(version), platform, channel: ch };
49
+ const detailsTpl = cfg.version_details || "https://raw.githubusercontent.com/Bedrock-OSS/BDS-Versions/main/{platform}/{version}.json";
50
+ const mirrorTpl = cfg.version_details_mirror || "https://cdn.jsdelivr.net/gh/Bedrock-OSS/BDS-Versions@main/{platform}/{version}.json";
51
+ const sources = [detailsTpl, mirrorTpl].filter(Boolean).map((t) => resolveTemplate(t, vars));
52
+ const json = await fetchJsonWithFallback(sources);
53
+ const mode = cfg.version_mode || "bedrock-oss";
54
+ if (mode === "endstone") {
55
+ const bw = json.binary?.windows;
76
56
  return {
77
- downloadUrl: json.download_url ?? "",
78
- sha1: json.sha1 ?? "",
79
- sha256: "",
80
- size: json.size_in_bytes ?? 0,
57
+ downloadUrl: bw?.url ?? "",
58
+ sha1: "",
59
+ sha256: bw?.sha256 ?? "",
60
+ size: bw?.size_in_bytes ?? 0
81
61
  };
62
+ }
63
+ return {
64
+ downloadUrl: json.download_url ?? "",
65
+ sha1: json.sha1 ?? "",
66
+ sha256: "",
67
+ size: json.size_in_bytes ?? 0
68
+ };
82
69
  }
83
- /** 候选下载 URL (按优先级) */
84
- export function buildDownloadUrls(cfg, channel, version, details) {
85
- const urls = [];
86
- if (cfg.download_mirror) {
87
- const mirrorVer = channel === "preview" ? `${version}-preview` : version;
88
- urls.push(resolveTemplate(cfg.download_mirror, { version: mirrorVer }));
89
- }
90
- if (details.downloadUrl)
91
- urls.push(details.downloadUrl);
92
- const cdnRoot = cfg.cdn_root || "https://www.minecraft.net/bedrockdedicatedserver";
93
- const suffix = channel === "preview"
94
- ? `/bin-win-preview/bedrock-server-${version}-preview.zip`
95
- : `/bin-win/bedrock-server-${version}.zip`;
96
- urls.push(cdnRoot + suffix);
97
- urls.push(`https://minecraft.azureedge.net${suffix}`);
98
- return [...new Set(urls)];
70
+ function buildDownloadUrls(cfg, channel, version, details) {
71
+ const urls = [];
72
+ if (cfg.download_mirror) {
73
+ const mirrorVer = channel === "preview" ? `${version}-preview` : version;
74
+ urls.push(resolveTemplate(cfg.download_mirror, { version: mirrorVer }));
75
+ }
76
+ if (details.downloadUrl) urls.push(details.downloadUrl);
77
+ const cdnRoot = cfg.cdn_root || "https://www.minecraft.net/bedrockdedicatedserver";
78
+ const suffix = channel === "preview" ? `/bin-win-preview/bedrock-server-${version}-preview.zip` : `/bin-win/bedrock-server-${version}.zip`;
79
+ urls.push(cdnRoot + suffix);
80
+ urls.push(`https://minecraft.azureedge.net${suffix}`);
81
+ return [...new Set(urls)];
99
82
  }
100
- /** 同步 / 异步校验文件哈希 */
101
- export async function verifyFileHash(filePath, expectedSha1, expectedSha256) {
102
- const expected = expectedSha256 || expectedSha1;
103
- if (!expected)
104
- return true;
105
- const algo = expectedSha256 ? "sha256" : "sha1";
106
- return new Promise((resolve, reject) => {
107
- const h = crypto.createHash(algo);
108
- const stream = fs.createReadStream(filePath);
109
- stream.on("data", (chunk) => {
110
- h.update(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
111
- });
112
- stream.on("end", () => {
113
- const actual = h.digest("hex").toLowerCase();
114
- resolve(actual === expected.toLowerCase());
115
- });
116
- stream.on("error", reject);
83
+ async function verifyFileHash(filePath, expectedSha1, expectedSha256) {
84
+ const expected = expectedSha256 || expectedSha1;
85
+ if (!expected) return true;
86
+ const algo = expectedSha256 ? "sha256" : "sha1";
87
+ return new Promise((resolve, reject) => {
88
+ const h = crypto.createHash(algo);
89
+ const stream = fs.createReadStream(filePath);
90
+ stream.on("data", (chunk) => {
91
+ h.update(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
92
+ });
93
+ stream.on("end", () => {
94
+ const actual = h.digest("hex").toLowerCase();
95
+ resolve(actual === expected.toLowerCase());
117
96
  });
97
+ stream.on("error", reject);
98
+ });
118
99
  }
119
- /** 检查版本兼容性 (白名单) */
120
- export function isVersionCompatible(cfg, version) {
121
- const allow = cfg.compatible_versions;
122
- if (!allow || allow.length === 0)
123
- return true;
124
- return allow.includes(version) || allow.includes(toVer3(version));
100
+ function isVersionCompatible(cfg, version) {
101
+ const allow = cfg.compatible_versions;
102
+ if (!allow || allow.length === 0) return true;
103
+ return allow.includes(version) || allow.includes(toVer3(version));
125
104
  }
126
- //# sourceMappingURL=upstream.js.map
105
+ export {
106
+ buildDownloadUrls,
107
+ fetchVersionDetails,
108
+ getVersionInfo,
109
+ isVersionCompatible,
110
+ verifyFileHash
111
+ };
112
+ //# sourceMappingURL=upstream.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"upstream.js","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"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"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/upstream.ts"],
4
+ "sourcesContent": ["/**\n * upstream.ts \u2014 \u7248\u672C\u6E90 / \u4E0B\u8F7D\u6E90 / \u54C8\u5E0C\u6821\u9A8C\n *\n * \u6539\u8FDB:\n * - 3 \u6B21\u91CD\u8BD5 + \u6307\u6570\u9000\u907F\n * - sha1 / sha256 \u540C\u65F6\u6821\u9A8C\n * - \u6D41\u5F0F\u6821\u9A8C + \u8FB9\u4E0B\u8FB9\u6821\u9A8C\n */\n\nimport crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport { fetchJsonWithFallback } from \"./http.js\";\nimport { log } from \"./log.js\";\nimport type { BdsUpdaterConfig, VersionDetails, VersionInfo } from \"./types.js\";\nimport { toVer3 } from \"./version.js\";\n\nconst DEFAULT_VERSIONS_API = \"https://raw.githubusercontent.com/Bedrock-OSS/BDS-Versions/main/versions.json\";\nconst DEFAULT_VERSIONS_MIRROR = \"https://cdn.jsdelivr.net/gh/Bedrock-OSS/BDS-Versions@main/versions.json\";\n\nfunction resolveTemplate(tpl: string, vars: Record<string, string>): string {\n let s = tpl;\n for (const [k, v] of Object.entries(vars)) {\n s = s.replace(new RegExp(`\\\\{${k}\\\\}`, \"g\"), v);\n }\n return s;\n}\n\n/** \u83B7\u53D6\u6700\u65B0\u7248\u672C\u53F7 (\u542B cdn_root)\uFF0C3 \u6B21\u91CD\u8BD5 */\nexport async function getVersionInfo(cfg: BdsUpdaterConfig, channel: string): Promise<VersionInfo> {\n const api = cfg.version_versions || process.env[\"BDS_VERSIONS_API\"] || DEFAULT_VERSIONS_API;\n const mirror = cfg.version_versions_mirror || process.env[\"BDS_VERSIONS_MIRROR\"] || DEFAULT_VERSIONS_MIRROR;\n const sources = [api, mirror].filter(Boolean);\n const versionMode = cfg.version_mode || \"bedrock-oss\";\n\n let lastErr: unknown;\n for (let attempt = 1; attempt <= 3; attempt++) {\n try {\n const json = await fetchJsonWithFallback<any>(sources);\n let ver: string | undefined;\n if (versionMode === \"endstone\") {\n const entry = channel === \"preview\" ? json.preview : json.release;\n ver = entry?.latest;\n } else {\n const platform = json.windows || json.linux;\n ver = channel === \"preview\" ? platform?.preview : platform?.stable;\n }\n if (!ver) throw new Error(\"\u672A\u627E\u5230\u6700\u65B0\u7248\u672C\u53F7\");\n return { version: ver, cdnRoot: json.cdn_root ?? \"\" };\n } catch (e) {\n lastErr = e;\n if (attempt < 3) {\n const wait = attempt * 3000;\n log.warn(`\u7248\u672C\u53F7\u83B7\u53D6\u5931\u8D25 (${attempt}/3): ${(e as Error).message}\uFF0C${wait / 1000}s \u540E\u91CD\u8BD5...`);\n await new Promise((r) => setTimeout(r, wait));\n }\n }\n }\n throw lastErr instanceof Error ? lastErr : new Error(\"\u7248\u672C\u53F7\u83B7\u53D6\u5931\u8D25\");\n}\n\n/** \u83B7\u53D6 per-version \u7684\u4E0B\u8F7D\u94FE\u63A5 + \u54C8\u5E0C (fallback GitHub \u2192 jsdelivr) */\nexport async function fetchVersionDetails(\n cfg: BdsUpdaterConfig,\n channel: string,\n version: string\n): Promise<VersionDetails> {\n const platform = channel === \"preview\" ? \"windows_preview\" : \"windows\";\n const ch = channel === \"preview\" ? \"preview\" : \"release\";\n const vars = { version, ver3: toVer3(version), platform, channel: ch };\n const detailsTpl =\n cfg.version_details || \"https://raw.githubusercontent.com/Bedrock-OSS/BDS-Versions/main/{platform}/{version}.json\";\n const mirrorTpl =\n cfg.version_details_mirror || \"https://cdn.jsdelivr.net/gh/Bedrock-OSS/BDS-Versions@main/{platform}/{version}.json\";\n const sources = [detailsTpl, mirrorTpl].filter(Boolean).map((t) => resolveTemplate(t, vars));\n\n const json = await fetchJsonWithFallback<any>(sources);\n const mode = cfg.version_mode || \"bedrock-oss\";\n if (mode === \"endstone\") {\n const bw = json.binary?.windows;\n return {\n downloadUrl: bw?.url ?? \"\",\n sha1: \"\",\n sha256: bw?.sha256 ?? \"\",\n size: bw?.size_in_bytes ?? 0,\n };\n }\n return {\n downloadUrl: json.download_url ?? \"\",\n sha1: json.sha1 ?? \"\",\n sha256: \"\",\n size: json.size_in_bytes ?? 0,\n };\n}\n\n/** \u5019\u9009\u4E0B\u8F7D URL (\u6309\u4F18\u5148\u7EA7) */\nexport function buildDownloadUrls(\n cfg: BdsUpdaterConfig,\n channel: string,\n version: string,\n details: VersionDetails\n): string[] {\n const urls: string[] = [];\n if (cfg.download_mirror) {\n const mirrorVer = channel === \"preview\" ? `${version}-preview` : version;\n urls.push(resolveTemplate(cfg.download_mirror, { version: mirrorVer }));\n }\n if (details.downloadUrl) urls.push(details.downloadUrl);\n const cdnRoot = cfg.cdn_root || \"https://www.minecraft.net/bedrockdedicatedserver\";\n const suffix =\n channel === \"preview\"\n ? `/bin-win-preview/bedrock-server-${version}-preview.zip`\n : `/bin-win/bedrock-server-${version}.zip`;\n urls.push(cdnRoot + suffix);\n urls.push(`https://minecraft.azureedge.net${suffix}`);\n return [...new Set(urls)];\n}\n\n/** \u540C\u6B65 / \u5F02\u6B65\u6821\u9A8C\u6587\u4EF6\u54C8\u5E0C */\nexport async function verifyFileHash(filePath: string, expectedSha1: string, expectedSha256: string): Promise<boolean> {\n const expected = expectedSha256 || expectedSha1;\n if (!expected) return true;\n const algo: \"sha1\" | \"sha256\" = expectedSha256 ? \"sha256\" : \"sha1\";\n\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\", () => {\n const actual = h.digest(\"hex\").toLowerCase();\n resolve(actual === expected.toLowerCase());\n });\n stream.on(\"error\", reject);\n });\n}\n\n/** \u68C0\u67E5\u7248\u672C\u517C\u5BB9\u6027 (\u767D\u540D\u5355) */\nexport function isVersionCompatible(cfg: BdsUpdaterConfig, version: string): boolean {\n const allow = cfg.compatible_versions;\n if (!allow || allow.length === 0) return true;\n return allow.includes(version) || allow.includes(toVer3(version));\n}\n\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }