@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
package/dist/routes/config.js
CHANGED
|
@@ -1,236 +1,190 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* routes/config.ts — 配置路由(直接读取 configs/*.json)
|
|
3
|
-
*
|
|
4
|
-
* 路由列表:
|
|
5
|
-
* GET /api/sfmc/configs/all — SAPI 启动时一次性拉取所有配置
|
|
6
|
-
* GET /api/sfmc/settings — 平铺 settings.json
|
|
7
|
-
* GET /api/sfmc/settings/:key — 含 land:* / bridge_channel_id 等 fallback 查询
|
|
8
|
-
* GET /api/sfmc/areas — areas.json
|
|
9
|
-
* GET /api/sfmc/permissions — permissions.json
|
|
10
|
-
* GET /api/sfmc/banned_items — banned_items.json
|
|
11
|
-
* GET /api/sfmc/clean — clean.json
|
|
12
|
-
* GET /api/sfmc/grids — grids.json
|
|
13
|
-
* GET /api/sfmc/peace_filters — peace_filters.json
|
|
14
|
-
* GET /api/sfmc/qa — questions.json
|
|
15
|
-
*/
|
|
16
1
|
import { configPath, readJson } from "@sfmc-bds/sdk/node/config";
|
|
17
2
|
function isMetaKey(k) {
|
|
18
|
-
|
|
3
|
+
return k === "$schema" || String(k).startsWith("_");
|
|
19
4
|
}
|
|
20
5
|
function stripMetaDeep(v) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (v && typeof v === "object") {
|
|
24
|
-
const out = {};
|
|
25
|
-
for (const [k, val] of Object.entries(v)) {
|
|
26
|
-
if (!isMetaKey(k))
|
|
27
|
-
out[k] = stripMetaDeep(val);
|
|
28
|
-
}
|
|
29
|
-
return out;
|
|
30
|
-
}
|
|
31
|
-
return v;
|
|
32
|
-
}
|
|
33
|
-
function stripMeta(obj) {
|
|
34
|
-
if (!obj || typeof obj !== "object" || Array.isArray(obj))
|
|
35
|
-
return {};
|
|
6
|
+
if (Array.isArray(v)) return v.map(stripMetaDeep);
|
|
7
|
+
if (v && typeof v === "object") {
|
|
36
8
|
const out = {};
|
|
37
|
-
for (const [k,
|
|
38
|
-
|
|
39
|
-
out[k] = v;
|
|
9
|
+
for (const [k, val] of Object.entries(v)) {
|
|
10
|
+
if (!isMetaKey(k)) out[k] = stripMetaDeep(val);
|
|
40
11
|
}
|
|
41
12
|
return out;
|
|
13
|
+
}
|
|
14
|
+
return v;
|
|
15
|
+
}
|
|
16
|
+
function stripMeta(obj) {
|
|
17
|
+
if (!obj || typeof obj !== "object" || Array.isArray(obj)) return {};
|
|
18
|
+
const out = {};
|
|
19
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
20
|
+
if (!isMetaKey(k)) out[k] = v;
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
42
23
|
}
|
|
43
24
|
function jsonValue(v) {
|
|
44
|
-
|
|
25
|
+
return v !== null && typeof v === "object" ? JSON.stringify(v) : String(v ?? "");
|
|
45
26
|
}
|
|
46
27
|
function arrayOrEmpty(v) {
|
|
47
|
-
|
|
28
|
+
return Array.isArray(v) ? v : [];
|
|
48
29
|
}
|
|
49
|
-
function createConfigRoutes({ json, projectRoot }) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
id: idx + 1,
|
|
78
|
-
weight: clean.weight ?? 1,
|
|
79
|
-
question: clean.question,
|
|
80
|
-
answers: clean.answers ?? [],
|
|
81
|
-
msg_right: clean.msg_right ?? "",
|
|
82
|
-
msg_wrong: clean.msg_wrong ?? "",
|
|
83
|
-
explanation: clean.explanation ?? "",
|
|
84
|
-
min_rank: clean.min_rank ?? null,
|
|
85
|
-
max_rank: clean.max_rank ?? null,
|
|
86
|
-
rewards: clean.rewards ?? [],
|
|
87
|
-
punishments: clean.punishments ?? [],
|
|
88
|
-
};
|
|
89
|
-
}),
|
|
90
|
-
};
|
|
30
|
+
function createConfigRoutes({ json, projectRoot, listModules, getModuleTokens }) {
|
|
31
|
+
const readCfg = (name) => readJson(configPath(projectRoot, name));
|
|
32
|
+
function getAllConfigs() {
|
|
33
|
+
const modules = typeof listModules === "function" ? listModules() : [];
|
|
34
|
+
const module_tokens = typeof getModuleTokens === "function" ? getModuleTokens() : {};
|
|
35
|
+
return {
|
|
36
|
+
// 与 /api/sfmc/modules 同源;ConfigManager.init 一次拉齐启停态(DRY)
|
|
37
|
+
modules,
|
|
38
|
+
// loopback-only 下发;SAPI 无 fs,靠此注入模块身份(DIP)
|
|
39
|
+
module_tokens,
|
|
40
|
+
settings: stripMeta(readCfg("settings.json")),
|
|
41
|
+
areas: getAreas(),
|
|
42
|
+
permissions: getPermissions(),
|
|
43
|
+
banned_items: getBannedItems(),
|
|
44
|
+
clean: getClean(),
|
|
45
|
+
grids: getGrids(),
|
|
46
|
+
peace_filters: getPeaceFilters(),
|
|
47
|
+
questions: getQA()
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function getSettingsFlat() {
|
|
51
|
+
const obj = stripMeta(readJson(configPath(projectRoot, "settings.json")));
|
|
52
|
+
return Object.entries(obj).map(([key, value]) => ({ key, value: jsonValue(value) }));
|
|
53
|
+
}
|
|
54
|
+
function getSettingByKey(key) {
|
|
55
|
+
const settings = readJson(configPath(projectRoot, "settings.json")) ?? {};
|
|
56
|
+
if (Object.prototype.hasOwnProperty.call(settings, key) && !isMetaKey(key)) {
|
|
57
|
+
return { value: settings[key], source: "settings.json" };
|
|
91
58
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
59
|
+
if (key === "bridge_channel_id") {
|
|
60
|
+
const qq = readCfg("qq_config.json") ?? {};
|
|
61
|
+
if (qq.bridge_channel_id) return { value: qq.bridge_channel_id, source: "qq_config.json" };
|
|
95
62
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (key === "bridge_channel_id") {
|
|
102
|
-
const qq = readCfg("qq_config.json") ?? {};
|
|
103
|
-
if (qq.bridge_channel_id)
|
|
104
|
-
return { value: qq.bridge_channel_id, source: "qq_config.json" };
|
|
105
|
-
}
|
|
106
|
-
if (key.startsWith("land:")) {
|
|
107
|
-
const land = readCfg("land.json") ?? {};
|
|
108
|
-
if (Object.prototype.hasOwnProperty.call(land, key) && !isMetaKey(key)) {
|
|
109
|
-
return { value: land[key], source: "land.json" };
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return { value: null };
|
|
63
|
+
if (key.startsWith("land:")) {
|
|
64
|
+
const land = readCfg("land.json") ?? {};
|
|
65
|
+
if (Object.prototype.hasOwnProperty.call(land, key) && !isMetaKey(key)) {
|
|
66
|
+
return { value: land[key], source: "land.json" };
|
|
67
|
+
}
|
|
113
68
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
69
|
+
return { value: null };
|
|
70
|
+
}
|
|
71
|
+
function getAreas() {
|
|
72
|
+
return arrayOrEmpty(readCfg("areas.json")).filter((r) => r && r.module && r.dimension != null).map((r) => stripMetaDeep(r));
|
|
73
|
+
}
|
|
74
|
+
function getPermissions() {
|
|
75
|
+
return arrayOrEmpty(readCfg("permissions.json")).filter((r) => r && r.player_name).map((r) => stripMetaDeep(r));
|
|
76
|
+
}
|
|
77
|
+
function getBannedItems() {
|
|
78
|
+
return arrayOrEmpty(readCfg("banned_items.json")).filter(
|
|
79
|
+
(i) => typeof i === "string" && i && !i.startsWith("_")
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
function getClean() {
|
|
83
|
+
const c = stripMetaDeep(readCfg("clean.json") ?? {});
|
|
84
|
+
return { item_max: c.item_max ?? 192, poll_interval: c.poll_interval ?? 60 };
|
|
85
|
+
}
|
|
86
|
+
function getGrids() {
|
|
87
|
+
return arrayOrEmpty(readCfg("grids.json")).filter((r) => r && r.name).map((r) => stripMetaDeep(r));
|
|
88
|
+
}
|
|
89
|
+
function getPeaceFilters() {
|
|
90
|
+
return arrayOrEmpty(readCfg("peace_filters.json")).filter((r) => r && r.family).map((r) => stripMetaDeep(r));
|
|
91
|
+
}
|
|
92
|
+
function getQA() {
|
|
93
|
+
return arrayOrEmpty(readCfg("questions.json")).filter((r) => r && r.question).map((r, idx) => {
|
|
94
|
+
const clean = stripMetaDeep(r);
|
|
95
|
+
return {
|
|
96
|
+
id: idx + 1,
|
|
97
|
+
weight: clean.weight ?? 1,
|
|
98
|
+
question: clean.question,
|
|
99
|
+
answers: clean.answers ?? [],
|
|
100
|
+
msg_right: clean.msg_right ?? "",
|
|
101
|
+
msg_wrong: clean.msg_wrong ?? "",
|
|
102
|
+
explanation: clean.explanation ?? "",
|
|
103
|
+
min_rank: clean.min_rank ?? null,
|
|
104
|
+
max_rank: clean.max_rank ?? null,
|
|
105
|
+
rewards: clean.rewards ?? [],
|
|
106
|
+
punishments: clean.punishments ?? []
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return async function handleConfigRoute({
|
|
111
|
+
path: requestPath,
|
|
112
|
+
method,
|
|
113
|
+
params,
|
|
114
|
+
res
|
|
115
|
+
}) {
|
|
116
|
+
void params;
|
|
117
|
+
if (requestPath === "/api/sfmc/configs/all") {
|
|
118
|
+
if (method !== "GET") {
|
|
119
|
+
json(res, { success: false, error: "not_found" }, 404);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
json(res, getAllConfigs());
|
|
123
|
+
return true;
|
|
118
124
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
125
|
+
if (requestPath === "/api/sfmc/settings") {
|
|
126
|
+
if (method === "GET") {
|
|
127
|
+
json(res, { settings: getSettingsFlat() });
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
json(res, { success: false, error: "not_found" }, 404);
|
|
131
|
+
return true;
|
|
123
132
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
if (requestPath.startsWith("/api/sfmc/settings/")) {
|
|
134
|
+
const key = decodeURIComponent(requestPath.slice("/api/sfmc/settings/".length));
|
|
135
|
+
if (method === "GET") {
|
|
136
|
+
json(res, getSettingByKey(key));
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
json(res, { success: false, error: "method_not_allowed" }, 405);
|
|
140
|
+
return true;
|
|
128
141
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
142
|
+
if (requestPath === "/api/sfmc/areas") {
|
|
143
|
+
if (method === "GET") {
|
|
144
|
+
json(res, { areas: getAreas() });
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
132
147
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
148
|
+
if (requestPath === "/api/sfmc/permissions") {
|
|
149
|
+
if (method === "GET") {
|
|
150
|
+
json(res, { permissions: getPermissions() });
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
137
153
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
154
|
+
if (requestPath === "/api/sfmc/banned_items") {
|
|
155
|
+
if (method === "GET") {
|
|
156
|
+
json(res, { items: getBannedItems() });
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
142
159
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return {
|
|
149
|
-
id: idx + 1,
|
|
150
|
-
weight: clean.weight ?? 1,
|
|
151
|
-
question: clean.question,
|
|
152
|
-
answers: clean.answers ?? [],
|
|
153
|
-
msg_right: clean.msg_right ?? "",
|
|
154
|
-
msg_wrong: clean.msg_wrong ?? "",
|
|
155
|
-
explanation: clean.explanation ?? "",
|
|
156
|
-
min_rank: clean.min_rank ?? null,
|
|
157
|
-
max_rank: clean.max_rank ?? null,
|
|
158
|
-
rewards: clean.rewards ?? [],
|
|
159
|
-
punishments: clean.punishments ?? [],
|
|
160
|
-
};
|
|
161
|
-
});
|
|
160
|
+
if (requestPath === "/api/sfmc/clean") {
|
|
161
|
+
if (method === "GET") {
|
|
162
|
+
json(res, { clean: getClean() });
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
162
165
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (method === "GET") {
|
|
184
|
-
json(res, getSettingByKey(key));
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
json(res, { success: false, error: "method_not_allowed" }, 405);
|
|
188
|
-
return true;
|
|
189
|
-
}
|
|
190
|
-
if (requestPath === "/api/sfmc/areas") {
|
|
191
|
-
if (method === "GET") {
|
|
192
|
-
json(res, { areas: getAreas() });
|
|
193
|
-
return true;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
if (requestPath === "/api/sfmc/permissions") {
|
|
197
|
-
if (method === "GET") {
|
|
198
|
-
json(res, { permissions: getPermissions() });
|
|
199
|
-
return true;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
if (requestPath === "/api/sfmc/banned_items") {
|
|
203
|
-
if (method === "GET") {
|
|
204
|
-
json(res, { items: getBannedItems().map((x) => x.item_id) });
|
|
205
|
-
return true;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
if (requestPath === "/api/sfmc/clean") {
|
|
209
|
-
if (method === "GET") {
|
|
210
|
-
json(res, { clean: getClean() });
|
|
211
|
-
return true;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
if (requestPath === "/api/sfmc/grids") {
|
|
215
|
-
if (method === "GET") {
|
|
216
|
-
json(res, { grids: getGrids() });
|
|
217
|
-
return true;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
if (requestPath === "/api/sfmc/peace_filters") {
|
|
221
|
-
if (method === "GET") {
|
|
222
|
-
json(res, { filters: getPeaceFilters() });
|
|
223
|
-
return true;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
if (requestPath === "/api/sfmc/qa") {
|
|
227
|
-
if (method === "GET") {
|
|
228
|
-
json(res, { questions: getQA() });
|
|
229
|
-
return true;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return false;
|
|
233
|
-
};
|
|
166
|
+
if (requestPath === "/api/sfmc/grids") {
|
|
167
|
+
if (method === "GET") {
|
|
168
|
+
json(res, { grids: getGrids() });
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (requestPath === "/api/sfmc/peace_filters") {
|
|
173
|
+
if (method === "GET") {
|
|
174
|
+
json(res, { filters: getPeaceFilters() });
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (requestPath === "/api/sfmc/qa") {
|
|
179
|
+
if (method === "GET") {
|
|
180
|
+
json(res, { questions: getQA() });
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return false;
|
|
185
|
+
};
|
|
234
186
|
}
|
|
235
|
-
export {
|
|
236
|
-
|
|
187
|
+
export {
|
|
188
|
+
createConfigRoutes
|
|
189
|
+
};
|
|
190
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/routes/config.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * routes/config.ts \u2014 \u914D\u7F6E\u8DEF\u7531\uFF08\u76F4\u63A5\u8BFB\u53D6 configs/*.json\uFF09\n *\n * \u8DEF\u7531\u5217\u8868\uFF1A\n * GET /api/sfmc/configs/all \u2014 SAPI \u542F\u52A8\u65F6\u4E00\u6B21\u6027\u62C9\u53D6\u6240\u6709\u914D\u7F6E\n * GET /api/sfmc/settings \u2014 \u5E73\u94FA settings.json\n * GET /api/sfmc/settings/:key \u2014 \u542B land:* / bridge_channel_id \u7B49 fallback \u67E5\u8BE2\n * GET /api/sfmc/areas \u2014 areas.json\n * GET /api/sfmc/permissions \u2014 permissions.json\n * GET /api/sfmc/banned_items \u2014 banned_items.json\n * GET /api/sfmc/clean \u2014 clean.json\n * GET /api/sfmc/grids \u2014 grids.json\n * GET /api/sfmc/peace_filters \u2014 peace_filters.json\n * GET /api/sfmc/qa \u2014 questions.json\n */\n\nimport { configPath, readJson, type ConfigName } from \"@sfmc-bds/sdk/node/config\";\n\ninterface Deps {\n json: (res: import(\"http\").ServerResponse, data: Record<string, unknown>, status?: number) => void;\n projectRoot: string;\n /**\n * \u6CE8\u5165\u6A21\u5757\u5217\u8868(\u4E0E GET /api/sfmc/modules \u540C\u6E90 \u2014 DRY)\u3002\n * \u52FF\u5728\u672C\u8DEF\u7531\u518D\u8BFB catalog/lock(DIP:\u9AD8\u5C42\u88C5\u914D,\u8DEF\u7531\u53EA\u6D88\u8D39\u62BD\u8C61)\u3002\n */\n listModules?: () => Array<Record<string, unknown>>;\n /**\n * \u6CE8\u5165\u6A21\u5757 HMAC token \u8868(\u4EC5 loopback \u53EF\u8FBE;\u4F9B SAPI host-bootstrap \u6CE8\u5165\n * set*ModuleContext,\u56E0 SAPI \u4E0D\u80FD\u76F4\u63A5\u8BFB\u4E0E DB \u540C\u76EE\u5F55\u7684 module-tokens.json)\u3002\n */\n getModuleTokens?: () => Record<string, string>;\n}\n\nfunction isMetaKey(k: string): boolean {\n return k === \"$schema\" || String(k).startsWith(\"_\");\n}\n\nfunction stripMetaDeep(v: unknown): unknown {\n if (Array.isArray(v)) return v.map(stripMetaDeep);\n if (v && typeof v === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, val] of Object.entries(v as Record<string, unknown>)) {\n if (!isMetaKey(k)) out[k] = stripMetaDeep(val);\n }\n return out;\n }\n return v;\n}\n\nfunction stripMeta(obj: Record<string, unknown> | null): Record<string, unknown> {\n if (!obj || typeof obj !== \"object\" || Array.isArray(obj)) return {};\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (!isMetaKey(k)) out[k] = v;\n }\n return out;\n}\n\nfunction jsonValue(v: unknown): string {\n return v !== null && typeof v === \"object\" ? JSON.stringify(v) : String(v ?? \"\");\n}\n\nfunction arrayOrEmpty(v: unknown): unknown[] {\n return Array.isArray(v) ? v : [];\n}\n\nfunction createConfigRoutes({ json, projectRoot, listModules, getModuleTokens }: Deps) {\n /** \u4ED3\u9876\u670D\u52A1 config \u8BFB\u53D6\u7EDF\u4E00\u8D70 SDK;\u95ED\u5305\u6355\u83B7 projectRoot\u3002 */\n const readCfg = (name: ConfigName): unknown => readJson(configPath(projectRoot, name));\n\n function getAllConfigs(): Record<string, unknown> {\n const modules = typeof listModules === \"function\" ? listModules() : [];\n const module_tokens = typeof getModuleTokens === \"function\" ? getModuleTokens() : {};\n /**\n * SAPI ConfigManager \u5951\u7EA6:banned_items \u4E3A string[](\u4E0E GET /banned_items \u540C\u6E90)\u3002\n * \u52FF\u518D\u6620\u5C04\u6210 {item_id} \u2014 \u5426\u5219 filter(typeof s === \"string\") \u4F1A\u5F97\u5230\u7A7A\u7F13\u5B58(LSP)\u3002\n * \u5176\u4F59\u8D44\u6E90\u590D\u7528\u5355\u8D44\u6E90 helpers,\u907F\u514D getAllConfigs \u4E0E\u4E13\u7528\u8DEF\u7531\u53CC\u5199(DRY)\u3002\n */\n return {\n // \u4E0E /api/sfmc/modules \u540C\u6E90;ConfigManager.init \u4E00\u6B21\u62C9\u9F50\u542F\u505C\u6001(DRY)\n modules,\n // loopback-only \u4E0B\u53D1;SAPI \u65E0 fs,\u9760\u6B64\u6CE8\u5165\u6A21\u5757\u8EAB\u4EFD(DIP)\n module_tokens,\n settings: stripMeta(readCfg(\"settings.json\") as Record<string, unknown> | null),\n areas: getAreas(),\n permissions: getPermissions(),\n banned_items: getBannedItems(),\n clean: getClean(),\n grids: getGrids(),\n peace_filters: getPeaceFilters(),\n questions: getQA(),\n };\n }\n\n function getSettingsFlat(): Array<{ key: string; value: string }> {\n const obj = stripMeta(readJson(configPath(projectRoot, \"settings.json\")) as Record<string, unknown> | null);\n return Object.entries(obj).map(([key, value]) => ({ key, value: jsonValue(value) }));\n }\n\n function getSettingByKey(key: string): { value: unknown; source?: string } {\n const settings = (readJson(configPath(projectRoot, \"settings.json\")) as Record<string, unknown> | null) ?? {};\n if (Object.prototype.hasOwnProperty.call(settings, key) && !isMetaKey(key)) {\n return { value: settings[key], source: \"settings.json\" };\n }\n if (key === \"bridge_channel_id\") {\n const qq = (readCfg(\"qq_config.json\") as Record<string, unknown> | null) ?? {};\n if (qq.bridge_channel_id) return { value: qq.bridge_channel_id, source: \"qq_config.json\" };\n }\n if (key.startsWith(\"land:\")) {\n const land = (readCfg(\"land.json\") as Record<string, unknown> | null) ?? {};\n if (Object.prototype.hasOwnProperty.call(land, key) && !isMetaKey(key)) {\n return { value: land[key], source: \"land.json\" };\n }\n }\n return { value: null };\n }\n\n function getAreas(): unknown[] {\n return (arrayOrEmpty(readCfg(\"areas.json\")) as Array<Record<string, unknown>>)\n .filter((r) => r && r.module && r.dimension != null)\n .map((r) => stripMetaDeep(r));\n }\n\n function getPermissions(): unknown[] {\n return (arrayOrEmpty(readCfg(\"permissions.json\")) as Array<Record<string, unknown>>)\n .filter((r) => r && r.player_name)\n .map((r) => stripMetaDeep(r));\n }\n\n function getBannedItems(): string[] {\n return (arrayOrEmpty(readCfg(\"banned_items.json\")) as Array<string>).filter(\n (i) => typeof i === \"string\" && i && !i.startsWith(\"_\")\n );\n }\n\n function getClean(): { item_max: number; poll_interval: number } {\n const c = stripMetaDeep(readCfg(\"clean.json\") ?? {}) as Record<string, unknown>;\n return { item_max: (c.item_max as number) ?? 192, poll_interval: (c.poll_interval as number) ?? 60 };\n }\n\n function getGrids(): unknown[] {\n return (arrayOrEmpty(readCfg(\"grids.json\")) as Array<Record<string, unknown>>)\n .filter((r) => r && r.name)\n .map((r) => stripMetaDeep(r));\n }\n\n function getPeaceFilters(): unknown[] {\n return (arrayOrEmpty(readCfg(\"peace_filters.json\")) as Array<Record<string, unknown>>)\n .filter((r) => r && r.family)\n .map((r) => stripMetaDeep(r));\n }\n\n function getQA(): Array<Record<string, unknown>> {\n return (arrayOrEmpty(readCfg(\"questions.json\")) as Array<Record<string, unknown>>)\n .filter((r) => r && r.question)\n .map((r, idx) => {\n const clean = stripMetaDeep(r) as Record<string, unknown>;\n return {\n id: idx + 1,\n weight: clean.weight ?? 1,\n question: clean.question,\n answers: clean.answers ?? [],\n msg_right: clean.msg_right ?? \"\",\n msg_wrong: clean.msg_wrong ?? \"\",\n explanation: clean.explanation ?? \"\",\n min_rank: clean.min_rank ?? null,\n max_rank: clean.max_rank ?? null,\n rewards: clean.rewards ?? [],\n punishments: clean.punishments ?? [],\n };\n });\n }\n\n return async function handleConfigRoute({\n path: requestPath,\n method,\n params,\n res,\n }: {\n path: string;\n method: string;\n params: URLSearchParams;\n res: import(\"http\").ServerResponse;\n }): Promise<boolean> {\n void params;\n if (requestPath === \"/api/sfmc/configs/all\") {\n if (method !== \"GET\") {\n json(res, { success: false, error: \"not_found\" }, 404);\n return true;\n }\n json(res, getAllConfigs());\n return true;\n }\n if (requestPath === \"/api/sfmc/settings\") {\n if (method === \"GET\") {\n json(res, { settings: getSettingsFlat() });\n return true;\n }\n json(res, { success: false, error: \"not_found\" }, 404);\n return true;\n }\n if (requestPath.startsWith(\"/api/sfmc/settings/\")) {\n const key = decodeURIComponent(requestPath.slice(\"/api/sfmc/settings/\".length));\n if (method === \"GET\") {\n json(res, getSettingByKey(key));\n return true;\n }\n json(res, { success: false, error: \"method_not_allowed\" }, 405);\n return true;\n }\n if (requestPath === \"/api/sfmc/areas\") {\n if (method === \"GET\") {\n json(res, { areas: getAreas() });\n return true;\n }\n }\n if (requestPath === \"/api/sfmc/permissions\") {\n if (method === \"GET\") {\n json(res, { permissions: getPermissions() });\n return true;\n }\n }\n if (requestPath === \"/api/sfmc/banned_items\") {\n if (method === \"GET\") {\n json(res, { items: getBannedItems() });\n return true;\n }\n }\n if (requestPath === \"/api/sfmc/clean\") {\n if (method === \"GET\") {\n json(res, { clean: getClean() });\n return true;\n }\n }\n if (requestPath === \"/api/sfmc/grids\") {\n if (method === \"GET\") {\n json(res, { grids: getGrids() });\n return true;\n }\n }\n if (requestPath === \"/api/sfmc/peace_filters\") {\n if (method === \"GET\") {\n json(res, { filters: getPeaceFilters() });\n return true;\n }\n }\n if (requestPath === \"/api/sfmc/qa\") {\n if (method === \"GET\") {\n json(res, { questions: getQA() });\n return true;\n }\n }\n return false;\n };\n}\n\nexport { createConfigRoutes };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -3,17 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 端点:
|
|
5
5
|
* POST /api/sfmc/db/define-table body {name, columns, softDelete?} → {table, created}
|
|
6
|
-
* POST /api/sfmc/db/tx body {steps[]} → TxResponse | TxError
|
|
6
|
+
* POST /api/sfmc/db/tx body {steps[]} → TxResponse | TxError (批量)
|
|
7
|
+
* POST /api/sfmc/db/tx/begin body {} → {txId}
|
|
8
|
+
* POST /api/sfmc/db/tx/step body {txId, step} → {result}
|
|
9
|
+
* POST /api/sfmc/db/tx/commit body {txId} → TxResponse
|
|
10
|
+
* POST /api/sfmc/db/tx/rollback body {txId} → {ok}
|
|
7
11
|
* POST /api/sfmc/db/query body {table, opts?} → {rows}
|
|
8
|
-
*
|
|
9
|
-
* POST /api/sfmc/db/insert body {table, row} → {row}
|
|
10
|
-
* POST /api/sfmc/db/update body {table, id, patch} → {row}
|
|
11
|
-
* POST /api/sfmc/db/delete body {table, id, hard?} → {changes}
|
|
12
|
-
* POST /api/sfmc/db/audit body {table, rowId, action, data?} → {ok}
|
|
13
|
-
* POST /api/sfmc/db/idempotent/probe body {action, key} → {replayed, cached?}
|
|
14
|
-
* POST /api/sfmc/db/idempotent/commit body {action, key, value?} → {ok}
|
|
15
|
-
*
|
|
16
|
-
* 鉴权:handle() 校验后把 {id, permissions} 写到 ctx.moduleAuth(不挂 req)。
|
|
12
|
+
* ...
|
|
17
13
|
*/
|
|
18
14
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
19
15
|
import { json as defaultJson, type Method } from "../lib/http.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-routes.d.ts","sourceRoot":"","sources":["../../src/routes/db-routes.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"db-routes.d.ts","sourceRoot":"","sources":["../../src/routes/db-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAEV,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAEV,QAAQ,EAET,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,WAAW,CAAC;CAC3B;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,SAOvC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,GAAG,EAAE,eAAe,CAAC;IACrB,GAAG,EAAE,cAAc,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClE,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,KAAG,OAAO,CAAC,OAAO,CAAC,CA6KrB"}
|