@sfmc-bds/qq-bridge 0.2.0-beta.12 → 0.2.0-beta.13

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 (70) hide show
  1. package/README.md +68 -1
  2. package/deploy/install-nginx-webhook.sh +34 -0
  3. package/deploy/nginx-webhook-location.conf +10 -0
  4. package/deploy/qq-bridge.service +23 -0
  5. package/deploy/qq-config-sync.ps1 +106 -0
  6. package/deploy/qq-tunnel.ps1 +15 -0
  7. package/deploy/sync-qq-config.mjs +229 -0
  8. package/dist/commands/account-format.js +41 -0
  9. package/dist/commands/account-format.js.map +7 -0
  10. package/dist/commands/content-format.js +114 -0
  11. package/dist/commands/content-format.js.map +7 -0
  12. package/dist/commands/db-api.js +21 -6
  13. package/dist/commands/db-api.js.map +2 -2
  14. package/dist/commands/handlers.js +392 -524
  15. package/dist/commands/handlers.js.map +2 -2
  16. package/dist/commands/index.js +5 -5
  17. package/dist/commands/index.js.map +3 -3
  18. package/dist/commands/interaction-router.js +38 -133
  19. package/dist/commands/interaction-router.js.map +2 -2
  20. package/dist/commands/join-settings-ui.js +1 -24
  21. package/dist/commands/join-settings-ui.js.map +2 -2
  22. package/dist/commands/menu-format.js +36 -33
  23. package/dist/commands/menu-format.js.map +2 -2
  24. package/dist/commands/menu-panel-sync.js +39 -13
  25. package/dist/commands/menu-panel-sync.js.map +2 -2
  26. package/dist/commands/message-text.js +91 -0
  27. package/dist/commands/message-text.js.map +7 -0
  28. package/dist/commands/pending.js +23 -16
  29. package/dist/commands/pending.js.map +2 -2
  30. package/dist/commands/permissions.js +17 -0
  31. package/dist/commands/permissions.js.map +7 -0
  32. package/dist/commands/registry.js +1 -1
  33. package/dist/commands/registry.js.map +2 -2
  34. package/dist/commands/render.js +7 -16
  35. package/dist/commands/render.js.map +2 -2
  36. package/dist/commands/reply-llbot.js +18 -7
  37. package/dist/commands/reply-llbot.js.map +2 -2
  38. package/dist/commands/reply-official.js +55 -39
  39. package/dist/commands/reply-official.js.map +3 -3
  40. package/dist/commands/router.js +116 -23
  41. package/dist/commands/router.js.map +2 -2
  42. package/dist/config.js +35 -27
  43. package/dist/config.js.map +2 -2
  44. package/dist/console.js +3 -3
  45. package/dist/console.js.map +2 -2
  46. package/dist/index.js +30 -16
  47. package/dist/index.js.map +2 -2
  48. package/dist/llbot-ws-api.js +2 -2
  49. package/dist/llbot-ws-api.js.map +2 -2
  50. package/dist/official/events.js +32 -7
  51. package/dist/official/events.js.map +2 -2
  52. package/dist/official/gateway.js +10 -1
  53. package/dist/official/gateway.js.map +2 -2
  54. package/dist/official/webhook.js +165 -0
  55. package/dist/official/webhook.js.map +7 -0
  56. package/dist/onebot.js +0 -4
  57. package/dist/onebot.js.map +2 -2
  58. package/package.json +4 -4
  59. package/dist/commands/join-settings-ui.test.js +0 -43
  60. package/dist/commands/join-settings-ui.test.js.map +0 -7
  61. package/dist/commands/menu-panel-sync.test.js +0 -27
  62. package/dist/commands/menu-panel-sync.test.js.map +0 -7
  63. package/dist/commands/render.test.js +0 -44
  64. package/dist/commands/render.test.js.map +0 -7
  65. package/dist/commands/router.test.js +0 -92
  66. package/dist/commands/router.test.js.map +0 -7
  67. package/dist/llbot-ws-api.test.js +0 -32
  68. package/dist/llbot-ws-api.test.js.map +0 -7
  69. package/dist/official/events.test.js +0 -123
  70. package/dist/official/events.test.js.map +0 -7
