befly 3.9.40 → 3.10.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.
Files changed (144) hide show
  1. package/README.md +47 -19
  2. package/befly.config.ts +19 -2
  3. package/checks/checkApi.ts +79 -77
  4. package/checks/checkHook.ts +48 -0
  5. package/checks/checkMenu.ts +168 -0
  6. package/checks/checkPlugin.ts +48 -0
  7. package/checks/checkTable.ts +137 -183
  8. package/docs/README.md +17 -11
  9. package/docs/api/api.md +16 -2
  10. package/docs/guide/quickstart.md +31 -10
  11. package/docs/hooks/hook.md +2 -2
  12. package/docs/hooks/rateLimit.md +1 -1
  13. package/docs/infra/redis.md +26 -14
  14. package/docs/plugins/plugin.md +23 -21
  15. package/docs/quickstart.md +5 -328
  16. package/docs/reference/addon.md +0 -4
  17. package/docs/reference/config.md +14 -31
  18. package/docs/reference/logger.md +3 -3
  19. package/docs/reference/sync.md +132 -237
  20. package/docs/reference/table.md +28 -30
  21. package/hooks/auth.ts +3 -4
  22. package/hooks/cors.ts +4 -6
  23. package/hooks/parser.ts +3 -4
  24. package/hooks/permission.ts +3 -4
  25. package/hooks/validator.ts +3 -4
  26. package/lib/cacheHelper.ts +89 -153
  27. package/lib/cacheKeys.ts +1 -1
  28. package/lib/connect.ts +9 -13
  29. package/lib/dbDialect.ts +285 -0
  30. package/lib/dbHelper.ts +179 -507
  31. package/lib/dbUtils.ts +450 -0
  32. package/lib/logger.ts +41 -5
  33. package/lib/redisHelper.ts +1 -0
  34. package/lib/sqlBuilder.ts +358 -58
  35. package/lib/sqlCheck.ts +136 -0
  36. package/lib/validator.ts +1 -1
  37. package/loader/loadApis.ts +23 -126
  38. package/loader/loadHooks.ts +31 -46
  39. package/loader/loadPlugins.ts +37 -52
  40. package/main.ts +58 -19
  41. package/package.json +24 -25
  42. package/paths.ts +14 -14
  43. package/plugins/cache.ts +12 -6
  44. package/plugins/cipher.ts +2 -2
  45. package/plugins/config.ts +6 -8
  46. package/plugins/db.ts +14 -19
  47. package/plugins/jwt.ts +6 -7
  48. package/plugins/logger.ts +7 -9
  49. package/plugins/redis.ts +8 -10
  50. package/plugins/tool.ts +3 -4
  51. package/router/api.ts +3 -2
  52. package/router/static.ts +7 -5
  53. package/sync/syncApi.ts +80 -235
  54. package/sync/syncCache.ts +16 -0
  55. package/sync/syncDev.ts +167 -202
  56. package/sync/syncMenu.ts +230 -444
  57. package/sync/syncTable.ts +1247 -0
  58. package/tests/_mocks/mockSqliteDb.ts +204 -0
  59. package/tests/addonHelper-cache.test.ts +32 -0
  60. package/tests/apiHandler-routePath-only.test.ts +32 -0
  61. package/tests/cacheHelper.test.ts +16 -51
  62. package/tests/checkApi-routePath-strict.test.ts +166 -0
  63. package/tests/checkMenu.test.ts +346 -0
  64. package/tests/checkTable-smoke.test.ts +157 -0
  65. package/tests/dbDialect-cache.test.ts +23 -0
  66. package/tests/dbDialect.test.ts +46 -0
  67. package/tests/dbHelper-advanced.test.ts +1 -1
  68. package/tests/dbHelper-all-array-types.test.ts +15 -15
  69. package/tests/dbHelper-batch-write.test.ts +90 -0
  70. package/tests/dbHelper-columns.test.ts +36 -54
  71. package/tests/dbHelper-execute.test.ts +26 -26
  72. package/tests/dbHelper-joins.test.ts +85 -176
  73. package/tests/fixtures/scanFilesAddon/node_modules/@befly-addon/demo/apis/sub/b.ts +3 -0
  74. package/tests/fixtures/scanFilesApis/a.ts +3 -0
  75. package/tests/fixtures/scanFilesApis/sub/b.ts +3 -0
  76. package/tests/loadPlugins-order-smoke.test.ts +75 -0
  77. package/tests/logger.test.ts +6 -6
  78. package/tests/redisHelper.test.ts +6 -1
  79. package/tests/scanFiles-routePath.test.ts +46 -0
  80. package/tests/smoke-sql.test.ts +24 -0
  81. package/tests/sqlBuilder-advanced.test.ts +18 -5
  82. package/tests/sqlBuilder.test.ts +24 -0
  83. package/tests/sync-init-guard.test.ts +105 -0
  84. package/tests/syncApi-insBatch-fields-consistent.test.ts +61 -0
  85. package/tests/syncApi-obsolete-records.test.ts +69 -0
  86. package/tests/syncApi-type-compat.test.ts +72 -0
  87. package/tests/syncDev-permissions.test.ts +81 -0
  88. package/tests/syncMenu-disableMenus-hard-delete.test.ts +88 -0
  89. package/tests/syncMenu-duplicate-path.test.ts +122 -0
  90. package/tests/syncMenu-obsolete-records.test.ts +161 -0
  91. package/tests/syncMenu-parentPath-from-tree.test.ts +75 -0
  92. package/tests/syncMenu-paths.test.ts +0 -9
  93. package/tests/{syncDb-apply.test.ts → syncTable-apply.test.ts} +14 -24
  94. package/tests/{syncDb-array-number.test.ts → syncTable-array-number.test.ts} +31 -31
  95. package/tests/syncTable-constants.test.ts +101 -0
  96. package/tests/syncTable-db-integration.test.ts +237 -0
  97. package/tests/{syncDb-ddl.test.ts → syncTable-ddl.test.ts} +67 -53
  98. package/tests/{syncDb-helpers.test.ts → syncTable-helpers.test.ts} +12 -26
  99. package/tests/syncTable-schema.test.ts +99 -0
  100. package/tests/syncTable-testkit.test.ts +25 -0
  101. package/tests/syncTable-types.test.ts +122 -0
  102. package/tests/tableRef-and-deserialize.test.ts +67 -0
  103. package/tsconfig.json +1 -1
  104. package/types/api.d.ts +1 -1
  105. package/types/befly.d.ts +13 -12
  106. package/types/cache.d.ts +2 -2
  107. package/types/context.d.ts +1 -1
  108. package/types/database.d.ts +0 -5
  109. package/types/hook.d.ts +1 -10
  110. package/types/plugin.d.ts +2 -96
  111. package/types/sync.d.ts +19 -25
  112. package/utils/convertBigIntFields.ts +38 -0
  113. package/utils/disableMenusGlob.ts +85 -0
  114. package/utils/importDefault.ts +21 -0
  115. package/utils/isDirentDirectory.ts +23 -0
  116. package/utils/loadMenuConfigs.ts +145 -0
  117. package/utils/processFields.ts +25 -0
  118. package/utils/scanAddons.ts +72 -0
  119. package/utils/scanFiles.ts +129 -21
  120. package/utils/scanSources.ts +64 -0
  121. package/utils/sortModules.ts +137 -0
  122. package/checks/checkApp.ts +0 -55
  123. package/docs/cipher.md +0 -582
  124. package/docs/database.md +0 -1176
  125. package/hooks/rateLimit.ts +0 -276
  126. package/sync/syncAll.ts +0 -35
  127. package/sync/syncDb/apply.ts +0 -192
  128. package/sync/syncDb/constants.ts +0 -119
  129. package/sync/syncDb/ddl.ts +0 -251
  130. package/sync/syncDb/helpers.ts +0 -84
  131. package/sync/syncDb/schema.ts +0 -202
  132. package/sync/syncDb/sqlite.ts +0 -48
  133. package/sync/syncDb/table.ts +0 -207
  134. package/sync/syncDb/tableCreate.ts +0 -163
  135. package/sync/syncDb/types.ts +0 -132
  136. package/sync/syncDb/version.ts +0 -69
  137. package/sync/syncDb.ts +0 -168
  138. package/tests/rateLimit-hook.test.ts +0 -477
  139. package/tests/syncDb-constants.test.ts +0 -130
  140. package/tests/syncDb-schema.test.ts +0 -179
  141. package/tests/syncDb-types.test.ts +0 -139
  142. package/utils/addonHelper.ts +0 -90
  143. package/utils/modules.ts +0 -98
  144. package/utils/route.ts +0 -23
