@sfmc-bds/bds-tools 0.1.0 → 0.2.0-beta.0

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 (71) 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 +226 -135
  13. package/dist/cli-pack-manager.js.map +7 -1
  14. package/dist/fsx.js +86 -100
  15. package/dist/fsx.js.map +7 -1
  16. package/dist/http.d.ts.map +1 -1
  17. package/dist/http.js +166 -185
  18. package/dist/http.js.map +7 -1
  19. package/dist/is-main.d.ts +17 -0
  20. package/dist/is-main.d.ts.map +1 -0
  21. package/dist/is-main.js +32 -0
  22. package/dist/is-main.js.map +7 -0
  23. package/dist/log.d.ts +2 -4
  24. package/dist/log.d.ts.map +1 -1
  25. package/dist/log.js +12 -19
  26. package/dist/log.js.map +7 -1
  27. package/dist/logger.js +6 -10
  28. package/dist/logger.js.map +7 -1
  29. package/dist/pack-manager.d.ts +88 -24
  30. package/dist/pack-manager.d.ts.map +1 -1
  31. package/dist/pack-manager.js +280 -245
  32. package/dist/pack-manager.js.map +7 -1
  33. package/dist/paths.d.ts +8 -3
  34. package/dist/paths.d.ts.map +1 -1
  35. package/dist/paths.js +53 -39
  36. package/dist/paths.js.map +7 -1
  37. package/dist/qqutil.d.ts.map +1 -1
  38. package/dist/qqutil.js +90 -87
  39. package/dist/qqutil.js.map +7 -1
  40. package/dist/recovery.js +26 -37
  41. package/dist/recovery.js.map +7 -1
  42. package/dist/rollback.d.ts +1 -1
  43. package/dist/rollback.js +55 -74
  44. package/dist/rollback.js.map +7 -1
  45. package/dist/server-properties.d.ts +12 -0
  46. package/dist/server-properties.d.ts.map +1 -0
  47. package/dist/server-properties.js +28 -0
  48. package/dist/server-properties.js.map +7 -0
  49. package/dist/taskbar.d.ts +2 -0
  50. package/dist/taskbar.d.ts.map +1 -1
  51. package/dist/taskbar.js +51 -82
  52. package/dist/taskbar.js.map +7 -1
  53. package/dist/types.js +1 -5
  54. package/dist/types.js.map +7 -1
  55. package/dist/update-result.d.ts +12 -0
  56. package/dist/update-result.d.ts.map +1 -0
  57. package/dist/update-result.js +15 -0
  58. package/dist/update-result.js.map +7 -0
  59. package/dist/upstream.js +94 -108
  60. package/dist/upstream.js.map +7 -1
  61. package/dist/version.js +63 -81
  62. package/dist/version.js.map +7 -1
  63. package/dist/world-packs.d.ts +112 -0
  64. package/dist/world-packs.d.ts.map +1 -0
  65. package/dist/world-packs.js +335 -0
  66. package/dist/world-packs.js.map +7 -0
  67. package/dist/zipx.d.ts +10 -0
  68. package/dist/zipx.d.ts.map +1 -0
  69. package/dist/zipx.js +48 -0
  70. package/dist/zipx.js.map +7 -0
  71. package/package.json +17 -6
package/dist/changelog.js CHANGED
@@ -1,59 +1,48 @@
1
- /**
2
- * changelog.ts — 更新日志抓取 (官方页面)
3
- */
4
1
  import { parse as parseHtml } from "node-html-parser";
5
2
  import { fetchJsonWithFallback, httpGetText } from "./http.js";
6
3
  import { log } from "./log.js";
7
4
  const CHANGELOG_BASE = "https://feedback.minecraft.net/hc/en-us/sections/360001186971";
8
- /**
9
- * node-html-parser 的 API 与 cheerio 略不同:它没有 first/length 链式判断,
10
- * 而是用 querySelector + 节点属性。这里包一层小工具让选择子语义集中。
11
- */
12
5
  function firstElement(root, selector) {
13
- return root.querySelector(selector);
6
+ return root.querySelector(selector);
14
7
  }