@@ -0,0 +1,114 @@
1
+ function moduleMatches(mod, keyword) {
2
+ const q = keyword.trim().toLowerCase();
3
+ if (!q) return true;
4
+ const name = String(mod.display_name || mod.id || "").toLowerCase();
5
+ return name.includes(q) || String(mod.id || "").toLowerCase().includes(q);
6
+ }
7
+ function formatModuleLines(modules, keyword = "") {
8
+ const matched = modules.filter((mod) => moduleMatches(mod, keyword));
9
+ if (!matched.length) {
10
+ return keyword ? [`\u6CA1\u6709\u540D\u79F0\u5305\u542B\u300C${keyword}\u300D\u7684\u6A21\u5757\u3002`] : ["\u5F53\u524D\u6CA1\u6709\u5DF2\u5B89\u88C5\u6A21\u5757\u3002"];
11
+ }
12
+ const enabled = matched.filter((mod) => mod.enabled !== false);
13
+ const disabled = matched.filter((mod) => mod.enabled === false);
14
+ const lines = [`\u5DF2\u542F\u7528 ${enabled.length}\uFF0C\u672A\u542F\u7528 ${disabled.length}`];
15
+ const render = (mod) => {
16
+ const name = mod.display_name || mod.id || "\u672A\u547D\u540D\u6A21\u5757";
17
+ const state = mod.enabled === false ? "\u5173" : "\u5F00";
18
+ const pack = mod.has_resource_pack ? " \xB7 \u542B\u8D44\u6E90\u5305" : "";
19
+ return `${name}\uFF08${state}${pack}\uFF09`;
20
+ };
21
+ if (enabled.length) {
22
+ lines.push("", "\u3010\u5DF2\u542F\u7528\u3011", ...enabled.map(render));
23
+ }
24
+ if (disabled.length) {
25
+ lines.push("", "\u3010\u672A\u542F\u7528\u3011", ...disabled.map(render));
26
+ }
27
+ return lines;
28
+ }
29
+ function formatWorldPackLine(pack) {
30
+ const resolved = String(pack.name || "").trim();
31
+ const folder = String(pack.folder_name || "").trim();
32
+ const name = !resolved || resolved.startsWith("pack.") || resolved === "pack" ? folder || pack.pack_id || "\u672A\u547D\u540D" : resolved;
33
+ const folderBit = folder && folder !== name ? `${folder} \xB7 ` : "";
34
+ const version = pack.version ? ` v${pack.version}` : "";
35
+ const state = pack.enabled === false ? "\u5173" : "\u5F00";
36
+ return `${folderBit}${name}${version}\uFF08${state}\uFF09`;
37
+ }
38
+ function markdownCell(value) {
39
+ const text = value.replace(/§[0-9a-zA-Z]/g, "").replace(/\|/g, "\\|").replace(/\r?\n/g, " ").trim();
40
+ return text || "\u2014";
41
+ }
42
+ function packFields(pack) {
43
+ const resolved = String(pack.name || "").trim();
44
+ const folder = String(pack.folder_name || "").trim();
45
+ const name = !resolved || resolved.startsWith("pack.") || resolved === "pack" ? folder || pack.pack_id || "\u672A\u547D\u540D" : resolved;
46
+ return {
47
+ state: pack.enabled === false ? "\u5173" : "\u5F00",
48
+ name: markdownCell(name),
49
+ version: markdownCell(pack.version || "\u2014")
50
+ };
51
+ }
52
+ function markdownTable(rows) {
53
+ return [
54
+ "| \u72B6\u6001 | \u540D\u79F0 | \u7248\u672C |",
55
+ "| --- | --- | --- |",
56
+ ...rows.map((row) => `| ${row.state} | ${row.name} | ${row.version} |`)
57
+ ];
58
+ }
59
+ function formatPackMarkdown(packs, worldNote) {
60
+ if (worldNote === "bds_unconfigured") {
61
+ return ["## \u4E16\u754C\u5305", "", "\u672A\u914D\u7F6E BDS \u8DEF\u5F84\uFF0C\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u4E16\u754C\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\u3002"].join("\n");
62
+ }
63
+ if (worldNote === "world_unread") {
64
+ return ["## \u4E16\u754C\u5305", "", "\u4E16\u754C\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\u6682\u65F6\u8BFB\u4E0D\u51FA\u6765\u3002"].join("\n");
65
+ }
66
+ const sections = [
67
+ { kind: "behavior", title: "\u884C\u4E3A\u5305", empty: "\u4E16\u754C\u91CC\u6CA1\u6709\u884C\u4E3A\u5305\u3002" },
68
+ { kind: "resource", title: "\u8D44\u6E90\u5305", empty: "\u4E16\u754C\u91CC\u6CA1\u6709\u8D44\u6E90\u5305\u3002" }
69
+ ];
70
+ const lines = ["## \u4E16\u754C\u5305", ""];
71
+ for (const section of sections) {
72
+ const group = packs.filter((pack) => (pack.kind ?? "resource") === section.kind);
73
+ const enabled = group.filter((pack) => pack.enabled !== false);
74
+ const disabled = group.filter((pack) => pack.enabled === false);
75
+ lines.push(`### ${section.title}`, "");
76
+ if (!group.length) {
77
+ lines.push(section.empty, "");
78
+ continue;
79
+ }
80
+ lines.push(`\u5DF2\u542F\u7528 ${enabled.length}\uFF0C\u672A\u542F\u7528 ${disabled.length}`, "");
81
+ lines.push(...markdownTable([...enabled, ...disabled].map(packFields)), "");
82
+ }
83
+ return lines.join("\n").trimEnd();
84
+ }
85
+ function formatPackLines(packs, worldNote) {
86
+ if (worldNote === "bds_unconfigured") return ["\u672A\u914D\u7F6E BDS \u8DEF\u5F84\uFF0C\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u4E16\u754C\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\u3002"];
87
+ if (worldNote === "world_unread") return ["\u4E16\u754C\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\u6682\u65F6\u8BFB\u4E0D\u51FA\u6765\u3002"];
88
+ const sections = [
89
+ { kind: "behavior", title: "\u3010\u884C\u4E3A\u5305\u3011", empty: "\u4E16\u754C\u91CC\u6CA1\u6709\u884C\u4E3A\u5305\u3002" },
90
+ { kind: "resource", title: "\u3010\u8D44\u6E90\u5305\u3011", empty: "\u4E16\u754C\u91CC\u6CA1\u6709\u8D44\u6E90\u5305\u3002" }
91
+ ];
92
+ const lines = [];
93
+ for (const section of sections) {
94
+ const group = packs.filter((pack) => (pack.kind ?? "resource") === section.kind);
95
+ const enabled = group.filter((pack) => pack.enabled !== false);
96
+ const disabled = group.filter((pack) => pack.enabled === false);
97
+ if (lines.length) lines.push("");
98
+ lines.push(section.title);
99
+ if (!group.length) {
100
+ lines.push(section.empty);
101
+ continue;
102
+ }
103
+ lines.push(`\u5DF2\u542F\u7528 ${enabled.length}\uFF0C\u672A\u542F\u7528 ${disabled.length}`);
104
+ lines.push(...enabled.map(formatWorldPackLine), ...disabled.map(formatWorldPackLine));
105
+ }
106
+ return lines;
107
+ }
108
+ export {
109
+ formatModuleLines,
110
+ formatPackLines,
111
+ formatPackMarkdown,
112
+ moduleMatches
113
+ };
114
+ //# sourceMappingURL=content-format.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/commands/content-format.ts"],
4
+ "sourcesContent": ["/**\n * content-format.ts \u2014 \u628A\u6A21\u5757 / \u4E16\u754C\u5305\u5FEB\u7167\u6392\u6210 QQ \u4FE1\u606F\u5361\u6B63\u6587\u3002\n *\n * \u300C\u6A21\u5757\u300D\u5217\u51FA\u542F\u505C\u548C\u662F\u5426\u81EA\u5E26\u8D44\u6E90\u5305\u3002\n * \u300C\u4E16\u754C\u5305\u300D\u7684 Markdown \u7528\u8868\u683C\u5206\u5217\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\uFF1B\u7EAF\u6587\u672C\u4ECD\u4FDD\u7559\u539F\u6765\u7684\u9010\u884C\u5217\u8868\uFF0C\u4F9B Markdown \u53D1\u9001\u5931\u8D25\u65F6\u964D\u7EA7\u3002\n */\n\nexport type ContentModuleView = {\n id: string;\n display_name?: string;\n enabled?: boolean;\n has_resource_pack?: boolean;\n};\n\n/** \u4E00\u6761\u4E16\u754C\u5305\u3002kind \u7F3A\u7701\u65F6\u6309\u8D44\u6E90\u5305\u5904\u7406\uFF0C\u517C\u5BB9\u8FD8\u6CA1\u5206\u5F00\u8FD4\u56DE\u7684\u65E7\u5FEB\u7167\u3002 */\nexport type WorldPackView = {\n kind?: \"behavior\" | \"resource\";\n name?: string;\n folder_name?: string;\n pack_id?: string;\n version?: string;\n enabled?: boolean;\n};\n\n/** \u5173\u952E\u5B57\u5339\u914D\u6A21\u5757\u540D\u6216 id\u3002\u7A7A\u5173\u952E\u5B57\u8868\u793A\u5168\u90E8\u3002 */\nexport function moduleMatches(mod: ContentModuleView, keyword: string): boolean {\n const q = keyword.trim().toLowerCase();\n if (!q) return true;\n const name = String(mod.display_name || mod.id || \"\").toLowerCase();\n return name.includes(q) || String(mod.id || \"\").toLowerCase().includes(q);\n}\n\n/** \u6A21\u5757\u67E5\u8BE2\u6B63\u6587\u3002\u5DF2\u542F\u7528\u6392\u5728\u524D\u9762\uFF0C\u4FBF\u4E8E\u5728\u7FA4\u91CC\u626B\u4E00\u773C\u5F53\u524D\u5728\u8DD1\u4EC0\u4E48\u3002 */\nexport function formatModuleLines(modules: ContentModuleView[], keyword = \"\"): string[] {\n const matched = modules.filter((mod) => moduleMatches(mod, keyword));\n if (!matched.length) {\n return keyword ? [`\u6CA1\u6709\u540D\u79F0\u5305\u542B\u300C${keyword}\u300D\u7684\u6A21\u5757\u3002`] : [\"\u5F53\u524D\u6CA1\u6709\u5DF2\u5B89\u88C5\u6A21\u5757\u3002\"];\n }\n const enabled = matched.filter((mod) => mod.enabled !== false);\n const disabled = matched.filter((mod) => mod.enabled === false);\n const lines = [`\u5DF2\u542F\u7528 ${enabled.length}\uFF0C\u672A\u542F\u7528 ${disabled.length}`];\n const render = (mod: ContentModuleView) => {\n const name = mod.display_name || mod.id || \"\u672A\u547D\u540D\u6A21\u5757\";\n const state = mod.enabled === false ? \"\u5173\" : \"\u5F00\";\n const pack = mod.has_resource_pack ? \" \u00B7 \u542B\u8D44\u6E90\u5305\" : \"\";\n return `${name}\uFF08${state}${pack}\uFF09`;\n };\n if (enabled.length) {\n lines.push(\"\", \"\u3010\u5DF2\u542F\u7528\u3011\", ...enabled.map(render));\n }\n if (disabled.length) {\n lines.push(\"\", \"\u3010\u672A\u542F\u7528\u3011\", ...disabled.map(render));\n }\n return lines;\n}\n\n/** \u5355\u6761\u4E16\u754C\u5305\uFF1A\u771F\u5B9E\u540D\u79F0\u4F18\u5148\uFF0C\u8BED\u8A00\u952E\u6B8B\u7559\u65F6\u9000\u56DE\u6587\u4EF6\u5939\u540D\u3002 */\nfunction formatWorldPackLine(pack: WorldPackView): string {\n const resolved = String(pack.name || \"\").trim();\n const folder = String(pack.folder_name || \"\").trim();\n const name =\n !resolved || resolved.startsWith(\"pack.\") || resolved === \"pack\"\n ? folder || pack.pack_id || \"\u672A\u547D\u540D\"\n : resolved;\n const folderBit = folder && folder !== name ? `${folder} \u00B7 ` : \"\";\n const version = pack.version ? ` v${pack.version}` : \"\";\n const state = pack.enabled === false ? \"\u5173\" : \"\u5F00\";\n return `${folderBit}${name}${version}\uFF08${state}\uFF09`;\n}\n\n/** \u8868\u683C\u5355\u5143\u683C\uFF1A\u53BB\u6389\u57FA\u5CA9\u7248\u989C\u8272\u7801\uFF0C\u5E76\u8F6C\u4E49\u4F1A\u62C6\u5217\u7684\u7AD6\u7EBF\u3002 */\nfunction markdownCell(value: string): string {\n const text = value.replace(/\u00A7[0-9a-zA-Z]/g, \"\").replace(/\\|/g, \"\\\\|\").replace(/\\r?\\n/g, \" \").trim();\n return text || \"\u2014\";\n}\n\n/** \u4E0E\u7EAF\u6587\u672C\u5217\u8868\u540C\u4E00\u5957\u540D\u79F0\u56DE\u9000\uFF1A\u8BED\u8A00\u952E\u6B8B\u7559\u65F6\u7528\u6587\u4EF6\u5939\u540D\u3002 */\nfunction packFields(pack: WorldPackView): { state: string; name: string; version: string } {\n const resolved = String(pack.name || \"\").trim();\n const folder = String(pack.folder_name || \"\").trim();\n const name =\n !resolved || resolved.startsWith(\"pack.\") || resolved === \"pack\"\n ? folder || pack.pack_id || \"\u672A\u547D\u540D\"\n : resolved;\n return {\n state: pack.enabled === false ? \"\u5173\" : \"\u5F00\",\n name: markdownCell(name),\n version: markdownCell(pack.version || \"\u2014\"),\n };\n}\n\nfunction markdownTable(rows: Array<{ state: string; name: string; version: string }>): string[] {\n return [\n \"| \u72B6\u6001 | \u540D\u79F0 | \u7248\u672C |\",\n \"| --- | --- | --- |\",\n ...rows.map((row) => `| ${row.state} | ${row.name} | ${row.version} |`),\n ];\n}\n\n/**\n * \u4E16\u754C\u5305\u7684 Markdown \u6B63\u6587\u3002\u884C\u4E3A\u5305\u3001\u8D44\u6E90\u5305\u5404\u4E00\u5F20\u8868\uFF0C\u5DF2\u542F\u7528\u6392\u5728\u524D\u9762\u3002\n * \u8BFB\u4E0D\u5230\u4E16\u754C\u65F6\u53EA\u7ED9\u8BF4\u660E\uFF0C\u4E0D\u8F93\u51FA\u7A7A\u8868\u3002\n */\nexport function formatPackMarkdown(packs: WorldPackView[], worldNote?: string): string {\n if (worldNote === \"bds_unconfigured\") {\n return [\"## \u4E16\u754C\u5305\", \"\", \"\u672A\u914D\u7F6E BDS \u8DEF\u5F84\uFF0C\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u4E16\u754C\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\u3002\"].join(\"\\n\");\n }\n if (worldNote === \"world_unread\") {\n return [\"## \u4E16\u754C\u5305\", \"\", \"\u4E16\u754C\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\u6682\u65F6\u8BFB\u4E0D\u51FA\u6765\u3002\"].join(\"\\n\");\n }\n const sections: Array<{ kind: \"behavior\" | \"resource\"; title: string; empty: string }> = [\n { kind: \"behavior\", title: \"\u884C\u4E3A\u5305\", empty: \"\u4E16\u754C\u91CC\u6CA1\u6709\u884C\u4E3A\u5305\u3002\" },\n { kind: \"resource\", title: \"\u8D44\u6E90\u5305\", empty: \"\u4E16\u754C\u91CC\u6CA1\u6709\u8D44\u6E90\u5305\u3002\" },\n ];\n const lines = [\"## \u4E16\u754C\u5305\", \"\"];\n for (const section of sections) {\n const group = packs.filter((pack) => (pack.kind ?? \"resource\") === section.kind);\n const enabled = group.filter((pack) => pack.enabled !== false);\n const disabled = group.filter((pack) => pack.enabled === false);\n lines.push(`### ${section.title}`, \"\");\n if (!group.length) {\n lines.push(section.empty, \"\");\n continue;\n }\n lines.push(`\u5DF2\u542F\u7528 ${enabled.length}\uFF0C\u672A\u542F\u7528 ${disabled.length}`, \"\");\n lines.push(...markdownTable([...enabled, ...disabled].map(packFields)), \"\");\n }\n return lines.join(\"\\n\").trimEnd();\n}\n\n/**\n * \u4E16\u754C\u5305\u67E5\u8BE2\u6B63\u6587\u3002\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\u5206\u5F00\u5C55\u793A\uFF0C\u5DF2\u542F\u7528\u6392\u5728\u524D\u9762\u3002\n * worldNote \u6765\u81EA db-server\uFF1A\u672A\u914D\u7F6E BDS \u6216\u4E16\u754C\u76EE\u5F55\u8BFB\u5931\u8D25\u65F6\u53EA\u8BF4\u660E\u539F\u56E0\u3002\n */\nexport function formatPackLines(packs: WorldPackView[], worldNote?: string): string[] {\n if (worldNote === \"bds_unconfigured\") return [\"\u672A\u914D\u7F6E BDS \u8DEF\u5F84\uFF0C\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u4E16\u754C\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\u3002\"];\n if (worldNote === \"world_unread\") return [\"\u4E16\u754C\u884C\u4E3A\u5305\u548C\u8D44\u6E90\u5305\u6682\u65F6\u8BFB\u4E0D\u51FA\u6765\u3002\"];\n const sections: Array<{ kind: \"behavior\" | \"resource\"; title: string; empty: string }> = [\n { kind: \"behavior\", title: \"\u3010\u884C\u4E3A\u5305\u3011\", empty: \"\u4E16\u754C\u91CC\u6CA1\u6709\u884C\u4E3A\u5305\u3002\" },\n { kind: \"resource\", title: \"\u3010\u8D44\u6E90\u5305\u3011\", empty: \"\u4E16\u754C\u91CC\u6CA1\u6709\u8D44\u6E90\u5305\u3002\" },\n ];\n const lines: string[] = [];\n for (const section of sections) {\n const group = packs.filter((pack) => (pack.kind ?? \"resource\") === section.kind);\n const enabled = group.filter((pack) => pack.enabled !== false);\n const disabled = group.filter((pack) => pack.enabled === false);\n if (lines.length) lines.push(\"\");\n lines.push(section.title);\n if (!group.length) {\n lines.push(section.empty);\n continue;\n }\n lines.push(`\u5DF2\u542F\u7528 ${enabled.length}\uFF0C\u672A\u542F\u7528 ${disabled.length}`);\n lines.push(...enabled.map(formatWorldPackLine), ...disabled.map(formatWorldPackLine));\n }\n return lines;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -25,10 +25,14 @@ function requestJson(ep, method, pathAndQuery, body) {
25
25
  });