@@ -0,0 +1,90 @@
1
+ import { describe, expect, it, mock } from "bun:test";
2
+
3
+ import { MySqlDialect } from "../lib/dbDialect.js";
4
+ import { DbHelper } from "../lib/dbHelper.js";
5
+
6
+ function createRedisMock() {
7
+ return {
8
+ getObject: async () => null,
9
+ setObject: async () => "OK",
10
+ genTimeID: async () => 1
11
+ };
12
+ }
13
+
14
+ describe("DbHelper - batch write helpers", () => {
15
+ it("delForceBatch: 空数组直接返回 0 且不执行 SQL", async () => {
16
+ const sqlMock = {
17
+ unsafe: mock(() => Promise.resolve({ changes: 0 }))
18
+ };
19
+
20
+ const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
21
+
22
+ const changes = await (dbHelper as any).delForceBatch("addon_admin_api", []);
23
+
24
+ expect(changes).toBe(0);
25
+ expect(sqlMock.unsafe).toHaveBeenCalledTimes(0);
26
+ });
27
+
28
+ it("delForceBatch: 生成单条 DELETE ... IN 并执行一次", async () => {
29
+ const sqlMock = {
30
+ unsafe: mock(() => Promise.resolve({ changes: 2 }))
31
+ };
32
+
33
+ const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
34
+
35
+ const changes = await (dbHelper as any).delForceBatch("addon_admin_api", [1, 2]);
36
+
37
+ expect(changes).toBe(2);
38
+ expect(sqlMock.unsafe).toHaveBeenCalledTimes(1);
39
+
40
+ const call = (sqlMock.unsafe as any).mock.calls[0];
41
+ expect(call[0]).toBe("DELETE FROM `addon_admin_api` WHERE `id` IN (?,?)");
42
+ expect(call[1]).toEqual([1, 2]);
43
+ });
44
+
45
+ it("updBatch: 空数组直接返回 0 且不执行 SQL", async () => {
46
+ const sqlMock = {
47
+ unsafe: mock(() => Promise.resolve({ changes: 0 }))
48
+ };
49
+
50
+ const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
51
+
52
+ const changes = await (dbHelper as any).updBatch("addon_admin_api", []);
53
+
54
+ expect(changes).toBe(0);
55
+ expect(sqlMock.unsafe).toHaveBeenCalledTimes(0);
56
+ });
57
+
58
+ it("updBatch: 生成单条 UPDATE + CASE 并执行一次", async () => {
59
+ const sqlMock = {
60
+ unsafe: mock(() => Promise.resolve({ changes: 2 }))
61
+ };
62
+
63
+ const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
64
+
65
+ const changes = await (dbHelper as any).updBatch("addon_admin_api", [
66
+ { id: 1, data: { name: "A", routePath: "/api/a", addonName: "x" } },
67
+ { id: 2, data: { name: "B", routePath: "/api/b", addonName: "y" } }
68
+ ]);
69
+
70
+ expect(changes).toBe(2);
71
+ expect(sqlMock.unsafe).toHaveBeenCalledTimes(1);
72
+
73
+ const call = (sqlMock.unsafe as any).mock.calls[0];
74
+ const sql = String(call[0]);
75
+ const params = call[1] as any[];
76
+
77
+ expect(sql.startsWith("UPDATE `addon_admin_api` SET")).toBe(true);
78
+ expect(sql.includes("`name` = CASE `id`")).toBe(true);
79
+ expect(sql.includes("`route_path` = CASE `id`")).toBe(true);
80
+ expect(sql.includes("`addon_name` = CASE `id`")).toBe(true);
81
+ expect(sql.includes("`updated_at` = ?")).toBe(true);
82
+ expect(sql.endsWith("WHERE `id` IN (?,?) AND `state` > 0")).toBe(true);
83
+
84
+ // 参数数量应包含:每个字段 2 行 * (id,value) *3字段 => 12,+ updated_at 1,+ where ids 2 => 15
85
+ expect(params.length).toBe(15);
86
+ // 末尾两个参数是 where ids
87
+ expect(params[params.length - 2]).toBe(1);
88
+ expect(params[params.length - 1]).toBe(2);
89
+ });
90
+ });
@@ -6,17 +6,20 @@
6
6
  import { test, expect, mock } from "bun:test";
