@sfmc-bds/db-server 0.1.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 (146) hide show
  1. package/README.md +21 -0
  2. package/dist/db-tables.d.ts +13 -0
  3. package/dist/db-tables.d.ts.map +1 -0
  4. package/dist/db-tables.js +35 -0
  5. package/dist/db-tables.js.map +1 -0
  6. package/dist/domain/bridge.d.ts +48 -0
  7. package/dist/domain/bridge.d.ts.map +1 -0
  8. package/dist/domain/bridge.js +82 -0
  9. package/dist/domain/bridge.js.map +1 -0
  10. package/dist/domain/economy.d.ts +120 -0
  11. package/dist/domain/economy.d.ts.map +1 -0
  12. package/dist/domain/economy.js +321 -0
  13. package/dist/domain/economy.js.map +1 -0
  14. package/dist/domain/schema.d.ts +26 -0
  15. package/dist/domain/schema.d.ts.map +1 -0
  16. package/dist/domain/schema.js +462 -0
  17. package/dist/domain/schema.js.map +1 -0
  18. package/dist/domain/transaction.d.ts +67 -0
  19. package/dist/domain/transaction.d.ts.map +1 -0
  20. package/dist/domain/transaction.js +85 -0
  21. package/dist/domain/transaction.js.map +1 -0
  22. package/dist/env.d.ts +22 -0
  23. package/dist/env.d.ts.map +1 -0
  24. package/dist/env.js +94 -0
  25. package/dist/env.js.map +1 -0
  26. package/dist/index.d.ts +33 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +313 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/lib/http.d.ts +18 -0
  31. package/dist/lib/http.d.ts.map +1 -0
  32. package/dist/lib/http.js +43 -0
  33. package/dist/lib/http.js.map +1 -0
  34. package/dist/lib/idempotency-store.d.ts +28 -0
  35. package/dist/lib/idempotency-store.d.ts.map +1 -0
  36. package/dist/lib/idempotency-store.js +49 -0
  37. package/dist/lib/idempotency-store.js.map +1 -0
  38. package/dist/lib/idempotency.d.ts +9 -0
  39. package/dist/lib/idempotency.d.ts.map +1 -0
  40. package/dist/lib/idempotency.js +14 -0
  41. package/dist/lib/idempotency.js.map +1 -0
  42. package/dist/lib/identifiers.d.ts +3 -0
  43. package/dist/lib/identifiers.d.ts.map +1 -0
  44. package/dist/lib/identifiers.js +18 -0
  45. package/dist/lib/identifiers.js.map +1 -0
  46. package/dist/lib/log.d.ts +11 -0
  47. package/dist/lib/log.d.ts.map +1 -0
  48. package/dist/lib/log.js +15 -0
  49. package/dist/lib/log.js.map +1 -0
  50. package/dist/lib/module-state.d.ts +15 -0
  51. package/dist/lib/module-state.d.ts.map +1 -0
  52. package/dist/lib/module-state.js +27 -0
  53. package/dist/lib/module-state.js.map +1 -0
  54. package/dist/lib/runtime.d.ts +21 -0
  55. package/dist/lib/runtime.d.ts.map +1 -0
  56. package/dist/lib/runtime.js +34 -0
  57. package/dist/lib/runtime.js.map +1 -0
  58. package/dist/lib/sql-helpers.d.ts +31 -0
  59. package/dist/lib/sql-helpers.d.ts.map +1 -0
  60. package/dist/lib/sql-helpers.js +30 -0
  61. package/dist/lib/sql-helpers.js.map +1 -0
  62. package/dist/lib/sqlite.d.ts +20 -0
  63. package/dist/lib/sqlite.d.ts.map +1 -0
  64. package/dist/lib/sqlite.js +59 -0
  65. package/dist/lib/sqlite.js.map +1 -0
  66. package/dist/manifest-loader.d.ts +69 -0
  67. package/dist/manifest-loader.d.ts.map +1 -0
  68. package/dist/manifest-loader.js +212 -0
  69. package/dist/manifest-loader.js.map +1 -0
  70. package/dist/manifest.d.ts +76 -0
  71. package/dist/manifest.d.ts.map +1 -0
  72. package/dist/manifest.js +128 -0
  73. package/dist/manifest.js.map +1 -0
  74. package/dist/module-auth.d.ts +58 -0
  75. package/dist/module-auth.d.ts.map +1 -0
  76. package/dist/module-auth.js +118 -0
  77. package/dist/module-auth.js.map +1 -0
  78. package/dist/permission-gate.d.ts +53 -0
  79. package/dist/permission-gate.d.ts.map +1 -0
  80. package/dist/permission-gate.js +94 -0
  81. package/dist/permission-gate.js.map +1 -0
  82. package/dist/routes/_shared.d.ts +68 -0
  83. package/dist/routes/_shared.d.ts.map +1 -0
  84. package/dist/routes/_shared.js +27 -0
  85. package/dist/routes/_shared.js.map +1 -0
  86. package/dist/routes/config.d.ts +27 -0
  87. package/dist/routes/config.d.ts.map +1 -0
  88. package/dist/routes/config.js +236 -0
  89. package/dist/routes/config.js.map +1 -0
  90. package/dist/routes/db-routes.d.ts +38 -0
  91. package/dist/routes/db-routes.d.ts.map +1 -0
  92. package/dist/routes/db-routes.js +186 -0
  93. package/dist/routes/db-routes.js.map +1 -0
  94. package/dist/routes/health.d.ts +10 -0
  95. package/dist/routes/health.d.ts.map +1 -0
  96. package/dist/routes/health.js +23 -0
  97. package/dist/routes/health.js.map +1 -0
  98. package/dist/routes/messages.d.ts +23 -0
  99. package/dist/routes/messages.d.ts.map +1 -0
  100. package/dist/routes/messages.js +72 -0
  101. package/dist/routes/messages.js.map +1 -0
  102. package/dist/routes/module-config-routes.d.ts +31 -0
  103. package/dist/routes/module-config-routes.d.ts.map +1 -0
  104. package/dist/routes/module-config-routes.js +128 -0
  105. package/dist/routes/module-config-routes.js.map +1 -0
  106. package/dist/routes/modules.d.ts +34 -0
  107. package/dist/routes/modules.d.ts.map +1 -0
  108. package/dist/routes/modules.js +92 -0
  109. package/dist/routes/modules.js.map +1 -0
  110. package/dist/routes/service-routes.d.ts +26 -0
  111. package/dist/routes/service-routes.d.ts.map +1 -0
  112. package/dist/routes/service-routes.js +68 -0
  113. package/dist/routes/service-routes.js.map +1 -0
  114. package/dist/runtime.test.d.ts +2 -0
  115. package/dist/runtime.test.d.ts.map +1 -0
  116. package/dist/runtime.test.js +66 -0
  117. package/dist/runtime.test.js.map +1 -0
  118. package/dist/schema-registry.d.ts +63 -0
  119. package/dist/schema-registry.d.ts.map +1 -0
  120. package/dist/schema-registry.js +178 -0
  121. package/dist/schema-registry.js.map +1 -0
  122. package/dist/server.d.ts +27 -0
  123. package/dist/server.d.ts.map +1 -0
  124. package/dist/server.js +82 -0
  125. package/dist/server.js.map +1 -0
  126. package/dist/service-registry.d.ts +46 -0
  127. package/dist/service-registry.d.ts.map +1 -0
  128. package/dist/service-registry.js +73 -0
  129. package/dist/service-registry.js.map +1 -0
  130. package/dist/services/builtin-handlers.d.ts +22 -0
  131. package/dist/services/builtin-handlers.d.ts.map +1 -0
  132. package/dist/services/builtin-handlers.js +23 -0
  133. package/dist/services/builtin-handlers.js.map +1 -0
  134. package/dist/services/economy-handlers.d.ts +14 -0
  135. package/dist/services/economy-handlers.d.ts.map +1 -0
  136. package/dist/services/economy-handlers.js +144 -0
  137. package/dist/services/economy-handlers.js.map +1 -0
  138. package/dist/tx-runner.d.ts +144 -0
  139. package/dist/tx-runner.d.ts.map +1 -0
  140. package/dist/tx-runner.js +273 -0
  141. package/dist/tx-runner.js.map +1 -0
  142. package/dist/where.d.ts +48 -0
  143. package/dist/where.d.ts.map +1 -0
  144. package/dist/where.js +107 -0
  145. package/dist/where.js.map +1 -0
  146. package/package.json +52 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * domain/transaction.ts — SQLite 事务执行器 + 共享业务结果类型
