befly 3.10.18 → 3.11.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 +83 -307
- package/dist/befly.config.d.ts +7 -0
- package/{befly.config.ts → dist/befly.config.js} +11 -36
- package/dist/befly.js +15621 -0
- package/dist/befly.min.js +21 -0
- package/dist/checks/checkApi.d.ts +1 -0
- package/{checks/checkApi.ts → dist/checks/checkApi.js} +12 -30
- package/dist/checks/checkHook.d.ts +1 -0
- package/dist/checks/checkHook.js +86 -0
- package/dist/checks/checkMenu.d.ts +7 -0
- package/{checks/checkMenu.ts → dist/checks/checkMenu.js} +18 -53
- package/dist/checks/checkPlugin.d.ts +1 -0
- package/dist/checks/checkPlugin.js +86 -0
- package/dist/checks/checkTable.d.ts +6 -0
- package/{checks/checkTable.ts → dist/checks/checkTable.js} +17 -41
- package/dist/configs/presetFields.d.ts +4 -0
- package/{configs/presetFields.ts → dist/configs/presetFields.js} +1 -1
- package/dist/configs/presetRegexp.d.ts +145 -0
- package/{utils/regex.ts → dist/configs/presetRegexp.js} +8 -31
- package/dist/hooks/auth.d.ts +7 -0
- package/{hooks/auth.ts → dist/hooks/auth.js} +8 -10
- package/dist/hooks/cors.d.ts +11 -0
- package/{hooks/cors.ts → dist/hooks/cors.js} +5 -13
- package/dist/hooks/parser.d.ts +14 -0
- package/{hooks/parser.ts → dist/hooks/parser.js} +31 -45
- package/dist/hooks/permission.d.ts +14 -0
- package/{hooks/permission.ts → dist/hooks/permission.js} +16 -25
- package/dist/hooks/validator.d.ts +11 -0
- package/{hooks/validator.ts → dist/hooks/validator.js} +9 -14
- package/dist/index.d.ts +26 -0
- package/{main.ts → dist/index.js} +61 -100
- package/dist/lib/asyncContext.d.ts +21 -0
- package/dist/lib/asyncContext.js +27 -0
- package/dist/lib/cacheHelper.d.ts +95 -0
- package/{lib/cacheHelper.ts → dist/lib/cacheHelper.js} +45 -105
- package/dist/lib/cacheKeys.d.ts +23 -0
- package/{lib/cacheKeys.ts → dist/lib/cacheKeys.js} +5 -10
- package/dist/lib/cipher.d.ts +153 -0
- package/{lib/cipher.ts → dist/lib/cipher.js} +23 -44
- package/dist/lib/connect.d.ts +91 -0
- package/{lib/connect.ts → dist/lib/connect.js} +47 -88
- package/dist/lib/dbDialect.d.ts +87 -0
- package/{lib/dbDialect.ts → dist/lib/dbDialect.js} +32 -112
- package/dist/lib/dbHelper.d.ts +204 -0
- package/{lib/dbHelper.ts → dist/lib/dbHelper.js} +82 -241
- package/dist/lib/dbUtils.d.ts +68 -0
- package/{lib/dbUtils.ts → dist/lib/dbUtils.js} +51 -126
- package/dist/lib/jwt.d.ts +13 -0
- package/{lib/jwt.ts → dist/lib/jwt.js} +11 -32
- package/dist/lib/logger.d.ts +42 -0
- package/dist/lib/logger.js +1144 -0
- package/dist/lib/redisHelper.d.ts +185 -0
- package/{lib/redisHelper.ts → dist/lib/redisHelper.js} +97 -141
- package/dist/lib/sqlBuilder.d.ts +160 -0
- package/{lib/sqlBuilder.ts → dist/lib/sqlBuilder.js} +132 -278
- package/dist/lib/sqlCheck.d.ts +23 -0
- package/{lib/sqlCheck.ts → dist/lib/sqlCheck.js} +24 -41
- package/dist/lib/validator.d.ts +45 -0
- package/{lib/validator.ts → dist/lib/validator.js} +44 -61
- package/dist/loader/loadApis.d.ts +12 -0
- package/{loader/loadApis.ts → dist/loader/loadApis.js} +10 -20
- package/dist/loader/loadHooks.d.ts +7 -0
- package/dist/loader/loadHooks.js +35 -0
- package/dist/loader/loadPlugins.d.ts +8 -0
- package/{loader/loadPlugins.ts → dist/loader/loadPlugins.js} +14 -26
- package/dist/paths.d.ts +93 -0
- package/{paths.ts → dist/paths.js} +6 -19
- package/dist/plugins/cache.d.ts +16 -0
- package/{plugins/cache.ts → dist/plugins/cache.js} +7 -12
- package/dist/plugins/cipher.d.ts +12 -0
- package/{plugins/cipher.ts → dist/plugins/cipher.js} +4 -6
- package/dist/plugins/config.d.ts +12 -0
- package/dist/plugins/config.js +8 -0
- package/dist/plugins/db.d.ts +16 -0
- package/{plugins/db.ts → dist/plugins/db.js} +11 -17
- package/dist/plugins/jwt.d.ts +12 -0
- package/dist/plugins/jwt.js +12 -0
- package/dist/plugins/logger.d.ts +32 -0
- package/{plugins/logger.ts → dist/plugins/logger.js} +5 -8
- package/dist/plugins/redis.d.ts +16 -0
- package/{plugins/redis.ts → dist/plugins/redis.js} +9 -12
- package/dist/plugins/tool.d.ts +81 -0
- package/{plugins/tool.ts → dist/plugins/tool.js} +9 -30
- package/dist/router/api.d.ts +14 -0
- package/dist/router/api.js +107 -0
- package/dist/router/static.d.ts +9 -0
- package/{router/static.ts → dist/router/static.js} +20 -34
- package/dist/scripts/ensureDist.d.ts +1 -0
- package/dist/scripts/ensureDist.js +296 -0
- package/dist/sync/syncApi.d.ts +3 -0
- package/{sync/syncApi.ts → dist/sync/syncApi.js} +35 -55
- package/dist/sync/syncCache.d.ts +2 -0
- package/{sync/syncCache.ts → dist/sync/syncCache.js} +1 -6
- package/dist/sync/syncDev.d.ts +6 -0
- package/{sync/syncDev.ts → dist/sync/syncDev.js} +29 -62
- package/dist/sync/syncMenu.d.ts +14 -0
- package/{sync/syncMenu.ts → dist/sync/syncMenu.js} +65 -125
- package/dist/sync/syncTable.d.ts +151 -0
- package/{sync/syncTable.ts → dist/sync/syncTable.js} +172 -379
- package/{types → dist/types}/api.d.ts +12 -51
- package/dist/types/api.js +4 -0
- package/{types → dist/types}/befly.d.ts +32 -227
- package/dist/types/befly.js +4 -0
- package/{types → dist/types}/cache.d.ts +7 -15
- package/dist/types/cache.js +4 -0
- package/dist/types/cipher.d.ts +27 -0
- package/dist/types/cipher.js +7 -0
- package/{types → dist/types}/common.d.ts +8 -33
- package/dist/types/common.js +5 -0
- package/{types → dist/types}/context.d.ts +3 -5
- package/dist/types/context.js +4 -0
- package/{types → dist/types}/crypto.d.ts +0 -3
- package/dist/types/crypto.js +4 -0
- package/dist/types/database.d.ts +138 -0
- package/dist/types/database.js +4 -0
- package/dist/types/hook.d.ts +17 -0
- package/dist/types/hook.js +6 -0
- package/dist/types/jwt.d.ts +75 -0
- package/dist/types/jwt.js +4 -0
- package/dist/types/logger.d.ts +59 -0
- package/dist/types/logger.js +6 -0
- package/dist/types/plugin.d.ts +16 -0
- package/dist/types/plugin.js +6 -0
- package/dist/types/redis.d.ts +71 -0
- package/dist/types/redis.js +4 -0
- package/{types/roleApisCache.ts → dist/types/roleApisCache.d.ts} +0 -2
- package/dist/types/roleApisCache.js +8 -0
- package/dist/types/sync.d.ts +92 -0
- package/dist/types/sync.js +4 -0
- package/dist/types/table.d.ts +34 -0
- package/dist/types/table.js +4 -0
- package/dist/types/validate.d.ts +67 -0
- package/dist/types/validate.js +4 -0
- package/dist/utils/calcPerfTime.d.ts +4 -0
- package/{utils/calcPerfTime.ts → dist/utils/calcPerfTime.js} +3 -3
- package/dist/utils/convertBigIntFields.d.ts +11 -0
- package/{utils/convertBigIntFields.ts → dist/utils/convertBigIntFields.js} +5 -9
- package/dist/utils/cors.d.ts +8 -0
- package/{utils/cors.ts → dist/utils/cors.js} +1 -3
- package/dist/utils/disableMenusGlob.d.ts +13 -0
- package/{utils/disableMenusGlob.ts → dist/utils/disableMenusGlob.js} +9 -29
- package/dist/utils/fieldClear.d.ts +11 -0
- package/{utils/fieldClear.ts → dist/utils/fieldClear.js} +15 -33
- package/dist/utils/getClientIp.d.ts +6 -0
- package/{utils/getClientIp.ts → dist/utils/getClientIp.js} +1 -7
- package/dist/utils/importDefault.d.ts +1 -0
- package/dist/utils/importDefault.js +29 -0
- package/dist/utils/isDirentDirectory.d.ts +2 -0
- package/{utils/isDirentDirectory.ts → dist/utils/isDirentDirectory.js} +3 -8
- package/dist/utils/loadMenuConfigs.d.ts +29 -0
- package/{utils/loadMenuConfigs.ts → dist/utils/loadMenuConfigs.js} +66 -52
- package/dist/utils/mergeAndConcat.d.ts +7 -0
- package/dist/utils/mergeAndConcat.js +72 -0
- package/dist/utils/processAtSymbol.d.ts +4 -0
- package/{utils/processFields.ts → dist/utils/processAtSymbol.js} +5 -9
- package/dist/utils/processInfo.d.ts +24 -0
- package/{utils/process.ts → dist/utils/processInfo.js} +2 -18
- package/dist/utils/response.d.ts +20 -0
- package/{utils/response.ts → dist/utils/response.js} +28 -49
- package/dist/utils/scanAddons.d.ts +17 -0
- package/{utils/scanAddons.ts → dist/utils/scanAddons.js} +7 -41
- package/dist/utils/scanConfig.d.ts +26 -0
- package/{utils/scanConfig.ts → dist/utils/scanConfig.js} +28 -66
- package/dist/utils/scanCoreBuiltins.d.ts +3 -0
- package/dist/utils/scanCoreBuiltins.js +65 -0
- package/dist/utils/scanFiles.d.ts +30 -0
- package/{utils/scanFiles.ts → dist/utils/scanFiles.js} +44 -71
- package/dist/utils/scanSources.d.ts +10 -0
- package/dist/utils/scanSources.js +46 -0
- package/dist/utils/sortModules.d.ts +28 -0
- package/{utils/sortModules.ts → dist/utils/sortModules.js} +26 -66
- package/dist/utils/util.d.ts +84 -0
- package/dist/utils/util.js +262 -0
- package/package.json +26 -34
- package/.gitignore +0 -0
- package/bunfig.toml +0 -3
- package/checks/checkHook.ts +0 -48
- package/checks/checkPlugin.ts +0 -48
- package/configs/presetRegexp.ts +0 -225
- package/docs/README.md +0 -98
- package/docs/api/api.md +0 -1921
- package/docs/guide/examples.md +0 -926
- package/docs/guide/quickstart.md +0 -354
- package/docs/hooks/auth.md +0 -38
- package/docs/hooks/cors.md +0 -28
- package/docs/hooks/hook.md +0 -838
- package/docs/hooks/parser.md +0 -19
- package/docs/hooks/rateLimit.md +0 -47
- package/docs/infra/redis.md +0 -628
- package/docs/plugins/cipher.md +0 -61
- package/docs/plugins/database.md +0 -189
- package/docs/plugins/plugin.md +0 -986
- package/docs/reference/addon.md +0 -510
- package/docs/reference/config.md +0 -573
- package/docs/reference/logger.md +0 -495
- package/docs/reference/sync.md +0 -478
- package/docs/reference/table.md +0 -763
- package/docs/reference/validator.md +0 -620
- package/lib/asyncContext.ts +0 -43
- package/lib/logger.ts +0 -811
- package/loader/loadHooks.ts +0 -51
- package/plugins/config.ts +0 -13
- package/plugins/jwt.ts +0 -15
- package/router/api.ts +0 -130
- package/tsconfig.json +0 -8
- package/types/database.d.ts +0 -541
- package/types/hook.d.ts +0 -25
- package/types/jwt.d.ts +0 -118
- package/types/logger.d.ts +0 -65
- package/types/plugin.d.ts +0 -19
- package/types/redis.d.ts +0 -83
- package/types/sync.d.ts +0 -398
- package/types/table.d.ts +0 -216
- package/types/validate.d.ts +0 -69
- package/utils/arrayKeysToCamel.ts +0 -18
- package/utils/configTypes.ts +0 -3
- package/utils/genShortId.ts +0 -12
- package/utils/importDefault.ts +0 -21
- package/utils/keysToCamel.ts +0 -22
- package/utils/keysToSnake.ts +0 -22
- package/utils/pickFields.ts +0 -19
- package/utils/scanSources.ts +0 -64
- package/utils/sqlLog.ts +0 -37
|
@@ -1,23 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type { ScanFileResult } from "../utils/scanFiles.ts";
|
|
3
|
-
|
|
4
|
-
import { Logger } from "../lib/logger.ts";
|
|
5
|
-
|
|
1
|
+
import { Logger } from "../lib/logger";
|
|
6
2
|
/**
|
|
7
3
|
* 保留字段列表
|
|
8
4
|
*/
|
|
9
|
-
const RESERVED_FIELDS = ["id", "created_at", "updated_at", "deleted_at", "state"]
|
|
10
|
-
|
|
5
|
+
const RESERVED_FIELDS = ["id", "created_at", "updated_at", "deleted_at", "state"];
|
|
11
6
|
/**
|
|
12
7
|
* 允许的字段类型
|
|
13
8
|
*/
|
|
14
|
-
const FIELD_TYPES = ["string", "number", "text", "array_string", "array_text", "array_number_string", "array_number_text"]
|
|
15
|
-
|
|
9
|
+
const FIELD_TYPES = ["string", "number", "text", "array_string", "array_text", "array_number_string", "array_number_text"];
|
|
16
10
|
/**
|
|
17
11
|
* 允许的字段属性列表
|
|
18
12
|
*/
|
|
19
|
-
const ALLOWED_FIELD_PROPERTIES = ["name", "type", "min", "max", "default", "detail", "index", "unique", "nullable", "unsigned", "regexp"]
|
|
20
|
-
|
|
13
|
+
const ALLOWED_FIELD_PROPERTIES = ["name", "type", "min", "max", "default", "detail", "index", "unique", "nullable", "unsigned", "regexp"];
|
|
21
14
|
/**
|
|
22
15
|
* 小驼峰命名正则
|
|
23
16
|
* 可选:以下划线开头(用于特殊文件,如通用字段定义)
|
|
@@ -25,34 +18,28 @@ const ALLOWED_FIELD_PROPERTIES = ["name", "type", "min", "max", "default", "deta
|
|
|
25
18
|
* 示例:userTable、testCustomers、common
|
|
26
19
|
*/
|
|
27
20
|
const LOWER_CAMEL_CASE_REGEX = /^_?[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$/;
|
|
28
|
-
|
|
29
21
|
/**
|
|
30
22
|
* 字段名称正则
|
|
31
23
|
* 必须为中文、数字、字母、下划线、短横线、空格
|
|
32
24
|
*/
|
|
33
25
|
const FIELD_NAME_REGEX = /^[\u4e00-\u9fa5a-zA-Z0-9 _-]+$/;
|
|
34
|
-
|
|
35
26
|
/**
|
|
36
27
|
* VARCHAR 最大长度限制
|
|
37
28
|
*/
|
|
38
29
|
const MAX_VARCHAR_LENGTH = 65535;
|
|
39
|
-
|
|
40
30
|
/**
|
|
41
31
|
* 检查表定义文件
|
|
42
32
|
* @throws 当检查失败时抛出异常
|
|
43
33
|
*/
|
|
44
|
-
export async function checkTable(tables
|
|
34
|
+
export async function checkTable(tables) {
|
|
45
35
|
// 收集所有表文件
|
|
46
36
|
let hasError = false;
|
|
47
|
-
|
|
48
37
|
// 合并进行验证逻辑
|
|
49
38
|
for (const item of tables) {
|
|
50
39
|
if (item.type !== "table") {
|
|
51
40
|
continue;
|
|
52
41
|
}
|
|
53
|
-
|
|
54
42
|
const sourceName = typeof item.sourceName === "string" ? item.sourceName : "";
|
|
55
|
-
|
|
56
43
|
try {
|
|
57
44
|
const fileName = item.fileName;
|
|
58
45
|
const table = item.content || {};
|
|
@@ -62,7 +49,6 @@ export async function checkTable(tables: ScanFileResult[]): Promise<void> {
|
|
|
62
49
|
hasError = true;
|
|
63
50
|
continue;
|
|
64
51
|
}
|
|
65
|
-
|
|
66
52
|
// 检查 table 中的每个验证规则
|
|
67
53
|
for (const [colKey, fieldDef] of Object.entries(table)) {
|
|
68
54
|
if (typeof fieldDef !== "object" || fieldDef === null || Array.isArray(fieldDef)) {
|
|
@@ -70,24 +56,20 @@ export async function checkTable(tables: ScanFileResult[]): Promise<void> {
|
|
|
70
56
|
hasError = true;
|
|
71
57
|
continue;
|
|
72
58
|
}
|
|
73
|
-
|
|
74
59
|
// 检查是否使用了保留字段
|
|
75
|
-
if (RESERVED_FIELDS.includes(colKey
|
|
60
|
+
if (RESERVED_FIELDS.includes(colKey)) {
|
|
76
61
|
Logger.warn(`${sourceName}表 ${fileName} 文件包含保留字段 ${colKey},` + `不能在表定义中使用以下字段: ${RESERVED_FIELDS.join(", ")}`);
|
|
77
62
|
hasError = true;
|
|
78
63
|
}
|
|
79
|
-
|
|
80
64
|
// 直接使用字段对象
|
|
81
|
-
const field = fieldDef
|
|
82
|
-
|
|
65
|
+
const field = fieldDef;
|
|
83
66
|
// 检查是否存在非法属性
|
|
84
67
|
const fieldKeys = Object.keys(field);
|
|
85
|
-
const illegalProps = fieldKeys.filter((key) => !ALLOWED_FIELD_PROPERTIES.includes(key
|
|
68
|
+
const illegalProps = fieldKeys.filter((key) => !ALLOWED_FIELD_PROPERTIES.includes(key));
|
|
86
69
|
if (illegalProps.length > 0) {
|
|
87
70
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 包含非法属性: ${illegalProps.join(", ")},` + `允许的属性为: ${ALLOWED_FIELD_PROPERTIES.join(", ")}`);
|
|
88
71
|
hasError = true;
|
|
89
72
|
}
|
|
90
|
-
|
|
91
73
|
// 检查必填字段:name, type
|
|
92
74
|
if (!field.name || typeof field.name !== "string") {
|
|
93
75
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 缺少必填字段 name 或类型错误`);
|
|
@@ -99,7 +81,6 @@ export async function checkTable(tables: ScanFileResult[]): Promise<void> {
|
|
|
99
81
|
hasError = true;
|
|
100
82
|
continue;
|
|
101
83
|
}
|
|
102
|
-
|
|
103
84
|
// 检查可选字段的类型
|
|
104
85
|
if (field.min !== undefined && !(field.min === null || typeof field.min === "number")) {
|
|
105
86
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 字段 min 类型错误,必须为 null 或数字`);
|
|
@@ -133,33 +114,27 @@ export async function checkTable(tables: ScanFileResult[]): Promise<void> {
|
|
|
133
114
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 字段 regexp 类型错误,必须为 null 或字符串`);
|
|
134
115
|
hasError = true;
|
|
135
116
|
}
|
|
136
|
-
|
|
137
117
|
const { name: fieldName, type: fieldType, min: fieldMin, max: fieldMax, default: fieldDefault } = field;
|
|
138
|
-
|
|
139
118
|
// 字段名称必须为中文、数字、字母、下划线、短横线、空格
|
|
140
119
|
if (!FIELD_NAME_REGEX.test(fieldName)) {
|
|
141
120
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 字段名称 "${fieldName}" 格式错误,` + `必须为中文、数字、字母、下划线、短横线、空格`);
|
|
142
121
|
hasError = true;
|
|
143
122
|
}
|
|
144
|
-
|
|
145
123
|
// 字段类型必须为string,number,text,array_string,array_text之一
|
|
146
|
-
if (!FIELD_TYPES.includes(fieldType
|
|
124
|
+
if (!FIELD_TYPES.includes(fieldType)) {
|
|
147
125
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 字段类型 "${fieldType}" 格式错误,` + `必须为${FIELD_TYPES.join("、")}之一`);
|
|
148
126
|
hasError = true;
|
|
149
127
|
}
|
|
150
|
-
|
|
151
128
|
// unsigned 仅对 number 类型有效(且仅 MySQL 语义上生效)
|
|
152
129
|
if (fieldType !== "number" && field.unsigned !== undefined) {
|
|
153
130
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 字段类型为 ${fieldType},不允许设置 unsigned(仅 number 类型有效)`);
|
|
154
131
|
hasError = true;
|
|
155
132
|
}
|
|
156
|
-
|
|
157
133
|
// 约束:unique 与 index 不能同时为 true(否则会重复索引),必须阻断启动。
|
|
158
134
|
if (field.unique === true && field.index === true) {
|
|
159
135
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 同时设置了 unique=true 和 index=true,` + `unique 和 index 不能同时设置,请删除其一(否则会创建重复索引)`);
|
|
160
136
|
hasError = true;
|
|
161
137
|
}
|
|
162
|
-
|
|
163
138
|
// 约束:当最小值与最大值均为数字时,要求最小值 <= 最大值
|
|
164
139
|
if (fieldMin !== undefined && fieldMax !== undefined && fieldMin !== null && fieldMax !== null) {
|
|
165
140
|
if (fieldMin > fieldMax) {
|
|
@@ -167,7 +142,6 @@ export async function checkTable(tables: ScanFileResult[]): Promise<void> {
|
|
|
167
142
|
hasError = true;
|
|
168
143
|
}
|
|
169
144
|
}
|
|
170
|
-
|
|
171
145
|
// 类型联动校验 + 默认值规则
|
|
172
146
|
if (fieldType === "text" || fieldType === "array_text" || fieldType === "array_number_text") {
|
|
173
147
|
// text / array_text / array_number_text:min/max 必须为 null,默认值必须为 null,且不支持索引/唯一约束
|
|
@@ -183,7 +157,6 @@ export async function checkTable(tables: ScanFileResult[]): Promise<void> {
|
|
|
183
157
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 为 ${fieldType} 类型,默认值必须为 null,当前为 "${fieldDefault}"`);
|
|
184
158
|
hasError = true;
|
|
185
159
|
}
|
|
186
|
-
|
|
187
160
|
if (field.index === true) {
|
|
188
161
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 为 ${fieldType} 类型,不支持创建索引(index=true 无效)`);
|
|
189
162
|
hasError = true;
|
|
@@ -192,15 +165,18 @@ export async function checkTable(tables: ScanFileResult[]): Promise<void> {
|
|
|
192
165
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 为 ${fieldType} 类型,不支持唯一约束(unique=true 无效)`);
|
|
193
166
|
hasError = true;
|
|
194
167
|
}
|
|
195
|
-
}
|
|
168
|
+
}
|
|
169
|
+
else if (fieldType === "string" || fieldType === "array_string" || fieldType === "array_number_string") {
|
|
196
170
|
if (fieldMax !== undefined && (fieldMax === null || typeof fieldMax !== "number")) {
|
|
197
171
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 为 ${fieldType} 类型,` + `最大长度必须为数字,当前为 "${fieldMax}"`);
|
|
198
172
|
hasError = true;
|
|
199
|
-
}
|
|
173
|
+
}
|
|
174
|
+
else if (fieldMax !== undefined && fieldMax > MAX_VARCHAR_LENGTH) {
|
|
200
175
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 最大长度 ${fieldMax} 越界,` + `${fieldType} 类型长度必须在 1..${MAX_VARCHAR_LENGTH} 范围内`);
|
|
201
176
|
hasError = true;
|
|
202
177
|
}
|
|
203
|
-
}
|
|
178
|
+
}
|
|
179
|
+
else if (fieldType === "number") {
|
|
204
180
|
// number 类型:default 如果存在,必须为 null 或 number
|
|
205
181
|
if (fieldDefault !== undefined && fieldDefault !== null && typeof fieldDefault !== "number") {
|
|
206
182
|
Logger.warn(`${sourceName}表 ${fileName} 文件 ${colKey} 为 number 类型,` + `默认值必须为数字或 null,当前为 "${fieldDefault}"`);
|
|
@@ -208,12 +184,12 @@ export async function checkTable(tables: ScanFileResult[]): Promise<void> {
|
|
|
208
184
|
}
|
|
209
185
|
}
|
|
210
186
|
}
|
|
211
|
-
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
212
189
|
Logger.error(`${sourceName}表 ${item.fileName} 解析失败`, error);
|
|
213
190
|
hasError = true;
|
|
214
191
|
}
|
|
215
192
|
}
|
|
216
|
-
|
|
217
193
|
if (hasError) {
|
|
218
194
|
throw new Error("表结构检查失败");
|
|
219
195
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 预定义的默认字段(API fields 的 @ 引用)
|
|
3
3
|
*/
|
|
4
|
-
export const presetFields
|
|
4
|
+
export const presetFields = {
|
|
5
5
|
"@id": { name: "ID", type: "number", min: 1, max: null },
|
|
6
6
|
"@page": { name: "页码", type: "number", min: 1, max: 9999, default: 1 },
|
|
7
7
|
"@limit": { name: "每页数量", type: "number", min: 1, max: 100, default: 30 },
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 内置正则表达式别名
|
|
3
|
+
* 用于表单验证和数据校验
|
|
4
|
+
* 命名规范:小驼峰格式
|
|
5
|
+
*/
|
|
6
|
+
export declare const RegexAliases: {
|
|
7
|
+
/** 正整数(不含0) */
|
|
8
|
+
readonly number: "^\\d+$";
|
|
9
|
+
/** 整数(含负数) */
|
|
10
|
+
readonly integer: "^-?\\d+$";
|
|
11
|
+
/** 浮点数 */
|
|
12
|
+
readonly float: "^-?\\d+(\\.\\d+)?$";
|
|
13
|
+
/** 正整数(不含0) */
|
|
14
|
+
readonly positive: "^[1-9]\\d*$";
|
|
15
|
+
/** 负整数 */
|
|
16
|
+
readonly negative: "^-\\d+$";
|
|
17
|
+
/** 零 */
|
|
18
|
+
readonly zero: "^0$";
|
|
19
|
+
/** 纯字母 */
|
|
20
|
+
readonly word: "^[a-zA-Z]+$";
|
|
21
|
+
/** 字母和数字 */
|
|
22
|
+
readonly alphanumeric: "^[a-zA-Z0-9]+$";
|
|
23
|
+
/** 字母、数字和下划线 */
|
|
24
|
+
readonly alphanumeric_: "^[a-zA-Z0-9_]+$";
|
|
25
|
+
/** 字母、数字、下划线和短横线 */
|
|
26
|
+
readonly alphanumericDash_: "^[a-zA-Z0-9_-]+$";
|
|
27
|
+
/** 小写字母 */
|
|
28
|
+
readonly lowercase: "^[a-z]+$";
|
|
29
|
+
/** 大写字母 */
|
|
30
|
+
readonly uppercase: "^[A-Z]+$";
|
|
31
|
+
/** 纯中文 */
|
|
32
|
+
readonly chinese: "^[\\u4e00-\\u9fa5]+$";
|
|
33
|
+
/** 中文和字母 */
|
|
34
|
+
readonly chineseWord: "^[\\u4e00-\\u9fa5a-zA-Z]+$";
|
|
35
|
+
/** 邮箱地址 */
|
|
36
|
+
readonly email: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
|
|
37
|
+
/** 中国大陆手机号 */
|
|
38
|
+
readonly phone: "^1[3-9]\\d{9}$";
|
|
39
|
+
/** 固定电话(区号-号码) */
|
|
40
|
+
readonly telephone: "^0\\d{2,3}-?\\d{7,8}$";
|
|
41
|
+
/** URL 地址 */
|
|
42
|
+
readonly url: "^https?://";
|
|
43
|
+
/** IPv4 地址 */
|
|
44
|
+
readonly ip: "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$";
|
|
45
|
+
/** IPv6 地址 */
|
|
46
|
+
readonly ipv6: "^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$";
|
|
47
|
+
/** 域名 */
|
|
48
|
+
readonly domain: "^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$";
|
|
49
|
+
/** UUID */
|
|
50
|
+
readonly uuid: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
|
|
51
|
+
/** 十六进制字符串 */
|
|
52
|
+
readonly hex: "^[0-9a-fA-F]+$";
|
|
53
|
+
/** Base64 编码 */
|
|
54
|
+
readonly base64: "^[A-Za-z0-9+/=]+$";
|
|
55
|
+
/** MD5 哈希 */
|
|
56
|
+
readonly md5: "^[a-f0-9]{32}$";
|
|
57
|
+
/** SHA1 哈希 */
|
|
58
|
+
readonly sha1: "^[a-f0-9]{40}$";
|
|
59
|
+
/** SHA256 哈希 */
|
|
60
|
+
readonly sha256: "^[a-f0-9]{64}$";
|
|
61
|
+
/** 日期 YYYY-MM-DD */
|
|
62
|
+
readonly date: "^\\d{4}-\\d{2}-\\d{2}$";
|
|
63
|
+
/** 时间 HH:MM:SS */
|
|
64
|
+
readonly time: "^\\d{2}:\\d{2}:\\d{2}$";
|
|
65
|
+
/** ISO 日期时间 */
|
|
66
|
+
readonly datetime: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}";
|
|
67
|
+
/** 年份 */
|
|
68
|
+
readonly year: "^\\d{4}$";
|
|
69
|
+
/** 月份 01-12 */
|
|
70
|
+
readonly month: "^(0[1-9]|1[0-2])$";
|
|
71
|
+
/** 日期 01-31 */
|
|
72
|
+
readonly day: "^(0[1-9]|[12]\\d|3[01])$";
|
|
73
|
+
/** 变量名 */
|
|
74
|
+
readonly variable: "^[a-zA-Z_][a-zA-Z0-9_]*$";
|
|
75
|
+
/** 常量名(全大写) */
|
|
76
|
+
readonly constant: "^[A-Z][A-Z0-9_]*$";
|
|
77
|
+
/** 包名(小写+连字符) */
|
|
78
|
+
readonly package: "^[a-z][a-z0-9-]*$";
|
|
79
|
+
/** 中国身份证号(18位) */
|
|
80
|
+
readonly idCard: "^\\d{17}[\\dXx]$";
|
|
81
|
+
/** 护照号 */
|
|
82
|
+
readonly passport: "^[a-zA-Z0-9]{5,17}$";
|
|
83
|
+
/** 银行卡号(16-19位数字) */
|
|
84
|
+
readonly bankCard: "^\\d{16,19}$";
|
|
85
|
+
/** 微信号(6-20位,字母开头,可包含字母、数字、下划线、减号) */
|
|
86
|
+
readonly wechat: "^[a-zA-Z][a-zA-Z0-9_-]{5,19}$";
|
|
87
|
+
/** QQ号(5-11位数字,首位非0) */
|
|
88
|
+
readonly qq: "^[1-9]\\d{4,10}$";
|
|
89
|
+
/** 支付宝账号(手机号或邮箱) */
|
|
90
|
+
readonly alipay: "^(1[3-9]\\d{9}|[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})$";
|
|
91
|
+
/** 用户名(4-20位,字母开头,可包含字母、数字、下划线) */
|
|
92
|
+
readonly username: "^[a-zA-Z][a-zA-Z0-9_]{3,19}$";
|
|
93
|
+
/** 昵称(2-20位,支持中文、字母、数字) */
|
|
94
|
+
readonly nickname: "^[\\u4e00-\\u9fa5a-zA-Z0-9]{2,20}$";
|
|
95
|
+
/** 弱密码(至少6位) */
|
|
96
|
+
readonly passwordWeak: "^.{6,}$";
|
|
97
|
+
/** 中等密码(至少8位,包含字母和数字) */
|
|
98
|
+
readonly passwordMedium: "^(?=.*[a-zA-Z])(?=.*\\d).{8,}$";
|
|
99
|
+
/** 强密码(至少8位,包含大小写字母、数字和特殊字符) */
|
|
100
|
+
readonly passwordStrong: "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*]).{8,}$";
|
|
101
|
+
/** 车牌号(新能源+普通) */
|
|
102
|
+
readonly licensePlate: "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$";
|
|
103
|
+
/** 邮政编码 */
|
|
104
|
+
readonly postalCode: "^\\d{6}$";
|
|
105
|
+
/** 版本号(语义化版本) */
|
|
106
|
+
readonly semver: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?(\\+[a-zA-Z0-9.]+)?$";
|
|
107
|
+
/** 颜色值(十六进制) */
|
|
108
|
+
readonly colorHex: "^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$";
|
|
109
|
+
/** 空字符串 */
|
|
110
|
+
readonly empty: "^$";
|
|
111
|
+
/** 非空 */
|
|
112
|
+
readonly notempty: ".+";
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* 正则别名类型
|
|
116
|
+
*/
|
|
117
|
+
export type RegexAliasName = keyof typeof RegexAliases;
|
|
118
|
+
/**
|
|
119
|
+
* 获取正则表达式字符串
|
|
120
|
+
* @param name 正则别名(以 @ 开头)或自定义正则字符串
|
|
121
|
+
* @returns 正则表达式字符串
|
|
122
|
+
*/
|
|
123
|
+
export declare function getRegex(name: string): string;
|
|
124
|
+
/**
|
|
125
|
+
* 获取编译后的正则表达式对象(带缓存)
|
|
126
|
+
* @param pattern 正则别名或正则字符串
|
|
127
|
+
* @param flags 正则标志(如 'i', 'g')
|
|
128
|
+
* @returns 编译后的 RegExp 对象
|
|
129
|
+
*/
|
|
130
|
+
export declare function getCompiledRegex(pattern: string, flags?: string): RegExp;
|
|
131
|
+
/**
|
|
132
|
+
* 验证值是否匹配正则(使用缓存)
|
|
133
|
+
* @param value 要验证的值
|
|
134
|
+
* @param pattern 正则别名或正则字符串
|
|
135
|
+
* @returns 是否匹配
|
|
136
|
+
*/
|
|
137
|
+
export declare function matchRegex(value: string, pattern: string): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* 清除正则缓存
|
|
140
|
+
*/
|
|
141
|
+
export declare function clearRegexCache(): void;
|
|
142
|
+
/**
|
|
143
|
+
* 获取缓存大小
|
|
144
|
+
*/
|
|
145
|
+
export declare function getRegexCacheSize(): number;
|
|
@@ -19,7 +19,6 @@ export const RegexAliases = {
|
|
|
19
19
|
negative: "^-\\d+$",
|
|
20
20
|
/** 零 */
|
|
21
21
|
zero: "^0$",
|
|
22
|
-
|
|
23
22
|
// ============================================
|
|
24
23
|
// 字符串类型
|
|
25
24
|
// ============================================
|
|
@@ -35,7 +34,6 @@ export const RegexAliases = {
|
|
|
35
34
|
lowercase: "^[a-z]+$",
|
|
36
35
|
/** 大写字母 */
|
|
37
36
|
uppercase: "^[A-Z]+$",
|
|
38
|
-
|
|
39
37
|
// ============================================
|
|
40
38
|
// 中文
|
|
41
39
|
// ============================================
|
|
@@ -43,7 +41,6 @@ export const RegexAliases = {
|
|
|
43
41
|
chinese: "^[\\u4e00-\\u9fa5]+$",
|
|
44
42
|
/** 中文和字母 */
|
|
45
43
|
chineseWord: "^[\\u4e00-\\u9fa5a-zA-Z]+$",
|
|
46
|
-
|
|
47
44
|
// ============================================
|
|
48
45
|
// 常用格式
|
|
49
46
|
// ============================================
|
|
@@ -61,7 +58,6 @@ export const RegexAliases = {
|
|
|
61
58
|
ipv6: "^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$",
|
|
62
59
|
/** 域名 */
|
|
63
60
|
domain: "^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$",
|
|
64
|
-
|
|
65
61
|
// ============================================
|
|
66
62
|
// 特殊格式
|
|
67
63
|
// ============================================
|
|
@@ -77,7 +73,6 @@ export const RegexAliases = {
|
|
|
77
73
|
sha1: "^[a-f0-9]{40}$",
|
|
78
74
|
/** SHA256 哈希 */
|
|
79
75
|
sha256: "^[a-f0-9]{64}$",
|
|
80
|
-
|
|
81
76
|
// ============================================
|
|
82
77
|
// 日期时间
|
|
83
78
|
// ============================================
|
|
@@ -93,7 +88,6 @@ export const RegexAliases = {
|
|
|
93
88
|
month: "^(0[1-9]|1[0-2])$",
|
|
94
89
|
/** 日期 01-31 */
|
|
95
90
|
day: "^(0[1-9]|[12]\\d|3[01])$",
|
|
96
|
-
|
|
97
91
|
// ============================================
|
|
98
92
|
// 代码相关
|
|
99
93
|
// ============================================
|
|
@@ -103,7 +97,6 @@ export const RegexAliases = {
|
|
|
103
97
|
constant: "^[A-Z][A-Z0-9_]*$",
|
|
104
98
|
/** 包名(小写+连字符) */
|
|
105
99
|
package: "^[a-z][a-z0-9-]*$",
|
|
106
|
-
|
|
107
100
|
// ============================================
|
|
108
101
|
// 证件相关
|
|
109
102
|
// ============================================
|
|
@@ -111,7 +104,6 @@ export const RegexAliases = {
|
|
|
111
104
|
idCard: "^\\d{17}[\\dXx]$",
|
|
112
105
|
/** 护照号 */
|
|
113
106
|
passport: "^[a-zA-Z0-9]{5,17}$",
|
|
114
|
-
|
|
115
107
|
// ============================================
|
|
116
108
|
// 账号相关(国内常用)
|
|
117
109
|
// ============================================
|
|
@@ -127,7 +119,6 @@ export const RegexAliases = {
|
|
|
127
119
|
username: "^[a-zA-Z][a-zA-Z0-9_]{3,19}$",
|
|
128
120
|
/** 昵称(2-20位,支持中文、字母、数字) */
|
|
129
121
|
nickname: "^[\\u4e00-\\u9fa5a-zA-Z0-9]{2,20}$",
|
|
130
|
-
|
|
131
122
|
// ============================================
|
|
132
123
|
// 密码强度
|
|
133
124
|
// ============================================
|
|
@@ -137,7 +128,6 @@ export const RegexAliases = {
|
|
|
137
128
|
passwordMedium: "^(?=.*[a-zA-Z])(?=.*\\d).{8,}$",
|
|
138
129
|
/** 强密码(至少8位,包含大小写字母、数字和特殊字符) */
|
|
139
130
|
passwordStrong: "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*]).{8,}$",
|
|
140
|
-
|
|
141
131
|
// ============================================
|
|
142
132
|
// 其他常用
|
|
143
133
|
// ============================================
|
|
@@ -149,7 +139,6 @@ export const RegexAliases = {
|
|
|
149
139
|
semver: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?(\\+[a-zA-Z0-9.]+)?$",
|
|
150
140
|
/** 颜色值(十六进制) */
|
|
151
141
|
colorHex: "^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$",
|
|
152
|
-
|
|
153
142
|
// ============================================
|
|
154
143
|
// 空值
|
|
155
144
|
// ============================================
|
|
@@ -157,41 +146,32 @@ export const RegexAliases = {
|
|
|
157
146
|
empty: "^$",
|
|
158
147
|
/** 非空 */
|
|
159
148
|
notempty: ".+"
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* 正则别名类型
|
|
164
|
-
*/
|
|
165
|
-
export type RegexAliasName = keyof typeof RegexAliases;
|
|
166
|
-
|
|
149
|
+
};
|
|
167
150
|
// ============================================
|
|
168
151
|
// 正则表达式缓存(性能优化)
|
|
169
152
|
// ============================================
|
|
170
|
-
const regexCache = new Map
|
|
171
|
-
|
|
153
|
+
const regexCache = new Map();
|
|
172
154
|
/**
|
|
173
155
|
* 获取正则表达式字符串
|
|
174
156
|
* @param name 正则别名(以 @ 开头)或自定义正则字符串
|
|
175
157
|
* @returns 正则表达式字符串
|
|
176
158
|
*/
|
|
177
|
-
export function getRegex(name
|
|
159
|
+
export function getRegex(name) {
|
|
178
160
|
if (name.startsWith("@")) {
|
|
179
|
-
const alias = name.slice(1)
|
|
161
|
+
const alias = name.slice(1);
|
|
180
162
|
return RegexAliases[alias] || name;
|
|
181
163
|
}
|
|
182
164
|
return name;
|
|
183
165
|
}
|
|
184
|
-
|
|
185
166
|
/**
|
|
186
167
|
* 获取编译后的正则表达式对象(带缓存)
|
|
187
168
|
* @param pattern 正则别名或正则字符串
|
|
188
169
|
* @param flags 正则标志(如 'i', 'g')
|
|
189
170
|
* @returns 编译后的 RegExp 对象
|
|
190
171
|
*/
|
|
191
|
-
export function getCompiledRegex(pattern
|
|
172
|
+
export function getCompiledRegex(pattern, flags) {
|
|
192
173
|
const regexStr = getRegex(pattern);
|
|
193
174
|
const cacheKey = `${regexStr}:${flags || ""}`;
|
|
194
|
-
|
|
195
175
|
let cached = regexCache.get(cacheKey);
|
|
196
176
|
if (!cached) {
|
|
197
177
|
cached = new RegExp(regexStr, flags);
|
|
@@ -199,27 +179,24 @@ export function getCompiledRegex(pattern: string, flags?: string): RegExp {
|
|
|
199
179
|
}
|
|
200
180
|
return cached;
|
|
201
181
|
}
|
|
202
|
-
|
|
203
182
|
/**
|
|
204
183
|
* 验证值是否匹配正则(使用缓存)
|
|
205
184
|
* @param value 要验证的值
|
|
206
185
|
* @param pattern 正则别名或正则字符串
|
|
207
186
|
* @returns 是否匹配
|
|
208
187
|
*/
|
|
209
|
-
export function matchRegex(value
|
|
188
|
+
export function matchRegex(value, pattern) {
|
|
210
189
|
return getCompiledRegex(pattern).test(value);
|
|
211
190
|
}
|
|
212
|
-
|
|
213
191
|
/**
|
|
214
192
|
* 清除正则缓存
|
|
215
193
|
*/
|
|
216
|
-
export function clearRegexCache()
|
|
194
|
+
export function clearRegexCache() {
|
|
217
195
|
regexCache.clear();
|
|
218
196
|
}
|
|
219
|
-
|
|
220
197
|
/**
|
|
221
198
|
* 获取缓存大小
|
|
222
199
|
*/
|
|
223
|
-
export function getRegexCacheSize()
|
|
200
|
+
export function getRegexCacheSize() {
|
|
224
201
|
return regexCache.size;
|
|
225
202
|
}
|
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { setCtxUser } from "../lib/asyncContext.ts";
|
|
4
|
-
|
|
1
|
+
import { setCtxUser } from "../lib/asyncContext";
|
|
5
2
|
export default {
|
|
3
|
+
name: "auth",
|
|
4
|
+
enable: true,
|
|
6
5
|
deps: ["cors"],
|
|
7
6
|
handler: async (befly, ctx) => {
|
|
8
7
|
const authHeader = ctx.req.headers.get("authorization");
|
|
9
|
-
|
|
10
8
|
if (authHeader && authHeader.startsWith("Bearer ")) {
|
|
11
9
|
const token = authHeader.substring(7);
|
|
12
|
-
|
|
13
10
|
try {
|
|
14
11
|
const payload = await befly.jwt.verify(token);
|
|
15
12
|
ctx.user = payload;
|
|
16
|
-
|
|
17
13
|
setCtxUser(payload.id, payload.roleCode, payload.nickname, payload.roleType);
|
|
18
|
-
}
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
19
16
|
ctx.user = {};
|
|
20
17
|
}
|
|
21
|
-
}
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
22
20
|
ctx.user = {};
|
|
23
21
|
}
|
|
24
22
|
}
|
|
25
|
-
}
|
|
23
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS 跨域处理钩子
|
|
3
|
+
* 设置跨域响应头并处理 OPTIONS 预检请求
|
|
4
|
+
*/
|
|
5
|
+
declare const _default: {
|
|
6
|
+
name: string;
|
|
7
|
+
enable: true;
|
|
8
|
+
deps: never[];
|
|
9
|
+
handler: (befly: import("../types/befly").BeflyContext, ctx: import("../types/context").RequestContext<Record<string, any>>) => Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
export default _default;
|
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
import type { CorsConfig } from "../types/befly.ts";
|
|
2
|
-
// 类型导入
|
|
3
|
-
import type { Hook } from "../types/hook.ts";
|
|
4
|
-
|
|
5
1
|
// 相对导入
|
|
6
|
-
import { setCorsOptions } from "../utils/cors
|
|
7
|
-
|
|
2
|
+
import { setCorsOptions } from "../utils/cors";
|
|
8
3
|
/**
|
|
9
4
|
* CORS 跨域处理钩子
|
|
10
5
|
* 设置跨域响应头并处理 OPTIONS 预检请求
|
|
11
6
|
*/
|
|
12
7
|
export default {
|
|
8
|
+
name: "cors",
|
|
9
|
+
enable: true,
|
|
13
10
|
deps: [],
|
|
14
11
|
handler: async (befly, ctx) => {
|
|
15
12
|
const req = ctx.req;
|
|
16
|
-
|
|
17
13
|
// 合并默认配置和用户配置
|
|
18
|
-
const defaultConfig
|
|
14
|
+
const defaultConfig = {
|
|
19
15
|
origin: "*",
|
|
20
16
|
methods: "GET, POST, PUT, DELETE, OPTIONS",
|
|
21
17
|
allowedHeaders: "Content-Type, Authorization, authorization, token",
|
|
@@ -23,14 +19,10 @@ export default {
|
|
|
23
19
|
maxAge: 86400,
|
|
24
20
|
credentials: "true"
|
|
25
21
|
};
|
|
26
|
-
|
|
27
22
|
const corsConfig = Object.assign({}, defaultConfig, befly.config && befly.config.cors ? befly.config.cors : {});
|
|
28
|
-
|
|
29
23
|
// 设置 CORS 响应头
|
|
30
24
|
const headers = setCorsOptions(req, corsConfig);
|
|
31
|
-
|
|
32
25
|
ctx.corsHeaders = headers;
|
|
33
|
-
|
|
34
26
|
// 处理 OPTIONS 预检请求
|
|
35
27
|
if (req.method === "OPTIONS") {
|
|
36
28
|
ctx.response = new Response(null, {
|
|
@@ -40,4 +32,4 @@ export default {
|
|
|
40
32
|
return;
|
|
41
33
|
}
|
|
42
34
|
}
|
|
43
|
-
}
|
|
35
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 请求参数解析钩子
|
|
3
|
+
* - GET 请求:解析 URL 查询参数
|
|
4
|
+
* - POST 请求:解析 JSON 或 XML 请求体
|
|
5
|
+
* - 根据 API 定义的 fields 过滤字段
|
|
6
|
+
* - rawBody: true 时跳过解析,由 handler 自行处理原始请求
|
|
7
|
+
*/
|
|
8
|
+
declare const _default: {
|
|
9
|
+
name: string;
|
|
10
|
+
enable: true;
|
|
11
|
+
deps: string[];
|
|
12
|
+
handler: (befly: import("../types/befly").BeflyContext, ctx: import("../types/context").RequestContext<Record<string, any>>) => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
export default _default;
|