7
7
 
8
8
  import { CacheKeys } from "../lib/cacheKeys.js";
9
+ import { MySqlDialect } from "../lib/dbDialect.js";
9
10
  import { DbHelper } from "../lib/dbHelper.js";
10
11
 
11
- // 创建 Mock Befly 上下文
12
- function createMockBefly(sqlMock: any, redisMock?: any) {
12
+ function createRedisMock(options?: { getObject?: any; setObject?: any; del?: any; genTimeID?: any }) {
13
+ const getObject = options?.getObject ? options.getObject : mock(async () => null);
14
+ const setObject = options?.setObject ? options.setObject : mock(async () => true);
15
+ const del = options?.del ? options.del : mock(async () => 1);
16
+ const genTimeID = options?.genTimeID ? options.genTimeID : mock(async () => 1);
17
+
13
18
  return {
14
- redis: redisMock || {
15
- getObject: mock(async () => null),
16
- setObject: mock(async () => true),
17
- del: mock(async () => 1)
18
- },
19
- db: null
19
+ getObject: getObject,
20
+ setObject: setObject,
21
+ del: del,
22
+ genTimeID: genTimeID
20
23
  };
21
24
  }
22
25
 
@@ -31,14 +34,11 @@ test("getTableColumns - 正常查询表字段", async () => {
31
34
  })
32
35
  };