15
- /** 抓取当前版本的更新说明 (文本 + 首张图 base64) */
16
- export async function fetchChangelog(channel) {
17
- try {
18
- const url = `https://www.minecraft.net/en-us/article/${channel === "preview" ? "bedrock-beta" : "bedrock"}-update`;
19
- const html = await httpGetText(url);
20
- const root = parseHtml(html);
21
- const article = firstElement(root, "article")
22
- ?? firstElement(root, ".article-content")
23
- ?? firstElement(root, '[class*="content"]');
24
- if (!article)
25
- return null;
26
- const paragraphs = [];
27
- for (const el of article.querySelectorAll("p, h2, h3, li")) {
28
- const t = el.text.trim();
29
- if (t)
30
- paragraphs.push(t);
31
- }
32
- const text = paragraphs.join("\n").slice(0, 2000);
33
- let imageBase64 = null;
34
- const firstImg = article.querySelector("img");
35
- if (firstImg) {
36
- const imgSrc = firstImg.getAttribute("src") ?? firstImg.getAttribute("data-src") ?? undefined;
37
- if (imgSrc) {
38
- try {
39
- const imgUrl = imgSrc.startsWith("http") ? imgSrc : `https://www.minecraft.net${imgSrc}`;
40
- const res = await fetchJsonWithFallback([], 15_000).catch(() => null);
41
- void res;
42
- const { httpRequest } = await import("./http.js");
43
- const img = await httpRequest(imgUrl);
44
- imageBase64 = img.body.toString("base64");
45
- }
46
- catch (e) {
47
- log.warn(`获取图片失败: ${e.message}`);
48
- }
49
- }
50
- }
51
- return { text: text.slice(0, 2000), imageBase64 };
8
+ async function fetchChangelog(channel) {
9
+ try {
10
+ const url = `https://www.minecraft.net/en-us/article/${channel === "preview" ? "bedrock-beta" : "bedrock"}-update`;
11
+ const html = await httpGetText(url);
12
+ const root = parseHtml(html);
13
+ const article = firstElement(root, "article") ?? firstElement(root, ".article-content") ?? firstElement(root, '[class*="content"]');
14
+ if (!article) return null;
15
+ const paragraphs = [];
16
+ for (const el of article.querySelectorAll("p, h2, h3, li")) {
17
+ const t = el.text.trim();
18
+ if (t) paragraphs.push(t);
52
19
  }
53
- catch (e) {
54
- log.warn(`获取更新日志失败: ${e.message}`);
55
- return null;
20
+ const text = paragraphs.join("\n").slice(0, 2e3);
21
+ let imageBase64 = null;
22
+ const firstImg = article.querySelector("img");
23
+ if (firstImg) {
24
+ const imgSrc = firstImg.getAttribute("src") ?? firstImg.getAttribute("data-src") ?? void 0;
25
+ if (imgSrc) {
26
+ try {
27
+ const imgUrl = imgSrc.startsWith("http") ? imgSrc : `https://www.minecraft.net${imgSrc}`;
28
+ const res = await fetchJsonWithFallback([], 15e3).catch(() => null);
29
+ void res;
30
+ const { httpRequest } = await import("./http.js");
31
+ const img = await httpRequest(imgUrl);
32
+ imageBase64 = img.body.toString("base64");
33
+ } catch (e) {
34
+ log.warn(`\u83B7\u53D6\u56FE\u7247\u5931\u8D25: ${e.message}`);
35
+ }
36
+ }
56
37
  }
38
+ return { text: text.slice(0, 2e3), imageBase64 };
39
+ } catch (e) {
40
+ log.warn(`\u83B7\u53D6\u66F4\u65B0\u65E5\u5FD7\u5931\u8D25: ${e.message}`);
41
+ return null;
42
+ }
57
43
  }
58
- export { CHANGELOG_BASE };
59
- //# sourceMappingURL=changelog.js.map
44
+ export {
45
+ CHANGELOG_BASE,
46
+ fetchChangelog
47
+ };
48
+ //# sourceMappingURL=changelog.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"changelog.js","sourceRoot":"","sources":["../src/changelog.ts"],"names":[],"mappings":"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"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/changelog.ts"],
4
+ "sourcesContent": ["/**\n * changelog.ts \u2014 \u66F4\u65B0\u65E5\u5FD7\u6293\u53D6 (\u5B98\u65B9\u9875\u9762)\n */\n\nimport { parse as parseHtml, HTMLElement } from \"node-html-parser\";\nimport { fetchJsonWithFallback, httpGetText } from \"./http.js\";\nimport type { ChangelogPayload } from \"./types.js\";\nimport { log } from \"./log.js\";\n\nconst CHANGELOG_BASE = \"https://feedback.minecraft.net/hc/en-us/sections/360001186971\";\n\n/**\n * node-html-parser \u7684 API \u4E0E cheerio \u7565\u4E0D\u540C:\u5B83\u6CA1\u6709 first/length \u94FE\u5F0F\u5224\u65AD,\n * \u800C\u662F\u7528 querySelector + \u8282\u70B9\u5C5E\u6027\u3002\u8FD9\u91CC\u5305\u4E00\u5C42\u5C0F\u5DE5\u5177\u8BA9\u9009\u62E9\u5B50\u8BED\u4E49\u96C6\u4E2D\u3002\n */\nfunction firstElement(root: HTMLElement, selector: string): HTMLElement | null {\n return root.querySelector(selector);\n}\n\n/** \u6293\u53D6\u5F53\u524D\u7248\u672C\u7684\u66F4\u65B0\u8BF4\u660E (\u6587\u672C + \u9996\u5F20\u56FE base64) */\nexport async function fetchChangelog(channel: string): Promise<ChangelogPayload | null> {\n try {\n const url = `https://www.minecraft.net/en-us/article/${channel === \"preview\" ? \"bedrock-beta\" : \"bedrock\"}-update`;\n const html = await httpGetText(url);\n const root = parseHtml(html);\n const article = firstElement(root, \"article\")\n ?? firstElement(root, \".article-content\")\n ?? firstElement(root, '[class*=\"content\"]');\n if (!article) return null;\n\n const paragraphs: string[] = [];\n for (const el of article.querySelectorAll(\"p, h2, h3, li\")) {\n const t = el.text.trim();\n if (t) paragraphs.push(t);\n }\n const text = paragraphs.join(\"\\n\").slice(0, 2000);\n\n let imageBase64: string | null = null;\n const firstImg = article.querySelector(\"img\");\n if (firstImg) {\n const imgSrc: string | undefined = firstImg.getAttribute(\"src\") ?? firstImg.getAttribute(\"data-src\") ?? undefined;\n if (imgSrc) {\n try {\n const imgUrl = imgSrc.startsWith(\"http\") ? imgSrc : `https://www.minecraft.net${imgSrc}`;\n const res = await fetchJsonWithFallback([], 15_000).catch(() => null);\n void res;\n const { httpRequest } = await import(\"./http.js\");\n const img = await httpRequest(imgUrl);\n imageBase64 = img.body.toString(\"base64\");\n } catch (e) {\n log.warn(`\u83B7\u53D6\u56FE\u7247\u5931\u8D25: ${(e as Error).message}`);\n }\n }\n }\n\n return { text: text.slice(0, 2000), imageBase64 };\n } catch (e) {\n log.warn(`\u83B7\u53D6\u66F4\u65B0\u65E5\u5FD7\u5931\u8D25: ${(e as Error).message}`);\n return null;\n }\n}\n\nexport { CHANGELOG_BASE };\n"],
5
+ "mappings": "AAIA,SAAS,SAAS,iBAA8B;AAChD,SAAS,uBAAuB,mBAAmB;AAEnD,SAAS,WAAW;AAEpB,MAAM,iBAAiB;AAMvB,SAAS,aAAa,MAAmB,UAAsC;AAC7E,SAAO,KAAK,cAAc,QAAQ;AACpC;AAGA,eAAsB,eAAe,SAAmD;AACtF,MAAI;AACF,UAAM,MAAM,2CAA2C,YAAY,YAAY,iBAAiB,SAAS;AACzG,UAAM,OAAO,MAAM,YAAY,GAAG;AAClC,UAAM,OAAO,UAAU,IAAI;AAC3B,UAAM,UAAU,aAAa,MAAM,SAAS,KACvC,aAAa,MAAM,kBAAkB,KACrC,aAAa,MAAM,oBAAoB;AAC5C,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,aAAuB,CAAC;AAC9B,eAAW,MAAM,QAAQ,iBAAiB,eAAe,GAAG;AAC1D,YAAM,IAAI,GAAG,KAAK,KAAK;AACvB,UAAI,EAAG,YAAW,KAAK,CAAC;AAAA,IAC1B;AACA,UAAM,OAAO,WAAW,KAAK,IAAI,EAAE,MAAM,GAAG,GAAI;AAEhD,QAAI,cAA6B;AACjC,UAAM,WAAW,QAAQ,cAAc,KAAK;AAC5C,QAAI,UAAU;AACZ,YAAM,SAA6B,SAAS,aAAa,KAAK,KAAK,SAAS,aAAa,UAAU,KAAK;AACxG,UAAI,QAAQ;AACV,YAAI;AACF,gBAAM,SAAS,OAAO,WAAW,MAAM,IAAI,SAAS,4BAA4B,MAAM;AACtF,gBAAM,MAAM,MAAM,sBAAsB,CAAC,GAAG,IAAM,EAAE,MAAM,MAAM,IAAI;AACpE,eAAK;AACL,gBAAM,EAAE,YAAY,IAAI,MAAM,OAAO,WAAW;AAChD,gBAAM,MAAM,MAAM,YAAY,MAAM;AACpC,wBAAc,IAAI,KAAK,SAAS,QAAQ;AAAA,QAC1C,SAAS,GAAG;AACV,cAAI,KAAK,yCAAY,EAAY,OAAO,EAAE;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,MAAM,KAAK,MAAM,GAAG,GAAI,GAAG,YAAY;AAAA,EAClD,SAAS,GAAG;AACV,QAAI,KAAK,qDAAc,EAAY,OAAO,EAAE;AAC5C,WAAO;AAAA,EACT;AACF;",
6
+ "names": []
7
+ }
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * check-update.ts — BDS 自动更新器 (主流程)
3
3
  *
4
- * 1. 临时 staging 目录 (mkdtempSync) - 避免污染 SCRIPT_DIR
4
+ * 1. 临时 staging 目录 (mkdtempSync) - 避免污染数据根
5
5
  * 2. 下载/解压失败 → 自动从备份回滚 preserves
6
6
  * 3. 流式 SHA256 校验 - 不把 250MB 文件读入内存
7
7
  * 4. 兼容版本白名单 - 不匹配则跳过升级
8
8
  * 5. QQ 通知统一加 5s 超时 - 永远不阻塞主流程
9
- * 6. Rollback marker 落盘 - 跨进程 / 跨重启可恢复
9
+ * 6. Rollback marker 落盘到 <ROOT>/.sfmc/ - 跨进程 / 跨重启可恢复
10
10
  */
11
11
  export declare function runUpdate(): Promise<number>;
12
12
  //# sourceMappingURL=check-update.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-update.d.ts","sourceRoot":"","sources":["../src/check-update.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA8JH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAuSjD"}
1
+ {"version":3,"file":"check-update.d.ts","sourceRoot":"","sources":["../src/check-update.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuJH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAyRjD"}