befly 3.10.0 → 3.10.2

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 (79) hide show
  1. package/.gitignore +0 -0
  2. package/README.md +10 -13
  3. package/configs/presetFields.ts +10 -0
  4. package/configs/presetRegexp.ts +225 -0
  5. package/docs/README.md +17 -11
  6. package/docs/api/api.md +15 -1
  7. package/docs/guide/quickstart.md +19 -5
  8. package/docs/infra/redis.md +23 -11
  9. package/docs/quickstart.md +5 -335
  10. package/docs/reference/addon.md +0 -15
  11. package/docs/reference/config.md +1 -1
  12. package/docs/reference/logger.md +3 -3
  13. package/docs/reference/sync.md +99 -73
  14. package/docs/reference/table.md +1 -1
  15. package/package.json +15 -16
  16. package/docs/cipher.md +0 -582
  17. package/docs/database.md +0 -1176
  18. package/tests/_mocks/mockSqliteDb.ts +0 -204
  19. package/tests/addonHelper-cache.test.ts +0 -32
  20. package/tests/api-integration-array-number.test.ts +0 -282
  21. package/tests/apiHandler-routePath-only.test.ts +0 -32
  22. package/tests/befly-config-env.test.ts +0 -78
  23. package/tests/cacheHelper.test.ts +0 -323
  24. package/tests/cacheKeys.test.ts +0 -41
  25. package/tests/checkApi-routePath-strict.test.ts +0 -166
  26. package/tests/checkMenu.test.ts +0 -346
  27. package/tests/checkTable-smoke.test.ts +0 -157
  28. package/tests/cipher.test.ts +0 -249
  29. package/tests/dbDialect-cache.test.ts +0 -23
  30. package/tests/dbDialect.test.ts +0 -46
  31. package/tests/dbHelper-advanced.test.ts +0 -723
  32. package/tests/dbHelper-all-array-types.test.ts +0 -316
  33. package/tests/dbHelper-array-serialization.test.ts +0 -258
  34. package/tests/dbHelper-batch-write.test.ts +0 -90
  35. package/tests/dbHelper-columns.test.ts +0 -234
  36. package/tests/dbHelper-execute.test.ts +0 -187
  37. package/tests/dbHelper-joins.test.ts +0 -221
  38. package/tests/fields-redis-cache.test.ts +0 -127
  39. package/tests/fields-validate.test.ts +0 -99
  40. package/tests/fixtures/scanFilesAddon/node_modules/@befly-addon/demo/apis/sub/b.ts +0 -3
  41. package/tests/fixtures/scanFilesApis/a.ts +0 -3
  42. package/tests/fixtures/scanFilesApis/sub/b.ts +0 -3
  43. package/tests/getClientIp.test.ts +0 -54
  44. package/tests/integration.test.ts +0 -189
  45. package/tests/jwt.test.ts +0 -65
  46. package/tests/loadPlugins-order-smoke.test.ts +0 -75
  47. package/tests/logger.test.ts +0 -325
  48. package/tests/redisHelper.test.ts +0 -495
  49. package/tests/redisKeys.test.ts +0 -9
  50. package/tests/scanConfig.test.ts +0 -144
  51. package/tests/scanFiles-routePath.test.ts +0 -46
  52. package/tests/smoke-sql.test.ts +0 -24
  53. package/tests/sqlBuilder-advanced.test.ts +0 -608
  54. package/tests/sqlBuilder.test.ts +0 -209
  55. package/tests/sync-connection.test.ts +0 -183
  56. package/tests/sync-init-guard.test.ts +0 -105
  57. package/tests/syncApi-insBatch-fields-consistent.test.ts +0 -61
  58. package/tests/syncApi-obsolete-records.test.ts +0 -69
  59. package/tests/syncApi-type-compat.test.ts +0 -72
  60. package/tests/syncDev-permissions.test.ts +0 -81
  61. package/tests/syncMenu-disableMenus-hard-delete.test.ts +0 -88
  62. package/tests/syncMenu-duplicate-path.test.ts +0 -122
  63. package/tests/syncMenu-obsolete-records.test.ts +0 -161
  64. package/tests/syncMenu-parentPath-from-tree.test.ts +0 -75
  65. package/tests/syncMenu-paths.test.ts +0 -59
  66. package/tests/syncTable-apply.test.ts +0 -279
  67. package/tests/syncTable-array-number.test.ts +0 -160
  68. package/tests/syncTable-constants.test.ts +0 -101
  69. package/tests/syncTable-db-integration.test.ts +0 -237
  70. package/tests/syncTable-ddl.test.ts +0 -245
  71. package/tests/syncTable-helpers.test.ts +0 -99
  72. package/tests/syncTable-schema.test.ts +0 -99
  73. package/tests/syncTable-testkit.test.ts +0 -25
  74. package/tests/syncTable-types.test.ts +0 -122
  75. package/tests/tableRef-and-deserialize.test.ts +0 -67
  76. package/tests/util.test.ts +0 -100
  77. package/tests/validator-array-number.test.ts +0 -310
  78. package/tests/validator-default.test.ts +0 -373
  79. package/tests/validator.test.ts +0 -679
