@sfmc-bds/db-server 0.1.0 → 0.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +1 -1
  2. package/dist/db-tables.js +16 -17
  3. package/dist/db-tables.js.map +7 -1
  4. package/dist/domain/bridge.js +54 -77
  5. package/dist/domain/bridge.js.map +7 -1
  6. package/dist/domain/economy.d.ts +83 -2
  7. package/dist/domain/economy.d.ts.map +1 -1
  8. package/dist/domain/economy.js +292 -281
  9. package/dist/domain/economy.js.map +7 -1
  10. package/dist/domain/schema.js +480 -426
  11. package/dist/domain/schema.js.map +7 -1
  12. package/dist/domain/transaction.js +32 -80
  13. package/dist/domain/transaction.js.map +7 -1
  14. package/dist/env.d.ts.map +1 -1
  15. package/dist/env.js +85 -84
  16. package/dist/env.js.map +7 -1
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +218 -240
  20. package/dist/index.js.map +7 -1
  21. package/dist/lib/http.js +30 -39
  22. package/dist/lib/http.js.map +7 -1
  23. package/dist/lib/idempotency-store.js +34 -47
  24. package/dist/lib/idempotency-store.js.map +7 -1
  25. package/dist/lib/idempotency.js +8 -13
  26. package/dist/lib/idempotency.js.map +7 -1
  27. package/dist/lib/identifiers.js +18 -14
  28. package/dist/lib/identifiers.js.map +7 -1
  29. package/dist/lib/log.d.ts +3 -6
  30. package/dist/lib/log.d.ts.map +1 -1
  31. package/dist/lib/log.js +13 -14
  32. package/dist/lib/log.js.map +7 -1
  33. package/dist/lib/module-state.d.ts.map +1 -1
  34. package/dist/lib/module-state.js +32 -21
  35. package/dist/lib/module-state.js.map +7 -1
  36. package/dist/lib/order-by.d.ts +17 -0
  37. package/dist/lib/order-by.d.ts.map +1 -0
  38. package/dist/lib/order-by.js +24 -0
  39. package/dist/lib/order-by.js.map +7 -0
  40. package/dist/lib/runtime.js +16 -31
  41. package/dist/lib/runtime.js.map +7 -1
  42. package/dist/lib/sql-helpers.js +9 -27
  43. package/dist/lib/sql-helpers.js.map +7 -1
  44. package/dist/lib/sqlite.js +40 -52
  45. package/dist/lib/sqlite.js.map +7 -1
  46. package/dist/manifest-loader.d.ts.map +1 -1
  47. package/dist/manifest-loader.js +154 -195
  48. package/dist/manifest-loader.js.map +7 -1
  49. package/dist/manifest.d.ts +3 -7
  50. package/dist/manifest.d.ts.map +1 -1
  51. package/dist/manifest.js +76 -115
  52. package/dist/manifest.js.map +7 -1
  53. package/dist/module-auth.d.ts +17 -6
  54. package/dist/module-auth.d.ts.map +1 -1
  55. package/dist/module-auth.js +93 -107
  56. package/dist/module-auth.js.map +7 -1
  57. package/dist/module-runtime-sync.d.ts +37 -0
  58. package/dist/module-runtime-sync.d.ts.map +1 -0
  59. package/dist/module-runtime-sync.js +54 -0
  60. package/dist/module-runtime-sync.js.map +7 -0
  61. package/dist/permission-gate.d.ts.map +1 -1
  62. package/dist/permission-gate.js +55 -86
  63. package/dist/permission-gate.js.map +7 -1
  64. package/dist/routes/_shared.d.ts +7 -2
  65. package/dist/routes/_shared.d.ts.map +1 -1
  66. package/dist/routes/_shared.js +16 -25
  67. package/dist/routes/_shared.js.map +7 -1
  68. package/dist/routes/config.d.ts +11 -1
  69. package/dist/routes/config.d.ts.map +1 -1
  70. package/dist/routes/config.js +167 -213
  71. package/dist/routes/config.js.map +7 -1
  72. package/dist/routes/db-routes.d.ts +6 -10
  73. package/dist/routes/db-routes.d.ts.map +1 -1
  74. package/dist/routes/db-routes.js +198 -172
  75. package/dist/routes/db-routes.js.map +7 -1
  76. package/dist/routes/health.js +15 -20
  77. package/dist/routes/health.js.map +7 -1
  78. package/dist/routes/messages.d.ts.map +1 -1
  79. package/dist/routes/messages.js +56 -63
  80. package/dist/routes/messages.js.map +7 -1
  81. package/dist/routes/module-config-routes.d.ts.map +1 -1
  82. package/dist/routes/module-config-routes.js +92 -111
  83. package/dist/routes/module-config-routes.js.map +7 -1
  84. package/dist/routes/modules.d.ts.map +1 -1
  85. package/dist/routes/modules.js +82 -88
  86. package/dist/routes/modules.js.map +7 -1
  87. package/dist/routes/service-routes.d.ts.map +1 -1
  88. package/dist/routes/service-routes.js +54 -61
  89. package/dist/routes/service-routes.js.map +7 -1
  90. package/dist/runtime.test.js +248 -49
  91. package/dist/runtime.test.js.map +7 -1
  92. package/dist/schema-registry.d.ts.map +1 -1
  93. package/dist/schema-registry.js +119 -160
  94. package/dist/schema-registry.js.map +7 -1
  95. package/dist/server.js +69 -72
  96. package/dist/server.js.map +7 -1
  97. package/dist/service-registry.d.ts.map +1 -1
  98. package/dist/service-registry.js +60 -67
  99. package/dist/service-registry.js.map +7 -1
  100. package/dist/services/builtin-handlers.d.ts +4 -0
  101. package/dist/services/builtin-handlers.d.ts.map +1 -1
  102. package/dist/services/builtin-handlers.js +34 -20
  103. package/dist/services/builtin-handlers.js.map +7 -1
  104. package/dist/services/economy-handlers.js +143 -132
  105. package/dist/services/economy-handlers.js.map +7 -1
  106. package/dist/tx-runner.d.ts +35 -11
  107. package/dist/tx-runner.d.ts.map +1 -1
  108. package/dist/tx-runner.js +293 -250
  109. package/dist/tx-runner.js.map +7 -1
  110. package/dist/where.js +71 -94
  111. package/dist/where.js.map +7 -1
  112. package/package.json +4 -4
@@ -1,59 +1,47 @@
1
1
  import { mkdirSync } from "node:fs";
2
2
  import { dirname } from "node:path";
3
3
  import { DatabaseSync, StatementSync } from "node:sqlite";
