@sfmc-bds/db-server 0.1.0 → 0.2.0-beta.1
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.
- package/README.md +1 -1
- package/dist/db-tables.js +16 -17
- package/dist/db-tables.js.map +7 -1
- package/dist/domain/bridge.js +54 -77
- package/dist/domain/bridge.js.map +7 -1
- package/dist/domain/economy.d.ts +83 -2
- package/dist/domain/economy.d.ts.map +1 -1
- package/dist/domain/economy.js +292 -281
- package/dist/domain/economy.js.map +7 -1
- package/dist/domain/schema.js +480 -426
- package/dist/domain/schema.js.map +7 -1
- package/dist/domain/transaction.js +32 -80
- package/dist/domain/transaction.js.map +7 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +85 -84
- package/dist/env.js.map +7 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +218 -240
- package/dist/index.js.map +7 -1
- package/dist/lib/http.js +30 -39
- package/dist/lib/http.js.map +7 -1
- package/dist/lib/idempotency-store.js +34 -47
- package/dist/lib/idempotency-store.js.map +7 -1
- package/dist/lib/idempotency.js +8 -13
- package/dist/lib/idempotency.js.map +7 -1
- package/dist/lib/identifiers.js +18 -14
- package/dist/lib/identifiers.js.map +7 -1
- package/dist/lib/log.d.ts +3 -6
- package/dist/lib/log.d.ts.map +1 -1
- package/dist/lib/log.js +13 -14
- package/dist/lib/log.js.map +7 -1
- package/dist/lib/module-state.d.ts.map +1 -1
- package/dist/lib/module-state.js +32 -21
- package/dist/lib/module-state.js.map +7 -1
- package/dist/lib/order-by.d.ts +17 -0
- package/dist/lib/order-by.d.ts.map +1 -0
- package/dist/lib/order-by.js +24 -0
- package/dist/lib/order-by.js.map +7 -0
- package/dist/lib/runtime.js +16 -31
- package/dist/lib/runtime.js.map +7 -1
- package/dist/lib/sql-helpers.js +9 -27
- package/dist/lib/sql-helpers.js.map +7 -1
- package/dist/lib/sqlite.js +40 -52
- package/dist/lib/sqlite.js.map +7 -1
- package/dist/manifest-loader.d.ts.map +1 -1
- package/dist/manifest-loader.js +154 -195
- package/dist/manifest-loader.js.map +7 -1
- package/dist/manifest.d.ts +3 -7
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +76 -115
- package/dist/manifest.js.map +7 -1
- package/dist/module-auth.d.ts +17 -6
- package/dist/module-auth.d.ts.map +1 -1
- package/dist/module-auth.js +93 -107
- package/dist/module-auth.js.map +7 -1
- package/dist/module-runtime-sync.d.ts +37 -0
- package/dist/module-runtime-sync.d.ts.map +1 -0
- package/dist/module-runtime-sync.js +54 -0
- package/dist/module-runtime-sync.js.map +7 -0
- package/dist/permission-gate.d.ts.map +1 -1
- package/dist/permission-gate.js +55 -86
- package/dist/permission-gate.js.map +7 -1
- package/dist/routes/_shared.d.ts +7 -2
- package/dist/routes/_shared.d.ts.map +1 -1
- package/dist/routes/_shared.js +16 -25
- package/dist/routes/_shared.js.map +7 -1
- package/dist/routes/config.d.ts +11 -1
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +167 -213
- package/dist/routes/config.js.map +7 -1
- package/dist/routes/db-routes.d.ts +6 -10
- package/dist/routes/db-routes.d.ts.map +1 -1
- package/dist/routes/db-routes.js +198 -172
- package/dist/routes/db-routes.js.map +7 -1
- package/dist/routes/health.js +15 -20
- package/dist/routes/health.js.map +7 -1
- package/dist/routes/messages.d.ts.map +1 -1
- package/dist/routes/messages.js +56 -63
- package/dist/routes/messages.js.map +7 -1
- package/dist/routes/module-config-routes.d.ts.map +1 -1
- package/dist/routes/module-config-routes.js +92 -111
- package/dist/routes/module-config-routes.js.map +7 -1
- package/dist/routes/modules.d.ts.map +1 -1
- package/dist/routes/modules.js +82 -88
- package/dist/routes/modules.js.map +7 -1
- package/dist/routes/service-routes.d.ts.map +1 -1
- package/dist/routes/service-routes.js +54 -61
- package/dist/routes/service-routes.js.map +7 -1
- package/dist/runtime.test.js +248 -49
- package/dist/runtime.test.js.map +7 -1
- package/dist/schema-registry.d.ts.map +1 -1
- package/dist/schema-registry.js +119 -160
- package/dist/schema-registry.js.map +7 -1
- package/dist/server.js +69 -72
- package/dist/server.js.map +7 -1
- package/dist/service-registry.d.ts.map +1 -1
- package/dist/service-registry.js +60 -67
- package/dist/service-registry.js.map +7 -1
- package/dist/services/builtin-handlers.d.ts +4 -0
- package/dist/services/builtin-handlers.d.ts.map +1 -1
- package/dist/services/builtin-handlers.js +34 -20
- package/dist/services/builtin-handlers.js.map +7 -1
- package/dist/services/economy-handlers.js +143 -132
- package/dist/services/economy-handlers.js.map +7 -1
- package/dist/tx-runner.d.ts +35 -11
- package/dist/tx-runner.d.ts.map +1 -1
- package/dist/tx-runner.js +293 -250
- package/dist/tx-runner.js.map +7 -1
- package/dist/where.js +71 -94
- package/dist/where.js.map +7 -1
- package/package.json +4 -4
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ensureModuleToken,
|
|
3
|
+
persistModuleAuth,
|
|
4
|
+
revokeModuleToken
|
|
5
|
+
} from "./module-auth.js";
|
|
6
|
+
import {
|
|
7
|
+
registerBuiltinPluginForModule,
|
|
8
|
+
unregisterBuiltinPluginForModule
|
|
9
|
+
} from "./services/builtin-handlers.js";
|
|
10
|
+
import { log } from "./lib/log.js";
|
|
11
|
+
function syncModuleRuntimeState(opts) {
|
|
12
|
+
const {
|
|
13
|
+
moduleId,
|
|
14
|
+
enabled,
|
|
15
|
+
dbPath,
|
|
16
|
+
envAuthToken,
|
|
17
|
+
enabledSet,
|
|
18
|
+
enabledManifests,
|
|
19
|
+
loadedManifest,
|
|
20
|
+
moduleAuth,
|
|
21
|
+
serviceRegistry,
|
|
22
|
+
builtinDeps
|
|
23
|
+
} = opts;
|
|
24
|
+
if (enabled) {
|
|
25
|
+
const manifest = loadedManifest.modules[moduleId];
|
|
26
|
+
if (!manifest) {
|
|
27
|
+
log.warn(`[modules] \u70ED\u542F\u7528 ${moduleId}: manifest \u7F3A\u5931(\u672A\u5B89\u88C5?),\u4EC5\u5199 lock`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
enabledSet.add(moduleId);
|
|
31
|
+
enabledManifests.set(moduleId, manifest);
|
|
32
|
+
if (ensureModuleToken(moduleAuth, moduleId)) {
|
|
33
|
+
log.info(`[modules] \u70ED\u542F\u7528 ${moduleId}: \u6D3E\u751F module token`);
|
|
34
|
+
}
|
|
35
|
+
persistModuleAuth(dbPath, moduleAuth, envAuthToken);
|
|
36
|
+
if (registerBuiltinPluginForModule(serviceRegistry, builtinDeps, moduleId)) {
|
|
37
|
+
log.success(`[modules] \u70ED\u542F\u7528 ${moduleId}: \u5DF2\u6CE8\u518C\u5185\u7F6E service handlers`);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
enabledSet.delete(moduleId);
|
|
42
|
+
enabledManifests.delete(moduleId);
|
|
43
|
+
if (revokeModuleToken(moduleAuth, moduleId)) {
|
|
44
|
+
persistModuleAuth(dbPath, moduleAuth, envAuthToken);
|
|
45
|
+
}
|
|
46
|
+
const n = unregisterBuiltinPluginForModule(serviceRegistry, moduleId);
|
|
47
|
+
if (n > 0) {
|
|
48
|
+
log.info(`[modules] \u70ED\u7981\u7528 ${moduleId}: \u5378\u4E0B ${n} \u4E2A\u5185\u7F6E handlers`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
syncModuleRuntimeState
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=module-runtime-sync.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/module-runtime-sync.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * module-runtime-sync.ts \u2014 enable/disable \u65F6\u540C\u6B65\u8FDB\u7A0B\u5185\u8FD0\u884C\u6001\n *\n * lock \u843D\u76D8\u540E,\u5185\u5B58\u6001(enabledSet / enabledManifests / moduleAuth.tokens /\n * builtin service handlers)\u5FC5\u987B\u4E0E\u4E4B\u4E00\u81F4,\u5426\u5219\u300C\u53EA\u91CD\u542F BDS\u300D\u62FF\u4E0D\u5230\u65B0 token\n * (DIP:\u8DEF\u7531\u53EA\u4F9D\u8D56\u6CE8\u5165\u7684\u96C6\u5408,\u4E0D\u611F\u77E5\u542F\u505C\u5B9E\u73B0)\u3002\n *\n * DRY:token \u843D\u76D8 / \u5185\u7F6E handler \u542F\u505C\u590D\u7528 module-auth \u4E0E builtin-handlers,\n * \u4E0D\u5728\u6B64\u5904\u518D\u5199\u4E00\u4EFD\u6D3E\u751F\u4E0E\u5378\u8F7D\u903B\u8F91\u3002\n */\n\nimport type { ModuleManifestV2 } from \"./manifest-loader.js\";\nimport {\n ensureModuleToken,\n persistModuleAuth,\n revokeModuleToken,\n type ModuleAuthMap,\n} from \"./module-auth.js\";\nimport {\n registerBuiltinPluginForModule,\n unregisterBuiltinPluginForModule,\n type BuiltinServiceDeps,\n} from \"./services/builtin-handlers.js\";\nimport type { ServiceRegistry } from \"./service-registry.js\";\nimport { log } from \"./lib/log.js\";\n\nexport type LoadedModules = {\n modules: Record<string, ModuleManifestV2 | undefined>;\n};\n\nexport type SyncModuleRuntimeOpts = {\n moduleId: string;\n enabled: boolean;\n /** SQLite \u8DEF\u5F84\uFF1Btoken \u6587\u4EF6\u5199\u5728\u540C\u76EE\u5F55 */\n dbPath: string;\n /** \u4E0E buildModuleAuth \u4E00\u81F4:\u65E0 AUTH_TOKEN \u65F6 secretGenerated=true */\n envAuthToken: string;\n enabledSet: Set<string>;\n enabledManifests: Map<string, ModuleManifestV2>;\n loadedManifest: LoadedModules;\n moduleAuth: ModuleAuthMap;\n serviceRegistry: ServiceRegistry;\n builtinDeps: BuiltinServiceDeps;\n};\n\n/**\n * \u540C\u6B65 enable/disable \u540E\u7684\u8FDB\u7A0B\u5185\u96C6\u5408\u4E0E token \u6587\u4EF6\u3002\n * \u8C03\u7528\u65B9\u8D1F\u8D23\u5148\u5199 lock;\u672C\u51FD\u6570\u4E0D\u78B0\u78C1\u76D8 lock\u3002\n */\nexport function syncModuleRuntimeState(opts: SyncModuleRuntimeOpts): void {\n const {\n moduleId,\n enabled,\n dbPath,\n envAuthToken,\n enabledSet,\n enabledManifests,\n loadedManifest,\n moduleAuth,\n serviceRegistry,\n builtinDeps,\n } = opts;\n\n if (enabled) {\n const manifest = loadedManifest.modules[moduleId];\n if (!manifest) {\n log.warn(`[modules] \u70ED\u542F\u7528 ${moduleId}: manifest \u7F3A\u5931(\u672A\u5B89\u88C5?),\u4EC5\u5199 lock`);\n return;\n }\n enabledSet.add(moduleId);\n enabledManifests.set(moduleId, manifest);\n if (ensureModuleToken(moduleAuth, moduleId)) {\n log.info(`[modules] \u70ED\u542F\u7528 ${moduleId}: \u6D3E\u751F module token`);\n }\n persistModuleAuth(dbPath, moduleAuth, envAuthToken);\n if (registerBuiltinPluginForModule(serviceRegistry, builtinDeps, moduleId)) {\n log.success(`[modules] \u70ED\u542F\u7528 ${moduleId}: \u5DF2\u6CE8\u518C\u5185\u7F6E service handlers`);\n }\n return;\n }\n\n enabledSet.delete(moduleId);\n enabledManifests.delete(moduleId);\n if (revokeModuleToken(moduleAuth, moduleId)) {\n persistModuleAuth(dbPath, moduleAuth, envAuthToken);\n }\n const n = unregisterBuiltinPluginForModule(serviceRegistry, moduleId);\n if (n > 0) {\n log.info(`[modules] \u70ED\u7981\u7528 ${moduleId}: \u5378\u4E0B ${n} \u4E2A\u5185\u7F6E handlers`);\n }\n}\n"],
|
|
5
|
+
"mappings": "AAYA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAEP,SAAS,WAAW;AAyBb,SAAS,uBAAuB,MAAmC;AACxE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,MAAI,SAAS;AACX,UAAM,WAAW,eAAe,QAAQ,QAAQ;AAChD,QAAI,CAAC,UAAU;AACb,UAAI,KAAK,gCAAiB,QAAQ,gEAA6B;AAC/D;AAAA,IACF;AACA,eAAW,IAAI,QAAQ;AACvB,qBAAiB,IAAI,UAAU,QAAQ;AACvC,QAAI,kBAAkB,YAAY,QAAQ,GAAG;AAC3C,UAAI,KAAK,gCAAiB,QAAQ,6BAAmB;AAAA,IACvD;AACA,sBAAkB,QAAQ,YAAY,YAAY;AAClD,QAAI,+BAA+B,iBAAiB,aAAa,QAAQ,GAAG;AAC1E,UAAI,QAAQ,gCAAiB,QAAQ,mDAA0B;AAAA,IACjE;AACA;AAAA,EACF;AAEA,aAAW,OAAO,QAAQ;AAC1B,mBAAiB,OAAO,QAAQ;AAChC,MAAI,kBAAkB,YAAY,QAAQ,GAAG;AAC3C,sBAAkB,QAAQ,YAAY,YAAY;AAAA,EACpD;AACA,QAAM,IAAI,iCAAiC,iBAAiB,QAAQ;AACpE,MAAI,IAAI,GAAG;AACT,QAAI,KAAK,gCAAiB,QAAQ,kBAAQ,CAAC,8BAAe;AAAA,EAC5D;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-gate.d.ts","sourceRoot":"","sources":["../src/permission-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AACnC,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,gBAAgB;IAChB,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,sBAAsB;IACtB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAoBD;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,IAAI,CAQN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,iBAAiB,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAChD,QAAQ,EAAE,MAAM,GACf,OAAO,CAUT;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAChD,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAG3B,QAAQ,EAAE,MAAM;IAAS,UAAU,EAAE,MAAM;IAF9D,IAAI,SAAuB;IAC3B,MAAM,SAAO;
|
|
1
|
+
{"version":3,"file":"permission-gate.d.ts","sourceRoot":"","sources":["../src/permission-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AACnC,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,gBAAgB;IAChB,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,sBAAsB;IACtB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAoBD;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,IAAI,CAQN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,iBAAiB,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAChD,QAAQ,EAAE,MAAM,GACf,OAAO,CAUT;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAChD,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAG3B,QAAQ,EAAE,MAAM;IAAS,UAAU,EAAE,MAAM;IAF9D,IAAI,SAAuB;IAC3B,MAAM,SAAO;IACb,YAAmB,QAAQ,EAAE,MAAM,EAAS,UAAU,EAAE,MAAM,EAE7D;CACF;AAED;;GAEG;AACH,eAAO,MAAM,IAAI;aACf,MAAM,UAAU,MAAM;aACtB,OAAO,UAAU,MAAM;aACvB,UAAU,QAAQ,MAAM;aACxB,WAAW,QAAQ,MAAM;aACzB,OAAO,SAAS,MAAM;CACd,CAAC;AAEX,eAAO,MAAM,wBAAwB,aAAkB,CAAC"}
|
package/dist/permission-gate.js
CHANGED
|
@@ -1,94 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*
|
|
8
|
-
* 运行时:发起 db / config / service 调用时,gatesdb.<op>.requirePermission =
|
|
9
|
-
* "db:read:<table>" / "db:write:<table>" / "config:read:<key>" /
|
|
10
|
-
* "config:write:<key>" / "service:<name>"
|
|
11
|
-
*
|
|
12
|
-
* 设计:gate 不替路由拦截,是业务逻辑自己检查(避免每条路由都验)。
|
|
13
|
-
* 路由层 fail-closed:不通过 manifest.permissions 表的调用 = 直接 403。
|
|
14
|
-
*/
|
|
15
|
-
const PERMISSION_KEYS = new Set([
|
|
16
|
-
// db:* 走模式匹配 db:read:* / db:write:*
|
|
17
|
-
// 配置权限
|
|
18
|
-
"config:read:*",
|
|
19
|
-
"config:write:*",
|
|
20
|
-
// service 在调用时按 service 名字匹配 service:* 通配
|
|
1
|
+
const PERMISSION_KEYS = /* @__PURE__ */ new Set([
|
|
2
|
+
// db:* 走模式匹配 db:read:* / db:write:*
|
|
3
|
+
// 配置权限
|
|
4
|
+
"config:read:*",
|
|
5
|
+
"config:write:*"
|
|
6
|
+
// service 在调用时按 service 名字匹配 service:* 通配
|
|
21
7
|
]);
|
|
22
8
|
function validPermissionKey(k) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// config:<op>:<key> (例 config:read:land / config:write:afk)
|
|
26
|
-
// service:<name> (例 service:economy.debit / service:land.byId — 名字可含 .)
|
|
27
|
-
// 不允许 raw "*"(要求明确对象) — 调试时一律 Resource-level
|
|
28
|
-
if (/^service:[A-Za-z0-9_.]+$/.test(k))
|
|
29
|
-
return true;
|
|
30
|
-
return /^[a-z]+:[a-z]+:[A-Za-z0-9_.]+$/.test(k);
|
|
9
|
+
if (/^service:[A-Za-z0-9_.]+$/.test(k)) return true;
|
|
10
|
+
return /^[a-z]+:[a-z]+:[A-Za-z0-9_.]+$/.test(k);
|
|
31
11
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
throw new Error(`[perm] ${moduleId}: permission 不是字符串 "${k}"`);
|
|
41
|
-
if (!validPermissionKey(k))
|
|
42
|
-
throw new Error(`[perm] ${moduleId}: permission 格式不合法 "${k}"`);
|
|
43
|
-
if (seen.has(k))
|
|
44
|
-
throw new Error(`[perm] ${moduleId}: permission 重复 "${k}"`);
|
|
45
|
-
seen.add(k);
|
|
46
|
-
}
|
|
12
|
+
function validateManifestPermissions(moduleId, permissions) {
|
|
13
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14
|
+
for (const k of permissions) {
|
|
15
|
+
if (!k || typeof k !== "string") throw new Error(`[perm] ${moduleId}: permission \u4E0D\u662F\u5B57\u7B26\u4E32 "${k}"`);
|
|
16
|
+
if (!validPermissionKey(k)) throw new Error(`[perm] ${moduleId}: permission \u683C\u5F0F\u4E0D\u5408\u6CD5 "${k}"`);
|
|
17
|
+
if (seen.has(k)) throw new Error(`[perm] ${moduleId}: permission \u91CD\u590D "${k}"`);
|
|
18
|
+
seen.add(k);
|
|
19
|
+
}
|
|
47
20
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return true;
|
|
58
|
-
// db:read:* / db:write:* / config:read:* / config:write:* 通配
|
|
59
|
-
const parts = required.split(":");
|
|
60
|
-
if (parts.length === 3) {
|
|
61
|
-
const wildcard = `${parts[0]}:${parts[1]}:*`;
|
|
62
|
-
if (modulePermissions.includes(wildcard))
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
return false;
|
|
21
|
+
function moduleHasPermission(modulePermissions, required) {
|
|
22
|
+
if (!modulePermissions) return false;
|
|
23
|
+
if (modulePermissions.includes(required)) return true;
|
|
24
|
+
const parts = required.split(":");
|
|
25
|
+
if (parts.length === 3) {
|
|
26
|
+
const wildcard = `${parts[0]}:${parts[1]}:*`;
|
|
27
|
+
if (modulePermissions.includes(wildcard)) return true;
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
66
30
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
31
|
+
function assertModulePermission(moduleId, modulePermissions, required) {
|
|
32
|
+
if (!moduleHasPermission(modulePermissions, required)) {
|
|
33
|
+
throw new PermissionDeniedError(moduleId, required);
|
|
34
|
+
}
|
|
71
35
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
permission;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
36
|
+
class PermissionDeniedError extends Error {
|
|
37
|
+
constructor(moduleId, permission) {
|
|
38
|
+
super(`[perm] \u6A21\u5757 ${moduleId} \u7F3A\u5C11\u6743\u9650 "${permission}"`);
|
|
39
|
+
this.moduleId = moduleId;
|
|
40
|
+
this.permission = permission;
|
|
41
|
+
}
|
|
42
|
+
moduleId;
|
|
43
|
+
permission;
|
|
44
|
+
code = "permission_denied";
|
|
45
|
+
status = 403;
|
|
82
46
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
configRead: (key) => `config:read:${key}`,
|
|
90
|
-
configWrite: (key) => `config:write:${key}`,
|
|
91
|
-
service: (name) => `service:${name}`,
|
|
47
|
+
const Perm = {
|
|
48
|
+
dbRead: (table) => `db:read:${table}`,
|
|
49
|
+
dbWrite: (table) => `db:write:${table}`,
|
|
50
|
+
configRead: (key) => `config:read:${key}`,
|
|
51
|
+
configWrite: (key) => `config:write:${key}`,
|
|
52
|
+
service: (name) => `service:${name}`
|
|
92
53
|
};
|
|
93
|
-
|
|
94
|
-
|
|
54
|
+
const PlatformTablePermissions = PERMISSION_KEYS;
|
|
55
|
+
export {
|
|
56
|
+
Perm,
|
|
57
|
+
PermissionDeniedError,
|
|
58
|
+
PlatformTablePermissions,
|
|
59
|
+
assertModulePermission,
|
|
60
|
+
moduleHasPermission,
|
|
61
|
+
validateManifestPermissions
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=permission-gate.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/permission-gate.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * permission-gate.ts \u2014 \u6A21\u5757\u6743\u9650\u6821\u9A8C\n *\n * \u542F\u52A8\u671F:manifest.permissions \u5168\u5728\u767D\u540D\u5355(PERMISSION_KEYS),\u5426\u5219\u629B\u9519\u542F\u52A8\u5931\u8D25\u3002\n * (\u767D\u540D\u5355 = db:read:*, db:write:*, config:read:*, config:write:*,\n * service:* + \u901A\u914D ** / <table>)\n *\n * \u8FD0\u884C\u65F6:\u53D1\u8D77 db / config / service \u8C03\u7528\u65F6,gatesdb.<op>.requirePermission =\n * \"db:read:<table>\" / \"db:write:<table>\" / \"config:read:<key>\" /\n * \"config:write:<key>\" / \"service:<name>\"\n *\n * \u8BBE\u8BA1:gate \u4E0D\u66FF\u8DEF\u7531\u62E6\u622A,\u662F\u4E1A\u52A1\u903B\u8F91\u81EA\u5DF1\u68C0\u67E5(\u907F\u514D\u6BCF\u6761\u8DEF\u7531\u90FD\u9A8C)\u3002\n * \u8DEF\u7531\u5C42 fail-closed:\u4E0D\u901A\u8FC7 manifest.permissions \u8868\u7684\u8C03\u7528 = \u76F4\u63A5 403\u3002\n */\n\nexport type PermissionKey = string;\nexport type PermissionLevel = \"Any\" | \"Member\" | \"OP\" | \"Admin\";\n\nexport interface ManifestPermissionRule {\n /** \u6A21\u5757\u58F0\u660E\u7684\u6743\u9650\u5168\u96C6 */\n permissions: PermissionKey[];\n /** \u8DE8\u6A21\u5757\u8C03\u7528\u5BF9\u5E94\u662F\u5426\u9700\u8981\u663E\u5F0F\u58F0\u660E */\n serviceRequires: string[];\n}\n\nconst PERMISSION_KEYS = new Set<string>([\n // db:* \u8D70\u6A21\u5F0F\u5339\u914D db:read:* / db:write:*\n // \u914D\u7F6E\u6743\u9650\n \"config:read:*\",\n \"config:write:*\",\n // service \u5728\u8C03\u7528\u65F6\u6309 service \u540D\u5B57\u5339\u914D service:* \u901A\u914D\n]);\n\nfunction validPermissionKey(k: string): boolean {\n // \u4E09\u7C7B\u5408\u6CD5\u683C\u5F0F:\n // db:<op>:<table> (\u4F8B db:read:lands / db:write:land_members)\n // config:<op>:<key> (\u4F8B config:read:land / config:write:afk)\n // service:<name> (\u4F8B service:economy.debit / service:land.byId \u2014 \u540D\u5B57\u53EF\u542B .)\n // \u4E0D\u5141\u8BB8 raw \"*\"(\u8981\u6C42\u660E\u786E\u5BF9\u8C61) \u2014 \u8C03\u8BD5\u65F6\u4E00\u5F8B Resource-level\n if (/^service:[A-Za-z0-9_.]+$/.test(k)) return true;\n return /^[a-z]+:[a-z]+:[A-Za-z0-9_.]+$/.test(k);\n}\n\n/**\n * \u542F\u52A8\u671F\u4E00\u6B21\u6027\u6821\u9A8C:manifest.permissions \u662F\u5426\u90FD\u5408\u89C4\u3002\n * \u5931\u8D25 = \u629B\u9519(\u542F\u52A8\u5931\u8D25)\u3002\n */\nexport function validateManifestPermissions(\n moduleId: string,\n permissions: readonly string[]\n): void {\n const seen = new Set<string>();\n for (const k of permissions) {\n if (!k || typeof k !== \"string\") throw new Error(`[perm] ${moduleId}: permission \u4E0D\u662F\u5B57\u7B26\u4E32 \"${k}\"`);\n if (!validPermissionKey(k)) throw new Error(`[perm] ${moduleId}: permission \u683C\u5F0F\u4E0D\u5408\u6CD5 \"${k}\"`);\n if (seen.has(k)) throw new Error(`[perm] ${moduleId}: permission \u91CD\u590D \"${k}\"`);\n seen.add(k);\n }\n}\n\n/**\n * \u8FD0\u884C\u65F6:\u6A21\u5757 id \u662F\u5426\u62E5\u6709\u6240\u9700 permission\u3002\n * \u5F53\u524D\u5B9E\u73B0:\u5FC5\u987B\u7CBE\u786E\u7B49\u4E8E\u624D\u653E\u884C,\u4E0D\u89E3\u91CA\u901A\u914D\u3002\n * (PoC \u7B80\u5316;\u751F\u4EA7\u53EF\u52A0 db:read:* \u2192 \u901A\u914D)\n */\nexport function moduleHasPermission(\n modulePermissions: readonly string[] | undefined,\n required: string\n): boolean {\n if (!modulePermissions) return false;\n if (modulePermissions.includes(required)) return true;\n // db:read:* / db:write:* / config:read:* / config:write:* \u901A\u914D\n const parts = required.split(\":\");\n if (parts.length === 3) {\n const wildcard = `${parts[0]}:${parts[1]}:*`;\n if (modulePermissions.includes(wildcard)) return true;\n }\n return false;\n}\n\nexport function assertModulePermission(\n moduleId: string,\n modulePermissions: readonly string[] | undefined,\n required: string\n): void {\n if (!moduleHasPermission(modulePermissions, required)) {\n throw new PermissionDeniedError(moduleId, required);\n }\n}\n\nexport class PermissionDeniedError extends Error {\n code = \"permission_denied\";\n status = 403;\n constructor(public moduleId: string, public permission: string) {\n super(`[perm] \u6A21\u5757 ${moduleId} \u7F3A\u5C11\u6743\u9650 \"${permission}\"`);\n }\n}\n\n/**\n * \u6240\u6709 platform \u6D3E\u53D1\u7684 required permission key \u8BA1\u7B97\u52A9\u624B\u3002\n */\nexport const Perm = {\n dbRead: (table: string) => `db:read:${table}`,\n dbWrite: (table: string) => `db:write:${table}`,\n configRead: (key: string) => `config:read:${key}`,\n configWrite: (key: string) => `config:write:${key}`,\n service: (name: string) => `service:${name}`,\n} as const;\n\nexport const PlatformTablePermissions = PERMISSION_KEYS;\n"],
|
|
5
|
+
"mappings": "AAyBA,MAAM,kBAAkB,oBAAI,IAAY;AAAA;AAAA;AAAA,EAGtC;AAAA,EACA;AAAA;AAEF,CAAC;AAED,SAAS,mBAAmB,GAAoB;AAM9C,MAAI,2BAA2B,KAAK,CAAC,EAAG,QAAO;AAC/C,SAAO,iCAAiC,KAAK,CAAC;AAChD;AAMO,SAAS,4BACd,UACA,aACM;AACN,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,KAAK,aAAa;AAC3B,QAAI,CAAC,KAAK,OAAO,MAAM,SAAU,OAAM,IAAI,MAAM,UAAU,QAAQ,gDAAuB,CAAC,GAAG;AAC9F,QAAI,CAAC,mBAAmB,CAAC,EAAG,OAAM,IAAI,MAAM,UAAU,QAAQ,gDAAuB,CAAC,GAAG;AACzF,QAAI,KAAK,IAAI,CAAC,EAAG,OAAM,IAAI,MAAM,UAAU,QAAQ,8BAAoB,CAAC,GAAG;AAC3E,SAAK,IAAI,CAAC;AAAA,EACZ;AACF;AAOO,SAAS,oBACd,mBACA,UACS;AACT,MAAI,CAAC,kBAAmB,QAAO;AAC/B,MAAI,kBAAkB,SAAS,QAAQ,EAAG,QAAO;AAEjD,QAAM,QAAQ,SAAS,MAAM,GAAG;AAChC,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,WAAW,GAAG,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;AACxC,QAAI,kBAAkB,SAAS,QAAQ,EAAG,QAAO;AAAA,EACnD;AACA,SAAO;AACT;AAEO,SAAS,uBACd,UACA,mBACA,UACM;AACN,MAAI,CAAC,oBAAoB,mBAAmB,QAAQ,GAAG;AACrD,UAAM,IAAI,sBAAsB,UAAU,QAAQ;AAAA,EACpD;AACF;AAEO,MAAM,8BAA8B,MAAM;AAAA,EAG/C,YAAmB,UAAyB,YAAoB;AAC9D,UAAM,uBAAa,QAAQ,8BAAU,UAAU,GAAG;AADjC;AAAyB;AAAA,EAE5C;AAAA,EAFmB;AAAA,EAAyB;AAAA,EAF5C,OAAO;AAAA,EACP,SAAS;AAIX;AAKO,MAAM,OAAO;AAAA,EAClB,QAAQ,CAAC,UAAkB,WAAW,KAAK;AAAA,EAC3C,SAAS,CAAC,UAAkB,YAAY,KAAK;AAAA,EAC7C,YAAY,CAAC,QAAgB,eAAe,GAAG;AAAA,EAC/C,aAAa,CAAC,QAAgB,gBAAgB,GAAG;AAAA,EACjD,SAAS,CAAC,SAAiB,WAAW,IAAI;AAC5C;AAEO,MAAM,2BAA2B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/routes/_shared.d.ts
CHANGED
|
@@ -60,9 +60,14 @@ export declare const json: typeof sharedJson;
|
|
|
60
60
|
export declare const body: typeof sharedBody;
|
|
61
61
|
/**
|
|
62
62
|
* v2 失败信封权威形态(DRY + LSP):
|
|
63
|
-
* 一律 `{ ok:false, error, code? }
|
|
63
|
+
* 一律 `{ ok:false, error, code? }`(+ 可选 extra),勿再混用 `{ success:false }`。
|
|
64
64
|
* service-routes / db / module-config / index 模块鉴权门应走此助手。
|
|
65
65
|
*/
|
|
66
|
-
export declare function jsonV2Fail(res: ServerResponse, error: string, status: number, code?: string): void;
|
|
66
|
+
export declare function jsonV2Fail(res: ServerResponse, error: string, status: number, code?: string, extra?: Record<string, unknown>): void;
|
|
67
|
+
/**
|
|
68
|
+
* v2 成功信封权威形态(DRY + LSP):
|
|
69
|
+
* 一律 `{ ok:true, ...fields }`,与 jsonV2Fail 对称;客户端已双认 ok/success。
|
|
70
|
+
*/
|
|
71
|
+
export declare function jsonV2Ok(res: ServerResponse, fields?: Record<string, unknown>, status?: number): void;
|
|
67
72
|
export {};
|
|
68
73
|
//# sourceMappingURL=_shared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/routes/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,IAAI,IAAI,UAAU,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,OAAO,EAAE,CAAC;AAExB,6CAA6C;AAC7C,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,EAAE,EAAE,YAAY,CAAC;IACjB,IAAI,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpF,IAAI,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjE,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC7D,oBAAoB,CAAC,EAAE,CACrB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,KACf;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7F,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnG,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC;CACxD,CAAC;AAEF,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,EAAE,eAAe,CAAC;IACxB,GAAG,EAAE,eAAe,CAAC;IACrB,GAAG,EAAE,cAAc,CAAC;IACpB,qBAAqB;IACrB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAEzE,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,YAAY,CAAC;AAEtE,sCAAsC;AACtC,eAAO,MAAM,IAAI,mBAAa,CAAC;AAC/B,eAAO,MAAM,IAAI,mBAAa,CAAC;AAE/B;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/routes/_shared.ts"],"names":[],"mappings":"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"}
|
package/dist/routes/_shared.js
CHANGED
|
@@ -1,27 +1,18 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* routes/_shared.ts — 路由模块共享类型 + 工厂
|
|
3
|
-
*
|
|
4
|
-
* 所有 db-server 路由统一:
|
|
5
|
-
* - deps: { query, db, body, json, ... } ← 共享注入
|
|
6
|
-
* - ctx: { path, method, params, req, res } ← 共享请求上下文
|
|
7
|
-
* - return: boolean ← true 表示已处理
|
|
8
|
-
*
|
|
9
|
-
* http 工具 (json / body) 来自 lib/http.ts
|
|
10
|
-
*/
|
|
11
1
|
import { body as sharedBody, json as sharedJson } from "../lib/http.js";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
* service-routes / db / module-config / index 模块鉴权门应走此助手。
|
|
19
|
-
*/
|
|
20
|
-
export function jsonV2Fail(res, error, status, code) {
|
|
21
|
-
const payload = { ok: false, error };
|
|
22
|
-
if (code)
|
|
23
|
-
payload.code = code;
|
|
24
|
-
sharedJson(res, payload, status);
|
|
2
|
+
const json = sharedJson;
|
|
3
|
+
const body = sharedBody;
|
|
4
|
+
function jsonV2Fail(res, error, status, code, extra) {
|
|
5
|
+
const payload = { ...extra ?? {}, ok: false, error };
|
|
6
|
+
if (code) payload.code = code;
|
|
7
|
+
sharedJson(res, payload, status);
|
|
25
8
|
}
|
|
26
|
-
|
|
27
|
-
|
|
9
|
+
function jsonV2Ok(res, fields = {}, status = 200) {
|
|
10
|
+
sharedJson(res, { ...fields, ok: true }, status);
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
body,
|
|
14
|
+
json,
|
|
15
|
+
jsonV2Fail,
|
|
16
|
+
jsonV2Ok
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=_shared.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/routes/_shared.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * routes/_shared.ts \u2014 \u8DEF\u7531\u6A21\u5757\u5171\u4EAB\u7C7B\u578B + \u5DE5\u5382\n *\n * \u6240\u6709 db-server \u8DEF\u7531\u7EDF\u4E00:\n * - deps: { query, db, body, json, ... } \u2190 \u5171\u4EAB\u6CE8\u5165\n * - ctx: { path, method, params, req, res } \u2190 \u5171\u4EAB\u8BF7\u6C42\u4E0A\u4E0B\u6587\n * - return: boolean \u2190 true \u8868\u793A\u5DF2\u5904\u7406\n *\n * http \u5DE5\u5177 (json / body) \u6765\u81EA lib/http.ts\n */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { DatabaseSync } from \"node:sqlite\";\nimport type { Method } from \"../lib/http.js\";\nimport { body as sharedBody, json as sharedJson } from \"../lib/http.js\";\nimport type { QueryFn } from \"../lib/sqlite.js\";\n\nexport type { Method } from \"../lib/http.js\";\nexport type { QueryFn };\n\n/** shared deps factory \u2014 \u8DEF\u7531\u53EF\u58F0\u660E\u6700\u5C0F\u5316 deps \u5B50\u96C6 */\nexport type RouteDeps = {\n query: QueryFn;\n db: DatabaseSync;\n json: (res: ServerResponse, data: Record<string, unknown>, status?: number) => void;\n body: (req: IncomingMessage) => Promise<Record<string, unknown>>;\n params: URLSearchParams;\n projectRoot: string;\n monitorState?: { metrics: object | null; players: object[] };\n ensureEconomyAccount?: (\n playerId: string,\n playerName: string\n ) => { balance: number; player_id: string; version: number };\n economyResult?: (account: object | undefined) => { balance: number; version: number } | null;\n forwardToQQBridge?: (channelId: string, fromName: string, content: string, fromId: string) => void;\n land?: Record<string, (...args: unknown[]) => unknown>;\n};\n\n/** v2 \u6A21\u5757\u8EAB\u4EFD \u2014 \u7531 handle \u6821\u9A8C\u540E\u5199\u5165\u8DEF\u7531 ctx(\u52FF\u6302 req \u79C1\u6709\u5B57\u6BB5,LoD)\u3002 */\nexport type ModuleAuth = { id: string; permissions: string[] };\n\nexport type RouteCtx = {\n path: string;\n method: Method | string;\n params: URLSearchParams;\n req: IncomingMessage;\n res: ServerResponse;\n /** v2 \u8DEF\u7531\u4E13\u7528:\u6A21\u5757\u9274\u6743\u7ED3\u679C */\n moduleAuth?: ModuleAuth;\n};\n\nexport type RouteHandler = (ctx: RouteCtx) => Promise<boolean> | boolean;\n\nexport type RouteFactory = (deps: Partial<RouteDeps>) => RouteHandler;\n\n/** \u4FBF\u6377 re-export\uFF1A\u8DEF\u7531\u9ED8\u8BA4\u4ECE\u8FD9\u91CC\u53D6 json/body */\nexport const json = sharedJson;\nexport const body = sharedBody;\n\n/**\n * v2 \u5931\u8D25\u4FE1\u5C01\u6743\u5A01\u5F62\u6001(DRY + LSP):\n * \u4E00\u5F8B `{ ok:false, error, code? }`(+ \u53EF\u9009 extra),\u52FF\u518D\u6DF7\u7528 `{ success:false }`\u3002\n * service-routes / db / module-config / index \u6A21\u5757\u9274\u6743\u95E8\u5E94\u8D70\u6B64\u52A9\u624B\u3002\n */\nexport function jsonV2Fail(\n res: ServerResponse,\n error: string,\n status: number,\n code?: string,\n extra?: Record<string, unknown>\n): void {\n const payload: Record<string, unknown> = { ...(extra ?? {}), ok: false, error };\n if (code) payload.code = code;\n sharedJson(res, payload, status);\n}\n\n/**\n * v2 \u6210\u529F\u4FE1\u5C01\u6743\u5A01\u5F62\u6001(DRY + LSP):\n * \u4E00\u5F8B `{ ok:true, ...fields }`,\u4E0E jsonV2Fail \u5BF9\u79F0;\u5BA2\u6237\u7AEF\u5DF2\u53CC\u8BA4 ok/success\u3002\n */\nexport function jsonV2Ok(\n res: ServerResponse,\n fields: Record<string, unknown> = {},\n status = 200\n): void {\n sharedJson(res, { ...fields, ok: true }, status);\n}\n\nexport {};\n\n"],
|
|
5
|
+
"mappings": "AAcA,SAAS,QAAQ,YAAY,QAAQ,kBAAkB;AA0ChD,MAAM,OAAO;AACb,MAAM,OAAO;AAOb,SAAS,WACd,KACA,OACA,QACA,MACA,OACM;AACN,QAAM,UAAmC,EAAE,GAAI,SAAS,CAAC,GAAI,IAAI,OAAO,MAAM;AAC9E,MAAI,KAAM,SAAQ,OAAO;AACzB,aAAW,KAAK,SAAS,MAAM;AACjC;AAMO,SAAS,SACd,KACA,SAAkC,CAAC,GACnC,SAAS,KACH;AACN,aAAW,KAAK,EAAE,GAAG,QAAQ,IAAI,KAAK,GAAG,MAAM;AACjD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/routes/config.d.ts
CHANGED
|
@@ -16,8 +16,18 @@
|
|
|
16
16
|
interface Deps {
|
|
17
17
|
json: (res: import("http").ServerResponse, data: Record<string, unknown>, status?: number) => void;
|
|
18
18
|
projectRoot: string;
|
|
19
|
+
/**
|
|
20
|
+
* 注入模块列表(与 GET /api/sfmc/modules 同源 — DRY)。
|
|
21
|
+
* 勿在本路由再读 catalog/lock(DIP:高层装配,路由只消费抽象)。
|
|
22
|
+
*/
|
|
23
|
+
listModules?: () => Array<Record<string, unknown>>;
|
|
24
|
+
/**
|
|
25
|
+
* 注入模块 HMAC token 表(仅 loopback 可达;供 SAPI host-bootstrap 注入
|
|
26
|
+
* set*ModuleContext,因 SAPI 不能直接读与 DB 同目录的 module-tokens.json)。
|
|
27
|
+
*/
|
|
28
|
+
getModuleTokens?: () => Record<string, string>;
|
|
19
29
|
}
|
|
20
|
-
declare function createConfigRoutes({ json, projectRoot }: Deps): ({ path: requestPath, method, params, res, }: {
|
|
30
|
+
declare function createConfigRoutes({ json, projectRoot, listModules, getModuleTokens }: Deps): ({ path: requestPath, method, params, res, }: {
|
|
21
31
|
path: string;
|
|
22
32
|
method: string;
|
|
23
33
|
params: URLSearchParams;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/routes/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,UAAU,IAAI;IACZ,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnG,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/routes/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,UAAU,IAAI;IACZ,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnG,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChD;AAmCD,iBAAS,kBAAkB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,EAAE,IAAI,iDAgHhF;IACD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,eAAe,CAAC;IACxB,GAAG,EAAE,OAAO,MAAM,EAAE,cAAc,CAAC;CACpC,KAAG,OAAO,CAAC,OAAO,CAAC,CAuErB;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|