chanjs 2.7.2 → 2.7.4

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 (67) hide show
  1. package/App.js +232 -16
  2. package/base/Aop.js +20 -3
  3. package/base/Container.js +80 -3
  4. package/base/Controller.js +38 -9
  5. package/base/Database.js +50 -0
  6. package/base/Event.js +12 -0
  7. package/base/{Service.js → Repository.js} +644 -539
  8. package/common/api.js +18 -8
  9. package/common/code.js +25 -15
  10. package/common/email.js +98 -17
  11. package/common/index.js +1 -1
  12. package/config/code.js +138 -82
  13. package/global/index.js +1 -1
  14. package/helper/index.js +43 -41
  15. package/index.js +19 -6
  16. package/loader/index.js +6 -0
  17. package/{helper → loader}/loader.js +41 -27
  18. package/middleware/compress.js +185 -0
  19. package/middleware/cors.js +36 -24
  20. package/middleware/header.js +5 -10
  21. package/middleware/index.js +1 -0
  22. package/middleware/log.js +27 -3
  23. package/middleware/setBody.js +9 -1
  24. package/middleware/static.js +2 -1
  25. package/middleware/template.js +139 -4
  26. package/middleware/waf.js +136 -76
  27. package/package.json +4 -4
  28. package/realtime/index.js +7 -0
  29. package/realtime/sse.js +424 -0
  30. package/realtime/websocket.js +540 -0
  31. package/response/index.js +12 -0
  32. package/response/response.js +258 -0
  33. package/schedule/index.js +6 -0
  34. package/schedule/schedule.js +491 -0
  35. package/{helper → security}/checker.js +23 -8
  36. package/security/index.js +14 -0
  37. package/{helper → security}/jwt.js +175 -107
  38. package/security/keywords.js +179 -0
  39. package/security/rate-limit.js +105 -0
  40. package/security/sign.js +210 -0
  41. package/security/xss-filter.js +63 -0
  42. package/storage/cache.js +258 -0
  43. package/storage/index.js +9 -0
  44. package/storage/redis.js +258 -0
  45. package/storage/store.js +266 -0
  46. package/{helper → utils}/file.js +106 -15
  47. package/{helper → utils}/filter.js +2 -1
  48. package/{helper → utils}/html.js +19 -1
  49. package/utils/index.js +34 -0
  50. package/{helper → utils}/ip.js +25 -16
  51. package/utils/request.js +172 -0
  52. package/{helper → utils}/time.js +1 -1
  53. package/utils/tree.js +121 -0
  54. package/common/category.js +0 -22
  55. package/common/sms.js +0 -104
  56. package/extend/art-template.js +0 -129
  57. package/extend/index.js +0 -6
  58. package/global/global.js +0 -63
  59. package/helper/cache.js +0 -187
  60. package/helper/keywords.js +0 -132
  61. package/helper/rate-limit.js +0 -116
  62. package/helper/request.js +0 -47
  63. package/helper/response.js +0 -180
  64. package/helper/sign.js +0 -96
  65. package/helper/tree.js +0 -77
  66. package/helper/xss-filter.js +0 -42
  67. /package/{helper → utils}/data-parse.js +0 -0