3
+ *
4
+ * 事务描述:
5
+ * - withTransaction(db, fn) IMMEDIATE 事务包裹器
6
+ * 自动 BEGIN IMMEDIATE / COMMIT / ROLLBACK,
7
+ * 异常时 ROLLBACK 并重新抛错;支持同步 + async 回调
8
+ * - withResult(db, fn) withTransaction 的语义别名(供"业务失败但不抛错"
9
+ * 的场景,函数返回 TxResult 自己判 ok)
10
+ *
11
+ * 共享类型:
12
+ * - Transactional 事务执行器所需的最小接口(Pick<DatabaseSync, "exec">),
13
+ * 让领域函数能接受 node:sqlite DatabaseSync 或 routes 注入的
14
+ * 窄化包装
15
+ * - TxResult<T> 领域事务统一结果类型:{ ok:true, data } | { ok:false, error, status, extra? }
16
+ * 所有领域模块(land / coop / economy / redpacket)都从此处引用,
17
+ * 避免跨域循环依赖
18
+ *
19
+ * 用法:
20
+ * const result = withTransaction(db, () => {
21
+ * const rows = query(SQL`SELECT 1`);
22
+ * return rows[0];
23
+ * });
24
+ *
25
+ * 行为约定:
26
+ * - return value → COMMIT 后透传给调用方
27
+ * - throw → ROLLBACK 后重新抛错
28
+ * - return Promise → await 后再 COMMIT / ROLLBACK
29
+ */
30
+ /**
31
+ * 在 IMMEDIATE 事务包裹下运行回调。回调内任何抛出都会触发 ROLLBACK 并重新抛错。
32
+ *
33
+ * 行为约定:
34
+ * - return value → COMMIT 后透传给调用方
35
+ * - throw → ROLLBACK 后重新抛错
36
+ * - return Promise → await 后再 COMMIT / ROLLBACK
37
+ */
38
+ export function withTransaction(db, fn) {
39
+ db.exec("BEGIN IMMEDIATE");
40
+ try {
41
+ const out = fn();
42
+ if (out instanceof Promise) {
43
+ // 同步/异步混合:等待 Promise 后决定提交
44
+ return Promise.resolve(out).then((v) => {
45
+ db.exec("COMMIT");
46
+ return v;
47
+ }, (err) => {
48
+ try {
49
+ db.exec("ROLLBACK");
50
+ }
51
+ catch {
52
+ /* ignore secondary failures */
53
+ }
54
+ throw err;
55
+ });
56
+ }
57
+ db.exec("COMMIT");
58
+ return out;
59
+ }
60
+ catch (error) {
61
+ try {
62
+ db.exec("ROLLBACK");
63
+ }
64
+ catch {
65
+ /* ignore rollback failures */
66
+ }
67
+ throw error;
68
+ }
69
+ }
70
+ /**
71
+ * withTransaction 的结果封装版 —— 适合领域函数想表达“业务失败但不抛错”的场景。
72
+ *
73
+ * 用法:
74
+ * const r = withResult(db, () => {
75
+ * if (bad) return { ok: false, error: "x" };
76
+ * return { ok: true, ... };
77
+ * });
78
+ * if (!r.ok) ...
79
+ *
80
+ * - 注意:仍由回调决定成功/失败;只在抛错时回滚。
81
+ */
82
+ export function withResult(db, fn) {
83
+ return withTransaction(db, fn);
84
+ }
85
+ //# sourceMappingURL=transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/domain/transaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAcH;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,EAAiB,EACjB,EAAwB;IAExB,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,EAAE,CAAC;QACjB,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;YAC3B,2BAA2B;YAC3B,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAC9B,CAAC,CAAC,EAAE,EAAE;gBACJ,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAClB,OAAO,CAAC,CAAC;YACX,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;gBACN,IAAI,CAAC;oBACH,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACtB,CAAC;gBAAC,MAAM,CAAC;oBACP,+BAA+B;gBACjC,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC,CACG,CAAC;QACT,CAAC;QACD,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClB,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC;YACH,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CACxB,EAAiB,EACjB,EAAwB;IAExB,OAAO,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * env.ts — 环境配置加载
3
+ */
4
+ export interface EnvConfig {
5
+ PROJECT_ROOT: string;
6
+ PORT: number;
7
+ HOST: string;
8
+ DB_PATH: string;
9
+ AUTH_TOKEN: string;
10
+ LLBOT_HOST: string;
11
+ LLBOT_PORT: number;
12
+ LLBOT_TOKEN: string;
13
+ QQ_GROUP_ID: string;
14
+ QQ_BRIDGE_CHANNEL_ID: string;
15
+ MODULES_DIR: string;
16
+ MODULE_CATALOG_PATH: string;
17
+ MODULE_LOCK_PATH: string;
18
+ dbconfig: Record<string, unknown>;
19
+ qqconfig: Record<string, unknown>;
20
+ }
21
+ export declare function loadEnv(): EnvConfig;
22
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyBH,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IAEnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IAEpB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,wBAAgB,OAAO,IAAI,SAAS,CA2FnC"}
package/dist/env.js ADDED
@@ -0,0 +1,94 @@
1
+ /**
2
+ * env.ts — 环境配置加载
3
+ */
4
+ import { ensureJsonConfig, modulePath, resolveRuntimeRoot } from "@sfmc-bds/sdk/node/config";
5
+ import { isAbsolute, join, resolve } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { log } from "./lib/log.js";
8
+ import { dirname } from "node:path";
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+ const DEFAULT_DB_CONFIG = {
12
+ db_port: 3001,
13
+ dbDir: "data/sfmc_data.db",
14
+ modulesDir: "modules",
15
+ };
16
+ const DEFAULT_QQ_CONFIG = {
17
+ llbot_host: "127.0.0.1",
18
+ llbot_port: 3004,
19
+ llbot_token: "",
20
+ };
21
+ export function loadEnv() {
22
+ const PROJECT_ROOT = resolveRuntimeRoot(resolve(__dirname, "..", ".."));
23
+ /* 启动时确认 db/qq config 存在;不存在就写带默认值的骨架。
24
+ * 不依赖 wizard:wizard 只填字段,骨架由服务自己 ensure。 */
25
+ const dbconfig = ensureJsonConfig(PROJECT_ROOT, "db_config.json", DEFAULT_DB_CONFIG);
26
+ const qqconfig = ensureJsonConfig(PROJECT_ROOT, "qq_config.json", DEFAULT_QQ_CONFIG);
27
+ // ── 优先级:JSON > 系统环境变量 > 默认值 ───────────────────────
28
+ const envBaseline = { ...process.env };
29
+ // 元数据前缀:`_` 开头视为注释/说明(如 _comment / _comment_group),不写 env、不打日志
30
+ const isMeta = (k) => String(k).startsWith("_");
31
+ for (const [k, v] of Object.entries(dbconfig)) {
32
+ if (isMeta(k))
33
+ continue;
34
+ const envKey = k.replace(/([A-Z])/g, "_$1").toUpperCase();
35
+ process.env[envKey] = String(v);
36
+ log.info(`db_config::${k} -> process.env.${envKey} = ${String(v)}`);
37
+ }
38
+ for (const [k, v] of Object.entries(qqconfig)) {
39
+ if (isMeta(k))
40
+ continue;
41
+ const envKey = k.replace(/([A-Z])/g, "_$1").toUpperCase();
42
+ if (process.env[envKey] === undefined) {
43
+ process.env[envKey] = String(v);
44
+ log.info(`qq_config::${k} -> process.env.${envKey} = ${String(v)}`);
45
+ }
46
+ }
47
+ // 工具:JSON > envBaseline(原 process.env) > default
48
+ // 语义:JSON 里有这个键(非 undefined / null)就用 JSON;空串、0、false 都算"显式配置"
49
+ // 只有 JSON 完全没这个键(或者显式 null)才 fall through 到 env
50
+ function pick(jsonVal, envKey, fallback, source) {
51
+ if (jsonVal !== undefined && jsonVal !== null) {
52
+ return jsonVal;
53
+ }
54
+ const fromEnv = envBaseline[envKey];
55
+ if (fromEnv !== undefined && fromEnv !== "") {
56
+ log.info(`${source} 未在 JSON 中配置,使用系统环境变量 ${envKey} = ${fromEnv}`);
57
+ return fromEnv;
58
+ }
59
+ return fallback;
60
+ }
61
+ const PORT = parseInt(String(pick(dbconfig["db_port"], "DB_PORT", 3001, "db_port")), 10);
62
+ const HOST = "127.0.0.1";
63
+ const DB_PATH_RAW = String(pick(dbconfig["dbDir"], "DB_DIR", "data/sfmc_data.db", "dbDir"));
64
+ const DB_PATH = isAbsolute(DB_PATH_RAW) ? DB_PATH_RAW : resolve(PROJECT_ROOT, DB_PATH_RAW);
65
+ const LLBOT_HOST = String(pick(qqconfig["llbot_host"], "LLBOT_HOST", "127.0.0.1", "llbot_host"));
66
+ const LLBOT_PORT = parseInt(String(pick(qqconfig["llbot_port"], "LLBOT_PORT", 3004, "llbot_port")), 10);
67
+ const LLBOT_TOKEN = String(pick(qqconfig["llbot_token"], "LLBOT_TOKEN", "", "llbot_token"));
68
+ const QQ_GROUP_ID = String(pick(qqconfig["qq_group_id"], "QQ_GROUP_ID", "", "qq_group_id"));
69
+ const QQ_BRIDGE_CHANNEL_ID = String(pick(qqconfig["bridge_channel_id"], "BRIDGE_CHANNEL_ID", "", "bridge_channel_id"));
70
+ const AUTH_TOKEN = String(pick(dbconfig["http_auth"], "HTTP_AUTH", "", "http_auth"));
71
+ const MODULES_DIR = dbconfig["modulesDir"]
72
+ ? resolve(PROJECT_ROOT, String(dbconfig["modulesDir"]))
73
+ : join(PROJECT_ROOT, "modules");
74
+ const MODULE_CATALOG_PATH = modulePath(MODULES_DIR, "catalog.json");
75
+ const MODULE_LOCK_PATH = modulePath(MODULES_DIR, "module-lock.json");
76
+ return {
77
+ PROJECT_ROOT,
78
+ PORT,
79
+ HOST,
80
+ DB_PATH,
81
+ AUTH_TOKEN,
82
+ LLBOT_HOST,
83
+ LLBOT_PORT,
84
+ LLBOT_TOKEN,
85
+ QQ_GROUP_ID,
86
+ QQ_BRIDGE_CHANNEL_ID,
87
+ MODULES_DIR,
88
+ MODULE_CATALOG_PATH,
89
+ MODULE_LOCK_PATH,
90
+ dbconfig,
91
+ qqconfig,
92
+ };
93
+ }
94
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * index.ts — 入口(v2 启动顺序)
3
+ *
4
+ * 工作流:
5
+ * 1. 加载 env
6
+ * 2. 校验 Node 版本
7
+ * 3. openDatabase + createPlatformTables(sfmc__audit / sfmc__idempotent)
8
+ * 4. loadManifestV2() — 失败 = 启动失败
9
+ * 5. filterEnabled(loaded, lockFileEnabled)
10
+ * 6. buildModuleAuth({auth_token, enabled_modules}) ← data/module-tokens.json
11
+ * 7. 实例化:SchemaRegistry / ServiceRegistry / IdempotencyStore / TxRunner
12
+ * 8. 装配 v2 路由 (/api/sfmc/db/* + /api/sfmc/services* + /api/sfmc/configs/:key/*)
13
+ * 另保留 messages(qq-bridge) + config/modules/health 平台路由
14
+ * 9. createServer + listen
15
+ *
16
+ * 鉴权(handle 层):
17
+ * - /api/sfmc/db/*, /api/sfmc/services*, /api/sfmc/configs/:key(/set|notify)*
18
+ * → module token (Authorization: Bearer ...) + ?moduleId=...
19
+ * - 其他:env.AUTH_TOKEN 旧 auth(NEEDS_AUTH)
20
+ */
21
+ import { SchemaRegistry } from "./schema-registry.js";
22
+ import { ServiceRegistry } from "./service-registry.js";
23
+ import { TxRunner } from "./tx-runner.js";
24
+ declare const env: import("./env.js").EnvConfig;
25
+ declare const db: import("node:sqlite").DatabaseSync;
26
+ declare const query: import("./lib/sqlite.js").QueryFn;
27
+ declare const enabledManifests: Map<string, import("./manifest-loader.js").ModuleManifestV2>;
28
+ declare const moduleAuth: import("./module-auth.js").ModuleAuthMap;
29
+ declare const schemaRegistry: SchemaRegistry;
30
+ declare const serviceRegistry: ServiceRegistry;
31
+ declare const txRunner: TxRunner;
32
+ export { db, env, query, schemaRegistry, serviceRegistry, txRunner, enabledManifests, moduleAuth };
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAuB1C,QAAA,MAAM,GAAG,8BAAY,CAAC;AACtB,QAAA,MAAM,EAAE,oCAA4B,CAAC;AAGrC,QAAA,MAAM,KAAK,mCAAkB,CAAC;AA4B9B,QAAA,MAAM,gBAAgB,8DAAwE,CAAC;AAU/F,QAAA,MAAM,UAAU,0CAId,CAAC;AAGH,QAAA,MAAM,cAAc,gBAAyB,CAAC;AAC9C,QAAA,MAAM,eAAe,iBAAwB,CAAC;AAE9C,QAAA,MAAM,QAAQ,UAMZ,CAAC;AAyOH,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,313 @@
1
+ /**
2
+ * index.ts — 入口(v2 启动顺序)
3
+ *
4
+ * 工作流:
5
+ * 1. 加载 env
6
+ * 2. 校验 Node 版本
7
+ * 3. openDatabase + createPlatformTables(sfmc__audit / sfmc__idempotent)
8
+ * 4. loadManifestV2() — 失败 = 启动失败
9
+ * 5. filterEnabled(loaded, lockFileEnabled)
10
+ * 6. buildModuleAuth({auth_token, enabled_modules}) ← data/module-tokens.json
11
+ * 7. 实例化:SchemaRegistry / ServiceRegistry / IdempotencyStore / TxRunner
12
+ * 8. 装配 v2 路由 (/api/sfmc/db/* + /api/sfmc/services* + /api/sfmc/configs/:key/*)
13
+ * 另保留 messages(qq-bridge) + config/modules/health 平台路由
14
+ * 9. createServer + listen
15
+ *
16
+ * 鉴权(handle 层):
17
+ * - /api/sfmc/db/*, /api/sfmc/services*, /api/sfmc/configs/:key(/set|notify)*
18
+ * → module token (Authorization: Bearer ...) + ?moduleId=...
19
+ * - 其他:env.AUTH_TOKEN 旧 auth(NEEDS_AUTH)
20
+ */
21
+ import http from "node:http";
22
+ import { createIdempotencyStore } from "./lib/idempotency-store.js";
23
+ import { loadEnv } from "./env.js";
24
+ import { buildModuleAuth, verifyModuleAuth } from "./module-auth.js";
25
+ import { loadManifestV2 } from "./manifest-loader.js";
26
+ import { log } from "./lib/log.js";
27
+ import { assertNodeVersion } from "./lib/runtime.js";
28
+ import { createQuery, openDatabase } from "./lib/sqlite.js";
29
+ import { createServer, startConsole } from "./server.js";
30
+ import { createPlatformTables } from "./db-tables.js";
31
+ import { initSchema } from "./domain/schema.js";
32
+ import { SchemaRegistry } from "./schema-registry.js";
33
+ import { ServiceRegistry } from "./service-registry.js";
34
+ import { TxRunner } from "./tx-runner.js";
35
+ import { registerEnabledBuiltinServices } from "./services/builtin-handlers.js";
36
+ import { readJson, writeJson } from "@sfmc-bds/sdk/node/config";
37
+ import { createModuleConfigRoutes } from "./routes/module-config-routes.js";
38
+ import { createDbRoutes } from "./routes/db-routes.js";
39
+ import { createServiceRoutes } from "./routes/service-routes.js";
40
+ import { jsonV2Fail } from "./routes/_shared.js";
41
+ import { createConfigRoutes } from "./routes/config.js";
42
+ import { createHealthRoutes } from "./routes/health.js";
43
+ import { createMessagesRoutes } from "./routes/messages.js";
44
+ import { createModuleRoutes } from "./routes/modules.js";
45
+ import { forwardToQQBridge, makeLLBotConfig } from "./domain/bridge.js";
46
+ import { isEnabled, loadModuleLock, updateModuleState } from "./lib/module-state.js";
47
+ import { body as sharedBody, json as sharedJson } from "./lib/http.js";
48
+ if (!assertNodeVersion(22, 13)) {
49
+ process.exit(2);
50
+ }
51
+ const env = loadEnv();
52
+ const db = openDatabase(env.DB_PATH);
53
+ createPlatformTables(db); // sfmc__audit / sfmc__idempotent
54
+ initSchema(db); // 平台业务 bootstrap 表(players/world/chat/...)——qq-bridge 在 SAPI defineTable 之前就需要
55
+ const query = createQuery(db);
56
+ // ── v2 manifest 加载(失败 = 启动失败)─────────────────────────
57
+ const loadedManifest = loadManifestV2(); // throws on violation
58
+ log.success(`[manifest v2] loaded ${Object.keys(loadedManifest.modules).length} modules; provides ${loadedManifest.providesMap.size} services`);
59
+ // ── enabled 集合(从 lock file)─────────────────────────────
60
+ const lockFile = loadModuleLock(env.MODULE_LOCK_PATH);
61
+ const moduleCatalog = readJson(env.MODULE_CATALOG_PATH) ?? { modules: [] };
62
+ const catalogIds = new Set(Array.isArray(moduleCatalog.modules)
63
+ ? moduleCatalog.modules
64
+ .map((m) => String(m.id || ""))
65
+ .filter((id) => id.length > 0)
66
+ : []);
67
+ const enabledSet = new Set();
68
+ for (const id of Object.keys(loadedManifest.modules)) {
69
+ if (!catalogIds.has(id))
70
+ continue;
71
+ const catalogEntry = moduleCatalog.modules.find((m) => String(m.id) === id);
72
+ if (!catalogEntry)
73
+ continue;
74
+ const defaultEnabled = catalogEntry.enabledByDefault !== false;
75
+ if (isEnabled(lockFile, id, defaultEnabled))
76
+ enabledSet.add(id);
77
+ }
78
+ const enabledManifests = new Map();
79
+ for (const id of enabledSet) {
80
+ const m = loadedManifest.modules[id];
81
+ if (m)
82
+ enabledManifests.set(id, m);
83
+ }
84
+ log.info(`[manifest v2] enabled: ${[...enabledSet].sort().join(", ") || "(none)"}`);
85
+ // ── 模块 HMAC token map(写到 data/module-tokens.json)────────
86
+ const moduleAuth = buildModuleAuth({
87
+ projectRoot: env.PROJECT_ROOT,
88
+ envAuthToken: env.AUTH_TOKEN,
89
+ enabledModuleIds: [...enabledSet],
90
+ });
91
+ // ── 三件套 + 路由工厂 ─────────────────────────────────────
92
+ const schemaRegistry = new SchemaRegistry(db);
93
+ const serviceRegistry = new ServiceRegistry();
94
+ const idempotent = createIdempotencyStore(db);
95
+ const txRunner = new TxRunner({
96
+ db,
97
+ query,
98
+ schema: schemaRegistry,
99
+ serviceRegistry,
100
+ enabled: enabledManifests,
101
+ });
102
+ // ── 进程内置 service handler(扩展点:BUILTIN_SERVICE_PLUGINS) ──
103
+ {
104
+ const plugins = registerEnabledBuiltinServices(serviceRegistry, { query, db }, enabledSet);
105
+ if (plugins > 0) {
106
+ log.success(`[service] registered ${serviceRegistry.list().length} handlers from ${plugins} builtin plugin(s)`);
107
+ }
108
+ }
109
+ const json = sharedJson;
110
+ const body = sharedBody;
111
+ // ── 工具函数 ──────────────────────────────────────────────
112
+ function loadModuleCatalog() {
113
+ return Array.isArray(moduleCatalog.modules) ? moduleCatalog.modules : [];
114
+ }
115
+ function buildModuleList() {
116
+ const catalog = loadModuleCatalog();
117
+ return catalog
118
+ .map((raw) => {
119
+ const entry = raw.entry && typeof raw.entry === "object"
120
+ ? raw.entry
121
+ : {};
122
+ const id = String(raw.id || "").trim();
123
+ const configKey = String(raw.configKey || raw.config_key || "").trim();
124
+ if (!id || !configKey)
125
+ return null;
126
+ const state = lockFile.modules[id];
127
+ const enabled = isEnabled(lockFile, id, raw.enabledByDefault !== false);
128
+ return {
129
+ id,
130
+ module_id: id,
131
+ name: configKey,
132
+ config_key: configKey,
133
+ display_name: String(raw.name || configKey),
134
+ type: String(raw.type || "feature"),
135
+ description: String(raw.description || ""),
136
+ default_enabled: raw.enabledByDefault !== false,
137
+ can_disable: raw.canDisable !== false,
138
+ requires: Array.isArray(raw.requires)
139
+ ? raw.requires.filter(Boolean).map(String)
140
+ : [],
141
+ optional: Array.isArray(raw.optional)
142
+ ? raw.optional.filter(Boolean).map(String)
143
+ : [],
144
+ commands: Array.isArray(raw.commands)
145
+ ? raw.commands.filter(Boolean).map(String)
146
+ : [],
147
+ entry: {
148
+ kind: String(entry.kind || ""),
149
+ path: String(entry.path || ""),
150
+ init: String(entry.init || ""),
151
+ },
152
+ updated_at: state?.updatedAt ?? null,
153
+ enabled: !!enabled,
154
+ };
155
+ })
156
+ .filter(Boolean);
157
+ }
158
+ function resolveModuleByKey(key) {
159
+ const k = String(key || "").trim();
160
+ const catalog = loadModuleCatalog();
161
+ return catalog.find((m) => String(m.id || "") === k ||
162
+ String(m.configKey || m.config_key || "") === k);
163
+ }
164
+ function setModuleEnabled(mod, enabled) {
165
+ // 直接更新启动时缓存的 lockFile(而非另读一份新副本),
166
+ // 否则 buildModuleList() 读的仍是旧缓存,导致启停后 enabled 状态不翻转。
167
+ updateModuleState(lockFile, mod.id, { enabled: !!enabled });
168
+ writeJson(env.MODULE_LOCK_PATH, lockFile);
169
+ }
170
+ // ── 平台路由(非模块业务) ───────────────────────────────────
171
+ const healthRoutes = createHealthRoutes();
172
+ const messagesRoutes = createMessagesRoutes({
173
+ query,
174
+ body,
175
+ json,
176
+ forwardToQQBridge: (channelId, fromName, content, fromId) => forwardToQQBridge(makeLLBotConfig({
177
+ LLBOT_HOST: env.LLBOT_HOST,
178
+ LLBOT_PORT: env.LLBOT_PORT,
179
+ LLBOT_TOKEN: env.LLBOT_TOKEN,
180
+ QQ_GROUP_ID: env.QQ_GROUP_ID,
181
+ }), channelId, fromName, content, fromId),
182
+ });
183
+ const configRoutes = createConfigRoutes({ json, projectRoot: env.PROJECT_ROOT });
184
+ const moduleRoutesInstance = createModuleRoutes({
185
+ loadModuleCatalog,
186
+ buildModuleList: buildModuleList,
187
+ resolveModuleByKey,
188
+ setModuleEnabled,
189
+ body,
190
+ json,
191
+ });
192
+ // ── v2 路由工厂 ───────────────────────────────────────────────
193
+ // 类型断言成 unknown 函数 — v2 routes 的 ctx 类型与 RouteCtx 不兼容,
194
+ // 但调用契约({path, method, params, req, res, body?})是稳定的。
195
+ const dbRoutes = createDbRoutes({ schemaRegistry, txRunner, idempotent, json });
196
+ const serviceRoutes = createServiceRoutes({
197
+ serviceRegistry,
198
+ enabled: enabledManifests,
199
+ json,
200
+ });
201
+ const moduleConfigRoutes = createModuleConfigRoutes({
202
+ projectRoot: env.PROJECT_ROOT,
203
+ enabled: enabledManifests,
204
+ json,
205
+ });
206
+ // ── 主请求处理器 ────────────────────────────────────────────
207
+ async function handle(req, res) {
208
+ const url = new URL(req.url || "/", `http://${req.headers.host || "localhost"}`);
209
+ const path = url.pathname;
210
+ const method = req.method || "GET";
211
+ const params = url.searchParams;
212
+ // loopback 绑定
213
+ const remote = req.socket.remoteAddress || "";
214
+ if (remote && !remote.startsWith("127.") && remote !== "::1" && remote !== "::ffff:127.") {
215
+ json(res, { success: false, error: "forbidden" }, 403);
216
+ return;
217
+ }
218
+ // ── 预读 body(所有路由共享) ───────────────────────────────
219
+ await body(req);
220
+ // ── v2 模块身份校验 → 写入路由 ctx.moduleAuth(LoD:不挂 req 私有字段) ──
221
+ // 注意:`/api/sfmc/configs/all` 是旧的一次性配置快照端点(SAPI ConfigManager.init
222
+ // 启动必用),不属于 v2 模块配置命名空间(configs/<模块 configKey>),必须豁免,
223
+ // 否则会被模块鉴权网关拦成 401,导致插件端起不来。
224
+ const isLegacyConfigAll = path === "/api/sfmc/configs/all";
225
+ const needsModuleAuth = path.startsWith("/api/sfmc/db/") ||
226
+ path.startsWith("/api/sfmc/services") ||
227
+ (/^\/api\/sfmc\/configs\/[A-Za-z0-9_-]+(?:\/(?:set|notify))?$/.test(path) && !isLegacyConfigAll);
228
+ let moduleAuthCtx = null;
229
+ if (needsModuleAuth) {
230
+ const id = verifyModuleAuth({
231
+ headers: req.headers,
232
+ params,
233
+ auth: moduleAuth,
234
+ enabledModuleIds: enabledSet,
235
+ });
236
+ if (!id) {
237
+ // LSP: v2 模块门与 service-routes 同用 ok 方言
238
+ jsonV2Fail(res, "unauthorized: module identity invalid", 401, "unauthorized");
239
+ return;
240
+ }
241
+ const manifest = enabledManifests.get(id);
242
+ moduleAuthCtx = {
243
+ id,
244
+ permissions: manifest?.permissions ?? [],
245
+ };
246
+ }
247
+ else {
248
+ // ── 旧 env token 鉴权(只对 POST/PUT 生效) ─────────────
249
+ const PUBLIC_GET = path === "/api/health" ||
250
+ (method === "GET" &&
251
+ (path === "/api/sfmc/modules" || path === "/api/sfmc/modules/catalog" || path.startsWith("/api/sfmc/modules/")));
252
+ const NEEDS_AUTH = !PUBLIC_GET && method !== "GET";
253
+ if (env.AUTH_TOKEN && NEEDS_AUTH) {
254
+ const auth = req.headers["authorization"] || "";
255
+ const provided = auth.startsWith("Bearer ") ? auth.slice(7) : req.headers["x-db-token"] || "";
256
+ if (provided !== env.AUTH_TOKEN) {
257
+ json(res, { success: false, error: "unauthorized" }, 401);
258
+ return;
259
+ }
260
+ }
261
+ }
262
+ try {
263
+ // ── v2 路由(优先匹配) ─────────────────────────────
264
+ if (moduleAuthCtx && (path.startsWith("/api/sfmc/db/") || path.startsWith("/api/sfmc/services") || (/^\/api\/sfmc\/configs\/[A-Za-z0-9_-]+/.test(path) && !isLegacyConfigAll))) {
265
+ const ctx = {
266
+ path,
267
+ method,
268
+ params,
269
+ req,
270
+ res,
271
+ moduleAuth: moduleAuthCtx,
272
+ };
273
+ // body 已在上面 `await body(req)` 预读并缓存到 req._bodyPromise;
274
+ // 这里复用缓存(原实现读的 req._body 从未被赋值,导致所有 v2 路由 body 恒为空)。
275
+ ctx["body"] = await body(req);
276
+ if (path.startsWith("/api/sfmc/db/")) {
277
+ if (await dbRoutes(ctx))
278
+ return;
279
+ }
280
+ else if (path.startsWith("/api/sfmc/services")) {
281
+ if (await serviceRoutes(ctx))
282
+ return;
283
+ }
284
+ else {
285
+ if (await moduleConfigRoutes(ctx))
286
+ return;
287
+ }
288
+ }
289
+ // ── 平台路由 ────────────────────────────────────
290
+ const ctxBase = { path, method, params, req, res };
291
+ if (await moduleRoutesInstance(ctxBase))
292
+ return;
293
+ if (await healthRoutes(ctxBase))
294
+ return;
295
+ if (await messagesRoutes(ctxBase))
296
+ return;
297
+ if (await configRoutes(ctxBase))
298
+ return;
299
+ json(res, { success: false, error: "not_found" }, 404);
300
+ }
301
+ catch (err) {
302
+ log.err(err, "DogeDB");
303
+ json(res, { success: false, error: err.message }, 500);
304
+ }
305
+ }
306
+ // ── 启动 ────────────────────────────────────────────────────
307
+ const server = createServer({
308
+ env: { PORT: env.PORT, HOST: env.HOST, AUTH_TOKEN: env.AUTH_TOKEN },
309
+ handle,
310
+ });
311
+ startConsole(server, db);
312
+ export { db, env, query, schemaRegistry, serviceRegistry, txRunner, enabledManifests, moduleAuth };
313
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * lib/http.ts — HTTP 工具(JSON 响应 + body 解析)
3
+ *
4
+ * 所有 db-server 路由统一走这里的 json / body / parseBody。
5
+ * 路由上下文 ({ path, method, params, req, res }) 在 routes/_shared.ts 定义。
6
+ */
7
+ import type { IncomingMessage, ServerResponse } from "node:http";
8
+ export type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
9
+ /** 写 JSON 响应并结束。 */
10
+ export declare function json(res: ServerResponse, data: Record<string, unknown>, status?: number): void;
11
+ /** 解析请求 body 字符串为对象(解析失败返回空对象)。 */
12
+ export declare function parseBody(raw: string): Record<string, unknown>;
13
+ /**
14
+ * 异步读取请求 body,结果会缓存到 req._bodyPromise 上以避免重复读取。
15
+ * Buffer 累积 + 异步拼接,正确处理 binary 字节流。
16
+ */
17
+ export declare function body(req: IncomingMessage): Promise<Record<string, unknown>>;
18
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,MAAM,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEjE,oBAAoB;AACpB,wBAAgB,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAE,MAAY,GAAG,IAAI,CAGnG;AAED,mCAAmC;AACnC,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAM9D;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAgB3E"}