chanjs 2.3.0 → 2.5.0

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/helper/db.js DELETED
@@ -1,79 +0,0 @@
1
- import knex from "knex";
2
-
3
- /**
4
- * 创建 Knex 数据库连接实例
5
- * @param {Object} config - 数据库配置对象
6
- * @param {string} config.client - 数据库客户端类型(如 mysql2, pg, sqlite3)
7
- * @param {Object} config.connection - 数据库连接配置
8
- * @param {Object} [config.pool] - 连接池配置
9
- * @returns {Knex} Knex 实例
10
- * @example
11
- * const db = db({
12
- * client: 'mysql2',
13
- * connection: {
14
- * host: 'localhost',
15
- * user: 'root',
16
- * password: 'password',
17
- * database: 'mydb'
18
- * }
19
- * });
20
- */
21
- export function db(config) {
22
- return knex(config);
23
- }
24
-
25
- /**
26
- * 根据前缀从环境变量中获取数据库配置
27
- * @param {string} prefix - 配置前缀(如 primary, secondary, redis)
28
- * @returns {Object|null} 解析后的配置对象,如果配置不存在或解析失败则返回 null
29
- * @description
30
- * 支持的前缀映射:
31
- * - primary -> DB_PRIMARY
32
- * - secondary -> DB_SECONDARY
33
- * - redis -> REDIS
34
- * - 其他 -> DB_{PREFIX.toUpperCase()}
35
- *
36
- * 配置格式为 JSON 字符串,存储在环境变量中
37
- * @example
38
- * // 环境变量: DB_PRIMARY='{"client":"mysql2","connection":{"host":"localhost"}}'
39
- * const config = prefixDbConfig('primary');
40
- * // 返回: { client: 'mysql2', connection: { host: 'localhost' } }
41
- */
42
- export function prefixDbConfig(prefix) {
43
- const prefixMap = {
44
- primary: "DB_PRIMARY",
45
- secondary: "DB_SECONDARY",
46
- redis: "REDIS",
47
- };
48
- const envKey = prefixMap[prefix] || `DB_${prefix.toUpperCase()}`;
49
- const configStr = process.env[envKey];
50
-
51
- if (configStr) {
52
- try {
53
- return JSON.parse(configStr);
54
- } catch (e) {
55
- console.error(`[DB] 配置解析失败: ${envKey}`);
56
- return null;
57
- }
58
- }
59
-
60
- const client = process.env.DB_CLIENT || "mysql2";
61
- if (client !== "mysql2") {
62
- return null;
63
- }
64
-
65
- return {
66
- client,
67
- connection: {
68
- host: process.env.DB_HOST || "localhost",
69
- port: parseInt(process.env.DB_PORT || "3306"),
70
- user: process.env.DB_USER || "root",
71
- password: process.env.DB_PASS || "123456",
72
- database: process.env.DB_DATABASE || "chancms"
73
- },
74
- pool: {
75
- min: parseInt(process.env.DB_POOL_MIN || "2"),
76
- max: parseInt(process.env.DB_POOL_MAX || "10")
77
- }
78
- };
79
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * 防止快速重复请求中间件
3
- * 使用 Cache 实现请求频率限制
4
- */
5
-
6
- import Cache from "../helper/cache.js";
7
-
8
- const sendResponse = (res, code, message, data = null) => {
9
- res.json({ code, msg: message, data });
10
- };
11
-
12
- const requestCache = new Cache({ maxSize: 1000, defaultTTL: 500 });
13
-
14
- export default () => {
15
- return (req, res, next) => {
16
- if (req.method !== 'GET') {
17
- return next();
18
- }
19
-
20
- const key = `${req.method}:${req.originalUrl}`;
21
-
22
- if (requestCache.has(key)) {
23
- console.log(`[preventRetry] 阻止快速重复请求: ${key}`);
24
- return sendResponse(res, 429, '请求过于频繁,请稍后再试');
25
- }
26
-
27
- requestCache.set(key, Date.now());
28
- next();
29
- };
30
- };
@@ -1,43 +0,0 @@
1
- /**
2
- * 请求验证中间件
3
- * 提供请求参数验证功能
4
- */
5
-
6
- /**
7
- * 创建验证中间件
8
- * @param {Object} schemas - 验证规则对象
9
- * @param {Object} [schemas.headers] - 请求头验证规则
10
- * @param {Object} [schemas.params] - 路径参数验证规则
11
- * @param {Object} [schemas.query] - 查询参数验证规则
12
- * @param {Object} [schemas.body] - 请求体验证规则
13
- * @returns {Function} Express 中间件函数
14
- * @description
15
- * 验证请求的 headers、params、query 和 body
16
- * 使用 Zod 风格的验证规则
17
- * 验证失败返回 400 状态码和错误信息
18
- * @example
19
- * const schema = {
20
- * body: z.object({ name: z.string() })
21
- * };
22
- * app.use(validator(schema));
23
- */
24
- export const validator = (schemas) => (req, res, next) => {
25
- const sections = {
26
- headers: schemas.headers,
27
- params: schemas.params,
28
- query: schemas.query,
29
- body: schemas.body,
30
- };
31
-
32
- for (const [key, schema] of Object.entries(sections)) {
33
- if (!schema) continue;
34
-
35
- const result = schema.safeParse(req[key]);
36
- if (!result.success) {
37
- const firstError = result.error.errors[0];
38
- return res.status(400).json({ error: firstError.message });
39
- }
40
- req[key] = result.data;
41
- }
42
- next();
43
- };
@@ -1,115 +0,0 @@
1
- /**
2
- * 数据库错误处理工具
3
- * 提供数据库错误解析和错误响应生成功能
4
- */
5
-
6
- export const DB_ERROR = {
7
- ECONNREFUSED: 6001,
8
- ER_ACCESS_DENIED_ERROR: 6002,
9
- ER_ROW_IS_REFERENCED_2: 6003,
10
- ER_BAD_FIELD_ERROR: 6004,
11
- ER_DUP_ENTRY: 6005,
12
- ER_NO_SUCH_TABLE: 6006,
13
- ETIMEOUT: 6007,
14
- ER_TABLE_EXISTS_ERROR: 4003,
15
- };
16
-
17
- export const ERROR_MESSAGES = {
18
- 6001: "数据库连接失败",
19
- 6002: "数据库访问被拒绝",
20
- 6003: "存在关联数据,操作失败",
21
- 6004: "数据库字段错误",
22
- 6005: "数据重复,违反唯一性约束",
23
- 6006: "目标表不存在",
24
- 6007: "数据库操作超时",
25
- 6008: "数据库语法错误,请检查查询语句",
26
- 6009: "数据库连接已关闭,请重试",
27
- 4003: "资源已存在",
28
- 5001: "系统内部错误",
29
- };
30
-
31
- /**
32
- * 解析数据库错误
33
- * @param {Error} error - 数据库错误对象
34
- * @returns {Object} 包含 code、msg 和 statusCode 的对象
35
- * @description
36
- * 根据数据库错误代码映射为业务状态码
37
- * 返回对应的错误消息和 HTTP 状态码
38
- * @example
39
- * const errorInfo = parseDatabaseError({ code: 'ER_DUP_ENTRY' });
40
- * console.log(errorInfo); // { code: 6005, msg: '数据重复...', statusCode: 500 }
41
- */
42
- export function parseDatabaseError(error) {
43
- const errorCode = error?.code && DB_ERROR[error.code]
44
- ? DB_ERROR[error.code]
45
- : error?.message?.includes("syntax") || error?.message?.includes("SQL")
46
- ? 6008
47
- : error?.message?.includes("Connection closed")
48
- ? 6009
49
- : error?.message?.includes("permission")
50
- ? 3003
51
- : 5001;
52
-
53
- return {
54
- code: errorCode,
55
- msg: ERROR_MESSAGES[errorCode] || error?.message || "服务器内部错误",
56
- statusCode: errorCode >= 6000 ? 500 : errorCode >= 4000 ? 400 : 500,
57
- };
58
- }
59
-
60
- /**
61
- * 生成 404 响应
62
- * @param {Object} req - Express 请求对象
63
- * @returns {Object} 404 响应对象
64
- * @description
65
- * 返回标准的接口不存在响应
66
- * 包含请求的路径和方法
67
- * @example
68
- * const response = notFoundResponse(req);
69
- */
70
- export function notFoundResponse(req) {
71
- return {
72
- success: false,
73
- msg: "接口不存在",
74
- code: 404,
75
- data: { path: req.path, method: req.method },
76
- };
77
- }
78
-
79
- /**
80
- * 生成错误响应
81
- * @param {Error} err - 错误对象
82
- * @param {Object} req - Express 请求对象
83
- * @returns {Object} 错误响应对象
84
- * @description
85
- * 根据错误类型生成相应的错误响应
86
- * 开发环境下包含详细的错误信息
87
- * @example
88
- * const response = errorResponse(error, req);
89
- */
90
- export function errorResponse(err, req) {
91
- const errorInfo = parseDatabaseError(err);
92
-
93
- console.error(`[Error Handler] ${errorInfo.msg} - ${err?.message}`, {
94
- code: errorInfo.code,
95
- path: req?.path,
96
- method: req?.method,
97
- sql: err?.sql,
98
- sqlMessage: err?.sqlMessage,
99
- stack: err?.stack,
100
- });
101
-
102
- return {
103
- success: false,
104
- msg: errorInfo.msg,
105
- code: errorInfo.code,
106
- data: process.env.NODE_ENV === "development"
107
- ? {
108
- message: err?.message,
109
- sql: err?.sql,
110
- sqlMessage: err?.sqlMessage,
111
- stack: err?.stack,
112
- }
113
- : {},
114
- };
115
- }
package/utils/error.js DELETED
@@ -1,81 +0,0 @@
1
- /**
2
- * 错误处理和日志工具
3
- * 提供错误码定义和错误日志记录功能
4
- */
5
-
6
- export const CODE = {
7
- SUCCESS: { code: 200, message: "操作成功" },
8
- FAIL: { code: 201, message: "操作失败" },
9
- ERROR: { code: 500, message: "服务器错误" },
10
- UNAUTHORIZED: { code: 401, message: "未授权" },
11
- FORBIDDEN: { code: 403, message: "禁止访问" },
12
- NOT_FOUND: { code: 404, message: "资源不存在" },
13
- VALIDATION: { code: 400, message: "参数校验失败" },
14
- CONFIG: { code: 500, message: "配置错误" },
15
- };
16
-
17
- /**
18
- * 记录错误日志
19
- * @private
20
- * @param {string} type - 错误类型
21
- * @param {string} message - 错误消息
22
- * @param {Object} [extra={}] - 额外信息
23
- * @description
24
- * 将错误信息格式化为 JSON 并输出到控制台
25
- * 包含时间戳、错误类型和消息
26
- */
27
- function logError(type, message, extra = {}) {
28
- const timestamp = new Date().toISOString();
29
- console.error(JSON.stringify({
30
- timestamp,
31
- type,
32
- message,
33
- ...extra,
34
- }));
35
- }
36
-
37
- /**
38
- * 创建错误对象
39
- * @private
40
- * @param {string} message - 错误消息
41
- * @param {number} [statusCode=500] - HTTP 状态码
42
- * @param {string} [code="ERROR"] - 错误代码
43
- * @returns {Object} 错误对象
44
- */
45
- function createError(message, statusCode = 500, code = "ERROR") {
46
- logError(code, message, { statusCode });
47
- return {
48
- isError: true,
49
- message,
50
- statusCode,
51
- code,
52
- };
53
- }
54
-
55
- /**
56
- * 生成配置错误
57
- * @param {string} message - 错误消息
58
- * @returns {Object} 配置错误对象
59
- * @description
60
- * 生成配置类型错误并记录日志
61
- * @example
62
- * const error = configError('数据库配置缺失');
63
- */
64
- export function configError(message) {
65
- logError("CONFIG_ERROR", message);
66
- return createError(message, CODE.CONFIG.code, "CONFIG_ERROR");
67
- }
68
-
69
- /**
70
- * 生成认证错误
71
- * @param {string} [message=CODE.UNAUTHORIZED.message] - 错误消息
72
- * @returns {Object} 认证错误对象
73
- * @description
74
- * 生成认证类型错误并记录日志
75
- * @example
76
- * const error = authError('Token已过期');
77
- */
78
- export function authError(message = CODE.UNAUTHORIZED.message) {
79
- logError("AUTH_ERROR", message);
80
- return createError(message, CODE.UNAUTHORIZED.code, "AUTH_ERROR");
81
- }