33
36
 
34
- const redisMock = {
35
- getObject: mock(async () => null), // 缓存未命中
36
- setObject: mock(async () => true),
37
- del: mock(async () => 1)
38
- };
37
+ const redisMock = createRedisMock({
38
+ getObject: mock(async () => null) // 缓存未命中
39
+ });
39
40
 
40
- const befly = createMockBefly(sqlMock, redisMock);
41
- const dbHelper = new DbHelper(befly as any, sqlMock);
41
+ const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
42
42
 
43
43
  const columns = await (dbHelper as any).getTableColumns("users");
44
44
 
@@ -50,11 +50,9 @@ test("getTableColumns - 正常查询表字段", async () => {
50
50
 
51
51
  test("getTableColumns - Redis 缓存命中", async () => {
52
52
  const cachedColumns = ["id", "name", "email"];
53
- const redisMock = {
54
- getObject: mock(async () => cachedColumns),
55
- setObject: mock(async () => true),
56
- del: mock(async () => 1)
57
- };
53
+ const redisMock = createRedisMock({
54
+ getObject: mock(async () => cachedColumns)
55
+ });
58
56
 
59
57
  const sqlMock = {
60
58
  unsafe: mock(async () => {
@@ -62,8 +60,7 @@ test("getTableColumns - Redis 缓存命中", async () => {
62
60
  })
63
61
  };
64
62
 
65
- const befly = createMockBefly(sqlMock, redisMock);
66
- const dbHelper = new DbHelper(befly as any, sqlMock);
63
+ const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
67
64
 
68
65
  const columns = await (dbHelper as any).getTableColumns("users");
69
66
 
@@ -78,14 +75,9 @@ test("getTableColumns - 表不存在错误", async () => {
78
75
  unsafe: mock(async () => []) // 返回空结果
79
76
  };
80
77
 
81
- const redisMock = {
82
- getObject: mock(async () => null),
83
- setObject: mock(async () => true),
84
- del: mock(async () => 1)
85
- };
78
+ const redisMock = createRedisMock();
86
79
 
87
- const befly = createMockBefly(sqlMock, redisMock);
88
- const dbHelper = new DbHelper(befly as any, sqlMock);
80
+ const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
89
81
 
90
82
  try {
91
83
  await (dbHelper as any).getTableColumns("non_existent_table");
@@ -106,8 +98,7 @@ test("getTableColumns - SQL 语法使用反引号", async () => {
106
98
  })
107
99
  };
108
100
 
109
- const befly = createMockBefly(sqlMock);
110
- const dbHelper = new DbHelper(befly as any, sqlMock);
101
+ const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
111
102
 
112
103
  await (dbHelper as any).getTableColumns("addon_admin_user");
113
104
 
@@ -123,8 +114,7 @@ test("getTableColumns - 表名特殊字符处理", async () => {
123
114
  unsafe: mock(async () => mockColumns)
124
115
  };
125
116
 
126
- const befly = createMockBefly(sqlMock);
127
- const dbHelper = new DbHelper(befly as any, sqlMock);
117
+ const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
128
118
 
129
119
  // 测试下划线表名
130
120
  await (dbHelper as any).getTableColumns("addon_admin_user");
@@ -141,7 +131,7 @@ test("getTableColumns - 缓存键格式正确", async () => {
141
131
  unsafe: mock(async () => mockColumns)
142
132
  };
143
133
 
144
- const redisMock = {
134
+ const redisMock = createRedisMock({
145
135
  getObject: mock(async () => null),
146
136
  setObject: mock(async (key: string, value: any, seconds: number) => {
147
137
  // 验证缓存键格式
@@ -151,12 +141,10 @@ test("getTableColumns - 缓存键格式正确", async () => {
151
141
  // 验证过期时间
152
142
  expect(seconds).toBe(3600); // 1 小时
153
143
  return true;
154
- }),
155
- del: mock(async () => 1)
156
- };
144
+ })
145
+ });
157
146
 
158
- const befly = createMockBefly(sqlMock, redisMock);
159
- const dbHelper = new DbHelper(befly as any, sqlMock);
147
+ const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
160
148
 
161
149
  await (dbHelper as any).getTableColumns("test_table");
162
150
 
@@ -175,17 +163,15 @@ test("getTableColumns - 多次调用相同表(缓存效果)", async () => {
175
163
  };
176
164
 
177
165
  const cache: Record<string, any> = {};
178
- const redisMock = {
166
+ const redisMock = createRedisMock({
179
167
  getObject: mock(async (key: string) => cache[key] || null),
180
168
  setObject: mock(async (key: string, value: any) => {
181
169
  cache[key] = value;
182
170
  return true;
183
- }),
184
- del: mock(async () => 1)
185
- };
171
+ })
172
+ });
186
173
 
187
- const befly = createMockBefly(sqlMock, redisMock);
188
- const dbHelper = new DbHelper(befly as any, sqlMock);
174
+ const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
189
175
 
190
176
  // 第一次调用 - 应该查询数据库
191
177
  const columns1 = await (dbHelper as any).getTableColumns("users");
@@ -209,16 +195,13 @@ test("getTableColumns - Redis 错误处理", async () => {
209
195
  unsafe: mock(async () => mockColumns)
210
196
  };
211
197
 
212
- const redisMock = {
198
+ const redisMock = createRedisMock({
213
199
  getObject: mock(async () => {
214
200
  throw new Error("Redis 连接失败");
215
- }),
216
- setObject: mock(async () => true),
217
- del: mock(async () => 1)
218
- };
201
+ })
202
+ });
219
203
 
220
- const befly = createMockBefly(sqlMock, redisMock);
221
- const dbHelper = new DbHelper(befly as any, sqlMock);
204
+ const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
222
205
 
223
206
  try {
224
207
  await (dbHelper as any).getTableColumns("users");
@@ -240,8 +223,7 @@ test("getTableColumns - 字段映射正确性", async () => {
240
223
  unsafe: mock(async () => mockColumns)
241
224
  };
242
225
 
243
- const befly = createMockBefly(sqlMock);
244
- const dbHelper = new DbHelper(befly as any, sqlMock);
226
+ const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
245
227
 
246
228
  const columns = await (dbHelper as any).getTableColumns("users");
247
229
 
@@ -5,17 +5,17 @@
5
5
 
6
6
  import { test, expect, mock } from "bun:test";
7
7
 
8
+ import { MySqlDialect } from "../lib/dbDialect.js";
8
9
  import { DbHelper } from "../lib/dbHelper.js";
9
10
 
10
- // 创建 Mock Befly 上下文
11
- function createMockBefly() {
11
+ function createMockRedis() {
12
12
  return {
13
- redis: {
14
- get: mock(async () => null),
15
- set: mock(async () => true),
16
- del: mock(async () => 1)
17
- },
18
- db: null
13
+ get: mock(async () => null),
14
+ set: mock(async () => true),
15
+ del: mock(async () => 1),
16
+ getObject: mock(async () => null),
17
+ setObject: mock(async () => true),
18
+ genTimeID: mock(async () => 1)
19
19
  };
20
20
  }
21
21
 
@@ -25,8 +25,8 @@ test("executeWithConn - 正常执行(无参数)", async () => {
25
25
  unsafe: mock(async () => mockResult)
26
26
  };
27
27
 
28
- const befly = createMockBefly();
29
- const dbHelper = new DbHelper(befly as any, sqlMock);
28
+ const redis = createMockRedis();
29
+ const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
30
30
 
31
31
  // 使用反射访问私有方法
32
32
  const result = await (dbHelper as any).executeWithConn("SELECT * FROM users");
@@ -41,8 +41,8 @@ test("executeWithConn - 正常执行(带参数)", async () => {
41
41
  unsafe: mock(async () => mockResult)
42
42
  };
43
43
 
44
- const befly = createMockBefly();
45
- const dbHelper = new DbHelper(befly as any, sqlMock);
44
+ const redis = createMockRedis();
45
+ const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
46
46
 
47
47
  const result = await (dbHelper as any).executeWithConn("SELECT * FROM users WHERE id = ?", [1]);
48
48
 
@@ -58,8 +58,8 @@ test("executeWithConn - SQL 错误捕获", async () => {
58
58
  })
59
59
  };
60
60
 
61
- const befly = createMockBefly();
62
- const dbHelper = new DbHelper(befly as any, sqlMock);
61
+ const redis = createMockRedis();
62
+ const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
63
63
 
64
64
  try {
65
65
  await (dbHelper as any).executeWithConn("SELECT * FROM invalid_table");
@@ -81,8 +81,8 @@ test("executeWithConn - 错误信息包含完整信息", async () => {
81
81
  })
82
82
  };
83
83
 
84
- const befly = createMockBefly();
85
- const dbHelper = new DbHelper(befly as any, sqlMock);
84
+ const redis = createMockRedis();
85
+ const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
86
86
 
87
87
  const testSql = "SHOW COLUMNS FROM ??";
88
88
  const testParams = ["users"];
@@ -106,8 +106,8 @@ test("executeWithConn - 超长 SQL 保留在错误对象中", async () => {
106
106
  })
107
107
  };
108
108
 
109
- const befly = createMockBefly();
110
- const dbHelper = new DbHelper(befly as any, sqlMock);
109
+ const redis = createMockRedis();
110
+ const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
111
111
 
112
112
  try {
113
113
  await (dbHelper as any).executeWithConn(longSql);
@@ -128,8 +128,8 @@ test("executeWithConn - 慢查询检测(>1000ms)", async () => {
128
128
  })
129
129
  };
130
130
 
131
- const befly = createMockBefly();
132
- const dbHelper = new DbHelper(befly as any, sqlMock);
131
+ const redis = createMockRedis();
132
+ const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
133
133
 
134
134
  const result = await (dbHelper as any).executeWithConn("SELECT SLEEP(1)");
135
135
 
@@ -138,8 +138,8 @@ test("executeWithConn - 慢查询检测(>1000ms)", async () => {
138
138
  });
139
139
 
140
140
  test("executeWithConn - 数据库未连接错误", async () => {
141
- const befly = createMockBefly(null);
142
- const dbHelper = new DbHelper(befly as any, null); // 没有 sql 实例
141
+ const redis = createMockRedis();
142
+ const dbHelper = new DbHelper({ redis: redis as any, sql: null, dialect: new MySqlDialect() }); // 没有 sql 实例
143
143
 
144
144
  try {
145
145
  await (dbHelper as any).executeWithConn("SELECT * FROM users");
@@ -155,8 +155,8 @@ test("executeWithConn - 空参数数组", async () => {
155
155
  unsafe: mock(async () => mockResult)
156
156
  };
157
157
 
158
- const befly = createMockBefly();
159
- const dbHelper = new DbHelper(befly as any, sqlMock);
158
+ const redis = createMockRedis();
159
+ const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
160
160
 
161
161
  const result = await (dbHelper as any).executeWithConn("SELECT COUNT(*) as count FROM users", []);
162
162
 
@@ -172,8 +172,8 @@ test("executeWithConn - 复杂参数处理", async () => {
172
172
  })
173
173
  };
174
174
 
175
- const befly = createMockBefly();
176
- const dbHelper = new DbHelper(befly as any, sqlMock);
175
+ const redis = createMockRedis();
176
+ const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
177
177
 
178
178
  const complexParams = [1, "test", { nested: "object" }, [1, 2, 3], null, undefined];
179
179