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.
Files changed (155) hide show
  1. package/README.md +38 -39
  2. package/befly.config.ts +62 -40
  3. package/checks/checkApi.ts +16 -16
  4. package/checks/checkApp.ts +19 -25
  5. package/checks/checkTable.ts +42 -42
  6. package/docs/README.md +42 -35
  7. package/docs/{api.md → api/api.md} +225 -235
  8. package/docs/cipher.md +71 -69
  9. package/docs/database.md +155 -153
  10. package/docs/{examples.md → guide/examples.md} +181 -181
  11. package/docs/guide/quickstart.md +331 -0
  12. package/docs/hooks/auth.md +38 -0
  13. package/docs/hooks/cors.md +28 -0
  14. package/docs/{hook.md → hooks/hook.md} +140 -57
  15. package/docs/hooks/parser.md +19 -0
  16. package/docs/hooks/rateLimit.md +47 -0
  17. package/docs/{redis.md → infra/redis.md} +84 -93
  18. package/docs/plugins/cipher.md +61 -0
  19. package/docs/plugins/database.md +128 -0
  20. package/docs/{plugin.md → plugins/plugin.md} +83 -81
  21. package/docs/quickstart.md +26 -26
  22. package/docs/{addon.md → reference/addon.md} +46 -46
  23. package/docs/{config.md → reference/config.md} +32 -80
  24. package/docs/{logger.md → reference/logger.md} +52 -52
  25. package/docs/{sync.md → reference/sync.md} +32 -35
  26. package/docs/{table.md → reference/table.md} +7 -7
  27. package/docs/{validator.md → reference/validator.md} +57 -57
  28. package/hooks/auth.ts +8 -4
  29. package/hooks/cors.ts +13 -13
  30. package/hooks/parser.ts +37 -17
  31. package/hooks/permission.ts +26 -14
  32. package/hooks/rateLimit.ts +276 -0
  33. package/hooks/validator.ts +15 -7
  34. package/lib/asyncContext.ts +43 -0
  35. package/lib/cacheHelper.ts +212 -81
  36. package/lib/cacheKeys.ts +38 -0
  37. package/lib/cipher.ts +30 -30
  38. package/lib/connect.ts +28 -28
  39. package/lib/dbHelper.ts +211 -109
  40. package/lib/jwt.ts +16 -16
  41. package/lib/logger.ts +610 -19
  42. package/lib/redisHelper.ts +185 -44
  43. package/lib/sqlBuilder.ts +90 -91
  44. package/lib/validator.ts +59 -39
  45. package/loader/loadApis.ts +53 -47
  46. package/loader/loadHooks.ts +40 -14
  47. package/loader/loadPlugins.ts +16 -17
  48. package/main.ts +57 -47
  49. package/package.json +47 -45
  50. package/paths.ts +15 -14
  51. package/plugins/cache.ts +5 -4
  52. package/plugins/cipher.ts +3 -3
  53. package/plugins/config.ts +2 -2
  54. package/plugins/db.ts +9 -9
  55. package/plugins/jwt.ts +3 -3
  56. package/plugins/logger.ts +8 -12
  57. package/plugins/redis.ts +8 -8
  58. package/plugins/tool.ts +6 -6
  59. package/router/api.ts +85 -56
  60. package/router/static.ts +12 -12
  61. package/sync/syncAll.ts +12 -12
  62. package/sync/syncApi.ts +55 -54
  63. package/sync/syncDb/apply.ts +20 -19
  64. package/sync/syncDb/constants.ts +25 -23
  65. package/sync/syncDb/ddl.ts +35 -36
  66. package/sync/syncDb/helpers.ts +6 -9
  67. package/sync/syncDb/schema.ts +10 -9
  68. package/sync/syncDb/sqlite.ts +7 -8
  69. package/sync/syncDb/table.ts +37 -35
  70. package/sync/syncDb/tableCreate.ts +21 -20
  71. package/sync/syncDb/types.ts +23 -20
  72. package/sync/syncDb/version.ts +10 -10
  73. package/sync/syncDb.ts +43 -36
  74. package/sync/syncDev.ts +74 -66
  75. package/sync/syncMenu.ts +190 -57
  76. package/tests/api-integration-array-number.test.ts +282 -0
  77. package/tests/befly-config-env.test.ts +78 -0
  78. package/tests/cacheHelper.test.ts +135 -104
  79. package/tests/cacheKeys.test.ts +41 -0
  80. package/tests/cipher.test.ts +90 -89
  81. package/tests/dbHelper-advanced.test.ts +140 -134
  82. package/tests/dbHelper-all-array-types.test.ts +316 -0
  83. package/tests/dbHelper-array-serialization.test.ts +258 -0
  84. package/tests/dbHelper-columns.test.ts +56 -55
  85. package/tests/dbHelper-execute.test.ts +45 -44
  86. package/tests/dbHelper-joins.test.ts +124 -119
  87. package/tests/fields-redis-cache.test.ts +29 -27
  88. package/tests/fields-validate.test.ts +38 -38
  89. package/tests/getClientIp.test.ts +54 -0
  90. package/tests/integration.test.ts +69 -67
  91. package/tests/jwt.test.ts +27 -26
  92. package/tests/logger.test.ts +267 -34
  93. package/tests/rateLimit-hook.test.ts +477 -0
  94. package/tests/redisHelper.test.ts +187 -188
  95. package/tests/redisKeys.test.ts +6 -73
  96. package/tests/scanConfig.test.ts +144 -0
  97. package/tests/sqlBuilder-advanced.test.ts +217 -215
  98. package/tests/sqlBuilder.test.ts +92 -91
  99. package/tests/sync-connection.test.ts +29 -29
  100. package/tests/syncDb-apply.test.ts +97 -96
  101. package/tests/syncDb-array-number.test.ts +160 -0
  102. package/tests/syncDb-constants.test.ts +48 -47
  103. package/tests/syncDb-ddl.test.ts +99 -98
  104. package/tests/syncDb-helpers.test.ts +29 -28
  105. package/tests/syncDb-schema.test.ts +61 -60
  106. package/tests/syncDb-types.test.ts +60 -59
  107. package/tests/syncMenu-paths.test.ts +68 -0
  108. package/tests/util.test.ts +42 -41
  109. package/tests/validator-array-number.test.ts +310 -0
  110. package/tests/validator-default.test.ts +373 -0
  111. package/tests/validator.test.ts +271 -266
  112. package/tsconfig.json +4 -5
  113. package/types/api.d.ts +7 -12
  114. package/types/befly.d.ts +60 -13
  115. package/types/cache.d.ts +8 -4
  116. package/types/common.d.ts +17 -9
  117. package/types/context.d.ts +2 -2
  118. package/types/crypto.d.ts +23 -0
  119. package/types/database.d.ts +19 -19
  120. package/types/hook.d.ts +2 -2
  121. package/types/jwt.d.ts +118 -0
  122. package/types/logger.d.ts +30 -0
  123. package/types/plugin.d.ts +4 -4
  124. package/types/redis.d.ts +7 -3
  125. package/types/roleApisCache.ts +23 -0
  126. package/types/sync.d.ts +10 -10
  127. package/types/table.d.ts +50 -9
  128. package/types/validate.d.ts +69 -0
  129. package/utils/addonHelper.ts +90 -0
  130. package/utils/arrayKeysToCamel.ts +18 -0
  131. package/utils/calcPerfTime.ts +13 -0
  132. package/utils/configTypes.ts +3 -0
  133. package/utils/cors.ts +19 -0
  134. package/utils/fieldClear.ts +75 -0
  135. package/utils/genShortId.ts +12 -0
  136. package/utils/getClientIp.ts +45 -0
  137. package/utils/keysToCamel.ts +22 -0
  138. package/utils/keysToSnake.ts +22 -0
  139. package/utils/modules.ts +98 -0
  140. package/utils/pickFields.ts +19 -0
  141. package/utils/process.ts +56 -0
  142. package/utils/regex.ts +225 -0
  143. package/utils/response.ts +115 -0
  144. package/utils/route.ts +23 -0
  145. package/utils/scanConfig.ts +142 -0
  146. package/utils/scanFiles.ts +48 -0
  147. package/.prettierignore +0 -2
  148. package/.prettierrc +0 -12
  149. package/docs/1-/345/237/272/346/234/254/344/273/213/347/273/215.md +0 -35
  150. package/docs/2-/345/210/235/346/255/245/344/275/223/351/252/214.md +0 -64
  151. package/docs/3-/347/254/254/344/270/200/344/270/252/346/216/245/345/217/243.md +0 -46
  152. package/docs/4-/346/223/215/344/275/234/346/225/260/346/215/256/345/272/223.md +0 -172
  153. package/hooks/requestLogger.ts +0 -84
  154. package/types/index.ts +0 -24
  155. package/util.ts +0 -283
