chanjs 2.1.1 → 2.3.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.
Files changed (61) hide show
  1. package/App.js +387 -0
  2. package/base/Context.js +78 -0
  3. package/base/Controller.js +137 -0
  4. package/base/Database.js +314 -0
  5. package/base/Service.js +539 -0
  6. package/common/api.js +25 -0
  7. package/common/category.js +22 -0
  8. package/common/code.js +42 -0
  9. package/common/email.js +110 -0
  10. package/common/index.js +7 -0
  11. package/common/pages.js +86 -0
  12. package/common/sms.js +104 -0
  13. package/common/utils.js +73 -0
  14. package/config/code.js +110 -52
  15. package/config/index.js +10 -0
  16. package/config/paths.js +60 -0
  17. package/extend/art-template.js +46 -28
  18. package/extend/index.js +6 -0
  19. package/global/env.js +11 -5
  20. package/global/global.js +63 -39
  21. package/global/import.js +43 -39
  22. package/global/index.js +8 -3
  23. package/helper/cache.js +182 -0
  24. package/helper/data-parse.js +121 -37
  25. package/helper/db.js +71 -83
  26. package/helper/file.js +158 -208
  27. package/helper/filter.js +34 -0
  28. package/helper/html.js +30 -47
  29. package/helper/index.js +29 -5
  30. package/helper/ip.js +48 -31
  31. package/helper/jwt.js +78 -11
  32. package/helper/loader.js +93 -50
  33. package/helper/request.js +41 -144
  34. package/helper/sign.js +96 -33
  35. package/helper/time.js +89 -74
  36. package/helper/tree.js +77 -0
  37. package/index.js +15 -181
  38. package/middleware/cookie.js +20 -4
  39. package/middleware/cors.js +20 -0
  40. package/middleware/favicon.js +21 -5
  41. package/middleware/header.js +26 -9
  42. package/middleware/index.js +14 -23
  43. package/middleware/preventRetry.js +30 -0
  44. package/middleware/setBody.js +24 -10
  45. package/middleware/static.js +31 -10
  46. package/middleware/template.js +34 -14
  47. package/middleware/validator.js +43 -23
  48. package/middleware/waf.js +147 -287
  49. package/package.json +1 -1
  50. package/utils/checker.js +68 -0
  51. package/utils/error-handler.js +115 -0
  52. package/utils/error.js +81 -0
  53. package/utils/index.js +6 -0
  54. package/utils/keywords.js +126 -0
  55. package/utils/rate-limit.js +116 -0
  56. package/utils/response.js +103 -64
  57. package/utils/xss-filter.js +42 -0
  58. package/core/controller.js +0 -33
  59. package/core/index.js +0 -3
  60. package/core/service.js +0 -307
  61. package/middleware/log.js +0 -21