26
26
  res.on("end", () => {
27
27
  const status = res.statusCode ?? 0;
28
+ if (status >= 500 || status === 401 || status === 404) {
29
+ reject(new Error(`db-server HTTP ${status}`));
30
+ return;
31
+ }
28
32
  try {
29
33
  resolve({ status, data: JSON.parse(buf) });
30
34
  } catch {
31
- reject(new Error(`db-server \u975E JSON (${status}): ${buf.slice(0, 120)}`));
35
+ reject(new Error(`db-server \u975E JSON (${status})`));
32
36
  }
33
37
  });
34
38
  });
@@ -42,6 +46,14 @@ async function fetchSfmcStatus(ep) {
42
46
  const { data } = await requestJson(ep, "GET", "/api/sfmc/status");
43
47
  return data;
44
48
  }
49
+ async function fetchQqEventSettings(ep) {
50
+ const { data } = await requestJson(ep, "GET", "/api/sfmc/qq/events/settings");
51
+ return data;
52
+ }
53
+ async function postQqEventSettings(ep, body) {
54
+ const { data } = await requestJson(ep, "POST", "/api/sfmc/qq/events/settings", body);
55
+ return data;
56
+ }
45
57
  async function postJoinRequest(ep, body) {
46
58
  return requestJson(ep, "POST", "/api/sfmc/qq/join/request", body);
47
59
  }
