befly 3.16.9 → 3.16.11
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 +0 -129
- package/befly.js +12769 -0
- package/befly.min.js +47 -0
- package/package.json +18 -29
- package/dist/befly.config.d.ts +0 -7
- package/dist/befly.config.js +0 -128
- package/dist/befly.js +0 -17276
- package/dist/befly.min.js +0 -23
- package/dist/checks/checkApi.d.ts +0 -1
- package/dist/checks/checkApi.js +0 -124
- package/dist/checks/checkConfig.d.ts +0 -9
- package/dist/checks/checkConfig.js +0 -255
- package/dist/checks/checkHook.d.ts +0 -1
- package/dist/checks/checkHook.js +0 -132
- package/dist/checks/checkMenu.d.ts +0 -3
- package/dist/checks/checkMenu.js +0 -106
- package/dist/checks/checkPlugin.d.ts +0 -1
- package/dist/checks/checkPlugin.js +0 -132
- package/dist/checks/checkTable.d.ts +0 -7
- package/dist/checks/checkTable.js +0 -431
- package/dist/configs/presetRegexp.d.ts +0 -145
- package/dist/configs/presetRegexp.js +0 -218
- package/dist/hooks/auth.d.ts +0 -3
- package/dist/hooks/auth.js +0 -24
- package/dist/hooks/cors.d.ts +0 -7
- package/dist/hooks/cors.js +0 -36
- package/dist/hooks/parser.d.ts +0 -10
- package/dist/hooks/parser.js +0 -76
- package/dist/hooks/permission.d.ts +0 -10
- package/dist/hooks/permission.js +0 -64
- package/dist/hooks/validator.d.ts +0 -7
- package/dist/hooks/validator.js +0 -52
- package/dist/index.d.ts +0 -28
- package/dist/index.js +0 -316
- package/dist/lib/asyncContext.d.ts +0 -21
- package/dist/lib/asyncContext.js +0 -27
- package/dist/lib/cacheHelper.d.ts +0 -128
- package/dist/lib/cacheHelper.js +0 -477
- package/dist/lib/cacheKeys.d.ts +0 -27
- package/dist/lib/cacheKeys.js +0 -37
- package/dist/lib/cipher.d.ts +0 -153
- package/dist/lib/cipher.js +0 -237
- package/dist/lib/connect.d.ts +0 -95
- package/dist/lib/connect.js +0 -313
- package/dist/lib/dbHelper.d.ts +0 -229
- package/dist/lib/dbHelper.js +0 -1069
- package/dist/lib/dbUtils.d.ts +0 -91
- package/dist/lib/dbUtils.js +0 -544
- package/dist/lib/jwt.d.ts +0 -13
- package/dist/lib/jwt.js +0 -77
- package/dist/lib/logger.d.ts +0 -46
- package/dist/lib/logger.js +0 -731
- package/dist/lib/redisHelper.d.ts +0 -193
- package/dist/lib/redisHelper.js +0 -598
- package/dist/lib/sqlBuilder.d.ts +0 -160
- package/dist/lib/sqlBuilder.js +0 -837
- package/dist/lib/sqlCheck.d.ts +0 -23
- package/dist/lib/sqlCheck.js +0 -119
- package/dist/lib/validator.d.ts +0 -45
- package/dist/lib/validator.js +0 -424
- package/dist/loader/loadApis.d.ts +0 -12
- package/dist/loader/loadApis.js +0 -71
- package/dist/loader/loadHooks.d.ts +0 -7
- package/dist/loader/loadHooks.js +0 -50
- package/dist/loader/loadPlugins.d.ts +0 -8
- package/dist/loader/loadPlugins.js +0 -69
- package/dist/paths.d.ts +0 -93
- package/dist/paths.js +0 -100
- package/dist/plugins/cache.d.ts +0 -10
- package/dist/plugins/cache.js +0 -24
- package/dist/plugins/cipher.d.ts +0 -7
- package/dist/plugins/cipher.js +0 -14
- package/dist/plugins/config.d.ts +0 -3
- package/dist/plugins/config.js +0 -9
- package/dist/plugins/db.d.ts +0 -10
- package/dist/plugins/db.js +0 -48
- package/dist/plugins/jwt.d.ts +0 -6
- package/dist/plugins/jwt.js +0 -13
- package/dist/plugins/logger.d.ts +0 -10
- package/dist/plugins/logger.js +0 -21
- package/dist/plugins/redis.d.ts +0 -10
- package/dist/plugins/redis.js +0 -40
- package/dist/plugins/tool.d.ts +0 -75
- package/dist/plugins/tool.js +0 -105
- package/dist/router/api.d.ts +0 -14
- package/dist/router/api.js +0 -109
- package/dist/router/static.d.ts +0 -9
- package/dist/router/static.js +0 -56
- package/dist/scripts/ensureDist.d.ts +0 -1
- package/dist/scripts/ensureDist.js +0 -296
- package/dist/sync/syncApi.d.ts +0 -3
- package/dist/sync/syncApi.js +0 -140
- package/dist/sync/syncCache.d.ts +0 -2
- package/dist/sync/syncCache.js +0 -14
- package/dist/sync/syncDev.d.ts +0 -6
- package/dist/sync/syncDev.js +0 -166
- package/dist/sync/syncMenu.d.ts +0 -14
- package/dist/sync/syncMenu.js +0 -308
- package/dist/sync/syncTable.d.ts +0 -126
- package/dist/sync/syncTable.js +0 -1129
- package/dist/types/api.d.ts +0 -175
- package/dist/types/api.js +0 -4
- package/dist/types/befly.d.ts +0 -231
- package/dist/types/befly.js +0 -4
- package/dist/types/cache.d.ts +0 -96
- package/dist/types/cache.js +0 -4
- package/dist/types/cipher.d.ts +0 -27
- package/dist/types/cipher.js +0 -7
- package/dist/types/common.d.ts +0 -127
- package/dist/types/common.js +0 -5
- package/dist/types/context.d.ts +0 -39
- package/dist/types/context.js +0 -4
- package/dist/types/coreError.d.ts +0 -31
- package/dist/types/coreError.js +0 -38
- package/dist/types/crypto.d.ts +0 -20
- package/dist/types/crypto.js +0 -4
- package/dist/types/database.d.ts +0 -182
- package/dist/types/database.js +0 -4
- package/dist/types/hook.d.ts +0 -30
- package/dist/types/hook.js +0 -19
- package/dist/types/jwt.d.ts +0 -76
- package/dist/types/jwt.js +0 -4
- package/dist/types/logger.d.ts +0 -95
- package/dist/types/logger.js +0 -6
- package/dist/types/plugin.d.ts +0 -27
- package/dist/types/plugin.js +0 -17
- package/dist/types/redis.d.ts +0 -80
- package/dist/types/redis.js +0 -4
- package/dist/types/roleApisCache.d.ts +0 -21
- package/dist/types/roleApisCache.js +0 -8
- package/dist/types/sync.d.ts +0 -93
- package/dist/types/sync.js +0 -4
- package/dist/types/table.d.ts +0 -34
- package/dist/types/table.js +0 -4
- package/dist/types/validate.d.ts +0 -113
- package/dist/types/validate.js +0 -4
- package/dist/utils/calcPerfTime.d.ts +0 -4
- package/dist/utils/calcPerfTime.js +0 -13
- package/dist/utils/cors.d.ts +0 -8
- package/dist/utils/cors.js +0 -17
- package/dist/utils/dbFieldRules.d.ts +0 -31
- package/dist/utils/dbFieldRules.js +0 -94
- package/dist/utils/fieldClear.d.ts +0 -11
- package/dist/utils/fieldClear.js +0 -57
- package/dist/utils/formatYmdHms.d.ts +0 -1
- package/dist/utils/formatYmdHms.js +0 -20
- package/dist/utils/getClientIp.d.ts +0 -6
- package/dist/utils/getClientIp.js +0 -39
- package/dist/utils/importDefault.d.ts +0 -1
- package/dist/utils/importDefault.js +0 -53
- package/dist/utils/isDirentDirectory.d.ts +0 -3
- package/dist/utils/isDirentDirectory.js +0 -18
- package/dist/utils/loadMenuConfigs.d.ts +0 -11
- package/dist/utils/loadMenuConfigs.js +0 -130
- package/dist/utils/loggerUtils.d.ts +0 -18
- package/dist/utils/loggerUtils.js +0 -171
- package/dist/utils/mergeAndConcat.d.ts +0 -7
- package/dist/utils/mergeAndConcat.js +0 -77
- package/dist/utils/normalizeFieldDefinition.d.ts +0 -18
- package/dist/utils/normalizeFieldDefinition.js +0 -27
- package/dist/utils/processInfo.d.ts +0 -26
- package/dist/utils/processInfo.js +0 -41
- package/dist/utils/response.d.ts +0 -20
- package/dist/utils/response.js +0 -96
- package/dist/utils/scanAddons.d.ts +0 -15
- package/dist/utils/scanAddons.js +0 -35
- package/dist/utils/scanCoreBuiltins.d.ts +0 -3
- package/dist/utils/scanCoreBuiltins.js +0 -72
- package/dist/utils/scanFiles.d.ts +0 -32
- package/dist/utils/scanFiles.js +0 -124
- package/dist/utils/scanSources.d.ts +0 -10
- package/dist/utils/scanSources.js +0 -46
- package/dist/utils/sortModules.d.ts +0 -28
- package/dist/utils/sortModules.js +0 -105
- package/dist/utils/sqlUtil.d.ts +0 -33
- package/dist/utils/sqlUtil.js +0 -146
- package/dist/utils/util.d.ts +0 -172
- package/dist/utils/util.js +0 -517
package/dist/lib/cipher.js
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 加密工具类 - TypeScript 版本
|
|
3
|
-
* 提供各种哈希、HMAC、密码加密等功能
|
|
4
|
-
*/
|
|
5
|
-
import { createSign } from "node:crypto";
|
|
6
|
-
/**
|
|
7
|
-
* 加密工具类
|
|
8
|
-
*/
|
|
9
|
-
export class Cipher {
|
|
10
|
-
/**
|
|
11
|
-
* MD5 哈希
|
|
12
|
-
* @param data - 要哈希的数据
|
|
13
|
-
* @param encoding - 输出编码
|
|
14
|
-
* @returns MD5 哈希值
|
|
15
|
-
*/
|
|
16
|
-
static md5(data, encoding = "hex") {
|
|
17
|
-
const hasher = new Bun.CryptoHasher("md5");
|
|
18
|
-
hasher.update(data);
|
|
19
|
-
return hasher.digest(encoding);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* HMAC-MD5 签名
|
|
23
|
-
* @param key - 密钥
|
|
24
|
-
* @param data - 要签名的数据
|
|
25
|
-
* @param encoding - 输出编码
|
|
26
|
-
* @returns HMAC-MD5 签名
|
|
27
|
-
*/
|
|
28
|
-
static hmacMd5(key, data, encoding = "hex") {
|
|
29
|
-
const hasher = new Bun.CryptoHasher("md5", key);
|
|
30
|
-
hasher.update(data);
|
|
31
|
-
return hasher.digest(encoding);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* SHA-1 哈希
|
|
35
|
-
* @param data - 要哈希的数据
|
|
36
|
-
* @param encoding - 输出编码
|
|
37
|
-
* @returns SHA-1 哈希值
|
|
38
|
-
*/
|
|
39
|
-
static sha1(data, encoding = "hex") {
|
|
40
|
-
const hasher = new Bun.CryptoHasher("sha1");
|
|
41
|
-
hasher.update(data);
|
|
42
|
-
return hasher.digest(encoding);
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* HMAC-SHA1 签名
|
|
46
|
-
* @param key - 密钥
|
|
47
|
-
* @param data - 要签名的数据
|
|
48
|
-
* @param encoding - 输出编码
|
|
49
|
-
* @returns HMAC-SHA1 签名
|
|
50
|
-
*/
|
|
51
|
-
static hmacSha1(key, data, encoding = "hex") {
|
|
52
|
-
const hasher = new Bun.CryptoHasher("sha1", key);
|
|
53
|
-
hasher.update(data);
|
|
54
|
-
return hasher.digest(encoding);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* SHA-256 哈希
|
|
58
|
-
* @param data - 要哈希的数据
|
|
59
|
-
* @param encoding - 输出编码
|
|
60
|
-
* @returns SHA-256 哈希值
|
|
61
|
-
*/
|
|
62
|
-
static sha256(data, encoding = "hex") {
|
|
63
|
-
const hasher = new Bun.CryptoHasher("sha256");
|
|
64
|
-
hasher.update(data);
|
|
65
|
-
return hasher.digest(encoding);
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* RSA-SHA256 签名
|
|
69
|
-
* @param data - 要签名的数据
|
|
70
|
-
* @param privateKey - 私钥
|
|
71
|
-
* @param encoding - 输出编码('hex' | 'base64' | 'base64url')
|
|
72
|
-
* @returns RSA-SHA256 签名
|
|
73
|
-
*/
|
|
74
|
-
static rsaSha256(data, privateKey, encoding = "hex") {
|
|
75
|
-
const sign = createSign("RSA-SHA256");
|
|
76
|
-
sign.update(data);
|
|
77
|
-
const signature = sign.sign(privateKey, encoding);
|
|
78
|
-
return signature;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* HMAC-SHA256 签名
|
|
82
|
-
* @param key - 密钥
|
|
83
|
-
* @param data - 要签名的数据
|
|
84
|
-
* @param encoding - 输出编码
|
|
85
|
-
* @returns HMAC-SHA256 签名
|
|
86
|
-
*/
|
|
87
|
-
static hmacSha256(key, data, encoding = "hex") {
|
|
88
|
-
const hasher = new Bun.CryptoHasher("sha256", key);
|
|
89
|
-
hasher.update(data);
|
|
90
|
-
return hasher.digest(encoding);
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* SHA-512 哈希
|
|
94
|
-
* @param data - 要哈希的数据
|
|
95
|
-
* @param encoding - 输出编码
|
|
96
|
-
* @returns SHA-512 哈希值
|
|
97
|
-
*/
|
|
98
|
-
static sha512(data, encoding = "hex") {
|
|
99
|
-
const hasher = new Bun.CryptoHasher("sha512");
|
|
100
|
-
hasher.update(data);
|
|
101
|
-
return hasher.digest(encoding);
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* HMAC-SHA512 签名
|
|
105
|
-
* @param key - 密钥
|
|
106
|
-
* @param data - 要签名的数据
|
|
107
|
-
* @param encoding - 输出编码
|
|
108
|
-
* @returns HMAC-SHA512 签名
|
|
109
|
-
*/
|
|
110
|
-
static hmacSha512(key, data, encoding = "hex") {
|
|
111
|
-
const hasher = new Bun.CryptoHasher("sha512", key);
|
|
112
|
-
hasher.update(data);
|
|
113
|
-
return hasher.digest(encoding);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* 通用哈希方法
|
|
117
|
-
* @param algorithm - 算法名称
|
|
118
|
-
* @param data - 要哈希的数据
|
|
119
|
-
* @param encoding - 输出编码
|
|
120
|
-
* @returns 哈希值
|
|
121
|
-
*/
|
|
122
|
-
static hash(algorithm, data, encoding = "hex") {
|
|
123
|
-
const hasher = new Bun.CryptoHasher(algorithm);
|
|
124
|
-
hasher.update(data);
|
|
125
|
-
return hasher.digest(encoding);
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* 通用 HMAC 方法
|
|
129
|
-
* @param algorithm - 算法名称
|
|
130
|
-
* @param key - 密钥
|
|
131
|
-
* @param data - 要签名的数据
|
|
132
|
-
* @param encoding - 输出编码
|
|
133
|
-
* @returns HMAC 签名
|
|
134
|
-
*/
|
|
135
|
-
static hmac(algorithm, key, data, encoding = "hex") {
|
|
136
|
-
const hasher = new Bun.CryptoHasher(algorithm, key);
|
|
137
|
-
hasher.update(data);
|
|
138
|
-
return hasher.digest(encoding);
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* 文件哈希
|
|
142
|
-
* @param filePath - 文件路径
|
|
143
|
-
* @param algorithm - 算法名称
|
|
144
|
-
* @param encoding - 输出编码
|
|
145
|
-
* @returns 文件哈希值
|
|
146
|
-
*/
|
|
147
|
-
static async hashFile(filePath, algorithm = "sha256", encoding = "hex") {
|
|
148
|
-
const file = Bun.file(filePath);
|
|
149
|
-
const hasher = new Bun.CryptoHasher(algorithm);
|
|
150
|
-
const stream = file.stream();
|
|
151
|
-
const reader = stream.getReader();
|
|
152
|
-
try {
|
|
153
|
-
while (true) {
|
|
154
|
-
const { done, value } = await reader.read();
|
|
155
|
-
if (done)
|
|
156
|
-
break;
|
|
157
|
-
hasher.update(value);
|
|
158
|
-
}
|
|
159
|
-
return hasher.digest(encoding);
|
|
160
|
-
}
|
|
161
|
-
finally {
|
|
162
|
-
reader.releaseLock();
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* 密码哈希(使用 bcrypt 算法)
|
|
167
|
-
* @param password - 密码
|
|
168
|
-
* @param options - 选项(可选,支持自定义 cost 参数)
|
|
169
|
-
* @returns 哈希后的密码(固定 60 字符)
|
|
170
|
-
* @example
|
|
171
|
-
* // 默认配置(推荐)
|
|
172
|
-
* const hash = await Cipher.hashPassword('123456');
|
|
173
|
-
*
|
|
174
|
-
* // 自定义强度(可选)
|
|
175
|
-
* const hash = await Cipher.hashPassword('123456', { cost: 12 });
|
|
176
|
-
*/
|
|
177
|
-
static async hashPassword(password, options = {}) {
|
|
178
|
-
// Bun 的类型定义要求 bcrypt 的 algorithm 必须是字面量 "bcrypt"。
|
|
179
|
-
// 这里强制锁定 bcrypt,且不允许 options.algorithm 覆盖。
|
|
180
|
-
const finalOptions = Object.assign({}, options, { algorithm: "bcrypt" });
|
|
181
|
-
return await Bun.password.hash(password, finalOptions);
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* 验证密码
|
|
185
|
-
* @param password - 原始密码
|
|
186
|
-
* @param hash - 存储的哈希值(自动识别算法和提取盐值)
|
|
187
|
-
* @returns 验证结果
|
|
188
|
-
* @example
|
|
189
|
-
* const isValid = await Cipher.verifyPassword('123456', storedHash);
|
|
190
|
-
* if (isValid) {
|
|
191
|
-
* // 密码正确
|
|
192
|
-
* }
|
|
193
|
-
*/
|
|
194
|
-
static async verifyPassword(password, hash) {
|
|
195
|
-
return await Bun.password.verify(password, hash);
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Base64 编码
|
|
199
|
-
* @param data - 要编码的数据
|
|
200
|
-
* @returns Base64 编码的字符串
|
|
201
|
-
*/
|
|
202
|
-
static base64Encode(data) {
|
|
203
|
-
return Buffer.from(data, "utf8").toString("base64");
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Base64 解码
|
|
207
|
-
* @param data - Base64 编码的字符串
|
|
208
|
-
* @returns 解码后的字符串
|
|
209
|
-
*/
|
|
210
|
-
static base64Decode(data) {
|
|
211
|
-
return Buffer.from(data, "base64").toString("utf8");
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* 生成随机十六进制字符串
|
|
215
|
-
* @param length - 字符串长度
|
|
216
|
-
* @returns 随机十六进制字符串
|
|
217
|
-
*/
|
|
218
|
-
static randomString(length) {
|
|
219
|
-
const bytes = Math.ceil(length / 2);
|
|
220
|
-
const randomBytes = crypto.getRandomValues(new Uint8Array(bytes));
|
|
221
|
-
let result = "";
|
|
222
|
-
for (let i = 0; i < randomBytes.length; i++) {
|
|
223
|
-
result += randomBytes[i].toString(16).padStart(2, "0");
|
|
224
|
-
}
|
|
225
|
-
return result.slice(0, length);
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* 快速哈希 (非密码学)
|
|
229
|
-
* @param data - 数据
|
|
230
|
-
* @param seed - 种子值
|
|
231
|
-
* @returns 64位哈希值
|
|
232
|
-
*/
|
|
233
|
-
static fastHash(data, seed = 0) {
|
|
234
|
-
const result = Bun.hash(data, seed);
|
|
235
|
-
return typeof result === "bigint" ? Number(result) : result;
|
|
236
|
-
}
|
|
237
|
-
}
|
package/dist/lib/connect.d.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 数据库连接管理器
|
|
3
|
-
* 统一管理 SQL 和 Redis 连接
|
|
4
|
-
*/
|
|
5
|
-
import type { DatabaseConfig, RedisConfig } from "../types/befly";
|
|
6
|
-
import { SQL, RedisClient } from "bun";
|
|
7
|
-
/**
|
|
8
|
-
* 数据库连接管理器
|
|
9
|
-
* 使用静态方法管理全局单例连接
|
|
10
|
-
*/
|
|
11
|
-
export declare class Connect {
|
|
12
|
-
private static sqlClient;
|
|
13
|
-
private static redisClient;
|
|
14
|
-
private static sqlConnectedAt;
|
|
15
|
-
private static redisConnectedAt;
|
|
16
|
-
private static sqlPoolMax;
|
|
17
|
-
private static mysqlVersionText;
|
|
18
|
-
private static mysqlVersionMajor;
|
|
19
|
-
/**
|
|
20
|
-
* 连接 SQL 数据库
|
|
21
|
-
* @returns SQL 客户端实例
|
|
22
|
-
*/
|
|
23
|
-
static connectSql(dbConfig: DatabaseConfig): Promise<SQL>;
|
|
24
|
-
/**
|
|
25
|
-
* 断开 SQL 连接
|
|
26
|
-
*/
|
|
27
|
-
static disconnectSql(): Promise<void>;
|
|
28
|
-
/**
|
|
29
|
-
* 获取 SQL 客户端实例
|
|
30
|
-
* @throws 如果未连接则抛出错误
|
|
31
|
-
*/
|
|
32
|
-
static getSql(): SQL;
|
|
33
|
-
/**
|
|
34
|
-
* 连接 Redis
|
|
35
|
-
* @returns Redis 客户端实例
|
|
36
|
-
*/
|
|
37
|
-
static connectRedis(redisConfig: RedisConfig): Promise<RedisClient>;
|
|
38
|
-
/**
|
|
39
|
-
* 断开 Redis 连接
|
|
40
|
-
*/
|
|
41
|
-
static disconnectRedis(): Promise<void>;
|
|
42
|
-
/**
|
|
43
|
-
* 获取 Redis 客户端实例
|
|
44
|
-
* @throws 如果未连接则抛出错误
|
|
45
|
-
*/
|
|
46
|
-
static getRedis(): RedisClient;
|
|
47
|
-
/**
|
|
48
|
-
* 连接所有数据库(SQL + Redis)
|
|
49
|
-
*/
|
|
50
|
-
static connect(config: {
|
|
51
|
-
db: DatabaseConfig;
|
|
52
|
-
redis: RedisConfig;
|
|
53
|
-
}): Promise<void>;
|
|
54
|
-
/**
|
|
55
|
-
* 断开所有数据库连接
|
|
56
|
-
*/
|
|
57
|
-
static disconnect(): Promise<void>;
|
|
58
|
-
/**
|
|
59
|
-
* 检查连接状态
|
|
60
|
-
*/
|
|
61
|
-
static isConnected(): {
|
|
62
|
-
sql: boolean;
|
|
63
|
-
redis: boolean;
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* 获取连接状态详细信息(用于监控和调试)
|
|
67
|
-
*/
|
|
68
|
-
static getStatus(): {
|
|
69
|
-
sql: {
|
|
70
|
-
connected: boolean;
|
|
71
|
-
connectedAt: number | null;
|
|
72
|
-
uptime: number | null;
|
|
73
|
-
poolMax: number;
|
|
74
|
-
mysqlVersionText: string | null;
|
|
75
|
-
mysqlVersionMajor: number | null;
|
|
76
|
-
};
|
|
77
|
-
redis: {
|
|
78
|
-
connected: boolean;
|
|
79
|
-
connectedAt: number | null;
|
|
80
|
-
uptime: number | null;
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
/**
|
|
84
|
-
* 设置 mock SQL 客户端(仅用于测试)
|
|
85
|
-
*/
|
|
86
|
-
static __setMockSql(mockClient: SQL): void;
|
|
87
|
-
/**
|
|
88
|
-
* 设置 mock Redis 客户端(仅用于测试)
|
|
89
|
-
*/
|
|
90
|
-
static __setMockRedis(mockClient: RedisClient): void;
|
|
91
|
-
/**
|
|
92
|
-
* 重置所有连接状态(仅用于测试)
|
|
93
|
-
*/
|
|
94
|
-
static __reset(): void;
|
|
95
|
-
}
|
package/dist/lib/connect.js
DELETED
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 数据库连接管理器
|
|
3
|
-
* 统一管理 SQL 和 Redis 连接
|
|
4
|
-
*/
|
|
5
|
-
import { SQL, RedisClient } from "bun";
|
|
6
|
-
import { CoreError } from "../types/coreError";
|
|
7
|
-
import { isCoreError } from "../types/coreError";
|
|
8
|
-
import { Logger } from "./logger";
|
|
9
|
-
/**
|
|
10
|
-
* 数据库连接管理器
|
|
11
|
-
* 使用静态方法管理全局单例连接
|
|
12
|
-
*/
|
|
13
|
-
export class Connect {
|
|
14
|
-
static sqlClient = null;
|
|
15
|
-
static redisClient = null;
|
|
16
|
-
// 连接统计信息
|
|
17
|
-
static sqlConnectedAt = null;
|
|
18
|
-
static redisConnectedAt = null;
|
|
19
|
-
static sqlPoolMax = 1;
|
|
20
|
-
// MySQL 版本信息(用于启动期校验与监控)
|
|
21
|
-
static mysqlVersionText = null;
|
|
22
|
-
static mysqlVersionMajor = null;
|
|
23
|
-
// ========================================
|
|
24
|
-
// SQL 连接管理
|
|
25
|
-
// ========================================
|
|
26
|
-
/**
|
|
27
|
-
* 连接 SQL 数据库
|
|
28
|
-
* @returns SQL 客户端实例
|
|
29
|
-
*/
|
|
30
|
-
static async connectSql(dbConfig) {
|
|
31
|
-
const config = dbConfig || {};
|
|
32
|
-
// 构建 MySQL 连接字符串(不做隐式默认;缺失直接报错,避免连错库/错密码)
|
|
33
|
-
const host = typeof config.host === "string" ? config.host.trim() : "";
|
|
34
|
-
const port = typeof config.port === "number" ? config.port : NaN;
|
|
35
|
-
const username = typeof config.username === "string" ? config.username.trim() : "";
|
|
36
|
-
const password = config.password === undefined ? "" : typeof config.password === "string" ? config.password : "";
|
|
37
|
-
const database = typeof config.database === "string" ? config.database.trim() : "";
|
|
38
|
-
if (!host) {
|
|
39
|
-
throw new CoreError({ message: "数据库配置不完整:db.host 缺失", kind: "validation" });
|
|
40
|
-
}
|
|
41
|
-
if (!Number.isFinite(port) || port < 1 || port > 65535) {
|
|
42
|
-
throw new CoreError({ message: `数据库配置不完整:db.port 非法(当前值:${String(config.port)})`, kind: "validation" });
|
|
43
|
-
}
|
|
44
|
-
if (!username) {
|
|
45
|
-
throw new CoreError({ message: "数据库配置不完整:db.username 缺失", kind: "validation" });
|
|
46
|
-
}
|
|
47
|
-
if (!database) {
|
|
48
|
-
throw new CoreError({ message: "数据库配置不完整:db.database 缺失", kind: "validation" });
|
|
49
|
-
}
|
|
50
|
-
const user = encodeURIComponent(username);
|
|
51
|
-
const pass = encodeURIComponent(password);
|
|
52
|
-
const db = encodeURIComponent(database);
|
|
53
|
-
const finalUrl = `mysql://${user}:${pass}@${host}:${port}/${db}`;
|
|
54
|
-
const sql = new SQL({
|
|
55
|
-
url: finalUrl,
|
|
56
|
-
max: config.poolMax ?? 1,
|
|
57
|
-
bigint: false
|
|
58
|
-
});
|
|
59
|
-
try {
|
|
60
|
-
const timeout = 30000;
|
|
61
|
-
const healthCheckPromise = (async () => {
|
|
62
|
-
const v = await sql `SELECT VERSION() AS version`;
|
|
63
|
-
const versionText = typeof v?.[0]?.version === "string" ? v?.[0]?.version : String(v?.[0]?.version || "");
|
|
64
|
-
// 常见格式:8.0.36 / 8.0.36-xxx
|
|
65
|
-
const majorText = versionText.split(".")[0];
|
|
66
|
-
const major = Number(majorText);
|
|
67
|
-
if (!Number.isFinite(major)) {
|
|
68
|
-
throw new CoreError({ message: `无法解析 MySQL 版本信息: ${versionText}`, kind: "runtime", meta: { subsystem: "sql", operation: "version" } });
|
|
69
|
-
}
|
|
70
|
-
if (major < 8) {
|
|
71
|
-
throw new CoreError({ message: `仅支持 MySQL 8.0+,当前版本:${versionText}`, kind: "policy", meta: { subsystem: "sql", operation: "version" } });
|
|
72
|
-
}
|
|
73
|
-
this.mysqlVersionText = versionText;
|
|
74
|
-
this.mysqlVersionMajor = major;
|
|
75
|
-
return versionText;
|
|
76
|
-
})();
|
|
77
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
78
|
-
setTimeout(() => {
|
|
79
|
-
reject(new Error(`数据库连接超时 (${timeout}ms)`));
|
|
80
|
-
}, timeout);
|
|
81
|
-
});
|
|
82
|
-
await Promise.race([healthCheckPromise, timeoutPromise]);
|
|
83
|
-
this.sqlClient = sql;
|
|
84
|
-
this.sqlConnectedAt = Date.now();
|
|
85
|
-
this.sqlPoolMax = config.poolMax ?? 1;
|
|
86
|
-
return sql;
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
Logger.error({ err: error, msg: "[Connect] SQL 连接失败" });
|
|
90
|
-
try {
|
|
91
|
-
await sql?.close();
|
|
92
|
-
}
|
|
93
|
-
catch { }
|
|
94
|
-
if (isCoreError(error)) {
|
|
95
|
-
error.logged = true;
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
const msg = `SQL 连接失败: ${error && typeof error.message === "string" ? error.message : String(error)}`;
|
|
99
|
-
throw new CoreError({
|
|
100
|
-
message: msg,
|
|
101
|
-
kind: "runtime",
|
|
102
|
-
logged: true,
|
|
103
|
-
cause: error,
|
|
104
|
-
meta: {
|
|
105
|
-
subsystem: "sql",
|
|
106
|
-
operation: "connect"
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* 断开 SQL 连接
|
|
113
|
-
*/
|
|
114
|
-
static async disconnectSql() {
|
|
115
|
-
if (this.sqlClient) {
|
|
116
|
-
try {
|
|
117
|
-
await this.sqlClient.close();
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
Logger.error({ err: error, msg: "[Connect] 关闭 SQL 连接时出错" });
|
|
121
|
-
}
|
|
122
|
-
this.sqlClient = null;
|
|
123
|
-
this.sqlConnectedAt = null;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* 获取 SQL 客户端实例
|
|
128
|
-
* @throws 如果未连接则抛出错误
|
|
129
|
-
*/
|
|
130
|
-
static getSql() {
|
|
131
|
-
if (!this.sqlClient) {
|
|
132
|
-
throw new Error("SQL 客户端未连接,请先调用 Connect.connectSql()");
|
|
133
|
-
}
|
|
134
|
-
return this.sqlClient;
|
|
135
|
-
}
|
|
136
|
-
// ========================================
|
|
137
|
-
// Redis 连接管理
|
|
138
|
-
// ========================================
|
|
139
|
-
/**
|
|
140
|
-
* 连接 Redis
|
|
141
|
-
* @returns Redis 客户端实例
|
|
142
|
-
*/
|
|
143
|
-
static async connectRedis(redisConfig) {
|
|
144
|
-
const config = redisConfig || {};
|
|
145
|
-
try {
|
|
146
|
-
// 构建 Redis URL
|
|
147
|
-
const host = config.host || "127.0.0.1";
|
|
148
|
-
const port = config.port || 6379;
|
|
149
|
-
const username = config.username || "";
|
|
150
|
-
const password = config.password || "";
|
|
151
|
-
const db = config.db || 0;
|
|
152
|
-
let auth = "";
|
|
153
|
-
const encodedUsername = username ? encodeURIComponent(username) : "";
|
|
154
|
-
const encodedPassword = password ? encodeURIComponent(password) : "";
|
|
155
|
-
if (encodedUsername && encodedPassword) {
|
|
156
|
-
auth = `${encodedUsername}:${encodedPassword}@`;
|
|
157
|
-
}
|
|
158
|
-
else if (encodedPassword) {
|
|
159
|
-
auth = `:${encodedPassword}@`;
|
|
160
|
-
}
|
|
161
|
-
const url = `redis://${auth}${host}:${port}/${db}`;
|
|
162
|
-
const redis = new RedisClient(url, {
|
|
163
|
-
connectionTimeout: 30000,
|
|
164
|
-
idleTimeout: 0,
|
|
165
|
-
autoReconnect: true,
|
|
166
|
-
maxRetries: 3,
|
|
167
|
-
enableOfflineQueue: true,
|
|
168
|
-
enableAutoPipelining: true
|
|
169
|
-
});
|
|
170
|
-
await redis.ping();
|
|
171
|
-
this.redisClient = redis;
|
|
172
|
-
this.redisConnectedAt = Date.now();
|
|
173
|
-
return redis;
|
|
174
|
-
}
|
|
175
|
-
catch (error) {
|
|
176
|
-
Logger.error({ err: error, msg: "[Connect] Redis 连接失败" });
|
|
177
|
-
const msg = `Redis 连接失败: ${error && typeof error.message === "string" ? error.message : String(error)}`;
|
|
178
|
-
throw new CoreError({
|
|
179
|
-
message: msg,
|
|
180
|
-
kind: "runtime",
|
|
181
|
-
logged: true,
|
|
182
|
-
cause: error,
|
|
183
|
-
meta: {
|
|
184
|
-
subsystem: "redis",
|
|
185
|
-
operation: "connect"
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* 断开 Redis 连接
|
|
192
|
-
*/
|
|
193
|
-
static async disconnectRedis() {
|
|
194
|
-
if (this.redisClient) {
|
|
195
|
-
try {
|
|
196
|
-
this.redisClient.close();
|
|
197
|
-
this.redisConnectedAt = null;
|
|
198
|
-
}
|
|
199
|
-
catch (error) {
|
|
200
|
-
Logger.error({ err: error, msg: "[Connect] 关闭 Redis 连接时出错" });
|
|
201
|
-
}
|
|
202
|
-
this.redisClient = null;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* 获取 Redis 客户端实例
|
|
207
|
-
* @throws 如果未连接则抛出错误
|
|
208
|
-
*/
|
|
209
|
-
static getRedis() {
|
|
210
|
-
if (!this.redisClient) {
|
|
211
|
-
throw new Error("Redis 客户端未连接,请先调用 Connect.connectRedis()");
|
|
212
|
-
}
|
|
213
|
-
return this.redisClient;
|
|
214
|
-
}
|
|
215
|
-
// ========================================
|
|
216
|
-
// 统一连接管理
|
|
217
|
-
// ========================================
|
|
218
|
-
/**
|
|
219
|
-
* 连接所有数据库(SQL + Redis)
|
|
220
|
-
*/
|
|
221
|
-
static async connect(config) {
|
|
222
|
-
try {
|
|
223
|
-
// 连接 SQL
|
|
224
|
-
await this.connectSql(config.db || {});
|
|
225
|
-
// 连接 Redis
|
|
226
|
-
await this.connectRedis(config.redis || {});
|
|
227
|
-
}
|
|
228
|
-
catch (error) {
|
|
229
|
-
const env = typeof process?.env?.NODE_ENV === "string" ? process.env.NODE_ENV : "";
|
|
230
|
-
Logger.error({ env: env, err: error, msg: "数据库连接初始化失败" });
|
|
231
|
-
await this.disconnect();
|
|
232
|
-
if (isCoreError(error)) {
|
|
233
|
-
error.logged = true;
|
|
234
|
-
throw error;
|
|
235
|
-
}
|
|
236
|
-
const msg = `数据库连接初始化失败: ${error && typeof error.message === "string" ? error.message : String(error)}`;
|
|
237
|
-
throw new CoreError({
|
|
238
|
-
message: msg,
|
|
239
|
-
kind: "runtime",
|
|
240
|
-
logged: true,
|
|
241
|
-
cause: error,
|
|
242
|
-
meta: {
|
|
243
|
-
subsystem: "connect",
|
|
244
|
-
operation: "connect"
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* 断开所有数据库连接
|
|
251
|
-
*/
|
|
252
|
-
static async disconnect() {
|
|
253
|
-
await this.disconnectSql();
|
|
254
|
-
await this.disconnectRedis();
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* 检查连接状态
|
|
258
|
-
*/
|
|
259
|
-
static isConnected() {
|
|
260
|
-
return {
|
|
261
|
-
sql: this.sqlClient !== null,
|
|
262
|
-
redis: this.redisClient !== null
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* 获取连接状态详细信息(用于监控和调试)
|
|
267
|
-
*/
|
|
268
|
-
static getStatus() {
|
|
269
|
-
const now = Date.now();
|
|
270
|
-
return {
|
|
271
|
-
sql: {
|
|
272
|
-
connected: this.sqlClient !== null,
|
|
273
|
-
connectedAt: this.sqlConnectedAt,
|
|
274
|
-
uptime: this.sqlConnectedAt ? now - this.sqlConnectedAt : null,
|
|
275
|
-
poolMax: this.sqlPoolMax,
|
|
276
|
-
mysqlVersionText: this.mysqlVersionText,
|
|
277
|
-
mysqlVersionMajor: this.mysqlVersionMajor
|
|
278
|
-
},
|
|
279
|
-
redis: {
|
|
280
|
-
connected: this.redisClient !== null,
|
|
281
|
-
connectedAt: this.redisConnectedAt,
|
|
282
|
-
uptime: this.redisConnectedAt ? now - this.redisConnectedAt : null
|
|
283
|
-
}
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
// ========================================
|
|
287
|
-
// 测试辅助方法
|
|
288
|
-
// ========================================
|
|
289
|
-
/**
|
|
290
|
-
* 设置 mock SQL 客户端(仅用于测试)
|
|
291
|
-
*/
|
|
292
|
-
static __setMockSql(mockClient) {
|
|
293
|
-
this.sqlClient = mockClient;
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* 设置 mock Redis 客户端(仅用于测试)
|
|
297
|
-
*/
|
|
298
|
-
static __setMockRedis(mockClient) {
|
|
299
|
-
this.redisClient = mockClient;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* 重置所有连接状态(仅用于测试)
|
|
303
|
-
*/
|
|
304
|
-
static __reset() {
|
|
305
|
-
this.sqlClient = null;
|
|
306
|
-
this.redisClient = null;
|
|
307
|
-
this.sqlConnectedAt = null;
|
|
308
|
-
this.redisConnectedAt = null;
|
|
309
|
-
this.sqlPoolMax = 1;
|
|
310
|
-
this.mysqlVersionText = null;
|
|
311
|
-
this.mysqlVersionMajor = null;
|
|
312
|
-
}
|
|
313
|
-
}
|