@@ -0,0 +1,258 @@
1
+ import {
2
+ CODE,
3
+ DB_ERROR,
4
+ CODE_OK,
5
+ CODE_BUSINESS_FAIL,
6
+ CODE_SYSTEM_ERROR,
7
+ CODE_NOT_FOUND,
8
+ getCodeMsg,
9
+ } from "../config/code.js";
10
+
11
+ /**
12
+ * 响应工具函数
13
+ * 提供统一的响应格式和错误处理
14
+ *
15
+ * ============================================================
16
+ * 统一响应格式(三层 code 体系)
17
+ * ============================================================
18
+ * 所有响应都遵循以下结构:
19
+ * {
20
+ * success: boolean, // 业务是否成功(true/false)
21
+ * code: number, // 业务 code(0 成功 / 1xxx 业务 / 5xxx 系统 / 6xxx 数据库)
22
+ * msg: string, // 用户可见消息
23
+ * data: any // 业务数据
24
+ * }
25
+ *
26
+ * HTTP Status 与业务 code 解耦:
27
+ * - HTTP Status 由网关/Express 控制(200/400/401/403/404/500)
28
+ * - 业务 code 由业务层控制(0 / 1xxx / 5xxx / 6xxx)
29
+ * - 前端先看 HTTP Status,再看业务 code
30
+ *
31
+ * ============================================================
32
+ * 使用示例
33
+ * ============================================================
34
+ * // 成功
35
+ * success({ data: { list: [] } })
36
+ * // → { success: true, code: 0, msg: '操作成功', data: { list: [] } }
37
+ *
38
+ * // 业务失败(通用)
39
+ * fail({ msg: '栏目下存在文章' })
40
+ * // → { success: false, code: 1008, msg: '栏目下存在文章', data: {} }
41
+ *
42
+ * // 业务失败(指定 code)
43
+ * fail({ msg: '参数缺失', code: 1007 })
44
+ * // → { success: false, code: 1007, msg: '参数缺失', data: {} }
45
+ *
46
+ * // 错误(系统/数据库异常,err 必传)
47
+ * error({ err: dbError })
48
+ * // → { success: false, code: 6005, msg: '数据重复', data: {} }
49
+ */
50
+
51
+ /**
52
+ * 错误消息映射(数据库错误码专用)
53
+ * 与 CODE 字典保持一致,独立出来便于按 code 取消息
54
+ * @private
55
+ */
56
+ const ERROR_MESSAGES = CODE;
57
+
58
+ /**
59
+ * 是否暴露错误详情(sql/stack)
60
+ * 显式环境变量控制,避免 development 模式自动暴露敏感信息
61
+ * - 默认 false:生产/开发都不暴露
62
+ * - 设 EXPOSE_ERR_DETAIL=true 后才返回 sql/stack/message 等详细信息
63
+ * @private
64
+ */
65
+ const EXPOSE_ERR_DETAIL = process.env.EXPOSE_ERR_DETAIL === 'true';
66
+
67
+ /**
68
+ * 根据错误对象推断业务 code
69
+ * @private
70
+ * @param {Error} error - 错误对象
71
+ * @returns {number} 业务 code
72
+ */
73
+ const inferErrorCode = (error) => {
74
+ if (!error?.message) return CODE_SYSTEM_ERROR;
75
+
76
+ const msg = error.message.toLowerCase();
77
+ if (msg.includes("syntax") || msg.includes("sql")) {
78
+ return 6008; // 数据库语法错误
79
+ }
80
+ if (msg.includes("connection closed") || msg.includes("connection lost")) {
81
+ return 6009; // 数据库连接关闭
82
+ }
83
+ if (msg.includes("permission") || msg.includes("access denied")) {
84
+ return 1003; // 权限不足
85
+ }
86
+ return CODE_SYSTEM_ERROR;
87
+ };
88
+
89
+ /**
90
+ * 解析数据库错误
91
+ * @param {Error} error - 数据库错误对象
92
+ * @returns {{code: number, msg: string, statusCode: number}} 包含 code、msg 和 HTTP statusCode
93
+ * @description
94
+ * 将数据库原生错误码映射为业务 code,并给出对应的 HTTP statusCode
95
+ * - 6xxx 数据库错误 → HTTP 500
96
+ * - 1xxx 业务错误 → HTTP 400
97
+ * - 其他 → HTTP 500
98
+ */
99
+ export function parseDatabaseError(error) {
100
+ let errorCode;
101
+ if (error?.code && DB_ERROR[error.code]) {
102
+ errorCode = DB_ERROR[error.code];
103
+ } else {
104
+ errorCode = inferErrorCode(error);
105
+ }
106
+
107
+ // 根据 code 段位决定 HTTP statusCode
108
+ let statusCode;
109
+ if (errorCode >= 6000) {
110
+ statusCode = 500; // 数据库错误 → 500
111
+ } else if (errorCode >= 5000) {
112
+ statusCode = 500; // 系统错误 → 500
113
+ } else if (errorCode >= 1000) {
114
+ statusCode = 400; // 业务错误 → 400
115
+ } else {
116
+ statusCode = 500; // 兜底
117
+ }
118
+
119
+ return {
120
+ code: errorCode,
121
+ msg: ERROR_MESSAGES[errorCode] || error?.message || "服务器内部错误",
122
+ statusCode,
123
+ };
124
+ }
125
+
126
+ /**
127
+ * 生成错误响应(系统/数据库异常用)
128
+ * @param {Object} options - 响应选项
129
+ * @param {Error} [options.err] - 错误对象(必传,用于解析 code)
130
+ * @param {Object} [options.data={}] - 响应数据
131
+ * @param {number} [options.code=5001] - 错误 code(err 为空时使用)
132
+ * @returns {Object} 错误响应对象
133
+ * @description
134
+ * - 传 err:自动解析数据库错误码并映射为业务 code
135
+ * - 不传 err:使用传入的 code 或默认 5001
136
+ * 开发环境下(NODE_ENV=development)附带数据库错误详情
137
+ */
138
+ export const error = ({ err, data = {}, code = CODE_SYSTEM_ERROR } = {}) => {
139
+ if (err) {
140
+ console.error("[DB Error]", err?.message || err);
141
+ const errorCode = err?.code && DB_ERROR[err.code]
142
+ ? DB_ERROR[err.code]
143
+ : inferErrorCode(err);
144
+ const msg = ERROR_MESSAGES[errorCode] || "操作失败";
145
+
146
+ return {
147
+ success: false,
148
+ msg,
149
+ code: errorCode,
150
+ data: EXPOSE_ERR_DETAIL ? {
151
+ sql: err?.sql,
152
+ sqlMessage: err?.sqlMessage,
153
+ message: err?.message,
154
+ } : {},
155
+ };
156
+ }
157
+
158
+ const msg = getCodeMsg(code, "操作失败");
159
+ return {
160
+ success: false,
161
+ msg,
162
+ code,
163
+ data,
164
+ };
165
+ };
166
+
167
+ /**
168
+ * 生成失败响应(业务失败用)
169
+ * @param {Object} options - 响应选项
170
+ * @param {string} [options.msg="操作失败"] - 错误消息
171
+ * @param {Object} [options.data={}] - 响应数据
172
+ * @param {number} [options.code=1008] - 业务 code(默认 1008 业务处理失败)
173
+ * @returns {Object} 失败响应对象
174
+ * @description
175
+ * 用于业务逻辑失败(如:栏目下存在文章、参数缺失等)
176
+ * 与 error() 区别:fail 用于业务可恢复错误,error 用于系统/数据库异常
177
+ *
178
+ * @example
179
+ * fail({ msg: '栏目下存在文章' }) // → code: 1008
180
+ * fail({ msg: '参数缺失', code: 1007 }) // → code: 1007
181
+ * fail({ msg: '权限不足', code: 1003 }) // → code: 1003
182
+ */
183
+ export const fail = ({ msg = "操作失败", data = {}, code = CODE_BUSINESS_FAIL } = {}) => {
184
+ return {
185
+ success: false,
186
+ msg,
187
+ code,
188
+ data,
189
+ };
190
+ };
191
+
192
+ /**
193
+ * 生成成功响应
194
+ * @param {Object} options - 响应选项
195
+ * @param {Object} [options.data={}] - 响应数据
196
+ * @param {string} [options.msg="操作成功"] - 成功消息
197
+ * @returns {Object} 成功响应对象
198
+ * @description
199
+ * code 固定为 0(不再用 200,避免与 HTTP 200 混淆)
200
+ */
201
+ export const success = ({ data = {}, msg = "操作成功" } = {}) => ({
202
+ success: true,
203
+ msg,
204
+ code: CODE_OK,
205
+ data,
206
+ });
207
+
208
+ /**
209
+ * 生成 404 响应(接口不存在)
210
+ * @param {Object} req - Express 请求对象
211
+ * @returns {Object} 404 响应对象
212
+ * @description
213
+ * HTTP Status 404,业务 code 1004
214
+ */
215
+ export function notFoundResponse(req) {
216
+ return {
217
+ success: false,
218
+ msg: "接口不存在",
219
+ code: CODE_NOT_FOUND,
220
+ data: { path: req.path, method: req.method },
221
+ };
222
+ }
223
+
224
+ /**
225
+ * 生成错误响应(Express 错误处理中间件用)
226
+ * @param {Error} err - 错误对象
227
+ * @param {Object} req - Express 请求对象
228
+ * @returns {Object} 错误响应对象
229
+ * @description
230
+ * 用于 Express 全局错误处理中间件
231
+ * 自动解析数据库错误并映射为业务 code
232
+ */
233
+ export function errorResponse(err, req) {
234
+ const errorInfo = parseDatabaseError(err);
235
+
236
+ console.error(`[Error Handler] ${errorInfo.msg} - ${err?.message}`, {
237
+ code: errorInfo.code,
238
+ path: req?.path,
239
+ method: req?.method,
240
+ sql: err?.sql,
241
+ sqlMessage: err?.sqlMessage,
242
+ stack: err?.stack,
243
+ });
244
+
245
+ return {
246
+ success: false,
247
+ msg: errorInfo.msg,
248
+ code: errorInfo.code,
249
+ data: EXPOSE_ERR_DETAIL
250
+ ? {
251
+ message: err?.message,
252
+ sql: err?.sql,
253
+ sqlMessage: err?.sqlMessage,
254
+ stack: err?.stack,
255
+ }
256
+ : {},
257
+ };
258
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 定时任务模块 - 支持 cron / every / delay
3
+ * 错误隔离 + 优雅停机
4
+ */
5
+ export { default as Schedule } from "./schedule.js";
6
+ export { schedule } from "./schedule.js";