4
- /**
5
- * 统一 SQL 查询接口 支持三种调用格式:
6
- * 1. query("SELECT * FROM t WHERE id=?", [1])
7
- * 2. query({ sql: "SELECT * FROM t WHERE id=?", values: [1] })
8
- * 3. query(SQL`SELECT * FROM t WHERE id=${1}`) ← sql-template-strings
9
- */
10
- export function createQuery(db, maxStatements = 200) {
11
- const stmts = new Map();
12
- function getStmt(sql) {
13
- let s = stmts.get(sql);
14
- if (!s) {
15
- s = db.prepare(sql);
16
- if (stmts.size >= maxStatements) {
17
- const first = stmts.keys().next().value;
18
- if (first !== undefined)
19
- stmts.delete(first);
20
- }
21
- stmts.set(sql, s);
22
- }
23
- return s;
4
+ function createQuery(db, maxStatements = 200) {
5
+ const stmts = /* @__PURE__ */ new Map();
6
+ function getStmt(sql) {
7
+ let s = stmts.get(sql);
8
+ if (!s) {
9
+ s = db.prepare(sql);
10
+ if (stmts.size >= maxStatements) {
11
+ const first = stmts.keys().next().value;
12
+ if (first !== void 0) stmts.delete(first);
13
+ }
14
+ stmts.set(sql, s);
24
15
  }
25
- function runQuery(sql, values) {
26
- const s = getStmt(sql);
27
- const upper = sql.trim().toUpperCase();
28
- const needsRows = upper.startsWith("SELECT") ||
29
- upper.startsWith("WITH") ||
30
- upper.startsWith("PRAGMA") ||
31
- /\bRETURNING\b/.test(upper);
32
- const bind = values;
33
- if (needsRows)
34
- return s.all(...bind);
35
- const r = s.run(...bind);
36
- return { changes: r.changes };
16
+ return s;
17
+ }
18
+ function runQuery(sql, values) {
19
+ const s = getStmt(sql);
20
+ const upper = sql.trim().toUpperCase();
21
+ const needsRows = upper.startsWith("SELECT") || upper.startsWith("WITH") || upper.startsWith("PRAGMA") || /\bRETURNING\b/.test(upper);
22
+ const bind = values;
23
+ if (needsRows) return s.all(...bind);
24
+ const r = s.run(...bind);
25
+ return { changes: r.changes };
26
+ }
27
+ return function query(raw, maybeValues) {
28
+ if (typeof raw === "string") {
29
+ return runQuery(raw, maybeValues ?? []);
37
30
  }
38
- return function query(raw, maybeValues) {
39
- // 格式 1:string + values
40
- if (typeof raw === "string") {
41
- return runQuery(raw, maybeValues ?? []);
42
- }
43
- // 格式 2 / 3:{ sql, values } 或 sql-template-strings 对象
44
- const o = raw;
45
- return runQuery(o.sql, o.values ?? []);
46
- };
31
+ const o = raw;
32
+ return runQuery(o.sql, o.values ?? []);
33
+ };
47
34
  }
48
- /**
49
- * 打开 SQLite 数据库(同步模式),启用外键、WAL、busy_timeout
50
- */
51
- export function openDatabase(filePath) {
52
- mkdirSync(dirname(filePath), { recursive: true });
53
- const db = new DatabaseSync(filePath);
54
- db.exec("PRAGMA foreign_keys = ON");
55
- db.exec("PRAGMA journal_mode = WAL");
56
- db.exec("PRAGMA busy_timeout = 5000");
57
- return db;
35
+ function openDatabase(filePath) {
36
+ mkdirSync(dirname(filePath), { recursive: true });
37
+ const db = new DatabaseSync(filePath);
38
+ db.exec("PRAGMA foreign_keys = ON");
39
+ db.exec("PRAGMA journal_mode = WAL");
40
+ db.exec("PRAGMA busy_timeout = 5000");
41
+ return db;
58
42
  }
59
- //# sourceMappingURL=sqlite.js.map
43
+ export {
44
+ createQuery,
45
+ openDatabase
46
+ };
47
+ //# sourceMappingURL=sqlite.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/lib/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQ1D;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,EAAgB,EAAE,gBAAwB,GAAG;IACvE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE/C,SAAS,OAAO,CAAC,GAAW;QAC1B,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpB,IAAI,KAAK,CAAC,IAAI,IAAI,aAAa,EAAE,CAAC;gBAChC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;gBACxC,IAAI,KAAK,KAAK,SAAS;oBAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/C,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,SAAS,QAAQ,CAAC,GAAW,EAAE,MAAiB;QAC9C,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,SAAS,GACb,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC1B,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;YACxB,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC1B,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAe,CAAC;QAC7B,IAAI,SAAS;YAAE,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;IAChC,CAAC;IAED,OAAO,SAAS,KAAK,CAAC,GAAiD,EAAE,WAAuB;QAC9F,uBAAuB;QACvB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC,GAAG,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,qDAAqD;QACrD,MAAM,CAAC,GAAG,GAA0C,CAAC;QACrD,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACpC,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACrC,EAAE,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IACtC,OAAO,EAAE,CAAC;AACZ,CAAC"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lib/sqlite.ts"],
4
+ "sourcesContent": ["import { mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { DatabaseSync, StatementSync } from \"node:sqlite\";\nimport type { SQLStatement } from \"sql-template-strings\";\n\nexport type QueryFn = (\n sql: string | SQLStatement | { sql: string; values?: unknown[] },\n values?: unknown[]\n) => unknown[] | { changes: number | bigint };\n\n/**\n * \u7EDF\u4E00 SQL \u67E5\u8BE2\u63A5\u53E3 \u2014 \u652F\u6301\u4E09\u79CD\u8C03\u7528\u683C\u5F0F\uFF1A\n * 1. query(\"SELECT * FROM t WHERE id=?\", [1])\n * 2. query({ sql: \"SELECT * FROM t WHERE id=?\", values: [1] })\n * 3. query(SQL`SELECT * FROM t WHERE id=${1}`) \u2190 sql-template-strings\n */\nexport function createQuery(db: DatabaseSync, maxStatements: number = 200): QueryFn {\n const stmts = new Map<string, StatementSync>();\n\n function getStmt(sql: string): StatementSync {\n let s = stmts.get(sql);\n if (!s) {\n s = db.prepare(sql);\n if (stmts.size >= maxStatements) {\n const first = stmts.keys().next().value;\n if (first !== undefined) stmts.delete(first);\n }\n stmts.set(sql, s);\n }\n return s;\n }\n\n function runQuery(sql: string, values: unknown[]): any[] | { changes: number | bigint } {\n const s = getStmt(sql);\n const upper = sql.trim().toUpperCase();\n const needsRows =\n upper.startsWith(\"SELECT\") ||\n upper.startsWith(\"WITH\") ||\n upper.startsWith(\"PRAGMA\") ||\n /\\bRETURNING\\b/.test(upper);\n const bind = values as any[];\n if (needsRows) return s.all(...bind);\n const r = s.run(...bind);\n return { changes: r.changes };\n }\n\n return function query(raw: string | { sql: string; values?: unknown[] }, maybeValues?: unknown[]): any[] | { changes: number | bigint } {\n // \u683C\u5F0F 1\uFF1Astring + values\n if (typeof raw === \"string\") {\n return runQuery(raw, maybeValues ?? []);\n }\n // \u683C\u5F0F 2 / 3\uFF1A{ sql, values } \u6216 sql-template-strings \u5BF9\u8C61\n const o = raw as { sql: string; values?: unknown[] };\n return runQuery(o.sql, o.values ?? []);\n };\n}\n\n/**\n * \u6253\u5F00 SQLite \u6570\u636E\u5E93\uFF08\u540C\u6B65\u6A21\u5F0F\uFF09\uFF0C\u542F\u7528\u5916\u952E\u3001WAL\u3001busy_timeout\n */\nexport function openDatabase(filePath: string): DatabaseSync {\n mkdirSync(dirname(filePath), { recursive: true });\n const db = new DatabaseSync(filePath);\n db.exec(\"PRAGMA foreign_keys = ON\");\n db.exec(\"PRAGMA journal_mode = WAL\");\n db.exec(\"PRAGMA busy_timeout = 5000\");\n return db;\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AACxB,SAAS,cAAc,qBAAqB;AAcrC,SAAS,YAAY,IAAkB,gBAAwB,KAAc;AAClF,QAAM,QAAQ,oBAAI,IAA2B;AAE7C,WAAS,QAAQ,KAA4B;AAC3C,QAAI,IAAI,MAAM,IAAI,GAAG;AACrB,QAAI,CAAC,GAAG;AACN,UAAI,GAAG,QAAQ,GAAG;AAClB,UAAI,MAAM,QAAQ,eAAe;AAC/B,cAAM,QAAQ,MAAM,KAAK,EAAE,KAAK,EAAE;AAClC,YAAI,UAAU,OAAW,OAAM,OAAO,KAAK;AAAA,MAC7C;AACA,YAAM,IAAI,KAAK,CAAC;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAEA,WAAS,SAAS,KAAa,QAAyD;AACtF,UAAM,IAAI,QAAQ,GAAG;AACrB,UAAM,QAAQ,IAAI,KAAK,EAAE,YAAY;AACrC,UAAM,YACJ,MAAM,WAAW,QAAQ,KACzB,MAAM,WAAW,MAAM,KACvB,MAAM,WAAW,QAAQ,KACzB,gBAAgB,KAAK,KAAK;AAC5B,UAAM,OAAO;AACb,QAAI,UAAW,QAAO,EAAE,IAAI,GAAG,IAAI;AACnC,UAAM,IAAI,EAAE,IAAI,GAAG,IAAI;AACvB,WAAO,EAAE,SAAS,EAAE,QAAQ;AAAA,EAC9B;AAEA,SAAO,SAAS,MAAM,KAAmD,aAA+D;AAEtI,QAAI,OAAO,QAAQ,UAAU;AAC3B,aAAO,SAAS,KAAK,eAAe,CAAC,CAAC;AAAA,IACxC;AAEA,UAAM,IAAI;AACV,WAAO,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;AAAA,EACvC;AACF;AAKO,SAAS,aAAa,UAAgC;AAC3D,YAAU,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,QAAM,KAAK,IAAI,aAAa,QAAQ;AACpC,KAAG,KAAK,0BAA0B;AAClC,KAAG,KAAK,2BAA2B;AACnC,KAAG,KAAK,4BAA4B;AACpC,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAOH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,CAAC,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE;QAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;QAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;IACjE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAKD,0CAA0C;AAC1C,qBAAa,oBAAqB,SAAQ,KAAK;IAC1B,QAAQ,EAAE,MAAM;IAAS,eAAe,EAAE,OAAO;gBAAjD,QAAQ,EAAE,MAAM,EAAS,eAAe,EAAE,OAAO;CAGrE;AA8FD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC1C,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,GAAE,MAA6B,GAAG,eAAe,CA8D1F;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAMlC"}
1
+ {"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAOH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,CAAC,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE;QAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;QAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;IACjE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAKD,0CAA0C;AAC1C,qBAAa,oBAAqB,SAAQ,KAAK;IAC1B,QAAQ,EAAE,MAAM;IAAS,eAAe,EAAE,OAAO;IAApE,YAAmB,QAAQ,EAAE,MAAM,EAAS,eAAe,EAAE,OAAO,EAEnE;CACF;AA8FD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC1C,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,GAAE,MAA6B,GAAG,eAAe,CA8D1F;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAMlC"}
@@ -1,212 +1,171 @@
1
- /**
2
- * manifest-loader.ts — 读 v2 manifest,失败 = 启动失败
3
- *
4
- * v2 schema:
5
- * {
6
- * "schemaVersion": 2,
7
- * "id": "feature-land",
8
- * "name": "领地",
9
- * "type": "feature",
10
- * "configKey": "land",
11
- * "requires": ["feature-economy"],
12
- * "permissions": ["db:read:lands", "service:economy.account"],
13
- * "services": {
14
- * "provides": [{ "name": "lands.byOwner", "input": {...}, "output": {...} }],
15
- * "requires": [{ "name": "economy.account" }]
16
- * },
17
- * "notes": "..."
18
- * }
19
- *
20
- * 不要 routes / tables / migrations / seeds / handlers / events。
21
- *
22
- * 调用方:db-server/src/index.ts 启动时一次 loadManifestV2,
23
- * throw 即 crash。
24
- */
25
1
  import { existsSync, readdirSync, readFileSync } from "node:fs";
26
2
  import { resolve } from "node:path";
27
3
  import { defaultPackagesDir } from "./manifest.js";
28
4
  import { validateManifestPermissions } from "./permission-gate.js";
29
- const VALID_TYPES = new Set(["core", "feature"]);
5
+ const VALID_TYPES = /* @__PURE__ */ new Set(["core", "feature"]);
30
6
  const IDENT = /^[A-Za-z0-9_-]+$/;
31
- /** v1 / schemaVersion:跳过(直到所有模块迁 v2) */
32
- export class ModuleV1SkippedError extends Error {
33
- moduleId;
34
- declaredVersion;
35
- constructor(moduleId, declaredVersion) {
36
- super(`moduleId=${moduleId} schemaVersion=${String(declaredVersion)} (需要 2),跳过`);
37
- this.moduleId = moduleId;
38
- this.declaredVersion = declaredVersion;
39
- }
7
+ class ModuleV1SkippedError extends Error {
8
+ constructor(moduleId, declaredVersion) {
9
+ super(`moduleId=${moduleId} schemaVersion=${String(declaredVersion)} (\u9700\u8981 2),\u8DF3\u8FC7`);
10
+ this.moduleId = moduleId;
11
+ this.declaredVersion = declaredVersion;
12
+ }
13
+ moduleId;
14
+ declaredVersion;
40
15
  }
41
16
  function assertModuleObject(modId, obj) {
42
- if (typeof obj.schemaVersion !== "number") {
43
- throw new Error(`[manifest] ${modId}: schemaVersion 缺失`);
44
- }
45
- if (obj.schemaVersion !== 2) {
46
- throw new Error(`[manifest] ${modId}: schemaVersion=${obj.schemaVersion} (需要 2)`);
47
- }
48
- if (typeof obj.id !== "string" || !IDENT.test(obj.id)) {
49
- throw new Error(`[manifest] ${modId}: id 缺失或非法 "${String(obj.id)}"`);
50
- }
51
- if (typeof obj.name !== "string" || obj.name.length === 0) {
52
- throw new Error(`[manifest] ${modId}: name 缺失`);
53
- }
54
- if (typeof obj.type !== "string" || !VALID_TYPES.has(obj.type)) {
55
- throw new Error(`[manifest] ${modId}: type 必须是 core|feature ("${String(obj.type)}")`);
56
- }
57
- if (typeof obj.configKey !== "string" || obj.configKey.length === 0) {
58
- throw new Error(`[manifest] ${modId}: configKey 缺失`);
59
- }
60
- if (Array.isArray(obj.routes)) {
61
- throw new Error(`[manifest] ${modId}: 不再支持 routes 字段,改用 db.defineTable + platform routes`);
62
- }
63
- if (Array.isArray(obj.migrations)) {
64
- throw new Error(`[manifest] ${modId}: 不再支持 migrations 字段,改用 db.defineTable 自动建表`);
65
- }
66
- if (Array.isArray(obj.tables)) {
67
- throw new Error(`[manifest] ${modId}: 不再支持 tables 字段,改用 db.defineTable`);
68
- }
69
- if (Array.isArray(obj.events)) {
70
- throw new Error(`[manifest] ${modId}: 不再支持 events 字段,改用 platform event-bus`);
71
- }
17
+ if (typeof obj.schemaVersion !== "number") {
18
+ throw new Error(`[manifest] ${modId}: schemaVersion \u7F3A\u5931`);
19
+ }
20
+ if (obj.schemaVersion !== 2) {
21
+ throw new Error(`[manifest] ${modId}: schemaVersion=${obj.schemaVersion} (\u9700\u8981 2)`);
22
+ }
23
+ if (typeof obj.id !== "string" || !IDENT.test(obj.id)) {
24
+ throw new Error(`[manifest] ${modId}: id \u7F3A\u5931\u6216\u975E\u6CD5 "${String(obj.id)}"`);
25
+ }
26
+ if (typeof obj.name !== "string" || obj.name.length === 0) {
27
+ throw new Error(`[manifest] ${modId}: name \u7F3A\u5931`);
28
+ }
29
+ if (typeof obj.type !== "string" || !VALID_TYPES.has(obj.type)) {
30
+ throw new Error(`[manifest] ${modId}: type \u5FC5\u987B\u662F core|feature ("${String(obj.type)}")`);
31
+ }
32
+ if (typeof obj.configKey !== "string" || obj.configKey.length === 0) {
33
+ throw new Error(`[manifest] ${modId}: configKey \u7F3A\u5931`);
34
+ }
35
+ if (Array.isArray(obj.routes)) {
36
+ throw new Error(`[manifest] ${modId}: \u4E0D\u518D\u652F\u6301 routes \u5B57\u6BB5,\u6539\u7528 db.defineTable + platform routes`);
37
+ }
38
+ if (Array.isArray(obj.migrations)) {
39
+ throw new Error(`[manifest] ${modId}: \u4E0D\u518D\u652F\u6301 migrations \u5B57\u6BB5,\u6539\u7528 db.defineTable \u81EA\u52A8\u5EFA\u8868`);
40
+ }
41
+ if (Array.isArray(obj.tables)) {
42
+ throw new Error(`[manifest] ${modId}: \u4E0D\u518D\u652F\u6301 tables \u5B57\u6BB5,\u6539\u7528 db.defineTable`);
43
+ }
44
+ if (Array.isArray(obj.events)) {
45
+ throw new Error(`[manifest] ${modId}: \u4E0D\u518D\u652F\u6301 events \u5B57\u6BB5,\u6539\u7528 platform event-bus`);
46
+ }
72
47
  }
73
48
  function parseServices(modId, raw) {
74
- if (raw === undefined)
75
- return { provides: [], requires: [] };
76
- if (typeof raw !== "object" || raw === null) {
77
- throw new Error(`[manifest] ${modId}: services 必须是对象`);
78
- }
79
- const obj = raw;
80
- const provides = parseServiceList(modId, "provides", obj.provides);
81
- const requires = parseServiceList(modId, "requires", obj.requires);
82
- for (const r of requires) {
83
- if (provides.find((p) => p.name === r.name)) {
84
- throw new Error(`[manifest] ${modId}: service "${r.name}" 既 provides 又 requires`);
85
- }
86
- }
87
- return { provides, requires };
49
+ if (raw === void 0) return { provides: [], requires: [] };
50
+ if (typeof raw !== "object" || raw === null) {
51
+ throw new Error(`[manifest] ${modId}: services \u5FC5\u987B\u662F\u5BF9\u8C61`);
52
+ }
53
+ const obj = raw;
54
+ const provides = parseServiceList(modId, "provides", obj.provides);
55
+ const requires = parseServiceList(modId, "requires", obj.requires);
56
+ for (const r of requires) {
57
+ if (provides.find((p) => p.name === r.name)) {
58
+ throw new Error(`[manifest] ${modId}: service "${r.name}" \u65E2 provides \u53C8 requires`);
59
+ }
60
+ }
61
+ return { provides, requires };
88
62
  }
89
63
  function parseServiceList(modId, dir, raw) {
90
- if (raw === undefined)
91
- return [];
92
- if (!Array.isArray(raw))
93
- throw new Error(`[manifest] ${modId}: services.${dir} 必须是数组`);
94
- const out = [];
95
- for (const item of raw) {
96
- if (typeof item !== "object" || item === null) {
97
- throw new Error(`[manifest] ${modId}: services.${dir} 项必须是对象`);
98
- }
99
- const e = item;
100
- if (typeof e.name !== "string" || e.name.length === 0) {
101
- throw new Error(`[manifest] ${modId}: services.${dir} 项缺少 name`);
102
- }
103
- const seen = new Set();
104
- if (seen.has(e.name)) {
105
- throw new Error(`[manifest] ${modId}: services.${dir} name 重复 "${e.name}"`);
106
- }
107
- seen.add(e.name);
108
- out.push({ name: e.name, input: e.input, output: e.output });
109
- }
110
- return out;
64
+ if (raw === void 0) return [];
65
+ if (!Array.isArray(raw)) throw new Error(`[manifest] ${modId}: services.${dir} \u5FC5\u987B\u662F\u6570\u7EC4`);
66
+ const out = [];
67
+ for (const item of raw) {
68
+ if (typeof item !== "object" || item === null) {
69
+ throw new Error(`[manifest] ${modId}: services.${dir} \u9879\u5FC5\u987B\u662F\u5BF9\u8C61`);
70
+ }
71
+ const e = item;
72
+ if (typeof e.name !== "string" || e.name.length === 0) {
73
+ throw new Error(`[manifest] ${modId}: services.${dir} \u9879\u7F3A\u5C11 name`);
74
+ }
75
+ const seen = /* @__PURE__ */ new Set();
76
+ if (seen.has(e.name)) {
77
+ throw new Error(`[manifest] ${modId}: services.${dir} name \u91CD\u590D "${e.name}"`);
78
+ }
79
+ seen.add(e.name);
80
+ out.push({ name: e.name, input: e.input, output: e.output });
81
+ }
82
+ return out;
111
83
  }
112
84
  function parseMod(modId, raw) {
113
- if (raw.schemaVersion !== 2) {
114
- throw new ModuleV1SkippedError(modId, raw.schemaVersion);
115
- }
116
- assertModuleObject(modId, raw);
117
- const requires = Array.isArray(raw.requires) ? raw.requires.filter((x) => typeof x === "string") : [];
118
- const permissions = Array.isArray(raw.permissions) ? raw.permissions.filter((x) => typeof x === "string") : [];
119
- validateManifestPermissions(modId, permissions);
120
- return {
121
- schemaVersion: 2,
122
- id: raw.id,
123
- name: raw.name,
124
- type: raw.type,
125
- configKey: raw.configKey,
126
- requires,
127
- permissions,
128
- services: parseServices(modId, raw.services),
129
- notes: typeof raw.notes === "string" ? raw.notes : undefined,
130
- };
85
+ if (raw.schemaVersion !== 2) {
86
+ throw new ModuleV1SkippedError(modId, raw.schemaVersion);
87
+ }
88
+ assertModuleObject(modId, raw);
89
+ const requires = Array.isArray(raw.requires) ? raw.requires.filter((x) => typeof x === "string") : [];
90
+ const permissions = Array.isArray(raw.permissions) ? raw.permissions.filter((x) => typeof x === "string") : [];
91
+ validateManifestPermissions(modId, permissions);
92
+ return {
93
+ schemaVersion: 2,
94
+ id: raw.id,
95
+ name: raw.name,
96
+ type: raw.type,
97
+ configKey: raw.configKey,
98
+ requires,
99
+ permissions,
100
+ services: parseServices(modId, raw.services),
101
+ notes: typeof raw.notes === "string" ? raw.notes : void 0
102
+ };
131
103
  }
132
- /**
133
- * 启动期调。throw = 启动失败。
134
- * 注:不读 v1 manifest。只有 schemaVersion=2 才走。
135
- */
136
- export function loadManifestV2(packagesDir = defaultPackagesDir()) {
137
- if (!existsSync(packagesDir)) {
138
- throw new Error(`[manifest] ${packagesDir} 不存在;无法启动 v2 协议`);
139
- }
140
- const ids = readdirSync(packagesDir, { withFileTypes: true })
141
- .filter((e) => e.isDirectory())
142
- .map((e) => e.name);
143
- const modules = {};
144
- const providesMap = new Map();
145
- for (const id of ids) {
146
- const p = resolve(packagesDir, id, "sapi", "manifest.json");
147
- if (!existsSync(p))
148
- continue;
149
- let raw;
150
- try {
151
- raw = readFileSync(p, "utf8");
152
- }
153
- catch (e) {
154
- throw new Error(`[manifest] ${id}: 读 ${p} 失败: ${e.message}`);
155
- }
156
- let parsed;
157
- try {
158
- parsed = JSON.parse(raw);
159
- }
160
- catch (e) {
161
- throw new Error(`[manifest] ${id}: ${p} 非合法 JSON: ${e.message}`);
104
+ function loadManifestV2(packagesDir = defaultPackagesDir()) {
105
+ if (!existsSync(packagesDir)) {
106
+ throw new Error(`[manifest] ${packagesDir} \u4E0D\u5B58\u5728;\u65E0\u6CD5\u542F\u52A8 v2 \u534F\u8BAE`);
107
+ }
108
+ const ids = readdirSync(packagesDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
109
+ const modules = {};
110
+ const providesMap = /* @__PURE__ */ new Map();
111
+ for (const id of ids) {
112
+ const p = resolve(packagesDir, id, "sapi", "manifest.json");
113
+ if (!existsSync(p)) continue;
114
+ let raw;
115
+ try {
116
+ raw = readFileSync(p, "utf8");
117
+ } catch (e) {
118
+ throw new Error(`[manifest] ${id}: \u8BFB ${p} \u5931\u8D25: ${e.message}`);
119
+ }
120
+ let parsed;
121
+ try {
122
+ parsed = JSON.parse(raw);
123
+ } catch (e) {
124
+ throw new Error(`[manifest] ${id}: ${p} \u975E\u5408\u6CD5 JSON: ${e.message}`);
125
+ }
126
+ try {
127
+ const m = parseMod(id, parsed);
128
+ modules[m.id] = m;
129
+ for (const s of m.services.provides) {
130
+ const prev = providesMap.get(s.name);
131
+ if (prev) {
132
+ throw new Error(`[manifest] service "${s.name}" \u5DF2\u88AB ${prev} provides,${m.id} \u62A2\u6CE8`);
162
133
  }
163
- try {
164
- const m = parseMod(id, parsed);
165
- modules[m.id] = m;
166
- for (const s of m.services.provides) {
167
- const prev = providesMap.get(s.name);
168
- if (prev) {
169
- throw new Error(`[manifest] service "${s.name}" 已被 ${prev} provides,${m.id} 抢注`);
170
- }
171
- providesMap.set(s.name, m.id);
172
- }
173
- }
174
- catch (e) {
175
- if (e instanceof ModuleV1SkippedError) {
176
- // PoC 兼容:不是 v2 的模块跳过,等到所有模块迁 v2 后改为 throw
177
- console.warn(`[manifest] ${id}: ${e.message}; v1 跳过`);
178
- continue;
179
- }
180
- throw e;
181
- }
182
- }
183
- // requires:校验目标 service 在某个 provides 里
184
- for (const m of Object.values(modules)) {
185
- for (const r of m.services.requires) {
186
- const owner = providesMap.get(r.name);
187
- if (!owner) {
188
- throw new Error(`[manifest] ${m.id}.services.requires.${r.name} 没有模块 provides`);
189
- }
190
- }
191
- // requires 模块依赖也要么 enabled 要么本身 installed (启动期不强求 enabled;运行时再查)
192
- for (const dep of m.requires) {
193
- if (!modules[dep]) {
194
- throw new Error(`[manifest] ${m.id}.requires.${dep} 没找到对应模块`);
195
- }
196
- }
197
- }
198
- return { modules, providesMap };
134
+ providesMap.set(s.name, m.id);
135
+ }
136
+ } catch (e) {
137
+ if (e instanceof ModuleV1SkippedError) {
138
+ console.warn(`[manifest] ${id}: ${e.message}; v1 \u8DF3\u8FC7`);
139
+ continue;
140
+ }
141
+ throw e;
142
+ }
143
+ }
144
+ for (const m of Object.values(modules)) {
145
+ for (const r of m.services.requires) {
146
+ const owner = providesMap.get(r.name);
147
+ if (!owner) {
148
+ throw new Error(`[manifest] ${m.id}.services.requires.${r.name} \u6CA1\u6709\u6A21\u5757 provides`);
149
+ }
150
+ }
151
+ for (const dep of m.requires) {
152
+ if (!modules[dep]) {
153
+ throw new Error(`[manifest] ${m.id}.requires.${dep} \u6CA1\u627E\u5230\u5BF9\u5E94\u6A21\u5757`);
154
+ }
155
+ }
156
+ }
157
+ return { modules, providesMap };
199
158
  }
200
- /**
201
- * 给定 moduleId 集合,过滤出 enabled (= lock 文件 enabled 的) 子集。
202
- * map(moduleId manifest) — 没装则跳过。
203
- */
204
- export function filterEnabled(loaded, enabledIds) {
205
- const out = {};
206
- for (const [id, m] of Object.entries(loaded.modules)) {
207
- if (enabledIds.has(id))
208
- out[id] = m;
209
- }
210
- return out;
159
+ function filterEnabled(loaded, enabledIds) {
160
+ const out = {};
161
+ for (const [id, m] of Object.entries(loaded.modules)) {
162
+ if (enabledIds.has(id)) out[id] = m;
163
+ }
164
+ return out;
211
165
  }
212
- //# sourceMappingURL=manifest-loader.js.map
166
+ export {
167
+ ModuleV1SkippedError,
168
+ filterEnabled,
169
+ loadManifestV2
170
+ };
171
+ //# sourceMappingURL=manifest-loader.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"manifest-loader.js","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AA0BnE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AACjD,MAAM,KAAK,GAAG,kBAAkB,CAAC;AAEjC,0CAA0C;AAC1C,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC1B;IAAyB;IAA5C,YAAmB,QAAgB,EAAS,eAAwB;QAClE,KAAK,CAAC,YAAY,QAAQ,kBAAkB,MAAM,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QADhE,aAAQ,GAAR,QAAQ,CAAQ;QAAS,oBAAe,GAAf,eAAe,CAAS;IAEpE,CAAC;CACF;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAE,GAA4B;IACrE,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,oBAAoB,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,GAAG,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,mBAAmB,GAAG,CAAC,aAAa,SAAS,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,eAAe,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,WAAW,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,6BAA6B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,gBAAgB,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,sDAAsD,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,6CAA6C,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,oCAAoC,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,wCAAwC,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAa,EAAE,GAAY;IAChD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC7D,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,kBAAkB,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnE,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc,CAAC,CAAC,IAAI,yBAAyB,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,GAAW,EAAE,GAAY;IAChE,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc,GAAG,QAAQ,CAAC,CAAC;IACvF,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc,GAAG,SAAS,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,CAAC,GAAG,IAA+B,CAAC;QAC1C,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc,GAAG,WAAW,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc,GAAG,aAAa,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACjB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAsC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAuC,EAAE,CAAC,CAAC;IACjI,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,GAA4B;IAC3D,IAAI,GAAG,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3D,CAAC;IACD,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,QAAsB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IACjI,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,WAAyB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1I,2BAA2B,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAChD,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,GAAG,CAAC,EAAY;QACpB,IAAI,EAAE,GAAG,CAAC,IAAc;QACxB,IAAI,EAAE,GAAG,CAAC,IAA0B;QACpC,SAAS,EAAE,GAAG,CAAC,SAAmB;QAClC,QAAQ;QACR,WAAW;QACX,QAAQ,EAAE,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC;QAC5C,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;KAC7D,CAAC;AACJ,CAAC;AAOD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,cAAsB,kBAAkB,EAAE;IACvE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,cAAc,WAAW,iBAAiB,CAAC,CAAC;IAC9D,CAAC;IACD,MAAM,GAAG,GAAG,WAAW,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC1D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,OAAO,GAAqC,EAAE,CAAC;IACrD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE9C,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;QAC5D,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,SAAS;QAC7B,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,cAAc,EAAE,OAAO,CAAC,QAAS,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,MAA+B,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QACtD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,cAAe,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC/B,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;YAClB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACpC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,IAAI,QAAQ,IAAI,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;gBACnF,CAAC;gBACD,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,oBAAoB,EAAE,CAAC;gBACtC,0CAA0C;gBAC1C,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC;gBACtD,SAAS;YACX,CAAC;YACD,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC;YAClF,CAAC;QACH,CAAC;QACD,iEAAiE;QACjE,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAuB,EACvB,UAA+B;IAE/B,MAAM,GAAG,GAAqC,EAAE,CAAC;IACjD,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/manifest-loader.ts"],
4
+ "sourcesContent": ["/**\n * manifest-loader.ts \u2014 \u8BFB v2 manifest,\u5931\u8D25 = \u542F\u52A8\u5931\u8D25\n *\n * v2 schema:\n * {\n * \"schemaVersion\": 2,\n * \"id\": \"feature-land\",\n * \"name\": \"\u9886\u5730\",\n * \"type\": \"feature\",\n * \"configKey\": \"land\",\n * \"requires\": [\"feature-economy\"],\n * \"permissions\": [\"db:read:lands\", \"service:economy.account\"],\n * \"services\": {\n * \"provides\": [{ \"name\": \"lands.byOwner\", \"input\": {...}, \"output\": {...} }],\n * \"requires\": [{ \"name\": \"economy.account\" }]\n * },\n * \"notes\": \"...\"\n * }\n *\n * \u4E0D\u8981 routes / tables / migrations / seeds / handlers / events\u3002\n *\n * \u8C03\u7528\u65B9:db-server/src/index.ts \u542F\u52A8\u65F6\u4E00\u6B21 loadManifestV2,\n * throw \u5373 crash\u3002\n */\n\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { defaultPackagesDir } from \"./manifest.js\";\nimport { validateManifestPermissions } from \"./permission-gate.js\";\n\nexport interface ManifestServiceIO {\n type: \"object\" | \"array\" | \"string\" | \"number\" | \"boolean\" | \"null\";\n properties?: Record<string, unknown>;\n required?: string[];\n}\n\nexport interface ServiceEntry {\n name: string;\n input?: ManifestServiceIO | undefined;\n output?: ManifestServiceIO | undefined;\n}\n\nexport interface ModuleManifestV2 {\n schemaVersion: 2;\n id: string;\n name: string;\n type: \"core\" | \"feature\";\n configKey: string;\n requires: string[];\n permissions: string[];\n services: { provides: ServiceEntry[]; requires: ServiceEntry[] };\n notes?: string | undefined;\n}\n\nconst VALID_TYPES = new Set([\"core\", \"feature\"]);\nconst IDENT = /^[A-Za-z0-9_-]+$/;\n\n/** v1 / \u7F3A schemaVersion:\u8DF3\u8FC7(\u76F4\u5230\u6240\u6709\u6A21\u5757\u8FC1 v2) */\nexport class ModuleV1SkippedError extends Error {\n constructor(public moduleId: string, public declaredVersion: unknown) {\n super(`moduleId=${moduleId} schemaVersion=${String(declaredVersion)} (\u9700\u8981 2),\u8DF3\u8FC7`);\n }\n}\n\nfunction assertModuleObject(modId: string, obj: Record<string, unknown>): void {\n if (typeof obj.schemaVersion !== \"number\") {\n throw new Error(`[manifest] ${modId}: schemaVersion \u7F3A\u5931`);\n }\n if (obj.schemaVersion !== 2) {\n throw new Error(`[manifest] ${modId}: schemaVersion=${obj.schemaVersion} (\u9700\u8981 2)`);\n }\n if (typeof obj.id !== \"string\" || !IDENT.test(obj.id)) {\n throw new Error(`[manifest] ${modId}: id \u7F3A\u5931\u6216\u975E\u6CD5 \"${String(obj.id)}\"`);\n }\n if (typeof obj.name !== \"string\" || obj.name.length === 0) {\n throw new Error(`[manifest] ${modId}: name \u7F3A\u5931`);\n }\n if (typeof obj.type !== \"string\" || !VALID_TYPES.has(obj.type)) {\n throw new Error(`[manifest] ${modId}: type \u5FC5\u987B\u662F core|feature (\"${String(obj.type)}\")`);\n }\n if (typeof obj.configKey !== \"string\" || obj.configKey.length === 0) {\n throw new Error(`[manifest] ${modId}: configKey \u7F3A\u5931`);\n }\n if (Array.isArray(obj.routes)) {\n throw new Error(`[manifest] ${modId}: \u4E0D\u518D\u652F\u6301 routes \u5B57\u6BB5,\u6539\u7528 db.defineTable + platform routes`);\n }\n if (Array.isArray(obj.migrations)) {\n throw new Error(`[manifest] ${modId}: \u4E0D\u518D\u652F\u6301 migrations \u5B57\u6BB5,\u6539\u7528 db.defineTable \u81EA\u52A8\u5EFA\u8868`);\n }\n if (Array.isArray(obj.tables)) {\n throw new Error(`[manifest] ${modId}: \u4E0D\u518D\u652F\u6301 tables \u5B57\u6BB5,\u6539\u7528 db.defineTable`);\n }\n if (Array.isArray(obj.events)) {\n throw new Error(`[manifest] ${modId}: \u4E0D\u518D\u652F\u6301 events \u5B57\u6BB5,\u6539\u7528 platform event-bus`);\n }\n}\n\nfunction parseServices(modId: string, raw: unknown): { provides: ServiceEntry[]; requires: ServiceEntry[] } {\n if (raw === undefined) return { provides: [], requires: [] };\n if (typeof raw !== \"object\" || raw === null) {\n throw new Error(`[manifest] ${modId}: services \u5FC5\u987B\u662F\u5BF9\u8C61`);\n }\n const obj = raw as Record<string, unknown>;\n const provides = parseServiceList(modId, \"provides\", obj.provides);\n const requires = parseServiceList(modId, \"requires\", obj.requires);\n for (const r of requires) {\n if (provides.find((p) => p.name === r.name)) {\n throw new Error(`[manifest] ${modId}: service \"${r.name}\" \u65E2 provides \u53C8 requires`);\n }\n }\n return { provides, requires };\n}\n\nfunction parseServiceList(modId: string, dir: string, raw: unknown): ServiceEntry[] {\n if (raw === undefined) return [];\n if (!Array.isArray(raw)) throw new Error(`[manifest] ${modId}: services.${dir} \u5FC5\u987B\u662F\u6570\u7EC4`);\n const out: ServiceEntry[] = [];\n for (const item of raw) {\n if (typeof item !== \"object\" || item === null) {\n throw new Error(`[manifest] ${modId}: services.${dir} \u9879\u5FC5\u987B\u662F\u5BF9\u8C61`);\n }\n const e = item as Record<string, unknown>;\n if (typeof e.name !== \"string\" || e.name.length === 0) {\n throw new Error(`[manifest] ${modId}: services.${dir} \u9879\u7F3A\u5C11 name`);\n }\n const seen = new Set<string>();\n if (seen.has(e.name)) {\n throw new Error(`[manifest] ${modId}: services.${dir} name \u91CD\u590D \"${e.name}\"`);\n }\n seen.add(e.name);\n out.push({ name: e.name, input: e.input as ManifestServiceIO | undefined, output: e.output as ManifestServiceIO | undefined });\n }\n return out;\n}\n\nfunction parseMod(modId: string, raw: Record<string, unknown>): ModuleManifestV2 {\n if (raw.schemaVersion !== 2) {\n throw new ModuleV1SkippedError(modId, raw.schemaVersion);\n }\n assertModuleObject(modId, raw);\n const requires = Array.isArray(raw.requires) ? (raw.requires as unknown[]).filter((x) => typeof x === \"string\") as string[] : [];\n const permissions = Array.isArray(raw.permissions) ? (raw.permissions as unknown[]).filter((x) => typeof x === \"string\") as string[] : [];\n validateManifestPermissions(modId, permissions);\n return {\n schemaVersion: 2,\n id: raw.id as string,\n name: raw.name as string,\n type: raw.type as \"core\" | \"feature\",\n configKey: raw.configKey as string,\n requires,\n permissions,\n services: parseServices(modId, raw.services),\n notes: typeof raw.notes === \"string\" ? raw.notes : undefined,\n };\n}\n\nexport interface LoadedManifests {\n modules: Record<string, ModuleManifestV2>;\n providesMap: Map<string, string>; // service name \u2192 moduleId\n}\n\n/**\n * \u542F\u52A8\u671F\u8C03\u3002throw = \u542F\u52A8\u5931\u8D25\u3002\n * \u6CE8:\u4E0D\u8BFB v1 manifest\u3002\u53EA\u6709 schemaVersion=2 \u624D\u8D70\u3002\n */\nexport function loadManifestV2(packagesDir: string = defaultPackagesDir()): LoadedManifests {\n if (!existsSync(packagesDir)) {\n throw new Error(`[manifest] ${packagesDir} \u4E0D\u5B58\u5728;\u65E0\u6CD5\u542F\u52A8 v2 \u534F\u8BAE`);\n }\n const ids = readdirSync(packagesDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n const modules: Record<string, ModuleManifestV2> = {};\n const providesMap = new Map<string, string>();\n\n for (const id of ids) {\n const p = resolve(packagesDir, id, \"sapi\", \"manifest.json\");\n if (!existsSync(p)) continue;\n let raw: string;\n try {\n raw = readFileSync(p, \"utf8\");\n } catch (e) {\n throw new Error(`[manifest] ${id}: \u8BFB ${p} \u5931\u8D25: ${(e as Error).message}`);\n }\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch (e) {\n throw new Error(`[manifest] ${id}: ${p} \u975E\u5408\u6CD5 JSON: ${(e as Error).message}`);\n }\n try {\n const m = parseMod(id, parsed);\n modules[m.id] = m;\n for (const s of m.services.provides) {\n const prev = providesMap.get(s.name);\n if (prev) {\n throw new Error(`[manifest] service \"${s.name}\" \u5DF2\u88AB ${prev} provides,${m.id} \u62A2\u6CE8`);\n }\n providesMap.set(s.name, m.id);\n }\n } catch (e) {\n if (e instanceof ModuleV1SkippedError) {\n // PoC \u517C\u5BB9:\u4E0D\u662F v2 \u7684\u6A21\u5757\u8DF3\u8FC7,\u7B49\u5230\u6240\u6709\u6A21\u5757\u8FC1 v2 \u540E\u6539\u4E3A throw\n console.warn(`[manifest] ${id}: ${e.message}; v1 \u8DF3\u8FC7`);\n continue;\n }\n throw e;\n }\n }\n\n // requires:\u6821\u9A8C\u76EE\u6807 service \u5728\u67D0\u4E2A provides \u91CC\n for (const m of Object.values(modules)) {\n for (const r of m.services.requires) {\n const owner = providesMap.get(r.name);\n if (!owner) {\n throw new Error(`[manifest] ${m.id}.services.requires.${r.name} \u6CA1\u6709\u6A21\u5757 provides`);\n }\n }\n // requires \u6A21\u5757\u4F9D\u8D56\u4E5F\u8981\u4E48 enabled \u8981\u4E48\u672C\u8EAB installed (\u542F\u52A8\u671F\u4E0D\u5F3A\u6C42 enabled;\u8FD0\u884C\u65F6\u518D\u67E5)\n for (const dep of m.requires) {\n if (!modules[dep]) {\n throw new Error(`[manifest] ${m.id}.requires.${dep} \u6CA1\u627E\u5230\u5BF9\u5E94\u6A21\u5757`);\n }\n }\n }\n\n return { modules, providesMap };\n}\n\n/**\n * \u7ED9\u5B9A moduleId \u96C6\u5408,\u8FC7\u6EE4\u51FA enabled (= lock \u6587\u4EF6 enabled \u7684) \u5B50\u96C6\u3002\n * map(moduleId \u2192 manifest) \u2014 \u6CA1\u88C5\u5219\u8DF3\u8FC7\u3002\n */\nexport function filterEnabled(\n loaded: LoadedManifests,\n enabledIds: ReadonlySet<string>\n): Record<string, ModuleManifestV2> {\n const out: Record<string, ModuleManifestV2> = {};\n for (const [id, m] of Object.entries(loaded.modules)) {\n if (enabledIds.has(id)) out[id] = m;\n }\n return out;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -4,8 +4,7 @@
4
4
  * At db-server startup, scan `modules/packages/<id>/sapi/manifest.json` for
5
5
  * every installed module and aggregate them into a single in-memory manifest.
6
6
  * No pre-built `modules/_manifests/module-manifests.json` is required; the
7
- * per-module files are the single source of truth (the SEA reads them at
8
- * runtime too).
7
+ * per-module files are the single source of truth.
9
8
  *
10
9
  * Behavior:
11
10
  * - Missing file: skip that module (WARN).
@@ -44,12 +43,9 @@ export type PackagesDirResolver = () => string;
44
43
  /** Resolve where db-server should look for `modules/packages/`.
45
44
  *
46
45
  * 优先级:
47
- * 1. `process.env.SFMC_PACKAGES_DIR` —— sfmc/SEA spawnService 在启动 db 时注入
48
- * (SEA 模式下 exe 目录, npm 模式下 process.cwd())
46
+ * 1. `process.env.SFMC_PACKAGES_DIR` —— sfmc spawnService 启动 db 时注入
47
+ * (通常与 SFMC_ROOT 对齐)
49
48
  * 2. `__dirname` 上溯两级到仓库根 —— 仅当 db-server 独立启动时兜底(CLI 调试)
50
- *
51
- * SEA 模式必须走 env 路径:SEA CJS bundle 里 `__dirname` 是虚拟路径,
52
- * 不能用 `import.meta.url` 解析;靠 SFMC_PACKAGES_DIR 才是稳定的。
53
49
  */
54
50
  export declare function defaultPackagesDir(): string;
55
51
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,UAAU,EAAE,uBAAuB,EAAE,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC9C;AAKD,MAAM,MAAM,mBAAmB,GAAG,MAAM,MAAM,CAAC;AAE/C;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,WAAW,GAAE,MAA6B,GAAG,cAAc,CA8CvF;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,cAAc,GAAG,eAAe,CAgB5D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAYnF"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,UAAU,EAAE,uBAAuB,EAAE,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC9C;AAKD,MAAM,MAAM,mBAAmB,GAAG,MAAM,MAAM,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,WAAW,GAAE,MAA6B,GAAG,cAAc,CA8CvF;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,cAAc,GAAG,eAAe,CAgB5D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAYnF"}