@@ -0,0 +1,314 @@
1
+ import knex from "knex";
2
+
3
+ /**
4
+ * 数据库管理器类
5
+ * 用于管理多个数据库连接和创建数据模型
6
+ */
7
+ class DatabaseManager {
8
+ /**
9
+ * 构造函数
10
+ * 初始化数据库连接存储和默认连接名称
11
+ */
12
+ constructor() {
13
+ this._connections = new Map();
14
+ this._defaultName = "default";
15
+ }
16
+
17
+ /**
18
+ * 添加数据库连接
19
+ * @param {string} name - 连接名称
20
+ * @param {Object} config - Knex配置对象
21
+ * @param {Object} options - 选项
22
+ * @param {boolean} options.isDefault - 是否设为默认连接
23
+ * @returns {Object} Knex连接实例
24
+ */
25
+ add(name, config, options = {}) {
26
+ const { isDefault = false } = options;
27
+
28
+ const connection = knex(config);
29
+ this._connections.set(name, connection);
30
+
31
+ if (isDefault || this._connections.size === 1) {
32
+ this._defaultName = name;
33
+ }
34
+
35
+ return connection;
36
+ }
37
+
38
+ /**
39
+ * 获取数据库连接
40
+ * @param {string} name - 连接名称,默认为默认连接
41
+ * @returns {Object} Knex连接实例
42
+ * @throws {Error} 连接不存在时抛出异常
43
+ */
44
+ get(name = this._defaultName) {
45
+ const connection = this._connections.get(name);
46
+ if (!connection) {
47
+ throw new Error(`Database connection "${name}" not found`);
48
+ }
49
+ return connection;
50
+ }
51
+
52
+ /**
53
+ * 获取默认数据库连接
54
+ * @returns {Object} Knex连接实例
55
+ */
56
+ getDefault() {
57
+ return this.get(this._defaultName);
58
+ }
59
+
60
+ /**
61
+ * 检查连接是否存在
62
+ * @param {string} name - 连接名称
63
+ * @returns {boolean} 是否存在
64
+ */
65
+ has(name) {
66
+ return this._connections.has(name);
67
+ }
68
+
69
+ /**
70
+ * 移除数据库连接
71
+ * @param {string} name - 连接名称
72
+ */
73
+ remove(name) {
74
+ const connection = this._connections.get(name);
75
+ if (connection) {
76
+ connection.destroy();
77
+ this._connections.delete(name);
78
+ }
79
+ }
80
+
81
+ /**
82
+ * 关闭所有数据库连接
83
+ * @returns {Promise<void>}
84
+ */
85
+ async closeAll() {
86
+ const closePromises = [];
87
+ for (const [name, connection] of this._connections) {
88
+ closePromises.push(
89
+ connection.destroy().catch((err) => {
90
+ console.error(`Error closing database "${name}":`, err);
91
+ })
92
+ );
93
+ }
94
+ await Promise.all(closePromises);
95
+ this._connections.clear();
96
+ }
97
+
98
+ /**
99
+ * 获取所有连接名称
100
+ * @returns {Array<string>} 连接名称数组
101
+ */
102
+ getConnections() {
103
+ return Array.from(this._connections.keys());
104
+ }
105
+
106
+ /**
107
+ * 创建数据模型
108
+ * @param {string} name - 模型名称
109
+ * @param {string} tableName - 表名
110
+ * @param {string} connectionName - 连接名称
111
+ * @returns {Object} 模型对象
112
+ */
113
+ createModel(name, tableName, connectionName) {
114
+ const db = this.get(connectionName);
115
+ return {
116
+ db,
117
+ tableName,
118
+
119
+ /**
120
+ * 查询字段
121
+ * @param {string} fields - 字段列表,默认"*"
122
+ * @returns {Object} Knex查询构建器
123
+ */
124
+ select(fields = "*") {
125
+ return db(this.tableName).select(fields);
126
+ },
127
+
128
+ /**
129
+ * 条件查询
130
+ * @param {Object} conditions - 查询条件
131
+ * @returns {Object} Knex查询构建器
132
+ */
133
+ where(conditions) {
134
+ return db(this.tableName).where(conditions);
135
+ },
136
+
137
+ /**
138
+ * 查找记录
139
+ * @param {Object} query - 查询参数
140
+ * @param {Object} query.sort - 排序条件
141
+ * @param {Object} query.where - 查询条件
142
+ * @returns {Promise<Array>} 查询结果数组
143
+ */
144
+ find(query = {}) {
145
+ let q = db(this.tableName);
146
+ const { sort, ...where } = query;
147
+
148
+ if (Object.keys(where).length > 0) {
149
+ q = q.where(where);
150
+ }
151
+
152
+ if (sort && typeof sort === "object") {
153
+ for (const [field, dir] of Object.entries(sort)) {
154
+ q = q.orderBy(field, dir);
155
+ }
156
+ }
157
+
158
+ return q.select();
159
+ },
160
+
161
+ /**
162
+ * 查找单条记录
163
+ * @param {Object} query - 查询条件
164
+ * @returns {Promise<Object|null>} 查询结果或null
165
+ */
166
+ findOne(query = {}) {
167
+ let q = db(this.tableName);
168
+ if (Object.keys(query).length > 0) {
169
+ q = q.where(query);
170
+ }
171
+ return q.first();
172
+ },
173
+
174
+ /**
175
+ * 根据ID查找记录
176
+ * @param {number|string} id - 记录ID
177
+ * @returns {Promise<Object|null>} 查询结果或null
178
+ */
179
+ findById(id) {
180
+ return db(this.tableName).where({ id }).first();
181
+ },
182
+
183
+ /**
184
+ * 创建记录
185
+ * @param {Object} data - 要插入的数据
186
+ * @returns {Promise<Array>} 插入结果
187
+ */
188
+ create(data) {
189
+ return db(this.tableName).insert(data);
190
+ },
191
+
192
+ /**
193
+ * 批量创建记录
194
+ * @param {Array} records - 要插入的记录数组
195
+ * @returns {Promise<Array>} 插入结果
196
+ */
197
+ createMany(records) {
198
+ return db(this.tableName).insert(records);
199
+ },
200
+
201
+ /**
202
+ * 更新记录
203
+ * @param {Object} conditions - 更新条件
204
+ * @param {Object} data - 更新数据
205
+ * @returns {Promise<number>} 影响的行数
206
+ */
207
+ update(conditions, data) {
208
+ return db(this.tableName).where(conditions).update(data);
209
+ },
210
+
211
+ /**
212
+ * 删除记录
213
+ * @param {Object} conditions - 删除条件
214
+ * @returns {Promise<number>} 影响的行数
215
+ */
216
+ delete(conditions) {
217
+ return db(this.tableName).where(conditions).del();
218
+ },
219
+
220
+ /**
221
+ * 统计记录数
222
+ * @param {Object} query - 查询条件
223
+ * @returns {Promise<number>} 记录总数
224
+ */
225
+ count(query = {}) {
226
+ let q = db(this.tableName).count("* as total");
227
+ if (Object.keys(query).length > 0) {
228
+ q = q.where(query);
229
+ }
230
+ return q.first().then((result) => result?.total ?? 0);
231
+ },
232
+
233
+ /**
234
+ * 分页查询
235
+ * @param {Object} options - 查询选项
236
+ * @param {number} options.current - 当前页码,默认1
237
+ * @param {number} options.pageSize - 每页大小,默认10
238
+ * @param {Object} options.where - 查询条件
239
+ * @param {Array} options.select - 查询字段
240
+ * @returns {Promise<Object>} 分页结果
241
+ */
242
+ query(options = {}) {
243
+ const { current = 1, pageSize = 10, where = {}, select } = options;
244
+ const offset = (current - 1) * pageSize;
245
+
246
+ const countQuery = db(this.tableName).count("* as total");
247
+ const dataQuery = db(this.tableName);
248
+
249
+ if (Object.keys(where).length > 0) {
250
+ countQuery.where(where);
251
+ dataQuery.where(where);
252
+ }
253
+
254
+ if (select) {
255
+ dataQuery.select(select);
256
+ }
257
+
258
+ return Promise.all([
259
+ countQuery.first(),
260
+ dataQuery.offset(offset).limit(pageSize),
261
+ ]).then(([totalResult, list]) => ({
262
+ list,
263
+ total: totalResult?.total ?? 0,
264
+ current,
265
+ pageSize,
266
+ }));
267
+ },
268
+
269
+ /**
270
+ * 关联查询
271
+ * @param {Object} options - 查询选项
272
+ * @param {string} options.joinTable - 关联表名
273
+ * @param {string} options.localField - 本地表字段
274
+ * @param {string} options.foreignField - 关联表字段
275
+ * @param {string} options.select - 查询字段,默认"*"
276
+ * @param {Object} options.where - 查询条件
277
+ * @returns {Object} Knex查询构建器
278
+ */
279
+ join(options) {
280
+ const { joinTable, localField, foreignField, select = "*", where = {} } = options;
281
+ let q = db(this.tableName)
282
+ .join(joinTable, `${this.tableName}.${localField}`, "=", `${joinTable}.${foreignField}`)
283
+ .select(select);
284
+
285
+ if (Object.keys(where).length > 0) {
286
+ q = q.where(where);
287
+ }
288
+
289
+ return q;
290
+ },
291
+
292
+ /**
293
+ * 执行事务
294
+ * @param {Function} callback - 事务回调函数
295
+ * @returns {Promise} 事务执行结果
296
+ */
297
+ transaction(callback) {
298
+ return db.transaction(callback);
299
+ },
300
+
301
+ /**
302
+ * 执行原生SQL
303
+ * @param {string} sql - SQL语句
304
+ * @param {Array} bindings - 绑定参数
305
+ * @returns {Promise} 查询结果
306
+ */
307
+ raw(sql, bindings) {
308
+ return db.raw(sql, bindings);
309
+ },
310
+ };
311
+ }
312
+ }
313
+
314
+ export default DatabaseManager;