@@ -1,249 +0,0 @@
1
- /**
2
- * Cipher 加密工具测试
3
- */
4
-
5
- import { describe, test, expect, beforeAll } from "bun:test";
6
- import { writeFileSync, existsSync, mkdirSync } from "node:fs";
7
- import { join } from "node:path";
8
-
9
- import { Cipher } from "../lib/cipher";
10
-
11
- describe("Cipher - 哈希功能", () => {
12
- const testData = "hello world";
13
- const testDataBytes = new TextEncoder().encode(testData);
14
-
15
- test("MD5 哈希 - 字符串输入", () => {
16
- const result = Cipher.md5(testData);
17
- expect(result).toBe("5eb63bbbe01eeed093cb22bb8f5acdc3");
18
- expect(result.length).toBe(32);
19
- });
20
-
21
- test("MD5 哈希 - Uint8Array 输入", () => {
22
- const result = Cipher.md5(testDataBytes);
23
- expect(result).toBe("5eb63bbbe01eeed093cb22bb8f5acdc3");
24
- });
25
-
26
- test("MD5 哈希 - base64 编码", () => {
27
- const result = Cipher.md5(testData, "base64");
28
- expect(typeof result).toBe("string");
29
- expect(result.length).toBeGreaterThan(0);
30
- });
31
-
32
- test("SHA1 哈希", () => {
33
- const result = Cipher.sha1(testData);
34
- expect(result).toBe("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
35
- expect(result.length).toBe(40);
36
- });
37
-
38
- test("SHA256 哈希", () => {
39
- const result = Cipher.sha256(testData);
40
- expect(result).toBe("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9");
41
- expect(result.length).toBe(64);
42
- });
43
-
44
- test("SHA512 哈希", () => {
45
- const result = Cipher.sha512(testData);
46
- expect(result.length).toBe(128);
47
- expect(typeof result).toBe("string");
48
- });
49
-
50
- test("通用 hash 方法 - SHA256", () => {
51
- const result = Cipher.hash("sha256", testData);
52
- expect(result).toBe("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9");
53
- });
54
-
55
- test("通用 hash 方法 - MD5", () => {
56
- const result = Cipher.hash("md5", testData);
57
- expect(result).toBe("5eb63bbbe01eeed093cb22bb8f5acdc3");
58
- });
59
- });
60
-
61
- describe("Cipher - HMAC 签名", () => {
62
- const key = "secret-key";
63
- const data = "test data";
64
-
65
- test("HMAC-MD5", () => {
66
- const result = Cipher.hmacMd5(key, data);
67
- expect(result.length).toBe(32);
68
- expect(typeof result).toBe("string");
69
- });
70
-
71
- test("HMAC-SHA1", () => {
72
- const result = Cipher.hmacSha1(key, data);
73
- expect(result.length).toBe(40);
74
- expect(typeof result).toBe("string");
75
- });
76
-
77
- test("HMAC-SHA256", () => {
78
- const result = Cipher.hmacSha256(key, data);
79
- expect(result.length).toBe(64);
80
- expect(typeof result).toBe("string");
81
- });
82
-
83
- test("HMAC-SHA512", () => {
84
- const result = Cipher.hmacSha512(key, data);
85
- expect(result.length).toBe(128);
86
- expect(typeof result).toBe("string");
87
- });
88
-
89
- test("通用 HMAC 方法", () => {
90
- const result1 = Cipher.hmac("sha256", key, data);
91
- const result2 = Cipher.hmacSha256(key, data);
92
- expect(result1).toBe(result2);
93
- });
94
-
95
- test("HMAC - Uint8Array 输入", () => {
96
- const keyBytes = new TextEncoder().encode(key);
97
- const dataBytes = new TextEncoder().encode(data);
98
- const result = Cipher.hmacSha256(keyBytes, dataBytes);
99
- expect(result.length).toBe(64);
100
- });
101
- });
102
-
103
- describe("Cipher - 密码加密", () => {
104
- const password = "MySecurePassword123!";
105
-
106
- test("密码哈希", async () => {
107
- const hash = await Cipher.hashPassword(password);
108
- expect(hash).toBeDefined();
109
- expect(hash.length).toBeGreaterThan(0);
110
- expect(hash).not.toBe(password);
111
- });
112
-
113
- test("密码验证 - 正确密码", async () => {
114
- const hash = await Cipher.hashPassword(password);
115
- const isValid = await Cipher.verifyPassword(password, hash);
116
- expect(isValid).toBe(true);
117
- });
118
-
119
- test("密码验证 - 错误密码", async () => {
120
- const hash = await Cipher.hashPassword(password);
121
- const isValid = await Cipher.verifyPassword("wrong-password", hash);
122
- expect(isValid).toBe(false);
123
- });
124
-
125
- test("相同密码生成不同哈希", async () => {
126
- const hash1 = await Cipher.hashPassword(password);
127
- const hash2 = await Cipher.hashPassword(password);
128
- expect(hash1).not.toBe(hash2);
129
- });
130
- });
131
-
132
- describe("Cipher - Base64 编码", () => {
133
- const original = "Hello, 世界!";
134
-
135
- test("Base64 编码", () => {
136
- const encoded = Cipher.base64Encode(original);
137
- expect(encoded).toBe("SGVsbG8sIOS4lueVjCE=");
138
- });
139
-
140
- test("Base64 解码", () => {
141
- const encoded = "SGVsbG8sIOS4lueVjCE=";
142
- const decoded = Cipher.base64Decode(encoded);
143
- expect(decoded).toBe(original);
144
- });
145
-
146
- test("Base64 编码解码循环", () => {
147
- const encoded = Cipher.base64Encode(original);
148
- const decoded = Cipher.base64Decode(encoded);
149
- expect(decoded).toBe(original);
150
- });
151
-
152
- test("Base64 编码空字符串", () => {
153
- const encoded = Cipher.base64Encode("");
154
- expect(encoded).toBe("");
155
- });
156
- });
157
-
158
- describe("Cipher - 随机字符串", () => {
159
- test("生成指定长度的随机字符串", () => {
160
- const result = Cipher.randomString(16);
161
- expect(result.length).toBe(16);
162
- expect(/^[0-9a-f]+$/.test(result)).toBe(true);
163
- });
164
-
165
- test("生成不同的随机字符串", () => {
166
- const result1 = Cipher.randomString(32);
167
- const result2 = Cipher.randomString(32);
168
- expect(result1).not.toBe(result2);
169
- });
170
-
171
- test("生成奇数长度的随机字符串", () => {
172
- const result = Cipher.randomString(15);
173
- expect(result.length).toBe(15);
174
- });
175
-
176
- test("生成 0 长度字符串", () => {
177
- const result = Cipher.randomString(0);
178
- expect(result).toBe("");
179
- });
180
- });
181
-
182
- describe("Cipher - 文件哈希", () => {
183
- const testFilePath = join(process.cwd(), "temp", "cipher-test-file.txt");
184
- const testContent = "Test file content for hashing";
185
-
186
- beforeAll(() => {
187
- const tempDir = join(process.cwd(), "temp");
188
- if (!existsSync(tempDir)) {
189
- mkdirSync(tempDir, { recursive: true });
190
- }
191
- writeFileSync(testFilePath, testContent, "utf8");
192
- });
193
-
194
- test("SHA256 文件哈希", async () => {
195
- const result = await Cipher.hashFile(testFilePath, "sha256");
196
- expect(result.length).toBe(64);
197
- expect(typeof result).toBe("string");
198
- });
199
-
200
- test("MD5 文件哈希", async () => {
201
- const result = await Cipher.hashFile(testFilePath, "md5");
202
- expect(result.length).toBe(32);
203
- });
204
-
205
- test("文件哈希与内容哈希一致", async () => {
206
- const fileHash = await Cipher.hashFile(testFilePath, "sha256");
207
- const contentHash = Cipher.sha256(testContent);
208
- expect(fileHash).toBe(contentHash);
209
- });
210
-
211
- test("文件哈希 - base64 编码", async () => {
212
- const result = await Cipher.hashFile(testFilePath, "sha256", "base64");
213
- expect(typeof result).toBe("string");
214
- expect(result.length).toBeGreaterThan(0);
215
- });
216
- });
217
-
218
- describe("Cipher - 快速哈希", () => {
219
- const testData = "quick hash test";
220
-
221
- test("快速哈希 - 字符串输入", () => {
222
- const result = Cipher.fastHash(testData);
223
- expect(typeof result).toBe("number");
224
- expect(result).toBeGreaterThan(0);
225
- });
226
-
227
- test("快速哈希 - Uint8Array 输入", () => {
228
- const bytes = new TextEncoder().encode(testData);
229
- const result = Cipher.fastHash(bytes);
230
- expect(typeof result).toBe("number");
231
- });
232
-
233
- test("快速哈希 - 相同输入产生相同哈希", () => {
234
- const result1 = Cipher.fastHash(testData);
235
- const result2 = Cipher.fastHash(testData);
236
- expect(result1).toBe(result2);
237
- });
238
-
239
- test("快速哈希 - 不同 seed 产生不同结果", () => {
240
- const result1 = Cipher.fastHash(testData, 0);
241
- const result2 = Cipher.fastHash(testData, 1);
242
- expect(result1).not.toBe(result2);
243
- });
244
-
245
- test("快速哈希 - 空字符串", () => {
246
- const result = Cipher.fastHash("");
247
- expect(typeof result).toBe("number");
248
- });
249
- });
@@ -1,23 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
-
3
- import { getDialectByName } from "../lib/dbDialect.js";
4
-
5
- describe("dbDialect - getDialectByName cache", () => {
6
- it("should return stable singleton instances", () => {
7
- const mysql1 = getDialectByName("mysql");
8
- const mysql2 = getDialectByName("mysql");
9
- expect(mysql1).toBe(mysql2);
10
-
11
- const pg1 = getDialectByName("postgresql");
12
- const pg2 = getDialectByName("postgresql");
13
- expect(pg1).toBe(pg2);
14
-
15
- const sqlite1 = getDialectByName("sqlite");
16
- const sqlite2 = getDialectByName("sqlite");
17
- expect(sqlite1).toBe(sqlite2);
18
-
19
- expect(mysql1).not.toBe(pg1);
20
- expect(mysql1).not.toBe(sqlite1);
21
- expect(pg1).not.toBe(sqlite1);
22
- });
23
- });
@@ -1,46 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
-
3
- import { MySqlDialect, PostgresDialect, SqliteDialect } from "../lib/dbDialect.js";
4
-
5
- describe("DbDialect - quoteIdent", () => {
6
- it("MySqlDialect: 使用反引号", () => {
7
- const dialect = new MySqlDialect();
8
- expect(dialect.quoteIdent("users")).toBe("`users`");
9
- expect(dialect.quoteIdent("created_at")).toBe("`created_at`");
10
- });
11
-
12
- it("PostgresDialect: 使用双引号", () => {
13
- const dialect = new PostgresDialect();
14
- expect(dialect.quoteIdent("users")).toBe('"users"');
15
- expect(dialect.quoteIdent("created_at")).toBe('"created_at"');
16
- });
17
-
18
- it("SqliteDialect: 使用双引号", () => {
19
- const dialect = new SqliteDialect();
20
- expect(dialect.quoteIdent("users")).toBe('"users"');
21
- expect(dialect.quoteIdent("created_at")).toBe('"created_at"');
22
- });
23
- });
24
-
25
- describe("DbDialect - getTableColumnsQuery/tableExistsQuery", () => {
26
- it("PostgresDialect: columns 查询应带参数", () => {
27
- const dialect = new PostgresDialect();
28
- const query = dialect.getTableColumnsQuery("users");
29
- expect(query.sql).toContain("information_schema.columns");
30
- expect(query.params).toEqual(["users"]);
31
- });
32
-
33
- it('SqliteDialect: columns 查询应为 PRAGMA table_info("table")', () => {
34
- const dialect = new SqliteDialect();
35
- const query = dialect.getTableColumnsQuery("users");
36
- expect(query.sql).toBe('PRAGMA table_info("users")');
37
- expect(query.params).toEqual([]);
38
- });
39
-
40
- it("SqliteDialect: tableExistsQuery 应查 sqlite_master", () => {
41
- const dialect = new SqliteDialect();
42
- const query = dialect.tableExistsQuery("users");
43
- expect(query.sql).toContain("sqlite_master");
44
- expect(query.params).toEqual(["users"]);
45
- });
46
- });