befly 3.14.0 → 3.14.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/dist/befly.js +299 -115
- package/dist/befly.min.js +11 -11
- package/dist/index.js +14 -5
- package/dist/lib/asyncContext.js +4 -4
- package/dist/lib/cacheHelper.d.ts +2 -2
- package/dist/lib/dbHelper.d.ts +21 -13
- package/dist/lib/dbHelper.js +37 -9
- package/dist/lib/dbUtils.js +95 -20
- package/dist/lib/jwt.js +31 -19
- package/dist/lib/logger.js +7 -7
- package/dist/lib/sqlBuilder.js +53 -13
- package/dist/lib/validator.js +1 -1
- package/dist/loader/loadHooks.js +1 -1
- package/dist/loader/loadPlugins.js +1 -1
- package/dist/router/api.js +7 -6
- package/dist/sync/syncTable.d.ts +1 -1
- package/dist/sync/syncTable.js +31 -10
- package/dist/types/common.d.ts +9 -9
- package/dist/types/database.d.ts +25 -22
- package/dist/utils/loadMenuConfigs.js +1 -1
- package/dist/utils/loggerUtils.js +7 -3
- package/dist/utils/processInfo.js +2 -2
- package/dist/utils/scanFiles.js +12 -12
- package/dist/utils/util.js +10 -3
- package/package.json +2 -2
package/dist/befly.js
CHANGED
|
@@ -105,16 +105,20 @@ function upperFirst(s) {
|
|
|
105
105
|
if (s.length === 0) {
|
|
106
106
|
return s;
|
|
107
107
|
}
|
|
108
|
-
return s
|
|
108
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
109
109
|
}
|
|
110
110
|
function camelCase(input) {
|
|
111
111
|
const parts = toWordParts(input);
|
|
112
112
|
if (parts.length === 0) {
|
|
113
113
|
return "";
|
|
114
114
|
}
|
|
115
|
-
const
|
|
115
|
+
const firstPart = parts[0];
|
|
116
|
+
if (!firstPart) {
|
|
117
|
+
return "";
|
|
118
|
+
}
|
|
119
|
+
const first = firstPart.toLowerCase();
|
|
116
120
|
const rest = parts.slice(1).map((p) => upperFirst(p.toLowerCase()));
|
|
117
|
-
return [first
|
|
121
|
+
return [first].concat(rest).join("");
|
|
118
122
|
}
|
|
119
123
|
function normalizeToWords(input) {
|
|
120
124
|
return String(input).replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[^a-zA-Z0-9]+/g, " ").trim();
|
|
@@ -235,7 +239,7 @@ function sanitizeErrorValue(err, options) {
|
|
|
235
239
|
message: truncateString(err.message || "", options.maxStringLen)
|
|
236
240
|
};
|
|
237
241
|
if (typeof err.stack === "string") {
|
|
238
|
-
out
|
|
242
|
+
out["stack"] = truncateString(err.stack, options.maxStringLen);
|
|
239
243
|
}
|
|
240
244
|
return out;
|
|
241
245
|
}
|
|
@@ -323,8 +327,12 @@ function sanitizeAny(value, options, state, depth, visited) {
|
|
|
323
327
|
const entries = Object.entries(obj);
|
|
324
328
|
const limit = entries.length > options.sanitizeObjectKeys ? options.sanitizeObjectKeys : entries.length;
|
|
325
329
|
for (let i = 0;i < limit; i++) {
|
|
326
|
-
const
|
|
327
|
-
|
|
330
|
+
const entry = entries[i];
|
|
331
|
+
if (!entry) {
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
const key = entry[0];
|
|
335
|
+
const child = entry[1];
|
|
328
336
|
if (isSensitiveKey(key, options.sensitiveKeyMatcher)) {
|
|
329
337
|
out[key] = "[MASKED]";
|
|
330
338
|
continue;
|
|
@@ -365,10 +373,10 @@ function setCtxUser(userId, roleCode, nickname, roleType) {
|
|
|
365
373
|
const store = storage.getStore();
|
|
366
374
|
if (!store)
|
|
367
375
|
return;
|
|
368
|
-
store.userId = userId;
|
|
369
|
-
store.roleCode = roleCode;
|
|
370
|
-
store.nickname = nickname;
|
|
371
|
-
store.roleType = roleType;
|
|
376
|
+
store.userId = userId === undefined ? null : userId;
|
|
377
|
+
store.roleCode = roleCode === undefined ? null : roleCode;
|
|
378
|
+
store.nickname = nickname === undefined ? null : nickname;
|
|
379
|
+
store.roleType = roleType === undefined ? null : roleType;
|
|
372
380
|
}
|
|
373
381
|
var storage;
|
|
374
382
|
var init_asyncContext = __esm(() => {
|
|
@@ -798,8 +806,8 @@ function buildLogLine(level, record) {
|
|
|
798
806
|
return `${safeJsonStringify(out)}
|
|
799
807
|
`;
|
|
800
808
|
}
|
|
801
|
-
if (base
|
|
802
|
-
base
|
|
809
|
+
if (base["msg"] === undefined) {
|
|
810
|
+
base["msg"] = "";
|
|
803
811
|
}
|
|
804
812
|
return `${safeJsonStringify(base)}
|
|
805
813
|
`;
|
|
@@ -809,7 +817,7 @@ function safeJsonStringify(obj) {
|
|
|
809
817
|
return JSON.stringify(obj);
|
|
810
818
|
} catch {
|
|
811
819
|
try {
|
|
812
|
-
return JSON.stringify({ level: obj
|
|
820
|
+
return JSON.stringify({ level: obj["level"], time: obj["time"], pid: obj["pid"], hostname: obj["hostname"], msg: "[Unserializable log record]" });
|
|
813
821
|
} catch {
|
|
814
822
|
return '{"msg":"[Unserializable log record]"}';
|
|
815
823
|
}
|
|
@@ -855,10 +863,10 @@ function metaToObject() {
|
|
|
855
863
|
now: meta.now,
|
|
856
864
|
durationSinceNowMs
|
|
857
865
|
};
|
|
858
|
-
obj
|
|
859
|
-
obj
|
|
860
|
-
obj
|
|
861
|
-
obj
|
|
866
|
+
obj["userId"] = meta.userId;
|
|
867
|
+
obj["roleCode"] = meta.roleCode;
|
|
868
|
+
obj["nickname"] = meta.nickname;
|
|
869
|
+
obj["roleType"] = meta.roleType;
|
|
862
870
|
return obj;
|
|
863
871
|
}
|
|
864
872
|
function mergeMetaIntoObject(input, meta) {
|
|
@@ -1309,7 +1317,7 @@ async function scanViewsDirToMenuConfigs(viewsDir, prefix, parentPath = "") {
|
|
|
1309
1317
|
return menus;
|
|
1310
1318
|
}
|
|
1311
1319
|
function getParentPath(path) {
|
|
1312
|
-
const parts = path.split("/").filter((p) =>
|
|
1320
|
+
const parts = path.split("/").filter((p) => Boolean(p));
|
|
1313
1321
|
if (parts.length <= 1) {
|
|
1314
1322
|
return "";
|
|
1315
1323
|
}
|
|
@@ -8468,7 +8476,7 @@ async function loadHooks(hooks) {
|
|
|
8468
8476
|
hooksMap.push({
|
|
8469
8477
|
name: hookName,
|
|
8470
8478
|
enable: true,
|
|
8471
|
-
deps: hook.deps,
|
|
8479
|
+
deps: Array.isArray(hook.deps) ? hook.deps : [],
|
|
8472
8480
|
handler: hook.handler
|
|
8473
8481
|
});
|
|
8474
8482
|
}
|
|
@@ -8502,7 +8510,7 @@ async function loadPlugins(plugins, context) {
|
|
|
8502
8510
|
pluginsMap.push({
|
|
8503
8511
|
name: pluginName,
|
|
8504
8512
|
enable: true,
|
|
8505
|
-
deps: plugin.deps,
|
|
8513
|
+
deps: Array.isArray(plugin.deps) ? plugin.deps : [],
|
|
8506
8514
|
handler: plugin.handler
|
|
8507
8515
|
});
|
|
8508
8516
|
} catch (error) {
|
|
@@ -8641,11 +8649,12 @@ function apiHandler(apis, hooks, context) {
|
|
|
8641
8649
|
requestId,
|
|
8642
8650
|
corsHeaders: {
|
|
8643
8651
|
"X-Request-ID": requestId
|
|
8644
|
-
}
|
|
8645
|
-
api: apis.get(apiPath),
|
|
8646
|
-
response: undefined,
|
|
8647
|
-
result: undefined
|
|
8652
|
+
}
|
|
8648
8653
|
};
|
|
8654
|
+
const api = apis.get(apiPath);
|
|
8655
|
+
if (api) {
|
|
8656
|
+
ctx.api = api;
|
|
8657
|
+
}
|
|
8649
8658
|
return withCtx({
|
|
8650
8659
|
requestId,
|
|
8651
8660
|
method: req.method,
|
|
@@ -8666,9 +8675,9 @@ function apiHandler(apis, hooks, context) {
|
|
|
8666
8675
|
apiName: ctx.api.name
|
|
8667
8676
|
};
|
|
8668
8677
|
if (ctx.body && Object.keys(ctx.body).length > 0) {
|
|
8669
|
-
logData
|
|
8678
|
+
logData["body"] = ctx.body;
|
|
8670
8679
|
}
|
|
8671
|
-
logData
|
|
8680
|
+
logData["msg"] = "request";
|
|
8672
8681
|
Logger.info(logData);
|
|
8673
8682
|
}
|
|
8674
8683
|
if (!ctx.api) {
|
|
@@ -10085,8 +10094,14 @@ async function getTableColumnsRuntime(runtime, tableName) {
|
|
|
10085
10094
|
let max = null;
|
|
10086
10095
|
const m = /^(\w+)\s*\((\d+)\)/.exec(baseType);
|
|
10087
10096
|
if (m) {
|
|
10088
|
-
|
|
10089
|
-
|
|
10097
|
+
const base = m[1];
|
|
10098
|
+
const maxText = m[2];
|
|
10099
|
+
if (typeof base === "string") {
|
|
10100
|
+
baseType = base;
|
|
10101
|
+
}
|
|
10102
|
+
if (typeof maxText === "string") {
|
|
10103
|
+
max = Number(maxText);
|
|
10104
|
+
}
|
|
10090
10105
|
}
|
|
10091
10106
|
columns[row.name] = {
|
|
10092
10107
|
type: baseType.toLowerCase(),
|
|
@@ -10115,9 +10130,13 @@ async function getTableIndexesRuntime(runtime, tableName) {
|
|
|
10115
10130
|
const q = getSyncTableIndexesQuery({ dialect: "mysql", table: tableName, dbName: runtime.dbName });
|
|
10116
10131
|
const result = await runtime.db.unsafe(q.sql, q.params);
|
|
10117
10132
|
for (const row of result.data) {
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10133
|
+
const indexName = row.INDEX_NAME;
|
|
10134
|
+
const current = indexes[indexName];
|
|
10135
|
+
if (Array.isArray(current)) {
|
|
10136
|
+
current.push(row.COLUMN_NAME);
|
|
10137
|
+
} else {
|
|
10138
|
+
indexes[indexName] = [row.COLUMN_NAME];
|
|
10139
|
+
}
|
|
10121
10140
|
}
|
|
10122
10141
|
} else if (runtime.dbDialect === "postgresql") {
|
|
10123
10142
|
const q = getSyncTableIndexesQuery({ dialect: "postgresql", table: tableName, dbName: runtime.dbName });
|
|
@@ -10125,7 +10144,8 @@ async function getTableIndexesRuntime(runtime, tableName) {
|
|
|
10125
10144
|
for (const row of result.data) {
|
|
10126
10145
|
const m = /\(([^)]+)\)/.exec(row.indexdef);
|
|
10127
10146
|
if (m) {
|
|
10128
|
-
const
|
|
10147
|
+
const colPart = m[1];
|
|
10148
|
+
const col = typeof colPart === "string" ? colPart.replace(/"/g, "").trim() : "";
|
|
10129
10149
|
indexes[row.indexname] = [col];
|
|
10130
10150
|
}
|
|
10131
10151
|
}
|
|
@@ -10158,7 +10178,8 @@ async function ensureDbVersion(dbDialect, db) {
|
|
|
10158
10178
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6 MySQL \u7248\u672C\u4FE1\u606F");
|
|
10159
10179
|
}
|
|
10160
10180
|
const version = r.data[0].version;
|
|
10161
|
-
const
|
|
10181
|
+
const majorPart = String(version).split(".")[0] || "0";
|
|
10182
|
+
const majorVersion = parseInt(majorPart, 10);
|
|
10162
10183
|
if (!Number.isFinite(majorVersion) || majorVersion < DB_VERSION_REQUIREMENTS.MYSQL_MIN_MAJOR) {
|
|
10163
10184
|
throw new Error(`\u6B64\u811A\u672C\u4EC5\u652F\u6301 MySQL ${DB_VERSION_REQUIREMENTS.MYSQL_MIN_MAJOR}.0+\uFF0C\u5F53\u524D\u7248\u672C: ${version}`);
|
|
10164
10185
|
}
|
|
@@ -10171,7 +10192,8 @@ async function ensureDbVersion(dbDialect, db) {
|
|
|
10171
10192
|
}
|
|
10172
10193
|
const versionText = r.data[0].version;
|
|
10173
10194
|
const m = /PostgreSQL\s+(\d+)/i.exec(versionText);
|
|
10174
|
-
const
|
|
10195
|
+
const majorText = m ? m[1] : undefined;
|
|
10196
|
+
const major = typeof majorText === "string" ? parseInt(majorText, 10) : NaN;
|
|
10175
10197
|
if (!Number.isFinite(major) || major < DB_VERSION_REQUIREMENTS.POSTGRES_MIN_MAJOR) {
|
|
10176
10198
|
throw new Error(`\u6B64\u811A\u672C\u8981\u6C42 PostgreSQL >= ${DB_VERSION_REQUIREMENTS.POSTGRES_MIN_MAJOR}\uFF0C\u5F53\u524D: ${versionText}`);
|
|
10177
10199
|
}
|
|
@@ -10183,7 +10205,10 @@ async function ensureDbVersion(dbDialect, db) {
|
|
|
10183
10205
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6 SQLite \u7248\u672C\u4FE1\u606F");
|
|
10184
10206
|
}
|
|
10185
10207
|
const version = r.data[0].version;
|
|
10186
|
-
const
|
|
10208
|
+
const parts = String(version).split(".").map((v) => parseInt(v, 10) || 0);
|
|
10209
|
+
const maj = parts[0] ?? 0;
|
|
10210
|
+
const min = parts[1] ?? 0;
|
|
10211
|
+
const patch = parts[2] ?? 0;
|
|
10187
10212
|
const vnum = maj * 1e4 + min * 100 + patch;
|
|
10188
10213
|
if (!Number.isFinite(vnum) || vnum < DB_VERSION_REQUIREMENTS.SQLITE_MIN_VERSION_NUM) {
|
|
10189
10214
|
throw new Error(`\u6B64\u811A\u672C\u8981\u6C42 SQLite >= ${DB_VERSION_REQUIREMENTS.SQLITE_MIN_VERSION}\uFF0C\u5F53\u524D: ${version}`);
|
|
@@ -10213,7 +10238,11 @@ function compareFieldDefinition(dbDialect, existingColumn, fieldDef) {
|
|
|
10213
10238
|
}
|
|
10214
10239
|
}
|
|
10215
10240
|
const typeMapping = getTypeMapping(dbDialect);
|
|
10216
|
-
const
|
|
10241
|
+
const mapped = typeMapping[fieldDef.type];
|
|
10242
|
+
if (typeof mapped !== "string") {
|
|
10243
|
+
throw new Error(`\u672A\u77E5\u5B57\u6BB5\u7C7B\u578B\u6620\u5C04\uFF1Adialect=${dbDialect} type=${String(fieldDef.type)}`);
|
|
10244
|
+
}
|
|
10245
|
+
const expectedType = mapped.toLowerCase();
|
|
10217
10246
|
const currentType = existingColumn.type.toLowerCase();
|
|
10218
10247
|
if (currentType !== expectedType) {
|
|
10219
10248
|
changes.push({
|
|
@@ -10523,8 +10552,8 @@ var calcPerfTime = (startTime, endTime = Bun.nanoseconds()) => {
|
|
|
10523
10552
|
// utils/processInfo.ts
|
|
10524
10553
|
function getProcessRole(env) {
|
|
10525
10554
|
const runtimeEnv = env || {};
|
|
10526
|
-
const bunWorkerId = runtimeEnv
|
|
10527
|
-
const pm2InstanceId = runtimeEnv
|
|
10555
|
+
const bunWorkerId = runtimeEnv["BUN_WORKER_ID"];
|
|
10556
|
+
const pm2InstanceId = runtimeEnv["PM2_INSTANCE_ID"];
|
|
10528
10557
|
if (bunWorkerId !== undefined) {
|
|
10529
10558
|
return {
|
|
10530
10559
|
role: bunWorkerId === "" ? "primary" : "worker",
|
|
@@ -12311,7 +12340,7 @@ class Validator {
|
|
|
12311
12340
|
return {
|
|
12312
12341
|
code: failed ? 1 : 0,
|
|
12313
12342
|
failed,
|
|
12314
|
-
firstError: failed ? errors[0] : null,
|
|
12343
|
+
firstError: failed ? errors[0] ?? null : null,
|
|
12315
12344
|
errors,
|
|
12316
12345
|
errorFields,
|
|
12317
12346
|
fieldErrors
|
|
@@ -12825,18 +12854,44 @@ class DbUtils {
|
|
|
12825
12854
|
throw new Error("tableRef \u4E0D\u80FD\u4E3A\u7A7A");
|
|
12826
12855
|
}
|
|
12827
12856
|
const parts = trimmed.split(/\s+/).filter((p) => p.length > 0);
|
|
12857
|
+
if (parts.length === 0) {
|
|
12858
|
+
throw new Error("tableRef \u4E0D\u80FD\u4E3A\u7A7A");
|
|
12859
|
+
}
|
|
12828
12860
|
if (parts.length > 2) {
|
|
12829
12861
|
throw new Error(`\u4E0D\u652F\u6301\u7684\u8868\u5F15\u7528\u683C\u5F0F\uFF08\u5305\u542B\u8FC7\u591A\u7247\u6BB5\uFF09\u3002\u8BF7\u4F7F\u7528\u6700\u7B80\u5F62\u5F0F\uFF1Atable \u6216 table alias \u6216 schema.table \u6216 schema.table alias (tableRef: ${trimmed})`);
|
|
12830
12862
|
}
|
|
12831
12863
|
const namePart = parts[0];
|
|
12832
|
-
|
|
12864
|
+
if (typeof namePart !== "string" || namePart.trim() === "") {
|
|
12865
|
+
throw new Error(`tableRef \u89E3\u6790\u5931\u8D25\uFF1A\u7F3A\u5C11\u8868\u540D (tableRef: ${trimmed})`);
|
|
12866
|
+
}
|
|
12867
|
+
let aliasPart = null;
|
|
12868
|
+
if (parts.length === 2) {
|
|
12869
|
+
const alias = parts[1];
|
|
12870
|
+
if (typeof alias !== "string" || alias.trim() === "") {
|
|
12871
|
+
throw new Error(`tableRef \u89E3\u6790\u5931\u8D25\uFF1A\u7F3A\u5C11 alias (tableRef: ${trimmed})`);
|
|
12872
|
+
}
|
|
12873
|
+
aliasPart = alias;
|
|
12874
|
+
}
|
|
12833
12875
|
const nameSegments = namePart.split(".");
|
|
12834
12876
|
if (nameSegments.length > 2) {
|
|
12835
12877
|
throw new Error(`\u4E0D\u652F\u6301\u7684\u8868\u5F15\u7528\u683C\u5F0F\uFF08schema \u5C42\u7EA7\u8FC7\u6DF1\uFF09 (tableRef: ${trimmed})`);
|
|
12836
12878
|
}
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
|
|
12879
|
+
if (nameSegments.length === 2) {
|
|
12880
|
+
const schema = nameSegments[0];
|
|
12881
|
+
const table2 = nameSegments[1];
|
|
12882
|
+
if (typeof schema !== "string" || schema.trim() === "") {
|
|
12883
|
+
throw new Error(`tableRef \u89E3\u6790\u5931\u8D25\uFF1Aschema \u4E3A\u7A7A (tableRef: ${trimmed})`);
|
|
12884
|
+
}
|
|
12885
|
+
if (typeof table2 !== "string" || table2.trim() === "") {
|
|
12886
|
+
throw new Error(`tableRef \u89E3\u6790\u5931\u8D25\uFF1Atable \u4E3A\u7A7A (tableRef: ${trimmed})`);
|
|
12887
|
+
}
|
|
12888
|
+
return { schema, table: table2, alias: aliasPart };
|
|
12889
|
+
}
|
|
12890
|
+
const table = nameSegments[0];
|
|
12891
|
+
if (typeof table !== "string" || table.trim() === "") {
|
|
12892
|
+
throw new Error(`tableRef \u89E3\u6790\u5931\u8D25\uFF1Atable \u4E3A\u7A7A (tableRef: ${trimmed})`);
|
|
12893
|
+
}
|
|
12894
|
+
return { schema: null, table, alias: aliasPart };
|
|
12840
12895
|
}
|
|
12841
12896
|
static normalizeTableRef(tableRef) {
|
|
12842
12897
|
const parsed = DbUtils.parseTableRef(tableRef);
|
|
@@ -12914,7 +12969,15 @@ class DbUtils {
|
|
|
12914
12969
|
if (typeof item !== "string" || !item.includes("#")) {
|
|
12915
12970
|
return item;
|
|
12916
12971
|
}
|
|
12917
|
-
const
|
|
12972
|
+
const parts = item.split("#");
|
|
12973
|
+
if (parts.length !== 2) {
|
|
12974
|
+
return item;
|
|
12975
|
+
}
|
|
12976
|
+
const field = parts[0];
|
|
12977
|
+
const direction = parts[1];
|
|
12978
|
+
if (typeof field !== "string" || typeof direction !== "string") {
|
|
12979
|
+
return item;
|
|
12980
|
+
}
|
|
12918
12981
|
return `${snakeCase(field.trim())}#${direction.trim()}`;
|
|
12919
12982
|
});
|
|
12920
12983
|
}
|
|
@@ -12924,14 +12987,26 @@ class DbUtils {
|
|
|
12924
12987
|
}
|
|
12925
12988
|
if (field.toUpperCase().includes(" AS ")) {
|
|
12926
12989
|
const parts = field.split(/\s+AS\s+/i);
|
|
12927
|
-
const fieldPart = parts[0]
|
|
12928
|
-
const aliasPart = parts[1]
|
|
12929
|
-
|
|
12990
|
+
const fieldPart = parts[0];
|
|
12991
|
+
const aliasPart = parts[1];
|
|
12992
|
+
if (typeof fieldPart !== "string" || typeof aliasPart !== "string") {
|
|
12993
|
+
return field;
|
|
12994
|
+
}
|
|
12995
|
+
return `${DbUtils.processJoinField(fieldPart.trim())} AS ${aliasPart.trim()}`;
|
|
12930
12996
|
}
|
|
12931
12997
|
if (field.includes(".")) {
|
|
12932
12998
|
const parts = field.split(".");
|
|
12933
|
-
|
|
12934
|
-
|
|
12999
|
+
if (parts.length < 2) {
|
|
13000
|
+
return snakeCase(field);
|
|
13001
|
+
}
|
|
13002
|
+
if (parts.some((p) => p.trim() === "")) {
|
|
13003
|
+
return field;
|
|
13004
|
+
}
|
|
13005
|
+
const fieldName = parts[parts.length - 1];
|
|
13006
|
+
const tableName = parts.slice(0, parts.length - 1).join(".");
|
|
13007
|
+
if (typeof fieldName !== "string" || typeof tableName !== "string") {
|
|
13008
|
+
return snakeCase(field);
|
|
13009
|
+
}
|
|
12935
13010
|
return `${tableName.trim()}.${snakeCase(fieldName)}`;
|
|
12936
13011
|
}
|
|
12937
13012
|
return snakeCase(field);
|
|
@@ -12946,16 +13021,34 @@ class DbUtils {
|
|
|
12946
13021
|
const operator = key.substring(lastDollarIndex);
|
|
12947
13022
|
if (fieldPart.includes(".")) {
|
|
12948
13023
|
const parts = fieldPart.split(".");
|
|
12949
|
-
|
|
12950
|
-
|
|
13024
|
+
if (parts.length < 2) {
|
|
13025
|
+
return `${snakeCase(fieldPart)}${operator}`;
|
|
13026
|
+
}
|
|
13027
|
+
if (parts.some((p) => p.trim() === "")) {
|
|
13028
|
+
return `${snakeCase(fieldPart)}${operator}`;
|
|
13029
|
+
}
|
|
13030
|
+
const fieldName = parts[parts.length - 1];
|
|
13031
|
+
const tableName = parts.slice(0, parts.length - 1).join(".");
|
|
13032
|
+
if (typeof fieldName !== "string" || typeof tableName !== "string") {
|
|
13033
|
+
return `${snakeCase(fieldPart)}${operator}`;
|
|
13034
|
+
}
|
|
12951
13035
|
return `${tableName.trim()}.${snakeCase(fieldName)}${operator}`;
|
|
12952
13036
|
}
|
|
12953
13037
|
return `${snakeCase(fieldPart)}${operator}`;
|
|
12954
13038
|
}
|
|
12955
13039
|
if (key.includes(".")) {
|
|
12956
13040
|
const parts = key.split(".");
|
|
12957
|
-
|
|
12958
|
-
|
|
13041
|
+
if (parts.length < 2) {
|
|
13042
|
+
return snakeCase(key);
|
|
13043
|
+
}
|
|
13044
|
+
if (parts.some((p) => p.trim() === "")) {
|
|
13045
|
+
return snakeCase(key);
|
|
13046
|
+
}
|
|
13047
|
+
const fieldName = parts[parts.length - 1];
|
|
13048
|
+
const tableName = parts.slice(0, parts.length - 1).join(".");
|
|
13049
|
+
if (typeof fieldName !== "string" || typeof tableName !== "string") {
|
|
13050
|
+
return snakeCase(key);
|
|
13051
|
+
}
|
|
12959
13052
|
return `${tableName.trim()}.${snakeCase(fieldName)}`;
|
|
12960
13053
|
}
|
|
12961
13054
|
return snakeCase(key);
|
|
@@ -12988,7 +13081,15 @@ class DbUtils {
|
|
|
12988
13081
|
if (typeof item !== "string" || !item.includes("#")) {
|
|
12989
13082
|
return item;
|
|
12990
13083
|
}
|
|
12991
|
-
const
|
|
13084
|
+
const parts = item.split("#");
|
|
13085
|
+
if (parts.length !== 2) {
|
|
13086
|
+
return item;
|
|
13087
|
+
}
|
|
13088
|
+
const field = parts[0];
|
|
13089
|
+
const direction = parts[1];
|
|
13090
|
+
if (typeof field !== "string" || typeof direction !== "string") {
|
|
13091
|
+
return item;
|
|
13092
|
+
}
|
|
12992
13093
|
return `${DbUtils.processJoinField(field.trim())}#${direction.trim()}`;
|
|
12993
13094
|
});
|
|
12994
13095
|
}
|
|
@@ -13109,10 +13210,10 @@ class DbUtils {
|
|
|
13109
13210
|
for (const [key, value] of Object.entries(userData)) {
|
|
13110
13211
|
result[key] = value;
|
|
13111
13212
|
}
|
|
13112
|
-
result
|
|
13113
|
-
result
|
|
13114
|
-
result
|
|
13115
|
-
result
|
|
13213
|
+
result["id"] = options.id;
|
|
13214
|
+
result["created_at"] = options.now;
|
|
13215
|
+
result["updated_at"] = options.now;
|
|
13216
|
+
result["state"] = 1;
|
|
13116
13217
|
return result;
|
|
13117
13218
|
}
|
|
13118
13219
|
static buildUpdateRow(options) {
|
|
@@ -13122,7 +13223,7 @@ class DbUtils {
|
|
|
13122
13223
|
for (const [key, value] of Object.entries(userData)) {
|
|
13123
13224
|
result[key] = value;
|
|
13124
13225
|
}
|
|
13125
|
-
result
|
|
13226
|
+
result["updated_at"] = options.now;
|
|
13126
13227
|
return result;
|
|
13127
13228
|
}
|
|
13128
13229
|
static buildPartialUpdateData(options) {
|
|
@@ -13246,6 +13347,7 @@ var SqlBuilderError = {
|
|
|
13246
13347
|
QUOTE_IDENT_NEED_STRING: (identifier) => `quoteIdent \u9700\u8981\u5B57\u7B26\u4E32\u7C7B\u578B\u6807\u8BC6\u7B26 (identifier: ${String(identifier)})`,
|
|
13247
13348
|
IDENT_EMPTY: "SQL \u6807\u8BC6\u7B26\u4E0D\u80FD\u4E3A\u7A7A",
|
|
13248
13349
|
FIELD_EXPR_NOT_ALLOWED: (field) => `\u5B57\u6BB5\u5305\u542B\u51FD\u6570/\u8868\u8FBE\u5F0F\uFF0C\u8BF7\u4F7F\u7528 selectRaw/whereRaw (field: ${field})`,
|
|
13350
|
+
FIELD_INVALID: (field) => `\u5B57\u6BB5\u683C\u5F0F\u975E\u6CD5\uFF0C\u8BF7\u4F7F\u7528\u7B80\u5355\u5B57\u6BB5\u540D\u6216\u5B89\u5168\u5F15\u7528\uFF0C\u590D\u6742\u8868\u8FBE\u5F0F\u8BF7\u4F7F\u7528 selectRaw/whereRaw (field: ${field})`,
|
|
13249
13351
|
FROM_EMPTY: "FROM \u8868\u540D\u4E0D\u80FD\u4E3A\u7A7A",
|
|
13250
13352
|
FROM_NEED_NON_EMPTY: (table) => `FROM \u8868\u540D\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32 (table: ${String(table)})`,
|
|
13251
13353
|
FROM_REQUIRED: "FROM \u8868\u540D\u662F\u5FC5\u9700\u7684",
|
|
@@ -13349,10 +13451,18 @@ class SqlBuilder {
|
|
|
13349
13451
|
}
|
|
13350
13452
|
if (field.toUpperCase().includes(" AS ")) {
|
|
13351
13453
|
const parts = field.split(/\s+AS\s+/i);
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
|
|
13355
|
-
|
|
13454
|
+
if (parts.length !== 2) {
|
|
13455
|
+
throw new Error(SqlBuilderError.FIELD_INVALID(field));
|
|
13456
|
+
}
|
|
13457
|
+
const fieldPart = parts[0];
|
|
13458
|
+
const aliasPart = parts[1];
|
|
13459
|
+
if (typeof fieldPart !== "string" || typeof aliasPart !== "string") {
|
|
13460
|
+
throw new Error(SqlBuilderError.FIELD_INVALID(field));
|
|
13461
|
+
}
|
|
13462
|
+
const cleanFieldPart = fieldPart.trim();
|
|
13463
|
+
const cleanAliasPart = aliasPart.trim();
|
|
13464
|
+
SqlCheck.assertSafeAlias(cleanAliasPart);
|
|
13465
|
+
return `${this._escapeField(cleanFieldPart)} AS ${cleanAliasPart}`;
|
|
13356
13466
|
}
|
|
13357
13467
|
if (field.includes(".")) {
|
|
13358
13468
|
const parts = field.split(".");
|
|
@@ -13386,16 +13496,26 @@ class SqlBuilder {
|
|
|
13386
13496
|
if (parts.length > 2) {
|
|
13387
13497
|
throw new Error(SqlBuilderError.TABLE_REF_TOO_MANY_PARTS(table));
|
|
13388
13498
|
}
|
|
13389
|
-
const
|
|
13390
|
-
|
|
13499
|
+
const namePartRaw = parts[0];
|
|
13500
|
+
if (typeof namePartRaw !== "string" || namePartRaw.trim() === "") {
|
|
13501
|
+
throw new Error(SqlBuilderError.FROM_EMPTY);
|
|
13502
|
+
}
|
|
13503
|
+
const namePart = namePartRaw.trim();
|
|
13504
|
+
const aliasPartRaw = parts.length === 2 ? parts[1] : null;
|
|
13505
|
+
const aliasPart = typeof aliasPartRaw === "string" ? aliasPartRaw.trim() : null;
|
|
13391
13506
|
const nameSegments = namePart.split(".");
|
|
13392
13507
|
if (nameSegments.length > 2) {
|
|
13393
13508
|
throw new Error(SqlBuilderError.TABLE_REF_SCHEMA_TOO_DEEP(table));
|
|
13394
13509
|
}
|
|
13395
13510
|
let escapedName = "";
|
|
13396
13511
|
if (nameSegments.length === 2) {
|
|
13397
|
-
const
|
|
13398
|
-
const
|
|
13512
|
+
const schemaRaw = nameSegments[0];
|
|
13513
|
+
const tableNameRaw = nameSegments[1];
|
|
13514
|
+
if (typeof schemaRaw !== "string" || typeof tableNameRaw !== "string") {
|
|
13515
|
+
throw new Error(SqlBuilderError.TABLE_REF_SCHEMA_TOO_DEEP(table));
|
|
13516
|
+
}
|
|
13517
|
+
const schema = schemaRaw.trim();
|
|
13518
|
+
const tableName = tableNameRaw.trim();
|
|
13399
13519
|
const escapedSchema = this._isQuotedIdent(schema) ? schema : (() => {
|
|
13400
13520
|
if (this._startsWithQuote(schema) && !this._isQuotedIdent(schema)) {
|
|
13401
13521
|
throw new Error(SqlBuilderError.SCHEMA_QUOTE_NOT_PAIRED(schema));
|
|
@@ -13412,7 +13532,11 @@ class SqlBuilder {
|
|
|
13412
13532
|
})();
|
|
13413
13533
|
escapedName = `${escapedSchema}.${escapedTableName}`;
|
|
13414
13534
|
} else {
|
|
13415
|
-
const
|
|
13535
|
+
const tableNameRaw = nameSegments[0];
|
|
13536
|
+
if (typeof tableNameRaw !== "string") {
|
|
13537
|
+
throw new Error(SqlBuilderError.FROM_EMPTY);
|
|
13538
|
+
}
|
|
13539
|
+
const tableName = tableNameRaw.trim();
|
|
13416
13540
|
if (this._isQuotedIdent(tableName)) {
|
|
13417
13541
|
escapedName = tableName;
|
|
13418
13542
|
} else {
|
|
@@ -13670,7 +13794,15 @@ class SqlBuilder {
|
|
|
13670
13794
|
if (typeof item !== "string" || !item.includes("#")) {
|
|
13671
13795
|
throw new Error(SqlBuilderError.ORDER_BY_ITEM_NEED_HASH(item));
|
|
13672
13796
|
}
|
|
13673
|
-
const
|
|
13797
|
+
const parts = item.split("#");
|
|
13798
|
+
if (parts.length !== 2) {
|
|
13799
|
+
throw new Error(SqlBuilderError.ORDER_BY_ITEM_NEED_HASH(item));
|
|
13800
|
+
}
|
|
13801
|
+
const fieldName = parts[0];
|
|
13802
|
+
const direction = parts[1];
|
|
13803
|
+
if (typeof fieldName !== "string" || typeof direction !== "string") {
|
|
13804
|
+
throw new Error(SqlBuilderError.ORDER_BY_ITEM_NEED_HASH(item));
|
|
13805
|
+
}
|
|
13674
13806
|
const cleanField = fieldName.trim();
|
|
13675
13807
|
const cleanDir = direction.trim().toUpperCase();
|
|
13676
13808
|
if (!cleanField) {
|
|
@@ -13767,7 +13899,9 @@ class SqlBuilder {
|
|
|
13767
13899
|
for (let i = 0;i < data.length; i++) {
|
|
13768
13900
|
const row = data[i];
|
|
13769
13901
|
for (const field of fields) {
|
|
13770
|
-
|
|
13902
|
+
const value = row[field];
|
|
13903
|
+
this._validateParam(value);
|
|
13904
|
+
params.push(value);
|
|
13771
13905
|
}
|
|
13772
13906
|
}
|
|
13773
13907
|
return { sql, params };
|
|
@@ -13782,7 +13916,12 @@ class SqlBuilder {
|
|
|
13782
13916
|
const escapedFields = fields.map((field) => this._escapeField(field));
|
|
13783
13917
|
const placeholders = fields.map(() => "?").join(", ");
|
|
13784
13918
|
const sql = `INSERT INTO ${escapedTable} (${escapedFields.join(", ")}) VALUES (${placeholders})`;
|
|
13785
|
-
const params =
|
|
13919
|
+
const params = [];
|
|
13920
|
+
for (const field of fields) {
|
|
13921
|
+
const value = data[field];
|
|
13922
|
+
this._validateParam(value);
|
|
13923
|
+
params.push(value);
|
|
13924
|
+
}
|
|
13786
13925
|
return { sql, params };
|
|
13787
13926
|
}
|
|
13788
13927
|
}
|
|
@@ -13884,7 +14023,9 @@ class SqlBuilder {
|
|
|
13884
14023
|
}
|
|
13885
14024
|
whenList.push("WHEN ? THEN ?");
|
|
13886
14025
|
args.push(row.id);
|
|
13887
|
-
|
|
14026
|
+
const value = row.data[field];
|
|
14027
|
+
SqlCheck.assertNoUndefinedParam(value, "SQL \u53C2\u6570\u503C");
|
|
14028
|
+
args.push(value);
|
|
13888
14029
|
}
|
|
13889
14030
|
if (whenList.length === 0) {
|
|
13890
14031
|
continue;
|
|
@@ -13916,7 +14057,7 @@ class DbHelper {
|
|
|
13916
14057
|
constructor(options) {
|
|
13917
14058
|
this.redis = options.redis;
|
|
13918
14059
|
this.sql = options.sql || null;
|
|
13919
|
-
this.isTransaction =
|
|
14060
|
+
this.isTransaction = Boolean(options.sql);
|
|
13920
14061
|
this.dialect = options.dialect ? options.dialect : new MySqlDialect;
|
|
13921
14062
|
}
|
|
13922
14063
|
createSqlBuilder() {
|
|
@@ -14046,7 +14187,8 @@ class DbHelper {
|
|
|
14046
14187
|
}
|
|
14047
14188
|
async getCount(options) {
|
|
14048
14189
|
const { table, where, joins, tableQualifier } = await this.prepareQueryOptions(options);
|
|
14049
|
-
const
|
|
14190
|
+
const hasJoins = Array.isArray(joins) && joins.length > 0;
|
|
14191
|
+
const builder = this.createSqlBuilder().selectRaw("COUNT(*) as count").from(table).where(DbUtils.addDefaultStateFilter(where, tableQualifier, hasJoins));
|
|
14050
14192
|
this.applyJoins(builder, joins);
|
|
14051
14193
|
const { sql, params } = builder.toSelectSql();
|
|
14052
14194
|
const execRes = await this.executeWithConn(sql, params);
|
|
@@ -14058,7 +14200,8 @@ class DbHelper {
|
|
|
14058
14200
|
}
|
|
14059
14201
|
async getOne(options) {
|
|
14060
14202
|
const { table, fields, where, joins, tableQualifier } = await this.prepareQueryOptions(options);
|
|
14061
|
-
const
|
|
14203
|
+
const hasJoins = Array.isArray(joins) && joins.length > 0;
|
|
14204
|
+
const builder = this.createSqlBuilder().select(fields).from(table).where(DbUtils.addDefaultStateFilter(where, tableQualifier, hasJoins));
|
|
14062
14205
|
this.applyJoins(builder, joins);
|
|
14063
14206
|
const { sql, params } = builder.toSelectSql();
|
|
14064
14207
|
const execRes = await this.executeWithConn(sql, params);
|
|
@@ -14078,12 +14221,16 @@ class DbHelper {
|
|
|
14078
14221
|
sql: execRes.sql
|
|
14079
14222
|
};
|
|
14080
14223
|
}
|
|
14081
|
-
const
|
|
14224
|
+
const convertedList = convertBigIntFields([deserialized]);
|
|
14225
|
+
const data = convertedList[0] ?? deserialized;
|
|
14082
14226
|
return {
|
|
14083
14227
|
data,
|
|
14084
14228
|
sql: execRes.sql
|
|
14085
14229
|
};
|
|
14086
14230
|
}
|
|
14231
|
+
async getDetail(options) {
|
|
14232
|
+
return await this.getOne(options);
|
|
14233
|
+
}
|
|
14087
14234
|
async getList(options) {
|
|
14088
14235
|
const prepared = await this.prepareQueryOptions(options);
|
|
14089
14236
|
if (prepared.page < 1 || prepared.page > 1e4) {
|
|
@@ -14092,7 +14239,7 @@ class DbHelper {
|
|
|
14092
14239
|
if (prepared.limit < 1 || prepared.limit > 1000) {
|
|
14093
14240
|
throw new Error(`\u6BCF\u9875\u6570\u91CF\u5FC5\u987B\u5728 1 \u5230 1000 \u4E4B\u95F4 (table: ${options.table}, page: ${prepared.page}, limit: ${prepared.limit})`);
|
|
14094
14241
|
}
|
|
14095
|
-
const whereFiltered = DbUtils.addDefaultStateFilter(prepared.where, prepared.tableQualifier,
|
|
14242
|
+
const whereFiltered = DbUtils.addDefaultStateFilter(prepared.where, prepared.tableQualifier, Array.isArray(prepared.joins) && prepared.joins.length > 0);
|
|
14096
14243
|
const countBuilder = this.createSqlBuilder().selectRaw("COUNT(*) as total").from(prepared.table).where(whereFiltered);
|
|
14097
14244
|
this.applyJoins(countBuilder, prepared.joins);
|
|
14098
14245
|
const { sql: countSql, params: countParams } = countBuilder.toSelectSql();
|
|
@@ -14140,8 +14287,21 @@ class DbHelper {
|
|
|
14140
14287
|
async getAll(options) {
|
|
14141
14288
|
const MAX_LIMIT = 1e4;
|
|
14142
14289
|
const WARNING_LIMIT = 1000;
|
|
14143
|
-
const
|
|
14144
|
-
|
|
14290
|
+
const prepareOptions = {
|
|
14291
|
+
table: options.table,
|
|
14292
|
+
page: 1,
|
|
14293
|
+
limit: 10
|
|
14294
|
+
};
|
|
14295
|
+
if (options.fields !== undefined)
|
|
14296
|
+
prepareOptions.fields = options.fields;
|
|
14297
|
+
if (options.where !== undefined)
|
|
14298
|
+
prepareOptions.where = options.where;
|
|
14299
|
+
if (options.joins !== undefined)
|
|
14300
|
+
prepareOptions.joins = options.joins;
|
|
14301
|
+
if (options.orderBy !== undefined)
|
|
14302
|
+
prepareOptions.orderBy = options.orderBy;
|
|
14303
|
+
const prepared = await this.prepareQueryOptions(prepareOptions);
|
|
14304
|
+
const whereFiltered = DbUtils.addDefaultStateFilter(prepared.where, prepared.tableQualifier, Array.isArray(prepared.joins) && prepared.joins.length > 0);
|
|
14145
14305
|
const countBuilder = this.createSqlBuilder().selectRaw("COUNT(*) as total").from(prepared.table).where(whereFiltered);
|
|
14146
14306
|
this.applyJoins(countBuilder, prepared.joins);
|
|
14147
14307
|
const { sql: countSql, params: countParams } = countBuilder.toSelectSql();
|
|
@@ -14201,7 +14361,7 @@ class DbHelper {
|
|
|
14201
14361
|
const builder = this.createSqlBuilder();
|
|
14202
14362
|
const { sql, params } = builder.toInsertSql(snakeTable, processed);
|
|
14203
14363
|
const execRes = await this.executeWithConn(sql, params);
|
|
14204
|
-
const insertedId = processed
|
|
14364
|
+
const insertedId = processed["id"] || execRes.data?.lastInsertRowid || 0;
|
|
14205
14365
|
return {
|
|
14206
14366
|
data: insertedId,
|
|
14207
14367
|
sql: execRes.sql
|
|
@@ -14226,7 +14386,11 @@ class DbHelper {
|
|
|
14226
14386
|
}
|
|
14227
14387
|
const now = Date.now();
|
|
14228
14388
|
const processedList = dataList.map((data, index) => {
|
|
14229
|
-
|
|
14389
|
+
const id = ids[index];
|
|
14390
|
+
if (typeof id !== "number") {
|
|
14391
|
+
throw new Error(`\u6279\u91CF\u63D2\u5165\u751F\u6210 ID \u5931\u8D25\uFF1Aids[${index}] \u4E0D\u662F number (table: ${snakeTable})`);
|
|
14392
|
+
}
|
|
14393
|
+
return DbUtils.buildInsertRow({ data, id, now });
|
|
14230
14394
|
});
|
|
14231
14395
|
const insertFields = SqlCheck.assertBatchInsertRowsConsistent(processedList, { table: snakeTable });
|
|
14232
14396
|
const builder = this.createSqlBuilder();
|
|
@@ -14509,38 +14673,50 @@ class Jwt {
|
|
|
14509
14673
|
};
|
|
14510
14674
|
}
|
|
14511
14675
|
sign(payload, options = {}) {
|
|
14512
|
-
const key = options.secret || this.config.secret
|
|
14676
|
+
const key = options.secret || this.config.secret;
|
|
14513
14677
|
const algorithm = options.algorithm || this.config.algorithm || "HS256";
|
|
14514
|
-
const
|
|
14678
|
+
const signerOptions = {
|
|
14515
14679
|
key,
|
|
14516
14680
|
algorithm,
|
|
14517
|
-
expiresIn: options.expiresIn
|
|
14518
|
-
|
|
14519
|
-
|
|
14520
|
-
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
|
|
14681
|
+
expiresIn: options.expiresIn ?? this.config.expiresIn
|
|
14682
|
+
};
|
|
14683
|
+
if (options.issuer !== undefined)
|
|
14684
|
+
signerOptions.iss = options.issuer;
|
|
14685
|
+
if (options.audience !== undefined)
|
|
14686
|
+
signerOptions.aud = options.audience;
|
|
14687
|
+
if (options.subject !== undefined)
|
|
14688
|
+
signerOptions.sub = options.subject;
|
|
14689
|
+
if (options.jwtId !== undefined)
|
|
14690
|
+
signerOptions.jti = options.jwtId;
|
|
14691
|
+
if (typeof options.notBefore === "number")
|
|
14692
|
+
signerOptions.notBefore = options.notBefore;
|
|
14693
|
+
const signer = import_fast_jwt.createSigner(signerOptions);
|
|
14524
14694
|
return signer(payload);
|
|
14525
14695
|
}
|
|
14526
14696
|
verify(token, options = {}) {
|
|
14527
14697
|
if (!token || typeof token !== "string") {
|
|
14528
14698
|
throw new Error("Token\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");
|
|
14529
14699
|
}
|
|
14530
|
-
const key = options.secret || this.config.secret
|
|
14700
|
+
const key = options.secret || this.config.secret;
|
|
14531
14701
|
const algorithm = this.config.algorithm || "HS256";
|
|
14532
14702
|
const algorithms = options.algorithms ? options.algorithms : [algorithm];
|
|
14533
|
-
const
|
|
14703
|
+
const verifierOptions = {
|
|
14534
14704
|
key,
|
|
14535
14705
|
algorithms,
|
|
14536
|
-
allowedIss: options.issuer,
|
|
14537
|
-
allowedAud: options.audience,
|
|
14538
|
-
allowedSub: options.subject,
|
|
14539
|
-
ignoreExpiration: options.ignoreExpiration,
|
|
14540
|
-
ignoreNotBefore: options.ignoreNotBefore,
|
|
14541
14706
|
cache: true,
|
|
14542
14707
|
cacheTTL: 600000
|
|
14543
|
-
}
|
|
14708
|
+
};
|
|
14709
|
+
if (options.issuer !== undefined)
|
|
14710
|
+
verifierOptions.allowedIss = options.issuer;
|
|
14711
|
+
if (options.audience !== undefined)
|
|
14712
|
+
verifierOptions.allowedAud = options.audience;
|
|
14713
|
+
if (options.subject !== undefined)
|
|
14714
|
+
verifierOptions.allowedSub = options.subject;
|
|
14715
|
+
if (typeof options.ignoreExpiration === "boolean")
|
|
14716
|
+
verifierOptions.ignoreExpiration = options.ignoreExpiration;
|
|
14717
|
+
if (typeof options.ignoreNotBefore === "boolean")
|
|
14718
|
+
verifierOptions.ignoreNotBefore = options.ignoreNotBefore;
|
|
14719
|
+
const verifier = import_fast_jwt.createVerifier(verifierOptions);
|
|
14544
14720
|
return verifier(token);
|
|
14545
14721
|
}
|
|
14546
14722
|
decode(token, complete = false) {
|
|
@@ -15151,7 +15327,7 @@ async function scanFiles(dir, source, type, pattern) {
|
|
|
15151
15327
|
const base = {
|
|
15152
15328
|
source,
|
|
15153
15329
|
type,
|
|
15154
|
-
sourceName:
|
|
15330
|
+
sourceName: source === "core" ? "\u6838\u5FC3" : source === "addon" ? "\u7EC4\u4EF6" : "\u9879\u76EE",
|
|
15155
15331
|
filePath: normalizedFile,
|
|
15156
15332
|
relativePath,
|
|
15157
15333
|
fileName,
|
|
@@ -15162,28 +15338,28 @@ async function scanFiles(dir, source, type, pattern) {
|
|
|
15162
15338
|
customKeys: isPlainObject(content) ? Object.keys(content) : []
|
|
15163
15339
|
};
|
|
15164
15340
|
if (type === "table") {
|
|
15165
|
-
base
|
|
15341
|
+
base["content"] = content;
|
|
15166
15342
|
results.push(base);
|
|
15167
15343
|
continue;
|
|
15168
15344
|
}
|
|
15169
15345
|
if (type === "api") {
|
|
15170
|
-
base
|
|
15171
|
-
base
|
|
15172
|
-
base
|
|
15173
|
-
base
|
|
15174
|
-
base
|
|
15346
|
+
base["auth"] = true;
|
|
15347
|
+
base["rawBody"] = false;
|
|
15348
|
+
base["method"] = "POST";
|
|
15349
|
+
base["fields"] = {};
|
|
15350
|
+
base["required"] = [];
|
|
15175
15351
|
}
|
|
15176
15352
|
if (type === "plugin" || type === "hook") {
|
|
15177
|
-
base
|
|
15178
|
-
base
|
|
15179
|
-
base
|
|
15353
|
+
base["deps"] = [];
|
|
15354
|
+
base["name"] = "";
|
|
15355
|
+
base["handler"] = null;
|
|
15180
15356
|
}
|
|
15181
15357
|
forOwn(content, (value, key) => {
|
|
15182
15358
|
base[key] = value;
|
|
15183
15359
|
});
|
|
15184
15360
|
if (type === "api") {
|
|
15185
|
-
base
|
|
15186
|
-
base
|
|
15361
|
+
base["routePrefix"] = source === "app" ? "/app" : `/addon/${addonName}`;
|
|
15362
|
+
base["path"] = `/api${base["routePrefix"]}/${relativePath}`;
|
|
15187
15363
|
}
|
|
15188
15364
|
results.push(base);
|
|
15189
15365
|
}
|
|
@@ -15239,11 +15415,11 @@ class Befly {
|
|
|
15239
15415
|
async start(env = {}) {
|
|
15240
15416
|
try {
|
|
15241
15417
|
const serverStartTime = Bun.nanoseconds();
|
|
15242
|
-
this.config = await loadBeflyConfig(env
|
|
15418
|
+
this.config = await loadBeflyConfig(env["NODE_ENV"] || "development");
|
|
15243
15419
|
this.context.config = this.config;
|
|
15244
15420
|
this.context.env = env;
|
|
15245
15421
|
const { apis, tables, plugins, hooks, addons } = await scanSources();
|
|
15246
|
-
this.context
|
|
15422
|
+
this.context["addons"] = addons;
|
|
15247
15423
|
await checkApi(apis);
|
|
15248
15424
|
await checkTable(tables);
|
|
15249
15425
|
await checkPlugin(plugins);
|
|
@@ -15266,15 +15442,23 @@ class Befly {
|
|
|
15266
15442
|
await syncTable(this.context, tables);
|
|
15267
15443
|
await syncApi(this.context, apis);
|
|
15268
15444
|
await syncMenu(this.context, checkedMenus);
|
|
15269
|
-
|
|
15445
|
+
const devEmail = this.config.devEmail;
|
|
15446
|
+
const devPassword = this.config.devPassword;
|
|
15447
|
+
if (typeof devEmail === "string" && devEmail.length > 0 && typeof devPassword === "string" && devPassword.length > 0) {
|
|
15448
|
+
await syncDev(this.context, { devEmail, devPassword });
|
|
15449
|
+
} else {
|
|
15450
|
+
Logger.debug("\u8DF3\u8FC7 syncDev\uFF1A\u672A\u914D\u7F6E devEmail/devPassword");
|
|
15451
|
+
}
|
|
15270
15452
|
await syncCache(this.context);
|
|
15271
15453
|
this.hooks = await loadHooks(hooks);
|
|
15272
15454
|
this.apis = await loadApis(apis);
|
|
15273
15455
|
const apiFetch = apiHandler(this.apis, this.hooks, this.context);
|
|
15274
15456
|
const staticFetch = staticHandler(this.config.cors);
|
|
15457
|
+
const port = typeof this.config.appPort === "number" ? this.config.appPort : 3000;
|
|
15458
|
+
const hostname = typeof this.config.appHost === "string" && this.config.appHost.length > 0 ? this.config.appHost : "0.0.0.0";
|
|
15275
15459
|
const server = Bun.serve({
|
|
15276
|
-
port
|
|
15277
|
-
hostname
|
|
15460
|
+
port,
|
|
15461
|
+
hostname,
|
|
15278
15462
|
development: this.config.nodeEnv === "development",
|
|
15279
15463
|
idleTimeout: 30,
|
|
15280
15464
|
fetch: async (req, bunServer) => {
|