@@ -60,9 +72,6 @@ async function fetchJoinPending(ep, openid, asGroupAdmin = false) {
60
72
  const { data } = await requestJson(ep, "GET", q);
61
73
  return data;
62
74
  }
63
- async function postAdminKick(ep, body) {
64
- return requestJson(ep, "POST", "/api/sfmc/qq/admin/kick", body);
65
- }
66
75
  async function fetchBindMe(ep, openid) {
67
76
  const q = `/api/sfmc/qq/bind/me?openid=${encodeURIComponent(openid)}`;
68
77
  const { data } = await requestJson(ep, "GET", q);
@@ -71,19 +80,25 @@ async function fetchBindMe(ep, openid) {
71
80
  async function postBindRequest(ep, body) {
72
81
  return requestJson(ep, "POST", "/api/sfmc/qq/bind/request", body);
73
82
  }
83
+ async function fetchContent(ep) {
84
+ const { data } = await requestJson(ep, "GET", "/api/sfmc/content");
85
+ return data;
86
+ }
74
87
  async function postBindUnbind(ep, body) {
75
88
  return requestJson(ep, "POST", "/api/sfmc/qq/bind/unbind", body);
76
89
  }
77
90
  export {
78
91
  fetchBindMe,
92
+ fetchContent,
79
93
  fetchJoinPending,
80
94
  fetchJoinSettings,
95
+ fetchQqEventSettings,
81
96
  fetchSfmcStatus,
82
- postAdminKick,
83
97
  postBindRequest,
84
98
  postBindUnbind,
85
99
  postJoinDecide,
86
100
  postJoinRequest,
87
- postJoinSettings
101
+ postJoinSettings,
102
+ postQqEventSettings
88
103
  };
89
104
  //# sourceMappingURL=db-api.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/db-api.ts"],
4
- "sourcesContent": ["/**\n * commands/db-api.ts \u2014 qq-bridge \u8C03 db-server \u5E73\u53F0 API\uFF08status / bind\uFF09\n */\n\nimport { request as httpRequest, type RequestOptions } from \"node:http\";\n\nexport type DbEndpoint = { host: string; port: number };\n\nconst TIMEOUT_MS = 5_000;\n\nfunction requestJson<T>(\n ep: DbEndpoint,\n method: string,\n pathAndQuery: string,\n body?: unknown\n): Promise<{ status: number; data: T }> {\n const payload = body === undefined ? undefined : JSON.stringify(body);\n const options: RequestOptions = {\n hostname: ep.host,\n port: ep.port,\n path: pathAndQuery,\n method,\n headers: {\n Accept: \"application/json\",\n ...(payload\n ? {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(payload),\n }\n : {}),\n },\n timeout: TIMEOUT_MS,\n };\n return new Promise((resolve, reject) => {\n const req = httpRequest(options, (res) => {\n let buf = \"\";\n res.setEncoding(\"utf-8\");\n res.on(\"data\", (c: string) => {\n buf += c;\n });\n res.on(\"end\", () => {\n const status = res.statusCode ?? 0;\n try {\n resolve({ status, data: JSON.parse(buf) as T });\n } catch {\n reject(new Error(`db-server \u975E JSON (${status}): ${buf.slice(0, 120)}`));\n }\n });\n });\n req.on(\"timeout\", () => req.destroy(new Error(`db-server \u8D85\u65F6 ${TIMEOUT_MS}ms`)));\n req.on(\"error\", reject);\n if (payload) req.write(payload);\n req.end();\n });\n}\n\nexport type SfmcHostStatus = {\n hostname?: string;\n platform?: string;\n arch?: string;\n release?: string;\n uptimeSec?: number;\n uptimeText?: string;\n cpu?: { model?: string; cores?: number };\n memory?: { totalMb?: number; freeMb?: number; usedMb?: number; usedPercent?: number };\n loadavg?: [number, number, number];\n};\n\nexport type SfmcProcessStatus = {\n pid?: number;\n running?: boolean;\n uptimeSec?: number | null;\n uptimeText?: string;\n state?: \"running\" | \"stopped\";\n};\n\nexport type SfmcStatusResponse = {\n online?: Array<{ id?: string; name?: string }>;\n world?: { day?: number; difficulty?: string } | null;\n updatedAt?: number;\n note?: string;\n host?: SfmcHostStatus | null;\n processes?: {\n db?: SfmcProcessStatus;\n bds?: SfmcProcessStatus;\n } | null;\n};\n\nexport async function fetchSfmcStatus(ep: DbEndpoint): Promise<SfmcStatusResponse> {\n const { data } = await requestJson<SfmcStatusResponse>(ep, \"GET\", \"/api/sfmc/status\");\n return data;\n}\n\nexport type JoinRequestResponse = {\n success?: boolean;\n id?: string;\n player_name?: string;\n status?: string;\n auto_approved?: boolean;\n admin_notify?: boolean;\n note?: string;\n error?: string;\n};\n\nexport async function postJoinRequest(\n ep: DbEndpoint,\n body: { openid: string; player_name: string; qq_backend: string }\n): Promise<{ status: number; data: JoinRequestResponse }> {\n return requestJson(ep, \"POST\", \"/api/sfmc/qq/join/request\", body);\n}\n\nexport type JoinSettingsResponse = {\n success?: boolean;\n allowlist_enabled?: boolean;\n require_approval?: boolean;\n treat_group_admins_as_admins?: boolean;\n error?: string;\n note?: string;\n};\n\nexport async function fetchJoinSettings(ep: DbEndpoint): Promise<JoinSettingsResponse> {\n const { data } = await requestJson<JoinSettingsResponse>(ep, \"GET\", \"/api/sfmc/qq/join/settings\");\n return data;\n}\n\nexport async function postJoinSettings(\n ep: DbEndpoint,\n body: {\n openid: string;\n as_group_admin?: boolean;\n allowlist_enabled?: boolean;\n require_approval?: boolean;\n }\n): Promise<{ status: number; data: JoinSettingsResponse }> {\n return requestJson(ep, \"POST\", \"/api/sfmc/qq/join/settings\", body);\n}\n\nexport type JoinDecideResponse = {\n success?: boolean;\n id?: string;\n status?: string;\n player_name?: string;\n applicant_openid?: string;\n error?: string;\n};\n\nexport async function postJoinDecide(\n ep: DbEndpoint,\n body: {\n id: string;\n decision: \"approve\" | \"reject\";\n decided_by: string;\n as_group_admin?: boolean;\n }\n): Promise<{ status: number; data: JoinDecideResponse }> {\n return requestJson(ep, \"POST\", \"/api/sfmc/qq/join/decide\", body);\n}\n\nexport async function fetchJoinPending(\n ep: DbEndpoint,\n openid: string,\n asGroupAdmin = false\n): Promise<{\n success?: boolean;\n pending?: Array<{ id?: string; player_name?: string; applicant_openid?: string }>;\n error?: string;\n}> {\n const q =\n `/api/sfmc/qq/join/pending?openid=${encodeURIComponent(openid)}` +\n (asGroupAdmin ? \"&as_group_admin=true\" : \"\");\n const { data } = await requestJson(ep, \"GET\", q);\n return data;\n}\n\nexport async function postAdminKick(\n ep: DbEndpoint,\n body: { openid: string; target_name: string; reason?: string; as_group_admin?: boolean }\n): Promise<{ status: number; data: { success?: boolean; id?: string; error?: string } }> {\n return requestJson(ep, \"POST\", \"/api/sfmc/qq/admin/kick\", body);\n}\n\nexport type BindMeResponse = {\n success?: boolean;\n bound?: boolean;\n binding?: {\n player_name?: string;\n player_xuid?: string;\n qq_user_openid?: string;\n bound_at?: number;\n } | null;\n};\n\nexport async function fetchBindMe(ep: DbEndpoint, openid: string): Promise<BindMeResponse> {\n const q = `/api/sfmc/qq/bind/me?openid=${encodeURIComponent(openid)}`;\n const { data } = await requestJson<BindMeResponse>(ep, \"GET\", q);\n return data;\n}\n\nexport type BindRequestResponse = {\n success?: boolean;\n code?: string;\n expires_at?: number;\n ttl_ms?: number;\n error?: string;\n player_name?: string;\n};\n\nexport async function postBindRequest(\n ep: DbEndpoint,\n body: { openid: string; qq_backend: string }\n): Promise<{ status: number; data: BindRequestResponse }> {\n return requestJson<BindRequestResponse>(ep, \"POST\", \"/api/sfmc/qq/bind/request\", body);\n}\n\nexport type BindUnbindResponse = {\n success?: boolean;\n unbound?: boolean;\n error?: string;\n};\n\nexport async function postBindUnbind(\n ep: DbEndpoint,\n body: { openid: string }\n): Promise<{ status: number; data: BindUnbindResponse }> {\n return requestJson<BindUnbindResponse>(ep, \"POST\", \"/api/sfmc/qq/bind/unbind\", body);\n}\n"],
5
- "mappings": "AAIA,SAAS,WAAW,mBAAwC;AAI5D,MAAM,aAAa;AAEnB,SAAS,YACP,IACA,QACA,cACA,MACsC;AACtC,QAAM,UAAU,SAAS,SAAY,SAAY,KAAK,UAAU,IAAI;AACpE,QAAM,UAA0B;AAAA,IAC9B,UAAU,GAAG;AAAA,IACb,MAAM,GAAG;AAAA,IACT,MAAM;AAAA,IACN;AAAA,IACA,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,GAAI,UACA;AAAA,QACE,gBAAgB;AAAA,QAChB,kBAAkB,OAAO,WAAW,OAAO;AAAA,MAC7C,IACA,CAAC;AAAA,IACP;AAAA,IACA,SAAS;AAAA,EACX;AACA,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,MAAM,YAAY,SAAS,CAAC,QAAQ;AACxC,UAAI,MAAM;AACV,UAAI,YAAY,OAAO;AACvB,UAAI,GAAG,QAAQ,CAAC,MAAc;AAC5B,eAAO;AAAA,MACT,CAAC;AACD,UAAI,GAAG,OAAO,MAAM;AAClB,cAAM,SAAS,IAAI,cAAc;AACjC,YAAI;AACF,kBAAQ,EAAE,QAAQ,MAAM,KAAK,MAAM,GAAG,EAAO,CAAC;AAAA,QAChD,QAAQ;AACN,iBAAO,IAAI,MAAM,0BAAqB,MAAM,MAAM,IAAI,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;AAAA,QACxE;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AACD,QAAI,GAAG,WAAW,MAAM,IAAI,QAAQ,IAAI,MAAM,0BAAgB,UAAU,IAAI,CAAC,CAAC;AAC9E,QAAI,GAAG,SAAS,MAAM;AACtB,QAAI,QAAS,KAAI,MAAM,OAAO;AAC9B,QAAI,IAAI;AAAA,EACV,CAAC;AACH;AAkCA,eAAsB,gBAAgB,IAA6C;AACjF,QAAM,EAAE,KAAK,IAAI,MAAM,YAAgC,IAAI,OAAO,kBAAkB;AACpF,SAAO;AACT;AAaA,eAAsB,gBACpB,IACA,MACwD;AACxD,SAAO,YAAY,IAAI,QAAQ,6BAA6B,IAAI;AAClE;AAWA,eAAsB,kBAAkB,IAA+C;AACrF,QAAM,EAAE,KAAK,IAAI,MAAM,YAAkC,IAAI,OAAO,4BAA4B;AAChG,SAAO;AACT;AAEA,eAAsB,iBACpB,IACA,MAMyD;AACzD,SAAO,YAAY,IAAI,QAAQ,8BAA8B,IAAI;AACnE;AAWA,eAAsB,eACpB,IACA,MAMuD;AACvD,SAAO,YAAY,IAAI,QAAQ,4BAA4B,IAAI;AACjE;AAEA,eAAsB,iBACpB,IACA,QACA,eAAe,OAKd;AACD,QAAM,IACJ,oCAAoC,mBAAmB,MAAM,CAAC,MAC7D,eAAe,yBAAyB;AAC3C,QAAM,EAAE,KAAK,IAAI,MAAM,YAAY,IAAI,OAAO,CAAC;AAC/C,SAAO;AACT;AAEA,eAAsB,cACpB,IACA,MACuF;AACvF,SAAO,YAAY,IAAI,QAAQ,2BAA2B,IAAI;AAChE;AAaA,eAAsB,YAAY,IAAgB,QAAyC;AACzF,QAAM,IAAI,+BAA+B,mBAAmB,MAAM,CAAC;AACnE,QAAM,EAAE,KAAK,IAAI,MAAM,YAA4B,IAAI,OAAO,CAAC;AAC/D,SAAO;AACT;AAWA,eAAsB,gBACpB,IACA,MACwD;AACxD,SAAO,YAAiC,IAAI,QAAQ,6BAA6B,IAAI;AACvF;AAQA,eAAsB,eACpB,IACA,MACuD;AACvD,SAAO,YAAgC,IAAI,QAAQ,4BAA4B,IAAI;AACrF;",
4
+ "sourcesContent": ["/**\n * commands/db-api.ts \u2014 qq-bridge \u8C03 db-server \u5E73\u53F0 API\uFF08status / bind\uFF09\n */\n\nimport { request as httpRequest, type RequestOptions } from \"node:http\";\n\nexport type DbEndpoint = { host: string; port: number };\n\nconst TIMEOUT_MS = 5_000;\n\nfunction requestJson<T>(\n ep: DbEndpoint,\n method: string,\n pathAndQuery: string,\n body?: unknown\n): Promise<{ status: number; data: T }> {\n const payload = body === undefined ? undefined : JSON.stringify(body);\n const options: RequestOptions = {\n hostname: ep.host,\n port: ep.port,\n path: pathAndQuery,\n method,\n headers: {\n Accept: \"application/json\",\n ...(payload\n ? {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(payload),\n }\n : {}),\n },\n timeout: TIMEOUT_MS,\n };\n return new Promise((resolve, reject) => {\n const req = httpRequest(options, (res) => {\n let buf = \"\";\n res.setEncoding(\"utf-8\");\n res.on(\"data\", (c: string) => {\n buf += c;\n });\n res.on(\"end\", () => {\n const status = res.statusCode ?? 0;\n if (status >= 500 || status === 401 || status === 404) {\n reject(new Error(`db-server HTTP ${status}`));\n return;\n }\n try {\n resolve({ status, data: JSON.parse(buf) as T });\n } catch {\n reject(new Error(`db-server \u975E JSON (${status})`));\n }\n });\n });\n req.on(\"timeout\", () => req.destroy(new Error(`db-server \u8D85\u65F6 ${TIMEOUT_MS}ms`)));\n req.on(\"error\", reject);\n if (payload) req.write(payload);\n req.end();\n });\n}\n\nexport type SfmcHostStatus = {\n hostname?: string;\n platform?: string;\n arch?: string;\n release?: string;\n uptimeSec?: number;\n uptimeText?: string;\n cpu?: { model?: string; cores?: number };\n memory?: { totalMb?: number; freeMb?: number; usedMb?: number; usedPercent?: number };\n loadavg?: [number, number, number];\n};\n\nexport type SfmcProcessStatus = {\n version?: string;\n pid?: number;\n running?: boolean;\n uptimeSec?: number | null;\n uptimeText?: string;\n state?: \"running\" | \"stopped\";\n};\n\nexport type SfmcStatusResponse = {\n online?: Array<{ id?: string; name?: string }>;\n world?: { day?: number; difficulty?: string } | null;\n updatedAt?: number;\n note?: string;\n host?: SfmcHostStatus | null;\n processes?: {\n db?: SfmcProcessStatus;\n bds?: SfmcProcessStatus;\n } | null;\n};\n\nexport async function fetchSfmcStatus(ep: DbEndpoint): Promise<SfmcStatusResponse> {\n const { data } = await requestJson<SfmcStatusResponse>(ep, \"GET\", \"/api/sfmc/status\");\n return data;\n}\n\nexport type QqEventSettings = {\n enabled: boolean;\n join: boolean;\n leave: boolean;\n death: boolean;\n crash: boolean;\n start: boolean;\n stop: boolean;\n window_sec: number;\n};\n\nexport type QqEventSettingsResponse = {\n success: boolean;\n settings?: QqEventSettings;\n error?: string;\n};\n\nexport async function fetchQqEventSettings(ep: DbEndpoint): Promise<QqEventSettingsResponse> {\n const { data } = await requestJson<QqEventSettingsResponse>(ep, \"GET\", \"/api/sfmc/qq/events/settings\");\n return data;\n}\n\nexport async function postQqEventSettings(\n ep: DbEndpoint,\n body: { openid: string; as_group_admin: boolean; field: keyof QqEventSettings; value: boolean | number }\n): Promise<QqEventSettingsResponse> {\n const { data } = await requestJson<QqEventSettingsResponse>(ep, \"POST\", \"/api/sfmc/qq/events/settings\", body);\n return data;\n}\n\nexport type JoinRequestResponse = {\n success?: boolean;\n id?: string;\n player_name?: string;\n status?: string;\n auto_approved?: boolean;\n admin_notify?: boolean;\n note?: string;\n error?: string;\n};\n\nexport async function postJoinRequest(\n ep: DbEndpoint,\n body: { openid: string; player_name: string; qq_backend: string }\n): Promise<{ status: number; data: JoinRequestResponse }> {\n return requestJson(ep, \"POST\", \"/api/sfmc/qq/join/request\", body);\n}\n\nexport type JoinSettingsResponse = {\n success?: boolean;\n allowlist_enabled?: boolean;\n require_approval?: boolean;\n treat_group_admins_as_admins?: boolean;\n error?: string;\n note?: string;\n};\n\nexport async function fetchJoinSettings(ep: DbEndpoint): Promise<JoinSettingsResponse> {\n const { data } = await requestJson<JoinSettingsResponse>(ep, \"GET\", \"/api/sfmc/qq/join/settings\");\n return data;\n}\n\nexport async function postJoinSettings(\n ep: DbEndpoint,\n body: {\n openid: string;\n as_group_admin?: boolean;\n allowlist_enabled?: boolean;\n require_approval?: boolean;\n }\n): Promise<{ status: number; data: JoinSettingsResponse }> {\n return requestJson(ep, \"POST\", \"/api/sfmc/qq/join/settings\", body);\n}\n\nexport type JoinDecideResponse = {\n success?: boolean;\n id?: string;\n status?: string;\n player_name?: string;\n applicant_openid?: string;\n error?: string;\n};\n\nexport async function postJoinDecide(\n ep: DbEndpoint,\n body: {\n id: string;\n decision: \"approve\" | \"reject\";\n decided_by: string;\n as_group_admin?: boolean;\n }\n): Promise<{ status: number; data: JoinDecideResponse }> {\n return requestJson(ep, \"POST\", \"/api/sfmc/qq/join/decide\", body);\n}\n\nexport async function fetchJoinPending(\n ep: DbEndpoint,\n openid: string,\n asGroupAdmin = false\n): Promise<{\n success?: boolean;\n pending?: Array<{ id?: string; player_name?: string; applicant_openid?: string }>;\n error?: string;\n}> {\n const q =\n `/api/sfmc/qq/join/pending?openid=${encodeURIComponent(openid)}` + (asGroupAdmin ? \"&as_group_admin=true\" : \"\");\n const { data } = await requestJson<Awaited<ReturnType<typeof fetchJoinPending>>>(ep, \"GET\", q);\n return data;\n}\n\nexport type BindMeResponse = {\n success?: boolean;\n bound?: boolean;\n binding?: {\n player_name?: string;\n player_xuid?: string;\n qq_user_openid?: string;\n bound_at?: number;\n } | null;\n /** \u5DF2\u7ED1\u5B9A\u65F6\u9644\u5E26\u7ECF\u6D4E\u4F59\u989D\u548C\u5728\u7EBF\u65F6\u957F\u3002\u65E7 db \u6CA1\u6709\u8FD9\u4E2A\u5B57\u6BB5\u3002 */\n profile?: {\n unit?: string;\n balance?: number | null;\n today_text?: string;\n month_text?: string;\n total_text?: string;\n } | null;\n};\n\nexport async function fetchBindMe(ep: DbEndpoint, openid: string): Promise<BindMeResponse> {\n const q = `/api/sfmc/qq/bind/me?openid=${encodeURIComponent(openid)}`;\n const { data } = await requestJson<BindMeResponse>(ep, \"GET\", q);\n return data;\n}\n\nexport type BindRequestResponse = {\n success?: boolean;\n code?: string;\n expires_at?: number;\n ttl_ms?: number;\n error?: string;\n player_name?: string;\n};\n\nexport async function postBindRequest(\n ep: DbEndpoint,\n body: { openid: string; qq_backend: string }\n): Promise<{ status: number; data: BindRequestResponse }> {\n return requestJson<BindRequestResponse>(ep, \"POST\", \"/api/sfmc/qq/bind/request\", body);\n}\n\nexport type BindUnbindResponse = {\n success?: boolean;\n unbound?: boolean;\n error?: string;\n};\n\nexport type ContentSnapshotResponse = {\n success?: boolean;\n error?: string;\n note?: \"bds_unconfigured\" | \"world_unread\";\n modules?: Array<{\n id: string;\n display_name?: string;\n enabled?: boolean;\n has_resource_pack?: boolean;\n }>;\n /** \u884C\u4E3A\u5305\u4E0E\u8D44\u6E90\u5305\u3002name \u5DF2\u662F\u89E3\u6790\u540E\u7684\u663E\u793A\u540D\u3002 */\n packs?: Array<{\n kind?: \"behavior\" | \"resource\";\n name?: string;\n folder_name?: string;\n pack_id?: string;\n version?: string;\n enabled?: boolean;\n }>;\n resource_packs?: Array<{\n name?: string;\n pack_id?: string;\n version?: string;\n }>;\n};\n\n/** \u67E5\u8BE2\u6E38\u620F\u673A\u4E0A\u7684\u6A21\u5757\u4E0E\u4E16\u754C\u884C\u4E3A\u5305\u3001\u8D44\u6E90\u5305\u3002\u5F53\u524D\u7ED9 QQ\u300C\u6A21\u5757\u300D\u300C\u4E16\u754C\u5305\u300D\u4F7F\u7528\u3002 */\nexport async function fetchContent(ep: DbEndpoint): Promise<ContentSnapshotResponse> {\n const { data } = await requestJson<ContentSnapshotResponse>(ep, \"GET\", \"/api/sfmc/content\");\n return data;\n}\n\nexport async function postBindUnbind(\n ep: DbEndpoint,\n body: { openid: string }\n): Promise<{ status: number; data: BindUnbindResponse }> {\n return requestJson<BindUnbindResponse>(ep, \"POST\", \"/api/sfmc/qq/bind/unbind\", body);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }