chanjs 2.8.12 → 2.8.13

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 CHANGED
@@ -21,7 +21,7 @@
21
21
  ### 核心架构
22
22
 
23
23
  - 原生基于 Express 5+ mysql/pgsql/sqlite 三款数据库支持
24
- - 最低运行环境 Node.js 22.18+
24
+ - 最低运行环境 Node.js 22.23.4+
25
25
  - 全量 ES Modules(import / export)
26
26
  - **标准 HMVC 架构:模块自治 + 双通道跨模块协作**
27
27
  - 约定优于配置,减少样板配置代码
@@ -92,7 +92,7 @@ function mapUrlFilters(query, fieldMap) {
92
92
  const filter = {};
93
93
  for (const [key, map] of Object.entries(fieldMap || {})) {
94
94
  const raw = query?.[key];
95
- if (raw === undefined || raw === null || String(raw).trim() === "") continue;
95
+ if (raw == null || String(raw).trim() === "") continue;
96
96
  let piece;
97
97
  try {
98
98
  piece = map(String(raw).trim());
package/core/errors.js CHANGED
@@ -50,7 +50,7 @@ export class AppError extends Error {
50
50
  const json = { name: this.name, message: this.message, code: this.code, httpStatus: this.httpStatus };
51
51
  for (const key of Object.getOwnPropertyNames(this)) {
52
52
  const val = this[key];
53
- if (val === undefined || val === null) continue;
53
+ if (val == null) continue;
54
54
  if (typeof val === 'function' || typeof val === 'symbol') continue;
55
55
  json[key] = val;
56
56
  }
@@ -3,7 +3,6 @@ import dayjs from "dayjs";
3
3
  import { createRequire } from "module";
4
4
  import relativeTime from "dayjs/plugin/relativeTime.js";
5
5
  import "dayjs/locale/zh-cn.js";
6
- import { marked } from "marked";
7
6
  import logger from "../utils/logger.js";
8
7
 
9
8
  const require = createRequire(import.meta.url);
@@ -73,33 +72,6 @@ artTemplate.defaults.imports.safeStringify = (obj, keys) => {
73
72
  artTemplate.defaults.imports.objKeys = (obj, separator = "\n") =>
74
73
  typeof obj === "object" && obj ? Object.keys(obj).join(separator) : "";
75
74
 
76
- /**
77
- * Markdown渲染 + XSS过滤
78
- * @param {string} content
79
- * @param {"md"|"rich"} [editorType="rich"]
80
- * @param {0|1} [allowScript=0] 1=信任内容不做XSS过滤
81
- * @returns {string}
82
- */
83
- artTemplate.defaults.imports.renderContent = (content, editorType = "rich", allowScript = 0) => {
84
- if (typeof content !== "string") return content || "";
85
- let html = content;
86
-
87
- if (editorType === "md") {
88
- try {
89
- // marked v4+ 支持异步扩展,返回 string | Promise<string>
90
- // 同步场景下直接取结果;若返回 Promise 则降级为空字符串
91
- const result = marked.parse(content);
92
- html = typeof result === "string" ? result : "";
93
- } catch (e) {
94
- logger.error(`[renderContent] MD解析失败: ${e.message}`);
95
- }
96
- }
97
-
98
- // 正文 XSS 已在后台保存时统一 sanitize(sanitizeRichText),
99
- // 此处不再二次转义,避免破坏第三方嵌入(B站 iframe)与自定义 class 样式。
100
- return html;
101
- };
102
-
103
75
  /**
104
76
  * art-template模板引擎中间件
105
77
  * @param {express.Application} app
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "chanjs",
4
- "version": "2.8.12",
4
+ "version": "2.8.13",
5
5
  "description": "chanjs基于 Node.js + Express 5 的标准 HMVC 框架(NHMVC),纯 JavaScript(ESM)开发。",
6
6
  "main": "index.js",
7
7
  "module": "index.js",
@@ -14,7 +14,7 @@
14
14
  "nodejs mvc"
15
15
  ],
16
16
  "engines": {
17
- "node": ">=22.18.0"
17
+ "node": ">=24.22.1"
18
18
  },
19
19
  "scripts": {
20
20
  "test": "node --test"
@@ -37,29 +37,28 @@
37
37
  "art-template": "^4.13.4",
38
38
  "cookie-parser": "^1.4.7",
39
39
  "cors": "^2.8.6",
40
- "dayjs": "^1.11.20",
41
- "dotenv": "^17.4.2",
42
- "express": "^5.2.1",
40
+ "dayjs": "^1.11.23",
41
+ "dotenv": "^18.0.9",
42
+ "express": "^5.3.0",
43
43
  "express-art-template": "^1.0.1",
44
- "i18next": "^24.2.0",
45
- "ioredis": "^5.4.6",
44
+ "i18next": "^26.5.11",
45
+ "ioredis": "^6.0.0",
46
46
  "jsonwebtoken": "^9.0.3",
47
- "knex": "^3.2.10",
48
- "marked": "^18.0.3",
49
- "mysql2": "^3.22.3",
50
- "node-cron": "^3.0.3",
51
- "pg": "^8.23.0",
52
- "pino": "^9.5.0",
53
- "pino-http": "^10.3.0",
54
- "pino-pretty": "^13.1.3",
47
+ "knex": "^3.3.0",
48
+ "mysql2": "^3.24.6",
49
+ "node-cron": "^4.6.0",
50
+ "pg": "^8.23.1",
51
+ "pino": "^10.4.0",
52
+ "pino-http": "^11.0.0",
53
+ "pino-pretty": "^13.2.0",
55
54
  "serve-favicon": "^2.5.1",
56
- "xss": "^1.0.15"
55
+ "xss": "^1.0.17"
57
56
  },
58
57
  "devDependencies": {
59
- "zod": "^4.4.3"
58
+ "zod": "^4.6.7"
60
59
  },
61
60
  "peerDependencies": {
62
- "zod": "^4.4.3"
61
+ "zod": "^4.6.7"
63
62
  },
64
63
  "peerDependenciesMeta": {
65
64
  "zod": {
@@ -38,7 +38,7 @@ export function serializeError(err, exposeDetail = false) {
38
38
  if (NEVER_EXPOSE.has(key)) continue;
39
39
  if (SENSITIVE.has(key) && !exposeDetail) continue; // 生产环境不泄露堆栈/根因(SQL)
40
40
  const val = err[key];
41
- if (val === undefined || val === null) continue;
41
+ if (val == null) continue;
42
42
  if (typeof val === "function" || typeof val === "symbol") continue;
43
43
  try { extra[key] = val && typeof val === "object" && !Array.isArray(val) ? JSON.stringify(val) : val; }
44
44
  catch { extra[key] = "[unserializable]"; }
package/utils/pages.js CHANGED
@@ -48,7 +48,7 @@ export function pageHtml({ baseUrl, query, total, pageSize = 10, current = 1, un
48
48
 
49
49
  const base = new URLSearchParams();
50
50
  Object.entries(query || {}).forEach(([k, v]) => {
51
- if (k === "current" || v === undefined || v === null || v === "") return;
51
+ if (k === "current" || v == null || v === "") return;
52
52
  base.set(k, v);
53
53
  });
54
54
  const link = (n) => {
@@ -116,8 +116,9 @@ export function pages(current, total, pageSize, href, query = '') {
116
116
  items.push(ellipsis(), pageLink(totalPage));
117
117
  }
118
118
 
119
- // 下一页
120
- items.push(navLink(current + 1, "下一页"));
119
+ // 下一页(最后一页不再给链接:current+1 恒为真值,不判断 totalPage 会渲染出越界页码,
120
+ // 点进去是空列表 —— 与 query 式 pageHtml() 的 current < totalPage 判断对齐)
121
+ items.push(navLink(current < totalPage ? current + 1 : 0, "下一页"));
121
122
 
122
123
  return items.join("");
123
124
  }