befly 3.9.37 → 3.9.39
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 +38 -39
- package/befly.config.ts +62 -40
- package/checks/checkApi.ts +16 -16
- package/checks/checkApp.ts +19 -25
- package/checks/checkTable.ts +42 -42
- package/docs/README.md +42 -35
- package/docs/{api.md → api/api.md} +225 -235
- package/docs/cipher.md +71 -69
- package/docs/database.md +155 -153
- package/docs/{examples.md → guide/examples.md} +181 -181
- package/docs/guide/quickstart.md +331 -0
- package/docs/hooks/auth.md +38 -0
- package/docs/hooks/cors.md +28 -0
- package/docs/{hook.md → hooks/hook.md} +140 -57
- package/docs/hooks/parser.md +19 -0
- package/docs/hooks/rateLimit.md +47 -0
- package/docs/{redis.md → infra/redis.md} +84 -93
- package/docs/plugins/cipher.md +61 -0
- package/docs/plugins/database.md +128 -0
- package/docs/{plugin.md → plugins/plugin.md} +83 -81
- package/docs/quickstart.md +26 -26
- package/docs/{addon.md → reference/addon.md} +46 -46
- package/docs/{config.md → reference/config.md} +32 -80
- package/docs/{logger.md → reference/logger.md} +52 -52
- package/docs/{sync.md → reference/sync.md} +32 -35
- package/docs/{table.md → reference/table.md} +7 -7
- package/docs/{validator.md → reference/validator.md} +57 -57
- package/hooks/auth.ts +8 -4
- package/hooks/cors.ts +13 -13
- package/hooks/parser.ts +37 -17
- package/hooks/permission.ts +26 -14
- package/hooks/rateLimit.ts +276 -0
- package/hooks/validator.ts +15 -7
- package/lib/asyncContext.ts +43 -0
- package/lib/cacheHelper.ts +212 -81
- package/lib/cacheKeys.ts +38 -0
- package/lib/cipher.ts +30 -30
- package/lib/connect.ts +28 -28
- package/lib/dbHelper.ts +211 -109
- package/lib/jwt.ts +16 -16
- package/lib/logger.ts +610 -19
- package/lib/redisHelper.ts +185 -44
- package/lib/sqlBuilder.ts +90 -91
- package/lib/validator.ts +59 -39
- package/loader/loadApis.ts +53 -47
- package/loader/loadHooks.ts +40 -14
- package/loader/loadPlugins.ts +16 -17
- package/main.ts +57 -47
- package/package.json +47 -45
- package/paths.ts +15 -14
- package/plugins/cache.ts +5 -4
- package/plugins/cipher.ts +3 -3
- package/plugins/config.ts +2 -2
- package/plugins/db.ts +9 -9
- package/plugins/jwt.ts +3 -3
- package/plugins/logger.ts +8 -12
- package/plugins/redis.ts +8 -8
- package/plugins/tool.ts +6 -6
- package/router/api.ts +85 -56
- package/router/static.ts +12 -12
- package/sync/syncAll.ts +12 -12
- package/sync/syncApi.ts +55 -54
- package/sync/syncDb/apply.ts +20 -19
- package/sync/syncDb/constants.ts +25 -23
- package/sync/syncDb/ddl.ts +35 -36
- package/sync/syncDb/helpers.ts +6 -9
- package/sync/syncDb/schema.ts +10 -9
- package/sync/syncDb/sqlite.ts +7 -8
- package/sync/syncDb/table.ts +37 -35
- package/sync/syncDb/tableCreate.ts +21 -20
- package/sync/syncDb/types.ts +23 -20
- package/sync/syncDb/version.ts +10 -10
- package/sync/syncDb.ts +43 -36
- package/sync/syncDev.ts +74 -66
- package/sync/syncMenu.ts +190 -57
- package/tests/api-integration-array-number.test.ts +282 -0
- package/tests/befly-config-env.test.ts +78 -0
- package/tests/cacheHelper.test.ts +135 -104
- package/tests/cacheKeys.test.ts +41 -0
- package/tests/cipher.test.ts +90 -89
- package/tests/dbHelper-advanced.test.ts +140 -134
- package/tests/dbHelper-all-array-types.test.ts +316 -0
- package/tests/dbHelper-array-serialization.test.ts +258 -0
- package/tests/dbHelper-columns.test.ts +56 -55
- package/tests/dbHelper-execute.test.ts +45 -44
- package/tests/dbHelper-joins.test.ts +124 -119
- package/tests/fields-redis-cache.test.ts +29 -27
- package/tests/fields-validate.test.ts +38 -38
- package/tests/getClientIp.test.ts +54 -0
- package/tests/integration.test.ts +69 -67
- package/tests/jwt.test.ts +27 -26
- package/tests/logger.test.ts +267 -34
- package/tests/rateLimit-hook.test.ts +477 -0
- package/tests/redisHelper.test.ts +187 -188
- package/tests/redisKeys.test.ts +6 -73
- package/tests/scanConfig.test.ts +144 -0
- package/tests/sqlBuilder-advanced.test.ts +217 -215
- package/tests/sqlBuilder.test.ts +92 -91
- package/tests/sync-connection.test.ts +29 -29
- package/tests/syncDb-apply.test.ts +97 -96
- package/tests/syncDb-array-number.test.ts +160 -0
- package/tests/syncDb-constants.test.ts +48 -47
- package/tests/syncDb-ddl.test.ts +99 -98
- package/tests/syncDb-helpers.test.ts +29 -28
- package/tests/syncDb-schema.test.ts +61 -60
- package/tests/syncDb-types.test.ts +60 -59
- package/tests/syncMenu-paths.test.ts +68 -0
- package/tests/util.test.ts +42 -41
- package/tests/validator-array-number.test.ts +310 -0
- package/tests/validator-default.test.ts +373 -0
- package/tests/validator.test.ts +271 -266
- package/tsconfig.json +4 -5
- package/types/api.d.ts +7 -12
- package/types/befly.d.ts +60 -13
- package/types/cache.d.ts +8 -4
- package/types/common.d.ts +17 -9
- package/types/context.d.ts +2 -2
- package/types/crypto.d.ts +23 -0
- package/types/database.d.ts +19 -19
- package/types/hook.d.ts +2 -2
- package/types/jwt.d.ts +118 -0
- package/types/logger.d.ts +30 -0
- package/types/plugin.d.ts +4 -4
- package/types/redis.d.ts +7 -3
- package/types/roleApisCache.ts +23 -0
- package/types/sync.d.ts +10 -10
- package/types/table.d.ts +50 -9
- package/types/validate.d.ts +69 -0
- package/utils/addonHelper.ts +90 -0
- package/utils/arrayKeysToCamel.ts +18 -0
- package/utils/calcPerfTime.ts +13 -0
- package/utils/configTypes.ts +3 -0
- package/utils/cors.ts +19 -0
- package/utils/fieldClear.ts +75 -0
- package/utils/genShortId.ts +12 -0
- package/utils/getClientIp.ts +45 -0
- package/utils/keysToCamel.ts +22 -0
- package/utils/keysToSnake.ts +22 -0
- package/utils/modules.ts +98 -0
- package/utils/pickFields.ts +19 -0
- package/utils/process.ts +56 -0
- package/utils/regex.ts +225 -0
- package/utils/response.ts +115 -0
- package/utils/route.ts +23 -0
- package/utils/scanConfig.ts +142 -0
- package/utils/scanFiles.ts +48 -0
- package/.prettierignore +0 -2
- package/.prettierrc +0 -12
- package/docs/1-/345/237/272/346/234/254/344/273/213/347/273/215.md +0 -35
- package/docs/2-/345/210/235/346/255/245/344/275/223/351/252/214.md +0 -64
- package/docs/3-/347/254/254/344/270/200/344/270/252/346/216/245/345/217/243.md +0 -46
- package/docs/4-/346/223/215/344/275/234/346/225/260/346/215/256/345/272/223.md +0 -172
- package/hooks/requestLogger.ts +0 -84
- package/types/index.ts +0 -24
- package/util.ts +0 -283
package/checks/checkTable.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
+
// 类型导入
|
|
2
|
+
import type { FieldDefinition } from "../types/validate.js";
|
|
3
|
+
|
|
1
4
|
// 内部依赖
|
|
2
|
-
import { existsSync } from
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
3
6
|
|
|
4
7
|
// 外部依赖
|
|
5
|
-
import { basename } from
|
|
6
|
-
import { scanFiles } from 'befly-shared/scanFiles';
|
|
7
|
-
import { scanAddons, getAddonDir } from 'befly-shared/addonHelper';
|
|
8
|
+
import { basename } from "pathe";
|
|
8
9
|
|
|
10
|
+
import { Logger } from "../lib/logger.js";
|
|
11
|
+
import { projectTableDir } from "../paths.js";
|
|
12
|
+
import { scanAddons, getAddonDir } from "../utils/addonHelper.js";
|
|
9
13
|
// 相对导入
|
|
10
|
-
import {
|
|
11
|
-
import { projectTableDir } from '../paths.js';
|
|
12
|
-
|
|
13
|
-
// 类型导入
|
|
14
|
-
import type { FieldDefinition } from 'befly-shared/types';
|
|
14
|
+
import { scanFiles } from "../utils/scanFiles.js";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* 表文件信息接口
|
|
@@ -20,7 +20,7 @@ interface TableFileInfo {
|
|
|
20
20
|
/** 表文件路径 */
|
|
21
21
|
file: string;
|
|
22
22
|
/** 文件类型:project(项目)或 addon(组件) */
|
|
23
|
-
type:
|
|
23
|
+
type: "project" | "addon";
|
|
24
24
|
/** 如果是 addon 类型,记录 addon 名称 */
|
|
25
25
|
addonName?: string;
|
|
26
26
|
/** 类型名称(用于日志) */
|
|
@@ -30,17 +30,17 @@ interface TableFileInfo {
|
|
|
30
30
|
/**
|
|
31
31
|
* 保留字段列表
|
|
32
32
|
*/
|
|
33
|
-
const RESERVED_FIELDS = [
|
|
33
|
+
const RESERVED_FIELDS = ["id", "created_at", "updated_at", "deleted_at", "state"] as const;
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* 允许的字段类型
|
|
37
37
|
*/
|
|
38
|
-
const FIELD_TYPES = [
|
|
38
|
+
const FIELD_TYPES = ["string", "number", "text", "array_string", "array_text", "array_number_string", "array_number_text"] as const;
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* 允许的字段属性列表
|
|
42
42
|
*/
|
|
43
|
-
const ALLOWED_FIELD_PROPERTIES = [
|
|
43
|
+
const ALLOWED_FIELD_PROPERTIES = ["name", "type", "min", "max", "default", "detail", "index", "unique", "nullable", "unsigned", "regexp"] as const;
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* 小驼峰命名正则
|
|
@@ -73,12 +73,12 @@ export async function checkTable(): Promise<void> {
|
|
|
73
73
|
|
|
74
74
|
// 收集项目表字段定义文件(如果目录存在)
|
|
75
75
|
if (existsSync(projectTableDir)) {
|
|
76
|
-
const files = await scanFiles(projectTableDir,
|
|
76
|
+
const files = await scanFiles(projectTableDir, "*.json");
|
|
77
77
|
for (const { filePath } of files) {
|
|
78
78
|
allTableFiles.push({
|
|
79
79
|
file: filePath,
|
|
80
|
-
type:
|
|
81
|
-
typeName:
|
|
80
|
+
type: "project",
|
|
81
|
+
typeName: "项目"
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
}
|
|
@@ -86,18 +86,18 @@ export async function checkTable(): Promise<void> {
|
|
|
86
86
|
// 收集 addon 表字段定义文件
|
|
87
87
|
const addons = scanAddons();
|
|
88
88
|
for (const addonName of addons) {
|
|
89
|
-
const addonTablesDir = getAddonDir(addonName,
|
|
89
|
+
const addonTablesDir = getAddonDir(addonName, "tables");
|
|
90
90
|
|
|
91
91
|
// 检查 addon tables 目录是否存在
|
|
92
92
|
if (!existsSync(addonTablesDir)) {
|
|
93
93
|
continue;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
const files = await scanFiles(addonTablesDir,
|
|
96
|
+
const files = await scanFiles(addonTablesDir, "*.json");
|
|
97
97
|
for (const { filePath } of files) {
|
|
98
98
|
allTableFiles.push({
|
|
99
99
|
file: filePath,
|
|
100
|
-
type:
|
|
100
|
+
type: "addon",
|
|
101
101
|
typeName: `组件${addonName}`,
|
|
102
102
|
addonName: addonName
|
|
103
103
|
});
|
|
@@ -107,7 +107,7 @@ export async function checkTable(): Promise<void> {
|
|
|
107
107
|
// 合并进行验证逻辑
|
|
108
108
|
for (const item of allTableFiles) {
|
|
109
109
|
const fileName = basename(item.file);
|
|
110
|
-
const fileBaseName = basename(item.file,
|
|
110
|
+
const fileBaseName = basename(item.file, ".json");
|
|
111
111
|
|
|
112
112
|
try {
|
|
113
113
|
// 1) 文件名小驼峰校验
|
|
@@ -118,12 +118,12 @@ export async function checkTable(): Promise<void> {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
// 动态导入 JSON 文件
|
|
121
|
-
const tableModule = await import(item.file, { with: { type:
|
|
121
|
+
const tableModule = await import(item.file, { with: { type: "json" } });
|
|
122
122
|
const table = tableModule.default;
|
|
123
123
|
|
|
124
124
|
// 检查 table 中的每个验证规则
|
|
125
125
|
for (const [colKey, fieldDef] of Object.entries(table)) {
|
|
126
|
-
if (typeof fieldDef !==
|
|
126
|
+
if (typeof fieldDef !== "object" || fieldDef === null || Array.isArray(fieldDef)) {
|
|
127
127
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 规则必须为对象`);
|
|
128
128
|
hasError = true;
|
|
129
129
|
continue;
|
|
@@ -131,7 +131,7 @@ export async function checkTable(): Promise<void> {
|
|
|
131
131
|
|
|
132
132
|
// 检查是否使用了保留字段
|
|
133
133
|
if (RESERVED_FIELDS.includes(colKey as any)) {
|
|
134
|
-
Logger.warn(`${item.typeName}表 ${fileName} 文件包含保留字段 ${colKey},` + `不能在表定义中使用以下字段: ${RESERVED_FIELDS.join(
|
|
134
|
+
Logger.warn(`${item.typeName}表 ${fileName} 文件包含保留字段 ${colKey},` + `不能在表定义中使用以下字段: ${RESERVED_FIELDS.join(", ")}`);
|
|
135
135
|
hasError = true;
|
|
136
136
|
}
|
|
137
137
|
|
|
@@ -142,52 +142,52 @@ export async function checkTable(): Promise<void> {
|
|
|
142
142
|
const fieldKeys = Object.keys(field);
|
|
143
143
|
const illegalProps = fieldKeys.filter((key) => !ALLOWED_FIELD_PROPERTIES.includes(key as any));
|
|
144
144
|
if (illegalProps.length > 0) {
|
|
145
|
-
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 包含非法属性: ${illegalProps.join(
|
|
145
|
+
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 包含非法属性: ${illegalProps.join(", ")},` + `允许的属性为: ${ALLOWED_FIELD_PROPERTIES.join(", ")}`);
|
|
146
146
|
hasError = true;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
// 检查必填字段:name, type
|
|
150
|
-
if (!field.name || typeof field.name !==
|
|
150
|
+
if (!field.name || typeof field.name !== "string") {
|
|
151
151
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 缺少必填字段 name 或类型错误`);
|
|
152
152
|
hasError = true;
|
|
153
153
|
continue;
|
|
154
154
|
}
|
|
155
|
-
if (!field.type || typeof field.type !==
|
|
155
|
+
if (!field.type || typeof field.type !== "string") {
|
|
156
156
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 缺少必填字段 type 或类型错误`);
|
|
157
157
|
hasError = true;
|
|
158
158
|
continue;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
// 检查可选字段的类型
|
|
162
|
-
if (field.min !== undefined && !(field.min === null || typeof field.min ===
|
|
162
|
+
if (field.min !== undefined && !(field.min === null || typeof field.min === "number")) {
|
|
163
163
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段 min 类型错误,必须为 null 或数字`);
|
|
164
164
|
hasError = true;
|
|
165
165
|
}
|
|
166
|
-
if (field.max !== undefined && !(field.max === null || typeof field.max ===
|
|
166
|
+
if (field.max !== undefined && !(field.max === null || typeof field.max === "number")) {
|
|
167
167
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段 max 类型错误,必须为 null 或数字`);
|
|
168
168
|
hasError = true;
|
|
169
169
|
}
|
|
170
|
-
if (field.detail !== undefined && typeof field.detail !==
|
|
170
|
+
if (field.detail !== undefined && typeof field.detail !== "string") {
|
|
171
171
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段 detail 类型错误,必须为字符串`);
|
|
172
172
|
hasError = true;
|
|
173
173
|
}
|
|
174
|
-
if (field.index !== undefined && typeof field.index !==
|
|
174
|
+
if (field.index !== undefined && typeof field.index !== "boolean") {
|
|
175
175
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段 index 类型错误,必须为布尔值`);
|
|
176
176
|
hasError = true;
|
|
177
177
|
}
|
|
178
|
-
if (field.unique !== undefined && typeof field.unique !==
|
|
178
|
+
if (field.unique !== undefined && typeof field.unique !== "boolean") {
|
|
179
179
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段 unique 类型错误,必须为布尔值`);
|
|
180
180
|
hasError = true;
|
|
181
181
|
}
|
|
182
|
-
if (field.nullable !== undefined && typeof field.nullable !==
|
|
182
|
+
if (field.nullable !== undefined && typeof field.nullable !== "boolean") {
|
|
183
183
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段 nullable 类型错误,必须为布尔值`);
|
|
184
184
|
hasError = true;
|
|
185
185
|
}
|
|
186
|
-
if (field.unsigned !== undefined && typeof field.unsigned !==
|
|
186
|
+
if (field.unsigned !== undefined && typeof field.unsigned !== "boolean") {
|
|
187
187
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段 unsigned 类型错误,必须为布尔值`);
|
|
188
188
|
hasError = true;
|
|
189
189
|
}
|
|
190
|
-
if (field.regexp !== undefined && field.regexp !== null && typeof field.regexp !==
|
|
190
|
+
if (field.regexp !== undefined && field.regexp !== null && typeof field.regexp !== "string") {
|
|
191
191
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段 regexp 类型错误,必须为 null 或字符串`);
|
|
192
192
|
hasError = true;
|
|
193
193
|
}
|
|
@@ -202,7 +202,7 @@ export async function checkTable(): Promise<void> {
|
|
|
202
202
|
|
|
203
203
|
// 字段类型必须为string,number,text,array_string,array_text之一
|
|
204
204
|
if (!FIELD_TYPES.includes(fieldType as any)) {
|
|
205
|
-
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段类型 "${fieldType}" 格式错误,` + `必须为${FIELD_TYPES.join(
|
|
205
|
+
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 字段类型 "${fieldType}" 格式错误,` + `必须为${FIELD_TYPES.join("、")}之一`);
|
|
206
206
|
hasError = true;
|
|
207
207
|
}
|
|
208
208
|
|
|
@@ -220,7 +220,7 @@ export async function checkTable(): Promise<void> {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
// 类型联动校验 + 默认值规则
|
|
223
|
-
if (fieldType ===
|
|
223
|
+
if (fieldType === "text") {
|
|
224
224
|
// text:min/max 应该为 null,默认值必须为 null
|
|
225
225
|
if (fieldMin !== undefined && fieldMin !== null) {
|
|
226
226
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 的 text 类型最小值应为 null,当前为 "${fieldMin}"`);
|
|
@@ -234,17 +234,17 @@ export async function checkTable(): Promise<void> {
|
|
|
234
234
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 为 text 类型,默认值必须为 null,当前为 "${fieldDefault}"`);
|
|
235
235
|
hasError = true;
|
|
236
236
|
}
|
|
237
|
-
} else if (fieldType ===
|
|
238
|
-
if (fieldMax !== undefined && (fieldMax === null || typeof fieldMax !==
|
|
237
|
+
} else if (fieldType === "string" || fieldType === "array_string" || fieldType === "array_number_string") {
|
|
238
|
+
if (fieldMax !== undefined && (fieldMax === null || typeof fieldMax !== "number")) {
|
|
239
239
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 为 ${fieldType} 类型,` + `最大长度必须为数字,当前为 "${fieldMax}"`);
|
|
240
240
|
hasError = true;
|
|
241
241
|
} else if (fieldMax !== undefined && fieldMax > MAX_VARCHAR_LENGTH) {
|
|
242
242
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 最大长度 ${fieldMax} 越界,` + `${fieldType} 类型长度必须在 1..${MAX_VARCHAR_LENGTH} 范围内`);
|
|
243
243
|
hasError = true;
|
|
244
244
|
}
|
|
245
|
-
} else if (fieldType ===
|
|
245
|
+
} else if (fieldType === "number") {
|
|
246
246
|
// number 类型:default 如果存在,必须为 null 或 number
|
|
247
|
-
if (fieldDefault !== undefined && fieldDefault !== null && typeof fieldDefault !==
|
|
247
|
+
if (fieldDefault !== undefined && fieldDefault !== null && typeof fieldDefault !== "number") {
|
|
248
248
|
Logger.warn(`${item.typeName}表 ${fileName} 文件 ${colKey} 为 number 类型,` + `默认值必须为数字或 null,当前为 "${fieldDefault}"`);
|
|
249
249
|
hasError = true;
|
|
250
250
|
}
|
|
@@ -257,10 +257,10 @@ export async function checkTable(): Promise<void> {
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
if (hasError) {
|
|
260
|
-
throw new Error(
|
|
260
|
+
throw new Error("表结构检查失败");
|
|
261
261
|
}
|
|
262
262
|
} catch (error: any) {
|
|
263
|
-
Logger.error(
|
|
263
|
+
Logger.error("数据表定义检查过程中出错", error);
|
|
264
264
|
throw error;
|
|
265
265
|
}
|
|
266
266
|
}
|
package/docs/README.md
CHANGED
|
@@ -4,73 +4,80 @@
|
|
|
4
4
|
|
|
5
5
|
## 快速开始
|
|
6
6
|
|
|
7
|
-
- [Quickstart 快速入门](./quickstart.md) - 5 分钟搭建第一个 API 服务
|
|
7
|
+
- [Quickstart 快速入门](./guide/quickstart.md) - 5 分钟搭建第一个 API 服务
|
|
8
8
|
|
|
9
9
|
## 核心概念
|
|
10
10
|
|
|
11
|
-
| 文档
|
|
12
|
-
|
|
|
13
|
-
| [API 开发](./api.md)
|
|
14
|
-
| [Table 表结构](./table.md)
|
|
15
|
-
| [Database 数据库](./database.md) | CRUD 操作、事务、批量操作 |
|
|
16
|
-
| [Config 配置](./config.md)
|
|
11
|
+
| 文档 | 说明 |
|
|
12
|
+
| ---------------------------------------- | ---------------------------- |
|
|
13
|
+
| [API 开发](./api/api.md) | API 定义、字段验证、权限控制 |
|
|
14
|
+
| [Table 表结构](./reference/table.md) | JSON 表定义格式、字段类型 |
|
|
15
|
+
| [Database 数据库](./plugins/database.md) | CRUD 操作、事务、批量操作 |
|
|
16
|
+
| [Config 配置](./reference/config.md) | 配置文件、环境分离 |
|
|
17
17
|
|
|
18
18
|
## 扩展开发
|
|
19
19
|
|
|
20
|
-
| 文档
|
|
21
|
-
|
|
|
22
|
-
| [Plugin 插件](./plugin.md)
|
|
23
|
-
| [Hook 钩子](./hook.md)
|
|
24
|
-
| [Addon 插件包](./addon.md) | 可复用功能模块 |
|
|
20
|
+
| 文档 | 说明 |
|
|
21
|
+
| ------------------------------------ | -------------- |
|
|
22
|
+
| [Plugin 插件](./plugins/plugin.md) | 自定义插件开发 |
|
|
23
|
+
| [Hook 钩子](./hooks/hook.md) | 请求处理钩子 |
|
|
24
|
+
| [Addon 插件包](./reference/addon.md) | 可复用功能模块 |
|
|
25
|
+
|
|
26
|
+
常用内置 Hook:
|
|
27
|
+
|
|
28
|
+
- [cors Hook](./hooks/cors.md)
|
|
29
|
+
- [auth Hook](./hooks/auth.md)
|
|
30
|
+
- [parser Hook](./hooks/parser.md)
|
|
31
|
+
- [rateLimit Hook](./hooks/rateLimit.md)
|
|
25
32
|
|
|
26
33
|
## 工具系统
|
|
27
34
|
|
|
28
|
-
| 文档
|
|
29
|
-
|
|
|
30
|
-
| [Validator 验证](./validator.md) | 参数验证、正则别名 |
|
|
31
|
-
| [Logger 日志](./logger.md) | 日志系统配置 |
|
|
32
|
-
| [Cipher 加密](./cipher.md)
|
|
33
|
-
| [Redis 缓存](./redis.md)
|
|
35
|
+
| 文档 | 说明 |
|
|
36
|
+
| ------------------------------------------ | ------------------ |
|
|
37
|
+
| [Validator 验证](./reference/validator.md) | 参数验证、正则别名 |
|
|
38
|
+
| [Logger 日志](./reference/logger.md) | 日志系统配置 |
|
|
39
|
+
| [Cipher 加密](./plugins/cipher.md) | 哈希、签名、JWT |
|
|
40
|
+
| [Redis 缓存](./infra/redis.md) | Redis 操作 |
|
|
34
41
|
|
|
35
42
|
## 命令工具
|
|
36
43
|
|
|
37
|
-
| 文档
|
|
38
|
-
|
|
|
39
|
-
| [Sync 同步](./sync.md) | 数据库、API、菜单同步 |
|
|
44
|
+
| 文档 | 说明 |
|
|
45
|
+
| -------------------------------- | --------------------- |
|
|
46
|
+
| [Sync 同步](./reference/sync.md) | 数据库、API、菜单同步 |
|
|
40
47
|
|
|
41
48
|
## 实战示例
|
|
42
49
|
|
|
43
|
-
- [Examples 实战示例](./examples.md) - 用户管理、文章管理、文件上传完整示例
|
|
50
|
+
- [Examples 实战示例](./guide/examples.md) - 用户管理、文章管理、文件上传完整示例
|
|
44
51
|
|
|
45
52
|
## 文档索引
|
|
46
53
|
|
|
47
54
|
### 入门篇
|
|
48
55
|
|
|
49
|
-
1. **[Quickstart](./quickstart.md)** - 环境准备、项目创建、第一个 API
|
|
56
|
+
1. **[Quickstart](./guide/quickstart.md)** - 环境准备、项目创建、第一个 API
|
|
50
57
|
|
|
51
58
|
### 开发篇
|
|
52
59
|
|
|
53
|
-
2. **[API](./api.md)** - API 路由定义、字段验证、权限控制、响应格式
|
|
54
|
-
3. **[Table](./table.md)** - 表定义格式、字段类型、系统字段、命名规范
|
|
55
|
-
4. **[Database](./database.md)** - 数据库连接、CRUD 操作、事务处理、批量操作
|
|
56
|
-
5. **[Config](./config.md)** - 配置文件结构、环境分离、运行时配置
|
|
60
|
+
2. **[API](./api/api.md)** - API 路由定义、字段验证、权限控制、响应格式
|
|
61
|
+
3. **[Table](./reference/table.md)** - 表定义格式、字段类型、系统字段、命名规范
|
|
62
|
+
4. **[Database](./plugins/database.md)** - 数据库连接、CRUD 操作、事务处理、批量操作
|
|
63
|
+
5. **[Config](./reference/config.md)** - 配置文件结构、环境分离、运行时配置
|
|
57
64
|
|
|
58
65
|
### 扩展篇
|
|
59
66
|
|
|
60
|
-
6. **[Plugin](./plugin.md)** - 插件生命周期、依赖管理、内置插件
|
|
61
|
-
7. **[Hook](./hook.md)** - 钩子执行顺序、洋葱模型、内置钩子
|
|
62
|
-
8. **[Addon](./addon.md)** - Addon 结构、创建发布、命名规范
|
|
67
|
+
6. **[Plugin](./plugins/plugin.md)** - 插件生命周期、依赖管理、内置插件
|
|
68
|
+
7. **[Hook](./hooks/hook.md)** - 钩子执行顺序、洋葱模型、内置钩子
|
|
69
|
+
8. **[Addon](./reference/addon.md)** - Addon 结构、创建发布、命名规范
|
|
63
70
|
|
|
64
71
|
### 工具篇
|
|
65
72
|
|
|
66
|
-
9. **[Validator](./validator.md)** - 验证规则、类型转换、正则别名
|
|
67
|
-
10. **[Logger](./logger.md)** - 日志级别、文件轮转、测试 Mock
|
|
68
|
-
11. **[Cipher](./cipher.md)** - 哈希算法、HMAC 签名、密码加密、JWT 令牌
|
|
69
|
-
12. **[Redis](./redis.md)** - 缓存操作、键值存储、过期管理
|
|
73
|
+
9. **[Validator](./reference/validator.md)** - 验证规则、类型转换、正则别名
|
|
74
|
+
10. **[Logger](./reference/logger.md)** - 日志级别、文件轮转、测试 Mock
|
|
75
|
+
11. **[Cipher](./plugins/cipher.md)** - 哈希算法、HMAC 签名、密码加密、JWT 令牌
|
|
76
|
+
12. **[Redis](./infra/redis.md)** - 缓存操作、键值存储、过期管理
|
|
70
77
|
|
|
71
78
|
### 运维篇
|
|
72
79
|
|
|
73
|
-
13. **[Sync](./sync.md)** - syncDb、syncApi、syncMenu、syncDev 命令
|
|
80
|
+
13. **[Sync](./reference/sync.md)** - syncDb、syncApi、syncMenu、syncDev 命令
|
|
74
81
|
|
|
75
82
|
## 常用链接
|
|
76
83
|
|