@@ -3,11 +3,10 @@
3
3
  * 测试 Redis 操作功能
4
4
  */
5
5
 
6
- import { describe, expect, it, test, beforeAll, afterAll } from 'bun:test';
7
- import { RedisClient } from 'bun';
6
+ import { describe, expect, test, beforeAll, afterAll } from "bun:test";
8
7
 
9
- import { Connect } from '../lib/connect.js';
10
- import { RedisHelper } from '../lib/redisHelper.js';
8
+ import { Connect } from "../lib/connect.js";
9
+ import { RedisHelper } from "../lib/redisHelper.js";
11
10
 
12
11
  let redis: RedisHelper;
13
12
 
@@ -22,203 +21,203 @@ afterAll(async () => {
22
21
  await Connect.disconnectRedis();
23
22
  });
24
23
 
25
- describe('RedisHelper - 字符串操作', () => {
26
- test('setString - 设置字符串', async () => {
27
- const result = await redis.setString('test:string', 'Hello Redis');
28
- expect(result).toBe('OK');
24
+ describe("RedisHelper - 字符串操作", () => {
25
+ test("setString - 设置字符串", async () => {
26
+ const result = await redis.setString("test:string", "Hello Redis");
27
+ expect(result).toBe("OK");
29
28
  });
30
29
 
31
- test('getString - 获取字符串', async () => {
32
- await redis.setString('test:string', 'Hello Redis');
33
- const value = await redis.getString('test:string');
34
- expect(value).toBe('Hello Redis');
30
+ test("getString - 获取字符串", async () => {
31
+ await redis.setString("test:string", "Hello Redis");
32
+ const value = await redis.getString("test:string");
33
+ expect(value).toBe("Hello Redis");
35
34
  });
36
35
 
37
- test('getString - 获取不存在的键', async () => {
38
- const value = await redis.getString('test:non_existent');
36
+ test("getString - 获取不存在的键", async () => {
37
+ const value = await redis.getString("test:non_existent");
39
38
  expect(value).toBeNull();
40
39
  });
41
40
 
42
- test('setString - 设置带过期时间的字符串', async () => {
43
- const result = await redis.setString('test:ttl', 'Expire Test', 2);
44
- expect(result).toBe('OK');
41
+ test("setString - 设置带过期时间的字符串", async () => {
42
+ const result = await redis.setString("test:ttl", "Expire Test", 2);
43
+ expect(result).toBe("OK");
45
44
 
46
- const value = await redis.getString('test:ttl');
47
- expect(value).toBe('Expire Test');
45
+ const value = await redis.getString("test:ttl");
46
+ expect(value).toBe("Expire Test");
48
47
 
49
48
  // 等待过期
50
49
  await new Promise((resolve) => setTimeout(resolve, 2100));
51
50
 
52
- const expiredValue = await redis.getString('test:ttl');
51
+ const expiredValue = await redis.getString("test:ttl");
53
52
  expect(expiredValue).toBeNull();
54
53
  });
55
54
  });
56
55
 
57
- describe('RedisHelper - 对象操作', () => {
58
- test('setObject - 设置对象', async () => {
59
- const obj = { name: 'Test', age: 25, tags: ['a', 'b'] };
60
- const result = await redis.setObject('test:object', obj);
61
- expect(result).toBe('OK');
56
+ describe("RedisHelper - 对象操作", () => {
57
+ test("setObject - 设置对象", async () => {
58
+ const obj = { name: "Test", age: 25, tags: ["a", "b"] };
59
+ const result = await redis.setObject("test:object", obj);
60
+ expect(result).toBe("OK");
62
61
  });
63
62
 
64
- test('getObject - 获取对象', async () => {
65
- const obj = { name: 'Test', age: 25, tags: ['a', 'b'] };
66
- await redis.setObject('test:object', obj);
63
+ test("getObject - 获取对象", async () => {
64
+ const obj = { name: "Test", age: 25, tags: ["a", "b"] };
65
+ await redis.setObject("test:object", obj);
67
66
 
68
- const value = await redis.getObject<any>('test:object');
67
+ const value = await redis.getObject<any>("test:object");
69
68
  expect(value).toEqual(obj);
70
69
  });
71
70
 
72
- test('getObject - 获取不存在的对象', async () => {
73
- const value = await redis.getObject('test:non_existent_obj');
71
+ test("getObject - 获取不存在的对象", async () => {
72
+ const value = await redis.getObject("test:non_existent_obj");
74
73
  expect(value).toBeNull();
75
74
  });
76
75
 
77
- test('setObject - 设置带过期时间的对象', async () => {
78
- const obj = { data: 'test' };
79
- const result = await redis.setObject('test:object:ttl', obj, 1);
80
- expect(result).toBe('OK');
76
+ test("setObject - 设置带过期时间的对象", async () => {
77
+ const obj = { data: "test" };
78
+ const result = await redis.setObject("test:object:ttl", obj, 1);
79
+ expect(result).toBe("OK");
81
80
 
82
81
  await new Promise((resolve) => setTimeout(resolve, 1100));
83
82
 
84
- const expiredValue = await redis.getObject('test:object:ttl');
83
+ const expiredValue = await redis.getObject("test:object:ttl");
85
84
  expect(expiredValue).toBeNull();
86
85
  });
87
86
 
88
- test('delObject - 删除对象', async () => {
89
- await redis.setObject('test:delete', { data: 'test' });
90
- await redis.delObject('test:delete');
87
+ test("delObject - 删除对象", async () => {
88
+ await redis.setObject("test:delete", { data: "test" });
89
+ await redis.delObject("test:delete");
91
90
 
92
- const value = await redis.getObject('test:delete');
91
+ const value = await redis.getObject("test:delete");
93
92
  expect(value).toBeNull();
94
93
  });
95
94
  });
96
95
 
97
- describe('RedisHelper - Set 操作', () => {
98
- test('sadd - 添加成员到 Set', async () => {
96
+ describe("RedisHelper - Set 操作", () => {
97
+ test("sadd - 添加成员到 Set", async () => {
99
98
  // 先清除,确保测试隔离
100
- await redis.del('test:set:sadd');
101
- const count = await redis.sadd('test:set:sadd', ['member1', 'member2', 'member3']);
99
+ await redis.del("test:set:sadd");
100
+ const count = await redis.sadd("test:set:sadd", ["member1", "member2", "member3"]);
102
101
  expect(count).toBeGreaterThan(0);
103
- await redis.del('test:set:sadd');
102
+ await redis.del("test:set:sadd");
104
103
  });
105
104
 
106
- test('sismember - 检查成员是否存在', async () => {
107
- await redis.del('test:set');
108
- await redis.sadd('test:set', ['member1']);
105
+ test("sismember - 检查成员是否存在", async () => {
106
+ await redis.del("test:set");
107
+ await redis.sadd("test:set", ["member1"]);
109
108
 
110
- const exists = await redis.sismember('test:set', 'member1');
109
+ const exists = await redis.sismember("test:set", "member1");
111
110
  expect(exists).toBe(true);
112
111
 
113
- const notExists = await redis.sismember('test:set', 'non_existent');
112
+ const notExists = await redis.sismember("test:set", "non_existent");
114
113
  expect(notExists).toBe(false);
115
114
  });
116
115
 
117
- test('scard - 获取 Set 成员数量', async () => {
118
- await redis.del('test:set:count');
119
- await redis.sadd('test:set:count', ['m1', 'm2', 'm3']);
116
+ test("scard - 获取 Set 成员数量", async () => {
117
+ await redis.del("test:set:count");
118
+ await redis.sadd("test:set:count", ["m1", "m2", "m3"]);
120
119
 
121
- const count = await redis.scard('test:set:count');
120
+ const count = await redis.scard("test:set:count");
122
121
  expect(count).toBe(3);
123
122
 
124
- await redis.del('test:set:count');
123
+ await redis.del("test:set:count");
125
124
  });
126
125
 
127
- test('smembers - 获取所有成员', async () => {
128
- await redis.del('test:set:members');
129
- await redis.sadd('test:set:members', ['a', 'b', 'c']);
126
+ test("smembers - 获取所有成员", async () => {
127
+ await redis.del("test:set:members");
128
+ await redis.sadd("test:set:members", ["a", "b", "c"]);
130
129
 
131
- const members = await redis.smembers('test:set:members');
130
+ const members = await redis.smembers("test:set:members");
132
131
  expect(members.length).toBe(3);
133
- expect(members).toContain('a');
134
- expect(members).toContain('b');
135
- expect(members).toContain('c');
132
+ expect(members).toContain("a");
133
+ expect(members).toContain("b");
134
+ expect(members).toContain("c");
136
135
 
137
- await redis.del('test:set:members');
136
+ await redis.del("test:set:members");
138
137
  });
139
138
 
140
- test('saddBatch - 批量向多个 Set 添加成员', async () => {
139
+ test("saddBatch - 批量向多个 Set 添加成员", async () => {
141
140
  const count = await redis.saddBatch([
142
- { key: 'test:saddBatch:1', members: ['a', 'b'] },
143
- { key: 'test:saddBatch:2', members: ['c', 'd', 'e'] }
141
+ { key: "test:saddBatch:1", members: ["a", "b"] },
142
+ { key: "test:saddBatch:2", members: ["c", "d", "e"] }
144
143
  ]);
145
144
  expect(count).toBe(5);
146
145
 
147
146
  // 验证
148
- const members1 = await redis.smembers('test:saddBatch:1');
149
- const members2 = await redis.smembers('test:saddBatch:2');
147
+ const members1 = await redis.smembers("test:saddBatch:1");
148
+ const members2 = await redis.smembers("test:saddBatch:2");
150
149
  expect(members1.length).toBe(2);
151
150
  expect(members2.length).toBe(3);
152
151
 
153
152
  // 清理
154
- await redis.delBatch(['test:saddBatch:1', 'test:saddBatch:2']);
153
+ await redis.delBatch(["test:saddBatch:1", "test:saddBatch:2"]);
155
154
  });
156
155
 
157
- test('saddBatch - 空数组返回 0', async () => {
156
+ test("saddBatch - 空数组返回 0", async () => {
158
157
  const count = await redis.saddBatch([]);
159
158
  expect(count).toBe(0);
160
159
  });
161
160
 
162
- test('sismemberBatch - 批量检查成员是否存在', async () => {
163
- await redis.sadd('test:sismemberBatch', ['a', 'b', 'c']);
161
+ test("sismemberBatch - 批量检查成员是否存在", async () => {
162
+ await redis.sadd("test:sismemberBatch", ["a", "b", "c"]);
164
163
 
165
164
  const results = await redis.sismemberBatch([
166
- { key: 'test:sismemberBatch', member: 'a' },
167
- { key: 'test:sismemberBatch', member: 'b' },
168
- { key: 'test:sismemberBatch', member: 'x' }
165
+ { key: "test:sismemberBatch", member: "a" },
166
+ { key: "test:sismemberBatch", member: "b" },
167
+ { key: "test:sismemberBatch", member: "x" }
169
168
  ]);
170
169
  expect(results).toEqual([true, true, false]);
171
170
 
172
171
  // 清理
173
- await redis.del('test:sismemberBatch');
172
+ await redis.del("test:sismemberBatch");
174
173
  });
175
174
 
176
- test('sismemberBatch - 空数组返回空数组', async () => {
175
+ test("sismemberBatch - 空数组返回空数组", async () => {
177
176
  const results = await redis.sismemberBatch([]);
178
177
  expect(results).toEqual([]);
179
178
  });
180
179
  });
181
180
 
182
- describe('RedisHelper - 键操作', () => {
183
- test('exists - 检查键是否存在', async () => {
184
- await redis.setString('test:exists', 'value');
181
+ describe("RedisHelper - 键操作", () => {
182
+ test("exists - 检查键是否存在", async () => {
183
+ await redis.setString("test:exists", "value");
185
184
 
186
- const exists = await redis.exists('test:exists');
185
+ const exists = await redis.exists("test:exists");
187
186
  expect(exists).toBe(true);
188
187
 
189
- const notExists = await redis.exists('test:not_exists');
188
+ const notExists = await redis.exists("test:not_exists");
190
189
  expect(notExists).toBe(false);
191
190
 
192
- await redis.del('test:exists');
191
+ await redis.del("test:exists");
193
192
  });
194
193
 
195
- test('expire - 设置过期时间', async () => {
196
- await redis.setString('test:expire', 'value');
197
- const result = await redis.expire('test:expire', 1);
194
+ test("expire - 设置过期时间", async () => {
195
+ await redis.setString("test:expire", "value");
196
+ const result = await redis.expire("test:expire", 1);
198
197
  expect(result).toBe(1);
199
198
 
200
199
  await new Promise((resolve) => setTimeout(resolve, 1100));
201
200
 
202
- const value = await redis.getString('test:expire');
201
+ const value = await redis.getString("test:expire");
203
202
  expect(value).toBeNull();
204
203
  });
205
204
 
206
- test('ttl - 获取剩余过期时间', async () => {
207
- await redis.setString('test:ttl:check', 'value', 10);
205
+ test("ttl - 获取剩余过期时间", async () => {
206
+ await redis.setString("test:ttl:check", "value", 10);
208
207
 
209
- const ttl = await redis.ttl('test:ttl:check');
208
+ const ttl = await redis.ttl("test:ttl:check");
210
209
  expect(ttl).toBeGreaterThan(0);
211
210
  expect(ttl).toBeLessThanOrEqual(10);
212
211
 
213
- await redis.del('test:ttl:check');
212
+ await redis.del("test:ttl:check");
214
213
  });
215
214
 
216
- test('ttlBatch - 批量获取剩余过期时间', async () => {
217
- await redis.setString('test:ttlBatch:1', 'value1', 60);
218
- await redis.setString('test:ttlBatch:2', 'value2', 120);
215
+ test("ttlBatch - 批量获取剩余过期时间", async () => {
216
+ await redis.setString("test:ttlBatch:1", "value1", 60);
217
+ await redis.setString("test:ttlBatch:2", "value2", 120);
219
218
  // test:ttlBatch:3 不存在
220
219
 
221
- const results = await redis.ttlBatch(['test:ttlBatch:1', 'test:ttlBatch:2', 'test:ttlBatch:3']);
220
+ const results = await redis.ttlBatch(["test:ttlBatch:1", "test:ttlBatch:2", "test:ttlBatch:3"]);
222
221
  expect(results.length).toBe(3);
223
222
  expect(results[0]).toBeGreaterThan(0);
224
223
  expect(results[0]).toBeLessThanOrEqual(60);
@@ -227,239 +226,239 @@ describe('RedisHelper - 键操作', () => {
227
226
  expect(results[2]).toBe(-2); // 键不存在
228
227
 
229
228
  // 清理
230
- await redis.delBatch(['test:ttlBatch:1', 'test:ttlBatch:2']);
229
+ await redis.delBatch(["test:ttlBatch:1", "test:ttlBatch:2"]);
231
230
  });
232
231
 
233
- test('ttlBatch - 空数组返回空数组', async () => {
232
+ test("ttlBatch - 空数组返回空数组", async () => {
234
233
  const results = await redis.ttlBatch([]);
235
234
  expect(results).toEqual([]);
236
235
  });
237
236
 
238
- test('ttlBatch - 无过期时间返回 -1', async () => {
239
- await redis.setString('test:ttlBatch:nox', 'value'); // 无 TTL
237
+ test("ttlBatch - 无过期时间返回 -1", async () => {
238
+ await redis.setString("test:ttlBatch:nox", "value"); // 无 TTL
240
239
 
241
- const results = await redis.ttlBatch(['test:ttlBatch:nox']);
240
+ const results = await redis.ttlBatch(["test:ttlBatch:nox"]);
242
241
  expect(results[0]).toBe(-1);
243
242
 
244
243
  // 清理
245
- await redis.del('test:ttlBatch:nox');
244
+ await redis.del("test:ttlBatch:nox");
246
245
  });
247
246
 
248
- test('del - 删除键', async () => {
249
- await redis.setString('test:delete:key', 'value');
247
+ test("del - 删除键", async () => {
248
+ await redis.setString("test:delete:key", "value");
250
249
 
251
- const count = await redis.del('test:delete:key');
250
+ const count = await redis.del("test:delete:key");
252
251
  expect(count).toBe(1);
253
252
 
254
- const value = await redis.getString('test:delete:key');
253
+ const value = await redis.getString("test:delete:key");
255
254
  expect(value).toBeNull();
256
255
  });
257
256
 
258
- test('delBatch - 批量删除键', async () => {
257
+ test("delBatch - 批量删除键", async () => {
259
258
  // 创建多个键
260
- await redis.setString('test:batch:1', 'value1');
261
- await redis.setString('test:batch:2', 'value2');
262
- await redis.setString('test:batch:3', 'value3');
259
+ await redis.setString("test:batch:1", "value1");
260
+ await redis.setString("test:batch:2", "value2");
261
+ await redis.setString("test:batch:3", "value3");
263
262
 
264
263
  // 批量删除
265
- const count = await redis.delBatch(['test:batch:1', 'test:batch:2', 'test:batch:3']);
264
+ const count = await redis.delBatch(["test:batch:1", "test:batch:2", "test:batch:3"]);
266
265
  expect(count).toBe(3);
267
266
 
268
267
  // 验证删除成功
269
- const value1 = await redis.getString('test:batch:1');
270
- const value2 = await redis.getString('test:batch:2');
271
- const value3 = await redis.getString('test:batch:3');
268
+ const value1 = await redis.getString("test:batch:1");
269
+ const value2 = await redis.getString("test:batch:2");
270
+ const value3 = await redis.getString("test:batch:3");
272
271
  expect(value1).toBeNull();
273
272
  expect(value2).toBeNull();
274
273
  expect(value3).toBeNull();
275
274
  });
276
275
 
277
- test('delBatch - 空数组返回 0', async () => {
276
+ test("delBatch - 空数组返回 0", async () => {
278
277
  const count = await redis.delBatch([]);
279
278
  expect(count).toBe(0);
280
279
  });
281
280
 
282
- test('delBatch - 删除不存在的键返回 0', async () => {
283
- const count = await redis.delBatch(['test:non:existent:1', 'test:non:existent:2']);
281
+ test("delBatch - 删除不存在的键返回 0", async () => {
282
+ const count = await redis.delBatch(["test:non:existent:1", "test:non:existent:2"]);
284
283
  expect(count).toBe(0);
285
284
  });
286
285
 
287
- test('delBatch - 部分存在的键', async () => {
288
- await redis.setString('test:partial:1', 'value1');
289
- await redis.setString('test:partial:2', 'value2');
286
+ test("delBatch - 部分存在的键", async () => {
287
+ await redis.setString("test:partial:1", "value1");
288
+ await redis.setString("test:partial:2", "value2");
290
289
  // test:partial:3 不存在
291
290
 
292
- const count = await redis.delBatch(['test:partial:1', 'test:partial:2', 'test:partial:3']);
291
+ const count = await redis.delBatch(["test:partial:1", "test:partial:2", "test:partial:3"]);
293
292
  expect(count).toBe(2); // 只有 2 个键被删除
294
293
  });
295
294
 
296
- test('setBatch - 批量设置对象', async () => {
295
+ test("setBatch - 批量设置对象", async () => {
297
296
  const items = [
298
- { key: 'test:setBatch:1', value: { name: 'Alice' } },
299
- { key: 'test:setBatch:2', value: { name: 'Bob' } },
300
- { key: 'test:setBatch:3', value: { name: 'Charlie' } }
297
+ { key: "test:setBatch:1", value: { name: "Alice" } },
298
+ { key: "test:setBatch:2", value: { name: "Bob" } },
299
+ { key: "test:setBatch:3", value: { name: "Charlie" } }
301
300
  ];
302
301
 
303
302
  const count = await redis.setBatch(items);
304
303
  expect(count).toBe(3);
305
304
 
306
305
  // 验证设置成功
307
- const value1 = await redis.getObject('test:setBatch:1');
308
- const value2 = await redis.getObject('test:setBatch:2');
309
- const value3 = await redis.getObject('test:setBatch:3');
310
- expect(value1).toEqual({ name: 'Alice' });
311
- expect(value2).toEqual({ name: 'Bob' });
312
- expect(value3).toEqual({ name: 'Charlie' });
306
+ const value1 = await redis.getObject("test:setBatch:1");
307
+ const value2 = await redis.getObject("test:setBatch:2");
308
+ const value3 = await redis.getObject("test:setBatch:3");
309
+ expect(value1).toEqual({ name: "Alice" });
310
+ expect(value2).toEqual({ name: "Bob" });
311
+ expect(value3).toEqual({ name: "Charlie" });
313
312
 
314
313
  // 清理
315
- await redis.delBatch(['test:setBatch:1', 'test:setBatch:2', 'test:setBatch:3']);
314
+ await redis.delBatch(["test:setBatch:1", "test:setBatch:2", "test:setBatch:3"]);
316
315
  });
317
316
 
318
- test('setBatch - 空数组返回 0', async () => {
317
+ test("setBatch - 空数组返回 0", async () => {
319
318
  const count = await redis.setBatch([]);
320
319
  expect(count).toBe(0);
321
320
  });
322
321
 
323
- test('setBatch - 带 TTL 的批量设置', async () => {
322
+ test("setBatch - 带 TTL 的批量设置", async () => {
324
323
  const items = [
325
- { key: 'test:setBatch:ttl:1', value: { data: 1 }, ttl: 10 },
326
- { key: 'test:setBatch:ttl:2', value: { data: 2 }, ttl: 10 }
324
+ { key: "test:setBatch:ttl:1", value: { data: 1 }, ttl: 10 },
325
+ { key: "test:setBatch:ttl:2", value: { data: 2 }, ttl: 10 }
327
326
  ];
328
327
 
329
328
  const count = await redis.setBatch(items);
330
329
  expect(count).toBe(2);
331
330
 
332
331
  // 验证 TTL 已设置
333
- const ttl1 = await redis.ttl('test:setBatch:ttl:1');
334
- const ttl2 = await redis.ttl('test:setBatch:ttl:2');
332
+ const ttl1 = await redis.ttl("test:setBatch:ttl:1");
333
+ const ttl2 = await redis.ttl("test:setBatch:ttl:2");
335
334
  expect(ttl1).toBeGreaterThan(0);
336
335
  expect(ttl1).toBeLessThanOrEqual(10);
337
336
  expect(ttl2).toBeGreaterThan(0);
338
337
  expect(ttl2).toBeLessThanOrEqual(10);
339
338
 
340
339
  // 清理
341
- await redis.delBatch(['test:setBatch:ttl:1', 'test:setBatch:ttl:2']);
340
+ await redis.delBatch(["test:setBatch:ttl:1", "test:setBatch:ttl:2"]);
342
341
  });
343
342
 
344
- test('getBatch - 批量获取对象', async () => {
343
+ test("getBatch - 批量获取对象", async () => {
345
344
  // 设置测试数据
346
- await redis.setObject('test:getBatch:1', { name: 'Alice' });
347
- await redis.setObject('test:getBatch:2', { name: 'Bob' });
348
- await redis.setObject('test:getBatch:3', { name: 'Charlie' });
345
+ await redis.setObject("test:getBatch:1", { name: "Alice" });
346
+ await redis.setObject("test:getBatch:2", { name: "Bob" });
347
+ await redis.setObject("test:getBatch:3", { name: "Charlie" });
349
348
 
350
349
  // 批量获取
351
- const results = await redis.getBatch(['test:getBatch:1', 'test:getBatch:2', 'test:getBatch:3']);
350
+ const results = await redis.getBatch(["test:getBatch:1", "test:getBatch:2", "test:getBatch:3"]);
352
351
  expect(results.length).toBe(3);
353
- expect(results[0]).toEqual({ name: 'Alice' });
354
- expect(results[1]).toEqual({ name: 'Bob' });
355
- expect(results[2]).toEqual({ name: 'Charlie' });
352
+ expect(results[0]).toEqual({ name: "Alice" });
353
+ expect(results[1]).toEqual({ name: "Bob" });
354
+ expect(results[2]).toEqual({ name: "Charlie" });
356
355
 
357
356
  // 清理
358
- await redis.delBatch(['test:getBatch:1', 'test:getBatch:2', 'test:getBatch:3']);
357
+ await redis.delBatch(["test:getBatch:1", "test:getBatch:2", "test:getBatch:3"]);
359
358
  });
360
359
 
361
- test('getBatch - 空数组返回空数组', async () => {
360
+ test("getBatch - 空数组返回空数组", async () => {
362
361
  const results = await redis.getBatch([]);
363
362
  expect(results).toEqual([]);
364
363
  });
365
364
 
366
- test('getBatch - 不存在的键返回 null', async () => {
367
- const results = await redis.getBatch(['test:non:existent:a', 'test:non:existent:b']);
365
+ test("getBatch - 不存在的键返回 null", async () => {
366
+ const results = await redis.getBatch(["test:non:existent:a", "test:non:existent:b"]);
368
367
  expect(results).toEqual([null, null]);
369
368
  });
370
369
 
371
- test('getBatch - 部分存在的键', async () => {
372
- await redis.setObject('test:partial:a', { data: 'a' });
370
+ test("getBatch - 部分存在的键", async () => {
371
+ await redis.setObject("test:partial:a", { data: "a" });
373
372
  // test:partial:b 不存在
374
373
 
375
- const results = await redis.getBatch(['test:partial:a', 'test:partial:b']);
374
+ const results = await redis.getBatch(["test:partial:a", "test:partial:b"]);
376
375
  expect(results.length).toBe(2);
377
- expect(results[0]).toEqual({ data: 'a' });
376
+ expect(results[0]).toEqual({ data: "a" });
378
377
  expect(results[1]).toBeNull();
379
378
 
380
379
  // 清理
381
- await redis.del('test:partial:a');
380
+ await redis.del("test:partial:a");
382
381
  });
383
382
 
384
- test('existsBatch - 批量检查键是否存在', async () => {
385
- await redis.setString('test:existsBatch:1', 'value1');
386
- await redis.setString('test:existsBatch:2', 'value2');
383
+ test("existsBatch - 批量检查键是否存在", async () => {
384
+ await redis.setString("test:existsBatch:1", "value1");
385
+ await redis.setString("test:existsBatch:2", "value2");
387
386
  // test:existsBatch:3 不存在
388
387
 
389
- const results = await redis.existsBatch(['test:existsBatch:1', 'test:existsBatch:2', 'test:existsBatch:3']);
388
+ const results = await redis.existsBatch(["test:existsBatch:1", "test:existsBatch:2", "test:existsBatch:3"]);
390
389
  expect(results).toEqual([true, true, false]);
391
390
 
392
391
  // 清理
393
- await redis.delBatch(['test:existsBatch:1', 'test:existsBatch:2']);
392
+ await redis.delBatch(["test:existsBatch:1", "test:existsBatch:2"]);
394
393
  });
395
394
 
396
- test('existsBatch - 空数组返回空数组', async () => {
395
+ test("existsBatch - 空数组返回空数组", async () => {
397
396
  const results = await redis.existsBatch([]);
398
397
  expect(results).toEqual([]);
399
398
  });
400
399
 
401
- test('existsBatch - 全部不存在', async () => {
402
- const results = await redis.existsBatch(['test:none:1', 'test:none:2']);
400
+ test("existsBatch - 全部不存在", async () => {
401
+ const results = await redis.existsBatch(["test:none:1", "test:none:2"]);
403
402
  expect(results).toEqual([false, false]);
404
403
  });
405
404
 
406
- test('expireBatch - 批量设置过期时间', async () => {
407
- await redis.setString('test:expireBatch:1', 'value1');
408
- await redis.setString('test:expireBatch:2', 'value2');
405
+ test("expireBatch - 批量设置过期时间", async () => {
406
+ await redis.setString("test:expireBatch:1", "value1");
407
+ await redis.setString("test:expireBatch:2", "value2");
409
408
 
410
409
  const count = await redis.expireBatch([
411
- { key: 'test:expireBatch:1', seconds: 60 },
412
- { key: 'test:expireBatch:2', seconds: 120 }
410
+ { key: "test:expireBatch:1", seconds: 60 },
411
+ { key: "test:expireBatch:2", seconds: 120 }
413
412
  ]);
414
413
  expect(count).toBe(2);
415
414
 
416
415
  // 验证 TTL 已设置
417
- const ttl1 = await redis.ttl('test:expireBatch:1');
418
- const ttl2 = await redis.ttl('test:expireBatch:2');
416
+ const ttl1 = await redis.ttl("test:expireBatch:1");
417
+ const ttl2 = await redis.ttl("test:expireBatch:2");
419
418
  expect(ttl1).toBeGreaterThan(0);
420
419
  expect(ttl1).toBeLessThanOrEqual(60);
421
420
  expect(ttl2).toBeGreaterThan(0);
422
421
  expect(ttl2).toBeLessThanOrEqual(120);
423
422
 
424
423
  // 清理
425
- await redis.delBatch(['test:expireBatch:1', 'test:expireBatch:2']);
424
+ await redis.delBatch(["test:expireBatch:1", "test:expireBatch:2"]);
426
425
  });
427
426
 
428
- test('expireBatch - 空数组返回 0', async () => {
427
+ test("expireBatch - 空数组返回 0", async () => {
429
428
  const count = await redis.expireBatch([]);
430
429
  expect(count).toBe(0);
431
430
  });
432
431
 
433
- test('expireBatch - 不存在的键返回 0', async () => {
432
+ test("expireBatch - 不存在的键返回 0", async () => {
434
433
  const count = await redis.expireBatch([
435
- { key: 'test:expire:none:1', seconds: 60 },
436
- { key: 'test:expire:none:2', seconds: 60 }
434
+ { key: "test:expire:none:1", seconds: 60 },
435
+ { key: "test:expire:none:2", seconds: 60 }
437
436
  ]);
438
437
  expect(count).toBe(0);
439
438
  });
440
439
 
441
- test('expireBatch - 部分存在的键', async () => {
442
- await redis.setString('test:expire:partial:1', 'value1');
440
+ test("expireBatch - 部分存在的键", async () => {
441
+ await redis.setString("test:expire:partial:1", "value1");
443
442
  // test:expire:partial:2 不存在
444
443
 
445
444
  const count = await redis.expireBatch([
446
- { key: 'test:expire:partial:1', seconds: 60 },
447
- { key: 'test:expire:partial:2', seconds: 60 }
445
+ { key: "test:expire:partial:1", seconds: 60 },
446
+ { key: "test:expire:partial:2", seconds: 60 }
448
447
  ]);
449
448
  expect(count).toBe(1);
450
449
 
451
450
  // 清理
452
- await redis.del('test:expire:partial:1');
451
+ await redis.del("test:expire:partial:1");
453
452
  });
454
453
  });
455
454
 
456
- describe('RedisHelper - ID 生成', () => {
457
- test('genTimeID - 生成唯一 ID', async () => {
455
+ describe("RedisHelper - ID 生成", () => {
456
+ test("genTimeID - 生成唯一 ID", async () => {
458
457
  const id1 = await redis.genTimeID();
459
458
  const id2 = await redis.genTimeID();
460
459
 
461
- expect(typeof id1).toBe('number');
462
- expect(typeof id2).toBe('number');
460
+ expect(typeof id1).toBe("number");
461
+ expect(typeof id2).toBe("number");
463
462
  expect(id1).not.toBe(id2);
464
463
  expect(id1.toString().length).toBe(16);
465
464
 
@@ -472,7 +471,7 @@ describe('RedisHelper - ID 生成', () => {
472
471
  expect(suffix2).toBeLessThan(1000);
473
472
  });
474
473
 
475
- test('genTimeID - 多次生成保持唯一', async () => {
474
+ test("genTimeID - 多次生成保持唯一", async () => {
476
475
  const ids: number[] = [];
477
476
  for (let i = 0; i < 10; i++) {
478
477
  ids.push(await redis.genTimeID());
@@ -483,9 +482,9 @@ describe('RedisHelper - ID 生成', () => {
483
482
  });
484
483
  });
485
484
 
486
- describe('RedisHelper - 连接测试', () => {
487
- test('ping - 测试连接', async () => {
485
+ describe("RedisHelper - 连接测试", () => {
486
+ test("ping - 测试连接", async () => {
488
487
  const result = await redis.ping();
489
- expect(result).toBe('PONG');
488
+ expect(result).toBe("PONG");
490
489
  });
491
490
  });