@sfmc-bds/db-server 0.2.0-beta.4 → 0.2.0-beta.6

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 (143) hide show
  1. package/LICENSE +663 -0
  2. package/dist/domain/bridge.d.ts +57 -23
  3. package/dist/domain/bridge.d.ts.map +1 -1
  4. package/dist/domain/bridge.js +77 -6
  5. package/dist/domain/bridge.js.map +2 -2
  6. package/dist/domain/bridge.test.d.ts +2 -0
  7. package/dist/domain/bridge.test.d.ts.map +1 -0
  8. package/dist/domain/bridge.test.js +87 -0
  9. package/dist/domain/bridge.test.js.map +7 -0
  10. package/dist/domain/economy.d.ts +38 -7
  11. package/dist/domain/economy.d.ts.map +1 -1
  12. package/dist/domain/economy.js.map +2 -2
  13. package/dist/domain/messages-bridge-filter.test.d.ts +5 -0
  14. package/dist/domain/messages-bridge-filter.test.d.ts.map +1 -0
  15. package/dist/domain/messages-bridge-filter.test.js +20 -0
  16. package/dist/domain/messages-bridge-filter.test.js.map +7 -0
  17. package/dist/domain/qq-bind-status.test.d.ts +2 -0
  18. package/dist/domain/qq-bind-status.test.d.ts.map +1 -0
  19. package/dist/domain/qq-bind-status.test.js +211 -0
  20. package/dist/domain/qq-bind-status.test.js.map +7 -0
  21. package/dist/domain/qq-events.d.ts +84 -0
  22. package/dist/domain/qq-events.d.ts.map +1 -0
  23. package/dist/domain/qq-events.js +193 -0
  24. package/dist/domain/qq-events.js.map +7 -0
  25. package/dist/domain/qq-events.test.d.ts +5 -0
  26. package/dist/domain/qq-events.test.d.ts.map +1 -0
  27. package/dist/domain/qq-events.test.js +170 -0
  28. package/dist/domain/qq-events.test.js.map +7 -0
  29. package/dist/domain/qq-join.test.d.ts +2 -0
  30. package/dist/domain/qq-join.test.d.ts.map +1 -0
  31. package/dist/domain/qq-join.test.js +353 -0
  32. package/dist/domain/qq-join.test.js.map +7 -0
  33. package/dist/domain/schema.d.ts +17 -19
  34. package/dist/domain/schema.d.ts.map +1 -1
  35. package/dist/domain/schema.js +69 -0
  36. package/dist/domain/schema.js.map +2 -2
  37. package/dist/domain/system-status.d.ts +75 -0
  38. package/dist/domain/system-status.d.ts.map +1 -0
  39. package/dist/domain/system-status.js +181 -0
  40. package/dist/domain/system-status.js.map +7 -0
  41. package/dist/domain/system-status.test.d.ts +5 -0
  42. package/dist/domain/system-status.test.d.ts.map +1 -0
  43. package/dist/domain/system-status.test.js +19 -0
  44. package/dist/domain/system-status.test.js.map +7 -0
  45. package/dist/domain/transaction.d.ts +5 -4
  46. package/dist/domain/transaction.d.ts.map +1 -1
  47. package/dist/domain/transaction.js.map +2 -2
  48. package/dist/env.d.ts +7 -0
  49. package/dist/env.d.ts.map +1 -1
  50. package/dist/env.js +55 -3
  51. package/dist/env.js.map +2 -2
  52. package/dist/index.d.ts +0 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +105 -19
  55. package/dist/index.js.map +2 -2
  56. package/dist/lib/idempotency-store.d.ts +17 -11
  57. package/dist/lib/idempotency-store.d.ts.map +1 -1
  58. package/dist/lib/idempotency-store.js.map +2 -2
  59. package/dist/lib/idempotency.d.ts +3 -4
  60. package/dist/lib/idempotency.d.ts.map +1 -1
  61. package/dist/lib/idempotency.js.map +2 -2
  62. package/dist/lib/module-state.d.ts +38 -8
  63. package/dist/lib/module-state.d.ts.map +1 -1
  64. package/dist/lib/module-state.js.map +2 -2
  65. package/dist/lib/order-by.d.ts +8 -6
  66. package/dist/lib/order-by.d.ts.map +1 -1
  67. package/dist/lib/order-by.js.map +2 -2
  68. package/dist/lib/sql-helpers.d.ts +25 -13
  69. package/dist/lib/sql-helpers.d.ts.map +1 -1
  70. package/dist/lib/sql-helpers.js.map +2 -2
  71. package/dist/lib/sqlite.d.ts +14 -5
  72. package/dist/lib/sqlite.d.ts.map +1 -1
  73. package/dist/lib/sqlite.js.map +2 -2
  74. package/dist/manifest-loader.d.ts +5 -2
  75. package/dist/manifest-loader.d.ts.map +1 -1
  76. package/dist/manifest-loader.js +16 -6
  77. package/dist/manifest-loader.js.map +2 -2
  78. package/dist/manifest.d.ts +1 -2
  79. package/dist/manifest.d.ts.map +1 -1
  80. package/dist/manifest.js +13 -8
  81. package/dist/manifest.js.map +2 -2
  82. package/dist/project-root.d.ts +1 -1
  83. package/dist/project-root.d.ts.map +1 -1
  84. package/dist/project-root.js +2 -2
  85. package/dist/project-root.js.map +2 -2
  86. package/dist/routes/_shared.d.ts +14 -5
  87. package/dist/routes/_shared.d.ts.map +1 -1
  88. package/dist/routes/_shared.js.map +2 -2
  89. package/dist/routes/config.d.ts +8 -11
  90. package/dist/routes/config.d.ts.map +1 -1
  91. package/dist/routes/config.js +17 -23
  92. package/dist/routes/config.js.map +2 -2
  93. package/dist/routes/db-routes.d.ts +6 -0
  94. package/dist/routes/db-routes.d.ts.map +1 -1
  95. package/dist/routes/db-routes.js.map +2 -2
  96. package/dist/routes/messages.d.ts +6 -2
  97. package/dist/routes/messages.d.ts.map +1 -1
  98. package/dist/routes/messages.js +17 -3
  99. package/dist/routes/messages.js.map +2 -2
  100. package/dist/routes/module-config-routes.d.ts +13 -9
  101. package/dist/routes/module-config-routes.d.ts.map +1 -1
  102. package/dist/routes/module-config-routes.js.map +2 -2
  103. package/dist/routes/modules.d.ts +6 -0
  104. package/dist/routes/modules.d.ts.map +1 -1
  105. package/dist/routes/modules.js.map +2 -2
  106. package/dist/routes/qq-bind.d.ts +24 -0
  107. package/dist/routes/qq-bind.d.ts.map +1 -0
  108. package/dist/routes/qq-bind.js +179 -0
  109. package/dist/routes/qq-bind.js.map +7 -0
  110. package/dist/routes/qq-events.d.ts +20 -0
  111. package/dist/routes/qq-events.d.ts.map +1 -0
  112. package/dist/routes/qq-events.js +39 -0
  113. package/dist/routes/qq-events.js.map +7 -0
  114. package/dist/routes/qq-join.d.ts +46 -0
  115. package/dist/routes/qq-join.d.ts.map +1 -0
  116. package/dist/routes/qq-join.js +277 -0
  117. package/dist/routes/qq-join.js.map +7 -0
  118. package/dist/routes/service-routes.d.ts +6 -0
  119. package/dist/routes/service-routes.d.ts.map +1 -1
  120. package/dist/routes/service-routes.js.map +2 -2
  121. package/dist/routes/status.d.ts +19 -0
  122. package/dist/routes/status.d.ts.map +1 -0
  123. package/dist/routes/status.js +74 -0
  124. package/dist/routes/status.js.map +7 -0
  125. package/dist/schema-registry.d.ts +16 -15
  126. package/dist/schema-registry.d.ts.map +1 -1
  127. package/dist/schema-registry.js +7 -1
  128. package/dist/schema-registry.js.map +2 -2
  129. package/dist/server.d.ts +19 -0
  130. package/dist/server.d.ts.map +1 -1
  131. package/dist/server.js.map +2 -2
  132. package/dist/service-registry.d.ts +39 -9
  133. package/dist/service-registry.d.ts.map +1 -1
  134. package/dist/service-registry.js +30 -2
  135. package/dist/service-registry.js.map +2 -2
  136. package/dist/services/builtin-handlers.d.ts +27 -7
  137. package/dist/services/builtin-handlers.d.ts.map +1 -1
  138. package/dist/services/builtin-handlers.js.map +2 -2
  139. package/dist/tx-runner.d.ts +29 -3
  140. package/dist/tx-runner.d.ts.map +1 -1
  141. package/dist/tx-runner.js +29 -3
  142. package/dist/tx-runner.js.map +2 -2
  143. package/package.json +17 -15
@@ -1,20 +1,17 @@
1
1
  /**
2
- * domain/bridge.ts — MC → QQ 桥接
3
- *
4
- * db-server 收到 SAPI 上报的消息后,直接调 LLBot HTTP `/send_group_msg`
5
- * 把消息转发到 QQ 群。不再走中间 qq-bridge 进程。
2
+ * domain/bridge.ts — MC → QQ 桥接(双后端)
6
3
  *
7
4
  * 数据流:
8
5
  * SAPI ──POST──→ db-server:3001/api/sfmc/messages
9
- * └─ 写库 + forwardToQQBridge() ──HTTP──→ LLBot:3004/send_group_msg
10
- *
11
- * 事务描述:
12
- * - 无 DB 事务(本文件不操作 SQLite,只做 HTTP 出站转发)
6
+ * └─ 写库 + forwardToQQBridge()
7
+ * ├─ llbot → LLBot:3004/send_group_msg
8
+ * └─ official → OpenAPI /v2/groups/{openid}/messages
13
9
  *
14
- * 领域函数:
15
- * - makeLLBotConfig(env) 工厂:从 env 构造 LLBotConfig
16
- * - forwardToQQBridge() 转发单条 MC 消息到 LLBot;失败仅 warn,不抛错
10
+ * 事件推送复用 sendGroupOutbound()(正文原样,不加聊天前缀)。
11
+ * 失败仅 warn,不抛错、不重试(与历史 LLBot 行为一致)。
17
12
  */
13
+ import { type QqOfficialCredentials } from "@sfmc-bds/sdk/node/qq-official";
14
+ import type { QQBackend } from "@sfmc-bds/sdk/node/config";
18
15
  type LLBotConfig = {
19
16
  host: string;
20
17
  port: number;
@@ -22,27 +19,64 @@ type LLBotConfig = {
22
19
  groupId: string;
23
20
  prefix: string;
24
21
  };
22
+ export type OfficialOutboundConfig = {
23
+ backend: "official";
24
+ creds: QqOfficialCredentials;
25
+ groupOpenid: string;
26
+ prefix: string;
27
+ };
28
+ export type LlbotOutboundConfig = {
29
+ backend: "llbot";
30
+ llbot: LLBotConfig;
31
+ };
32
+ export type OutboundConfig = OfficialOutboundConfig | LlbotOutboundConfig;
25
33
  /**
26
- * 构造 LLBotConfig。允许显式传入(测试),默认从 env 推不出,
27
- * 所以调用方需自己把 env 里读到的值传进来。
34
+ * 构造 LLBot 桥接配置对象。
35
+ *
36
+ * @param env 环境变量或配置字典。
37
+ * @returns 规范化的 LLBotConfig 配置。
28
38
  */
29
39
  export declare function makeLLBotConfig(env: {
30
40
  LLBOT_HOST: string;
31
41
  LLBOT_PORT: number;
32
42
  LLBOT_TOKEN: string;
33
43
  QQ_GROUP_ID: string;
44
+ MCTOQQ_PREFIX?: string;
34
45
  }): LLBotConfig;
35
46
  /**
36
- * @description
37
- * @author Shiroha7z
38
- * @date 17/07/2026
39
- * @export
40
- * @param {LLBotConfig} config LLBot 连接信息(host/port/token/groupId/prefix)
41
- * @param {string} channelId MC 频道 ID(用于过滤 / 标记,目前仅做日志)
42
- * @param {string} fromName MC 玩家名
43
- * @param {string} content 消息正文
44
- * @param {string} fromId MC 玩家 ID
47
+ * 根据环境变量与配置组装出站配置(支持 official 官方开放平台与 llbot 双后端)。
48
+ *
49
+ * @param env 环境变量与配置字典。
50
+ * @returns 规范化的 OutboundConfig 出站配置。
51
+ */
52
+ export declare function makeOutboundConfig(env: {
53
+ QQ_BACKEND: QQBackend;
54
+ LLBOT_HOST: string;
55
+ LLBOT_PORT: number;
56
+ LLBOT_TOKEN: string;
57
+ QQ_GROUP_ID: string;
58
+ QQ_APP_ID: string;
59
+ QQ_APP_SECRET: string;
60
+ QQ_SANDBOX: boolean;
61
+ QQ_GROUP_OPENID: string;
62
+ MCTOQQ_PREFIX: string;
63
+ }): OutboundConfig;
64
+ /**
65
+ * 将文本内容直接发送至目标 QQ 群(供服务器事件通知使用,不附加玩家聊天前缀)。
66
+ *
67
+ * @param config 出站配置对象。
68
+ * @param text 待发送的文本内容。
69
+ */
70
+ export declare function sendGroupOutbound(config: OutboundConfig | LLBotConfig, text: string): void;
71
+ /**
72
+ * 将游戏内玩家聊天消息附加前缀后转发至 QQ 群。
73
+ *
74
+ * @param config 出站配置对象。
75
+ * @param channelId 来源频道 ID。
76
+ * @param fromName 消息发送者玩家名称。
77
+ * @param content 聊天消息正文。
78
+ * @param fromId 发送者唯一标识(如 XUID)。
45
79
  */
46
- export declare function forwardToQQBridge(config: LLBotConfig, channelId: string, fromName: string, content: string, fromId: string): void;
80
+ export declare function forwardToQQBridge(config: OutboundConfig | LLBotConfig, channelId: string, fromName: string, content: string, fromId: string): void;
47
81
  export {};
48
82
  //# sourceMappingURL=bridge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/domain/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,WAAW,CAQd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,IAAI,CA6CN"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/domain/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAI3D,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,qBAAqB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,sBAAsB,GAAG,mBAAmB,CAAC;AAE1E;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,WAAW,CAQd;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE;IACtC,UAAU,EAAE,SAAS,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,cAAc,CAkBjB;AAoED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAW1F;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,cAAc,GAAG,WAAW,EACpC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,IAAI,CAYN"}
@@ -1,4 +1,7 @@
1
1
  import { request } from "node:http";
2
+ import {
3
+ sendGroupTextMessage
4
+ } from "@sfmc-bds/sdk/node/qq-official";
2
5
  import { log } from "../lib/log.js";
3
6
  function makeLLBotConfig(env) {
4
7
  return {
@@ -6,15 +9,32 @@ function makeLLBotConfig(env) {
6
9
  port: env.LLBOT_PORT,
7
10
  token: env.LLBOT_TOKEN,
8
11
  groupId: env.QQ_GROUP_ID,
9
- prefix: "[MC]"
12
+ prefix: env.MCTOQQ_PREFIX ?? "[MC]"
10
13
  };
11
14
  }
12
- function forwardToQQBridge(config, channelId, fromName, content, fromId) {
15
+ function makeOutboundConfig(env) {
16
+ if (env.QQ_BACKEND === "llbot") {
17
+ return {
18
+ backend: "llbot",
19
+ llbot: makeLLBotConfig(env)
20
+ };
21
+ }
22
+ return {
23
+ backend: "official",
24
+ creds: {
25
+ appId: env.QQ_APP_ID,
26
+ appSecret: env.QQ_APP_SECRET,
27
+ sandbox: env.QQ_SANDBOX
28
+ },
29
+ groupOpenid: env.QQ_GROUP_OPENID,
30
+ prefix: env.MCTOQQ_PREFIX || "[MC]"
31
+ };
32
+ }
33
+ function sendViaLlbot(config, text, logCtx) {
13
34
  if (!config.groupId || config.groupId === "0") {
14
- log.warn(`QQ \u7FA4\u672A\u914D\u7F6E (qq_group_id),\u8DF3\u8FC7 MC\u2192QQ \u8F6C\u53D1 (channel=${channelId})`);
35
+ log.warn(`QQ \u7FA4\u672A\u914D\u7F6E (qq_group_id),\u8DF3\u8FC7 MC\u2192QQ (${logCtx})`);
15
36
  return;
16
37
  }
17
- const text = `${config.prefix} ${fromName}: ${content}`;
18
38
  const payload = JSON.stringify({
19
39
  group_id: parseInt(config.groupId, 10),
20
40
  message: [{ type: "text", data: { text } }]
@@ -40,7 +60,7 @@ function forwardToQQBridge(config, channelId, fromName, content, fromId) {
40
60
  res.on("end", () => {
41
61
  if (res.statusCode !== 200) {
42
62
  log.warn(
43
- `LLBot send_group_msg \u2192 ${res.statusCode}: ${String(body).slice(0, 200)} (from=${fromId}, channel=${channelId})`
63
+ `LLBot send_group_msg \u2192 ${res.statusCode}: ${String(body).slice(0, 200)} (${logCtx})`
44
64
  );
45
65
  }
46
66
  });
@@ -52,8 +72,59 @@ function forwardToQQBridge(config, channelId, fromName, content, fromId) {
52
72
  req.write(payload);
53
73
  req.end();
54
74
  }
75
+ function sendViaOfficial(config, text, logCtx) {
76
+ if (!config.groupOpenid) {
77
+ log.warn(`\u5B98\u65B9\u7FA4 openid \u672A\u914D\u7F6E (qq_group_openid),\u8DF3\u8FC7 MC\u2192QQ (${logCtx})`);
78
+ return;
79
+ }
80
+ if (!config.creds.appId || !config.creds.appSecret) {
81
+ log.warn(`\u5B98\u65B9 AppID/Secret \u672A\u914D\u7F6E,\u8DF3\u8FC7 MC\u2192QQ (${logCtx})`);
82
+ return;
83
+ }
84
+ void sendGroupTextMessage(config.creds, {
85
+ groupOpenid: config.groupOpenid,
86
+ content: text
87
+ }).then((result) => {
88
+ if (!result.ok) {
89
+ log.warn(`\u5B98\u65B9\u53D1\u7FA4\u5931\u8D25: ${result.error} (${logCtx}, status=${result.status})`);
90
+ }
91
+ });
92
+ }
93
+ function sendGroupOutbound(config, text) {
94
+ const logCtx = "outbound";
95
+ if (!("backend" in config)) {
96
+ sendViaLlbot(config, text, logCtx);
97
+ return;
98
+ }
99
+ if (config.backend === "llbot") {
100
+ sendViaLlbot(config.llbot, text, logCtx);
101
+ return;
102
+ }
103
+ sendViaOfficial(config, text, logCtx);
104
+ }
105
+ function forwardViaLlbot(config, channelId, fromName, content, fromId) {
106
+ const text = `${config.prefix} ${fromName}: ${content}`;
107
+ sendViaLlbot(config, text, `from=${fromId}, channel=${channelId}`);
108
+ }
109
+ function forwardViaOfficial(config, channelId, fromName, content, fromId) {
110
+ const text = `${config.prefix} ${fromName}: ${content}`;
111
+ sendViaOfficial(config, text, `from=${fromId}, channel=${channelId}`);
112
+ }
113
+ function forwardToQQBridge(config, channelId, fromName, content, fromId) {
114
+ if (!("backend" in config)) {
115
+ forwardViaLlbot(config, channelId, fromName, content, fromId);
116
+ return;
117
+ }
118
+ if (config.backend === "llbot") {
119
+ forwardViaLlbot(config.llbot, channelId, fromName, content, fromId);
120
+ return;
121
+ }
122
+ forwardViaOfficial(config, channelId, fromName, content, fromId);
123
+ }
55
124
  export {
56
125
  forwardToQQBridge,
57
- makeLLBotConfig
126
+ makeLLBotConfig,
127
+ makeOutboundConfig,
128
+ sendGroupOutbound
58
129
  };
59
130
  //# sourceMappingURL=bridge.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/domain/bridge.ts"],
4
- "sourcesContent": ["/**\n * domain/bridge.ts \u2014 MC \u2192 QQ \u6865\u63A5\n *\n * db-server \u6536\u5230 SAPI \u4E0A\u62A5\u7684\u6D88\u606F\u540E,\u76F4\u63A5\u8C03 LLBot HTTP `/send_group_msg`\n * \u628A\u6D88\u606F\u8F6C\u53D1\u5230 QQ \u7FA4\u3002\u4E0D\u518D\u8D70\u4E2D\u95F4 qq-bridge \u8FDB\u7A0B\u3002\n *\n * \u6570\u636E\u6D41:\n * SAPI \u2500\u2500POST\u2500\u2500\u2192 db-server:3001/api/sfmc/messages\n * \u2514\u2500 \u5199\u5E93 + forwardToQQBridge() \u2500\u2500HTTP\u2500\u2500\u2192 LLBot:3004/send_group_msg\n *\n * \u4E8B\u52A1\u63CF\u8FF0:\n * - \u65E0 DB \u4E8B\u52A1(\u672C\u6587\u4EF6\u4E0D\u64CD\u4F5C SQLite,\u53EA\u505A HTTP \u51FA\u7AD9\u8F6C\u53D1)\n *\n * \u9886\u57DF\u51FD\u6570:\n * - makeLLBotConfig(env) \u5DE5\u5382:\u4ECE env \u6784\u9020 LLBotConfig\n * - forwardToQQBridge() \u8F6C\u53D1\u5355\u6761 MC \u6D88\u606F\u5230 LLBot;\u5931\u8D25\u4EC5 warn,\u4E0D\u629B\u9519\n */\n\nimport { request } from \"node:http\";\n\nimport { log } from \"../lib/log.js\";\n\ntype LLBotConfig = {\n host: string;\n port: number;\n token: string;\n groupId: string;\n prefix: string;\n};\n\n/**\n * \u6784\u9020 LLBotConfig\u3002\u5141\u8BB8\u663E\u5F0F\u4F20\u5165(\u6D4B\u8BD5),\u9ED8\u8BA4\u4ECE env \u63A8\u4E0D\u51FA,\n * \u6240\u4EE5\u8C03\u7528\u65B9\u9700\u81EA\u5DF1\u628A env \u91CC\u8BFB\u5230\u7684\u503C\u4F20\u8FDB\u6765\u3002\n */\nexport function makeLLBotConfig(env: {\n LLBOT_HOST: string;\n LLBOT_PORT: number;\n LLBOT_TOKEN: string;\n QQ_GROUP_ID: string;\n}): LLBotConfig {\n return {\n host: env.LLBOT_HOST,\n port: env.LLBOT_PORT,\n token: env.LLBOT_TOKEN,\n groupId: env.QQ_GROUP_ID,\n prefix: \"[MC]\",\n };\n}\n\n/**\n * @description\n * @author Shiroha7z\n * @date 17/07/2026\n * @export\n * @param {LLBotConfig} config LLBot \u8FDE\u63A5\u4FE1\u606F(host/port/token/groupId/prefix)\n * @param {string} channelId MC \u9891\u9053 ID(\u7528\u4E8E\u8FC7\u6EE4 / \u6807\u8BB0,\u76EE\u524D\u4EC5\u505A\u65E5\u5FD7)\n * @param {string} fromName MC \u73A9\u5BB6\u540D\n * @param {string} content \u6D88\u606F\u6B63\u6587\n * @param {string} fromId MC \u73A9\u5BB6 ID\n */\nexport function forwardToQQBridge(\n config: LLBotConfig,\n channelId: string,\n fromName: string,\n content: string,\n fromId: string\n): void {\n if (!config.groupId || config.groupId === \"0\") {\n log.warn(`QQ \u7FA4\u672A\u914D\u7F6E (qq_group_id),\u8DF3\u8FC7 MC\u2192QQ \u8F6C\u53D1 (channel=${channelId})`);\n return;\n }\n\n const text = `${config.prefix} ${fromName}: ${content}`;\n const payload = JSON.stringify({\n group_id: parseInt(config.groupId, 10),\n message: [{ type: \"text\", data: { text } }],\n });\n\n const headers: Record<string, string | number> = {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(payload),\n };\n if (config.token) {\n headers[\"Authorization\"] = `Bearer ${config.token}`;\n }\n\n const req = request(\n {\n hostname: config.host,\n port: config.port,\n path: \"/send_group_msg\",\n method: \"POST\",\n headers,\n },\n (res) => {\n let body = \"\";\n res.on(\"data\", (c) => (body += c));\n res.on(\"end\", () => {\n if (res.statusCode !== 200) {\n log.warn(\n `LLBot send_group_msg \u2192 ${res.statusCode}: ${String(body).slice(0, 200)} (from=${fromId}, channel=${channelId})`\n );\n }\n });\n }\n );\n req.on(\"error\", (err) => {\n log.warn(`LLBot \u4E0D\u53EF\u8FBE (${config.host}:${config.port}): ${err.message}`);\n });\n req.write(payload);\n req.end();\n}\n"],
5
- "mappings": "AAkBA,SAAS,eAAe;AAExB,SAAS,WAAW;AAcb,SAAS,gBAAgB,KAKhB;AACd,SAAO;AAAA,IACL,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,OAAO,IAAI;AAAA,IACX,SAAS,IAAI;AAAA,IACb,QAAQ;AAAA,EACV;AACF;AAaO,SAAS,kBACd,QACA,WACA,UACA,SACA,QACM;AACN,MAAI,CAAC,OAAO,WAAW,OAAO,YAAY,KAAK;AAC7C,QAAI,KAAK,2FAA8C,SAAS,GAAG;AACnE;AAAA,EACF;AAEA,QAAM,OAAO,GAAG,OAAO,MAAM,IAAI,QAAQ,KAAK,OAAO;AACrD,QAAM,UAAU,KAAK,UAAU;AAAA,IAC7B,UAAU,SAAS,OAAO,SAAS,EAAE;AAAA,IACrC,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,EAAE,KAAK,EAAE,CAAC;AAAA,EAC5C,CAAC;AAED,QAAM,UAA2C;AAAA,IAC/C,gBAAgB;AAAA,IAChB,kBAAkB,OAAO,WAAW,OAAO;AAAA,EAC7C;AACA,MAAI,OAAO,OAAO;AAChB,YAAQ,eAAe,IAAI,UAAU,OAAO,KAAK;AAAA,EACnD;AAEA,QAAM,MAAM;AAAA,IACV;AAAA,MACE,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,MACb,MAAM;AAAA,MACN,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ;AACP,UAAI,OAAO;AACX,UAAI,GAAG,QAAQ,CAAC,MAAO,QAAQ,CAAE;AACjC,UAAI,GAAG,OAAO,MAAM;AAClB,YAAI,IAAI,eAAe,KAAK;AAC1B,cAAI;AAAA,YACF,+BAA0B,IAAI,UAAU,KAAK,OAAO,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,UAAU,MAAM,aAAa,SAAS;AAAA,UAC/G;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,MAAI,GAAG,SAAS,CAAC,QAAQ;AACvB,QAAI,KAAK,6BAAc,OAAO,IAAI,IAAI,OAAO,IAAI,MAAM,IAAI,OAAO,EAAE;AAAA,EACtE,CAAC;AACD,MAAI,MAAM,OAAO;AACjB,MAAI,IAAI;AACV;",
4
+ "sourcesContent": ["/**\n * domain/bridge.ts \u2014 MC \u2192 QQ \u6865\u63A5\uFF08\u53CC\u540E\u7AEF\uFF09\n *\n * \u6570\u636E\u6D41:\n * SAPI \u2500\u2500POST\u2500\u2500\u2192 db-server:3001/api/sfmc/messages\n * \u2514\u2500 \u5199\u5E93 + forwardToQQBridge()\n * \u251C\u2500 llbot \u2192 LLBot:3004/send_group_msg\n * \u2514\u2500 official \u2192 OpenAPI /v2/groups/{openid}/messages\n *\n * \u4E8B\u4EF6\u63A8\u9001\u590D\u7528 sendGroupOutbound()\uFF08\u6B63\u6587\u539F\u6837\uFF0C\u4E0D\u52A0\u804A\u5929\u524D\u7F00\uFF09\u3002\n * \u5931\u8D25\u4EC5 warn\uFF0C\u4E0D\u629B\u9519\u3001\u4E0D\u91CD\u8BD5\uFF08\u4E0E\u5386\u53F2 LLBot \u884C\u4E3A\u4E00\u81F4\uFF09\u3002\n */\n\nimport { request } from \"node:http\";\nimport {\n sendGroupTextMessage,\n type QqOfficialCredentials,\n} from \"@sfmc-bds/sdk/node/qq-official\";\nimport type { QQBackend } from \"@sfmc-bds/sdk/node/config\";\n\nimport { log } from \"../lib/log.js\";\n\ntype LLBotConfig = {\n host: string;\n port: number;\n token: string;\n groupId: string;\n prefix: string;\n};\n\nexport type OfficialOutboundConfig = {\n backend: \"official\";\n creds: QqOfficialCredentials;\n groupOpenid: string;\n prefix: string;\n};\n\nexport type LlbotOutboundConfig = {\n backend: \"llbot\";\n llbot: LLBotConfig;\n};\n\nexport type OutboundConfig = OfficialOutboundConfig | LlbotOutboundConfig;\n\n/**\n * \u6784\u9020 LLBot \u6865\u63A5\u914D\u7F6E\u5BF9\u8C61\u3002\n *\n * @param env \u73AF\u5883\u53D8\u91CF\u6216\u914D\u7F6E\u5B57\u5178\u3002\n * @returns \u89C4\u8303\u5316\u7684 LLBotConfig \u914D\u7F6E\u3002\n */\nexport function makeLLBotConfig(env: {\n LLBOT_HOST: string;\n LLBOT_PORT: number;\n LLBOT_TOKEN: string;\n QQ_GROUP_ID: string;\n MCTOQQ_PREFIX?: string;\n}): LLBotConfig {\n return {\n host: env.LLBOT_HOST,\n port: env.LLBOT_PORT,\n token: env.LLBOT_TOKEN,\n groupId: env.QQ_GROUP_ID,\n prefix: env.MCTOQQ_PREFIX ?? \"[MC]\",\n };\n}\n\n/**\n * \u6839\u636E\u73AF\u5883\u53D8\u91CF\u4E0E\u914D\u7F6E\u7EC4\u88C5\u51FA\u7AD9\u914D\u7F6E\uFF08\u652F\u6301 official \u5B98\u65B9\u5F00\u653E\u5E73\u53F0\u4E0E llbot \u53CC\u540E\u7AEF\uFF09\u3002\n *\n * @param env \u73AF\u5883\u53D8\u91CF\u4E0E\u914D\u7F6E\u5B57\u5178\u3002\n * @returns \u89C4\u8303\u5316\u7684 OutboundConfig \u51FA\u7AD9\u914D\u7F6E\u3002\n */\nexport function makeOutboundConfig(env: {\n QQ_BACKEND: QQBackend;\n LLBOT_HOST: string;\n LLBOT_PORT: number;\n LLBOT_TOKEN: string;\n QQ_GROUP_ID: string;\n QQ_APP_ID: string;\n QQ_APP_SECRET: string;\n QQ_SANDBOX: boolean;\n QQ_GROUP_OPENID: string;\n MCTOQQ_PREFIX: string;\n}): OutboundConfig {\n\n if (env.QQ_BACKEND === \"llbot\") {\n return {\n backend: \"llbot\",\n llbot: makeLLBotConfig(env),\n };\n }\n return {\n backend: \"official\",\n creds: {\n appId: env.QQ_APP_ID,\n appSecret: env.QQ_APP_SECRET,\n sandbox: env.QQ_SANDBOX,\n },\n groupOpenid: env.QQ_GROUP_OPENID,\n prefix: env.MCTOQQ_PREFIX || \"[MC]\",\n };\n}\n\nfunction sendViaLlbot(config: LLBotConfig, text: string, logCtx: string): void {\n if (!config.groupId || config.groupId === \"0\") {\n log.warn(`QQ \u7FA4\u672A\u914D\u7F6E (qq_group_id),\u8DF3\u8FC7 MC\u2192QQ (${logCtx})`);\n return;\n }\n\n const payload = JSON.stringify({\n group_id: parseInt(config.groupId, 10),\n message: [{ type: \"text\", data: { text } }],\n });\n\n const headers: Record<string, string | number> = {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(payload),\n };\n if (config.token) {\n headers[\"Authorization\"] = `Bearer ${config.token}`;\n }\n\n const req = request(\n {\n hostname: config.host,\n port: config.port,\n path: \"/send_group_msg\",\n method: \"POST\",\n headers,\n },\n (res) => {\n let body = \"\";\n res.on(\"data\", (c) => (body += c));\n res.on(\"end\", () => {\n if (res.statusCode !== 200) {\n log.warn(\n `LLBot send_group_msg \u2192 ${res.statusCode}: ${String(body).slice(0, 200)} (${logCtx})`\n );\n }\n });\n }\n );\n req.on(\"error\", (err) => {\n log.warn(`LLBot \u4E0D\u53EF\u8FBE (${config.host}:${config.port}): ${err.message}`);\n });\n req.write(payload);\n req.end();\n}\n\nfunction sendViaOfficial(config: OfficialOutboundConfig, text: string, logCtx: string): void {\n if (!config.groupOpenid) {\n log.warn(`\u5B98\u65B9\u7FA4 openid \u672A\u914D\u7F6E (qq_group_openid),\u8DF3\u8FC7 MC\u2192QQ (${logCtx})`);\n return;\n }\n if (!config.creds.appId || !config.creds.appSecret) {\n log.warn(`\u5B98\u65B9 AppID/Secret \u672A\u914D\u7F6E,\u8DF3\u8FC7 MC\u2192QQ (${logCtx})`);\n return;\n }\n\n void sendGroupTextMessage(config.creds, {\n groupOpenid: config.groupOpenid,\n content: text,\n }).then((result) => {\n if (!result.ok) {\n log.warn(`\u5B98\u65B9\u53D1\u7FA4\u5931\u8D25: ${result.error} (${logCtx}, status=${result.status})`);\n }\n });\n}\n\n/**\n * \u5C06\u6587\u672C\u5185\u5BB9\u76F4\u63A5\u53D1\u9001\u81F3\u76EE\u6807 QQ \u7FA4\uFF08\u4F9B\u670D\u52A1\u5668\u4E8B\u4EF6\u901A\u77E5\u4F7F\u7528\uFF0C\u4E0D\u9644\u52A0\u73A9\u5BB6\u804A\u5929\u524D\u7F00\uFF09\u3002\n *\n * @param config \u51FA\u7AD9\u914D\u7F6E\u5BF9\u8C61\u3002\n * @param text \u5F85\u53D1\u9001\u7684\u6587\u672C\u5185\u5BB9\u3002\n */\nexport function sendGroupOutbound(config: OutboundConfig | LLBotConfig, text: string): void {\n const logCtx = \"outbound\";\n if (!(\"backend\" in config)) {\n sendViaLlbot(config, text, logCtx);\n return;\n }\n if (config.backend === \"llbot\") {\n sendViaLlbot(config.llbot, text, logCtx);\n return;\n }\n sendViaOfficial(config, text, logCtx);\n}\n\nfunction forwardViaLlbot(\n config: LLBotConfig,\n channelId: string,\n fromName: string,\n content: string,\n fromId: string\n): void {\n const text = `${config.prefix} ${fromName}: ${content}`;\n sendViaLlbot(config, text, `from=${fromId}, channel=${channelId}`);\n}\n\nfunction forwardViaOfficial(\n config: OfficialOutboundConfig,\n channelId: string,\n fromName: string,\n content: string,\n fromId: string\n): void {\n const text = `${config.prefix} ${fromName}: ${content}`;\n sendViaOfficial(config, text, `from=${fromId}, channel=${channelId}`);\n}\n\n/**\n * \u5C06\u6E38\u620F\u5185\u73A9\u5BB6\u804A\u5929\u6D88\u606F\u9644\u52A0\u524D\u7F00\u540E\u8F6C\u53D1\u81F3 QQ \u7FA4\u3002\n *\n * @param config \u51FA\u7AD9\u914D\u7F6E\u5BF9\u8C61\u3002\n * @param channelId \u6765\u6E90\u9891\u9053 ID\u3002\n * @param fromName \u6D88\u606F\u53D1\u9001\u8005\u73A9\u5BB6\u540D\u79F0\u3002\n * @param content \u804A\u5929\u6D88\u606F\u6B63\u6587\u3002\n * @param fromId \u53D1\u9001\u8005\u552F\u4E00\u6807\u8BC6\uFF08\u5982 XUID\uFF09\u3002\n */\nexport function forwardToQQBridge(\n config: OutboundConfig | LLBotConfig,\n channelId: string,\n fromName: string,\n content: string,\n fromId: string\n): void {\n\n // \u517C\u5BB9\u65E7\u8C03\u7528\uFF1A\u76F4\u63A5\u4F20 LLBotConfig\n if (!(\"backend\" in config)) {\n forwardViaLlbot(config, channelId, fromName, content, fromId);\n return;\n }\n if (config.backend === \"llbot\") {\n forwardViaLlbot(config.llbot, channelId, fromName, content, fromId);\n return;\n }\n forwardViaOfficial(config, channelId, fromName, content, fromId);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bridge.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.test.d.ts","sourceRoot":"","sources":["../../src/domain/bridge.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,87 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { makeLLBotConfig, makeOutboundConfig, forwardToQQBridge } from "./bridge.js";
4
+ test("makeOutboundConfig\uFF1Aofficial / llbot \u5206\u652F", () => {
5
+ const official = makeOutboundConfig({
6
+ QQ_BACKEND: "official",
7
+ LLBOT_HOST: "127.0.0.1",
8
+ LLBOT_PORT: 3004,
9
+ LLBOT_TOKEN: "",
10
+ QQ_GROUP_ID: "123",
11
+ QQ_APP_ID: "app",
12
+ QQ_APP_SECRET: "sec",
13
+ QQ_SANDBOX: true,
14
+ QQ_GROUP_OPENID: "GOPEN",
15
+ MCTOQQ_PREFIX: "[MC]"
16
+ });
17
+ assert.equal(official.backend, "official");
18
+ if (official.backend === "official") {
19
+ assert.equal(official.groupOpenid, "GOPEN");
20
+ assert.equal(official.creds.sandbox, true);
21
+ assert.equal(official.prefix, "[MC]");
22
+ }
23
+ const llbot = makeOutboundConfig({
24
+ QQ_BACKEND: "llbot",
25
+ LLBOT_HOST: "127.0.0.1",
26
+ LLBOT_PORT: 3004,
27
+ LLBOT_TOKEN: "t",
28
+ QQ_GROUP_ID: "99",
29
+ QQ_APP_ID: "",
30
+ QQ_APP_SECRET: "",
31
+ QQ_SANDBOX: false,
32
+ QQ_GROUP_OPENID: "",
33
+ MCTOQQ_PREFIX: "[X]"
34
+ });
35
+ assert.equal(llbot.backend, "llbot");
36
+ if (llbot.backend === "llbot") {
37
+ assert.equal(llbot.llbot.groupId, "99");
38
+ assert.equal(llbot.llbot.prefix, "[X]");
39
+ }
40
+ });
41
+ test("makeLLBotConfig \u4F7F\u7528 mctoqq_prefix", () => {
42
+ const cfg = makeLLBotConfig({
43
+ LLBOT_HOST: "h",
44
+ LLBOT_PORT: 1,
45
+ LLBOT_TOKEN: "",
46
+ QQ_GROUP_ID: "1",
47
+ MCTOQQ_PREFIX: "[P]"
48
+ });
49
+ assert.equal(cfg.prefix, "[P]");
50
+ });
51
+ test("forwardToQQBridge official\uFF1A\u7F3A group_openid \u4E0D\u629B\u9519", () => {
52
+ assert.doesNotThrow(() => {
53
+ forwardToQQBridge(
54
+ {
55
+ backend: "official",
56
+ creds: { appId: "a", appSecret: "s" },
57
+ groupOpenid: "",
58
+ prefix: "[MC]"
59
+ },
60
+ "ch",
61
+ "Steve",
62
+ "hi",
63
+ "xuid"
64
+ );
65
+ });
66
+ });
67
+ test("forwardToQQBridge llbot\uFF1A\u7F3A\u7FA4\u53F7\u4E0D\u629B\u9519", () => {
68
+ assert.doesNotThrow(() => {
69
+ forwardToQQBridge(
70
+ {
71
+ backend: "llbot",
72
+ llbot: {
73
+ host: "127.0.0.1",
74
+ port: 3004,
75
+ token: "",
76
+ groupId: "0",
77
+ prefix: "[MC]"
78
+ }
79
+ },
80
+ "ch",
81
+ "Steve",
82
+ "hi",
83
+ "xuid"
84
+ );
85
+ });
86
+ });
87
+ //# sourceMappingURL=bridge.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/domain/bridge.test.ts"],
4
+ "sourcesContent": ["import assert from \"node:assert/strict\";\r\nimport test from \"node:test\";\r\nimport { makeLLBotConfig, makeOutboundConfig, forwardToQQBridge } from \"./bridge.js\";\r\n\r\ntest(\"makeOutboundConfig\uFF1Aofficial / llbot \u5206\u652F\", () => {\r\n const official = makeOutboundConfig({\r\n QQ_BACKEND: \"official\",\r\n LLBOT_HOST: \"127.0.0.1\",\r\n LLBOT_PORT: 3004,\r\n LLBOT_TOKEN: \"\",\r\n QQ_GROUP_ID: \"123\",\r\n QQ_APP_ID: \"app\",\r\n QQ_APP_SECRET: \"sec\",\r\n QQ_SANDBOX: true,\r\n QQ_GROUP_OPENID: \"GOPEN\",\r\n MCTOQQ_PREFIX: \"[MC]\",\r\n });\r\n assert.equal(official.backend, \"official\");\r\n if (official.backend === \"official\") {\r\n assert.equal(official.groupOpenid, \"GOPEN\");\r\n assert.equal(official.creds.sandbox, true);\r\n assert.equal(official.prefix, \"[MC]\");\r\n }\r\n\r\n const llbot = makeOutboundConfig({\r\n QQ_BACKEND: \"llbot\",\r\n LLBOT_HOST: \"127.0.0.1\",\r\n LLBOT_PORT: 3004,\r\n LLBOT_TOKEN: \"t\",\r\n QQ_GROUP_ID: \"99\",\r\n QQ_APP_ID: \"\",\r\n QQ_APP_SECRET: \"\",\r\n QQ_SANDBOX: false,\r\n QQ_GROUP_OPENID: \"\",\r\n MCTOQQ_PREFIX: \"[X]\",\r\n });\r\n assert.equal(llbot.backend, \"llbot\");\r\n if (llbot.backend === \"llbot\") {\r\n assert.equal(llbot.llbot.groupId, \"99\");\r\n assert.equal(llbot.llbot.prefix, \"[X]\");\r\n }\r\n});\r\n\r\ntest(\"makeLLBotConfig \u4F7F\u7528 mctoqq_prefix\", () => {\r\n const cfg = makeLLBotConfig({\r\n LLBOT_HOST: \"h\",\r\n LLBOT_PORT: 1,\r\n LLBOT_TOKEN: \"\",\r\n QQ_GROUP_ID: \"1\",\r\n MCTOQQ_PREFIX: \"[P]\",\r\n });\r\n assert.equal(cfg.prefix, \"[P]\");\r\n});\r\n\r\ntest(\"forwardToQQBridge official\uFF1A\u7F3A group_openid \u4E0D\u629B\u9519\", () => {\r\n assert.doesNotThrow(() => {\r\n forwardToQQBridge(\r\n {\r\n backend: \"official\",\r\n creds: { appId: \"a\", appSecret: \"s\" },\r\n groupOpenid: \"\",\r\n prefix: \"[MC]\",\r\n },\r\n \"ch\",\r\n \"Steve\",\r\n \"hi\",\r\n \"xuid\"\r\n );\r\n });\r\n});\r\n\r\ntest(\"forwardToQQBridge llbot\uFF1A\u7F3A\u7FA4\u53F7\u4E0D\u629B\u9519\", () => {\r\n assert.doesNotThrow(() => {\r\n forwardToQQBridge(\r\n {\r\n backend: \"llbot\",\r\n llbot: {\r\n host: \"127.0.0.1\",\r\n port: 3004,\r\n token: \"\",\r\n groupId: \"0\",\r\n prefix: \"[MC]\",\r\n },\r\n },\r\n \"ch\",\r\n \"Steve\",\r\n \"hi\",\r\n \"xuid\"\r\n );\r\n });\r\n});\r\n\r"],
5
+ "mappings": "AAAA,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,SAAS,iBAAiB,oBAAoB,yBAAyB;AAEvE,KAAK,yDAA0C,MAAM;AACnD,QAAM,WAAW,mBAAmB;AAAA,IAClC,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB,CAAC;AACD,SAAO,MAAM,SAAS,SAAS,UAAU;AACzC,MAAI,SAAS,YAAY,YAAY;AACnC,WAAO,MAAM,SAAS,aAAa,OAAO;AAC1C,WAAO,MAAM,SAAS,MAAM,SAAS,IAAI;AACzC,WAAO,MAAM,SAAS,QAAQ,MAAM;AAAA,EACtC;AAEA,QAAM,QAAQ,mBAAmB;AAAA,IAC/B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB,CAAC;AACD,SAAO,MAAM,MAAM,SAAS,OAAO;AACnC,MAAI,MAAM,YAAY,SAAS;AAC7B,WAAO,MAAM,MAAM,MAAM,SAAS,IAAI;AACtC,WAAO,MAAM,MAAM,MAAM,QAAQ,KAAK;AAAA,EACxC;AACF,CAAC;AAED,KAAK,8CAAoC,MAAM;AAC7C,QAAM,MAAM,gBAAgB;AAAA,IAC1B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,eAAe;AAAA,EACjB,CAAC;AACD,SAAO,MAAM,IAAI,QAAQ,KAAK;AAChC,CAAC;AAED,KAAK,0EAAiD,MAAM;AAC1D,SAAO,aAAa,MAAM;AACxB;AAAA,MACE;AAAA,QACE,SAAS;AAAA,QACT,OAAO,EAAE,OAAO,KAAK,WAAW,IAAI;AAAA,QACpC,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH,CAAC;AAED,KAAK,qEAAkC,MAAM;AAC3C,SAAO,aAAa,MAAM;AACxB;AAAA,MACE;AAAA,QACE,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
@@ -50,7 +50,7 @@ export interface EconomyTransactionRow {
50
50
  reason: string;
51
51
  created_at: number;
52
52
  idempotency_key: string;
53
- /** JS-side alias fields used by domain/economy.ts */
53
+ /** 兼容 JS 领域模型访问的驼峰别名字段。 */
54
54
  actorId?: string;
55
55
  type?: string;
56
56
  referenceType?: string;
@@ -95,7 +95,7 @@ export interface EconomyTransactionRow {
95
95
  reason: string;
96
96
  created_at: number;
97
97
  idempotency_key: string;
98
- /** JS-side alias fields used by domain/economy.ts */
98
+ /** 兼容 JS 领域模型访问的驼峰别名字段。 */
99
99
  actorId?: string;
100
100
  type?: string;
101
101
  referenceType?: string;
@@ -159,12 +159,24 @@ export type ApplyEconomyResult = {
159
159
  */
160
160
  export declare function applyEconomySteps(query: AnyQuery, data: ApplyEconomyInput): ApplyEconomyResult;
161
161
  /**
162
- * 独立经济事务包装。alreadyInTx=true 时复用外层事务(不再 BEGIN)。
162
+ * 独立经济事务包装。若指定 `alreadyInTx: true` 则复用外层事务(不再单独开启 BEGIN)。
163
+ *
164
+ * @param query 数据库查询执行函数。
165
+ * @param db 数据库连接实例。
166
+ * @param data 经济操作输入参数。
167
+ * @param opts 可选事务参数。
168
+ * @returns 经济变动结果。
163
169
  */
164
170
  export declare function applyEconomyTransaction(query: AnyQuery, db: DatabaseSync, data: ApplyEconomyInput, opts?: {
165
171
  alreadyInTx?: boolean;
166
172
  }): ApplyEconomyResult;
167
- /** 列出日常任务(默认仅 active 且未过期) */
173
+ /**
174
+ * 列出日常任务列表(默认仅查询 active 状态且尚未过期的任务)。
175
+ *
176
+ * @param query 数据库查询执行函数。
177
+ * @param filter 过滤条件(可指定状态或是否包含已过期任务)。
178
+ * @returns 任务行记录数组。
179
+ */
168
180
  export declare function listDailyTasks(query: AnyQuery, filter?: {
169
181
  status?: string;
170
182
  includeExpired?: boolean;
@@ -174,14 +186,28 @@ export interface SubmitDailyTaskInput {
174
186
  taskId: string;
175
187
  quantity: number;
176
188
  }
177
- /** 日常任务提交核心(无 BEGIN) */
189
+ /**
190
+ * 日常任务提交核心逻辑(无显式事务控制,供内部或外层事务调用)。
191
+ *
192
+ * @param query 数据库查询执行函数。
193
+ * @param data 任务提交数据(玩家 ID、任务 ID、提交数量)。
194
+ * @returns 提交结果(含奖励金额、更新后的余额及版本号)。
195
+ */
178
196
  export declare function submitDailyTaskSteps(query: AnyQuery, data: SubmitDailyTaskInput): TxResult<{
179
197
  transactionId: string;
180
198
  reward: number;
181
199
  balance: number;
182
200
  balanceVersion: number;
183
201
  }>;
184
- /** 日常任务提交包装(可独立事务或嵌入外层 tx) */
202
+ /**
203
+ * 日常任务提交事务包装(可作为独立 IMMEDIATE 事务运行,或嵌入外层现有事务)。
204
+ *
205
+ * @param query 数据库查询执行函数。
206
+ * @param db 数据库连接实例。
207
+ * @param data 任务提交数据。
208
+ * @param opts 可选配置项。
209
+ * @returns 任务提交事务结果。
210
+ */
185
211
  export declare function submitDailyTaskTx(query: AnyQuery, db: DatabaseSync, data: SubmitDailyTaskInput, opts?: {
186
212
  alreadyInTx?: boolean;
187
213
  }): TxResult<{
@@ -190,7 +216,12 @@ export declare function submitDailyTaskTx(query: AnyQuery, db: DatabaseSync, dat
190
216
  balance: number;
191
217
  balanceVersion: number;
192
218
  }>;
193
- /** 月度/全局经济白皮书(优先读 sfmc_economy_stats,否则现场聚合) */
219
+ /**
220
+ * 获取月度或全局经济统计指标白皮书(优先读取 `sfmc_economy_stats` 统计表,无缓存时现场聚合计算)。
221
+ *
222
+ * @param query 数据库查询执行函数。
223
+ * @returns 包含发行总量、销毁总量、现存总量与活跃账户数的统计快照。
224
+ */
194
225
  export declare function monthlyEconomyStats(query: AnyQuery): {
195
226
  id: string;
196
227
  total_issued: number;
@@ -1 +1 @@
1
- {"version":3,"file":"economy.d.ts","sourceRoot":"","sources":["../../src/domain/economy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"economy.d.ts","sourceRoot":"","sources":["../../src/domain/economy.ts"],"names":[],"mappings":"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"}