@twikoojs/edgeone-makers 2.0.13 → 2.0.14

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.
@@ -43,7 +43,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
43
43
  var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
44
44
  //#endregion
45
45
  //#region ../shared/dist/index.mjs
46
- /*! @twikoojs/shared v2.0.13 */
46
+ /*! @twikoojs/shared v2.0.14 */
47
47
  /**
48
48
  * Twikoo 统一版本号常量(构建期占位符)。
49
49
  *
@@ -56,7 +56,7 @@ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
56
56
  * 占位符字面量由 `@twikoojs/tsdown-config` 的 `VERSION_PLACEHOLDER` 常量定义,
57
57
  * 客户端与服务端统一读取本常量,避免版本号在多包之间手工同步。
58
58
  */
59
- const VERSION = "2.0.13";
59
+ const VERSION = "2.0.14";
60
60
  /**
61
61
  * 后端事件名常量(Scope E:24 个客户端事件 + 1 个服务端内部事件)。
62
62
  *
@@ -24334,19 +24334,33 @@ async function getXml2js() {
24334
24334
  return pickDefault(await loadLib("xml2js"));
24335
24335
  }
24336
24336
  /**
24337
- * 获取 html-to-text 编译产物(通知纯文本;配置 1.x 对齐:忽略链接 href、跳过图片)。
24337
+ * 获取 html-to-text 编译产物;通知忽略图片,长度检查按替代文本或固定占位计数。
24338
+ * @param options 是否使用评论长度计数规则
24338
24339
  * @returns 编译后的转换函数
24339
24340
  */
24340
- async function getHtmlToText() {
24341
+ async function getHtmlToText(options = {}) {
24341
24342
  return pickDefault(await loadLib("html-to-text")).compile({
24342
24343
  wordwrap: false,
24343
- selectors: [{
24344
- selector: "a",
24345
- options: { ignoreHref: true }
24346
- }, {
24347
- selector: "img",
24348
- format: "skip"
24349
- }]
24344
+ formatters: {
24345
+ /** 图片按替代文本计数;无替代文本的图片和分隔线各占 10 个字符。 */
24346
+ wordCount(elem, _walk, builder) {
24347
+ const text = elem.name === "img" ? elem.attribs.alt?.trim() : "";
24348
+ builder.addInline(text || "-".repeat(10), { noWordTransform: true });
24349
+ } },
24350
+ selectors: [
24351
+ {
24352
+ selector: "a",
24353
+ options: { ignoreHref: true }
24354
+ },
24355
+ {
24356
+ selector: "img",
24357
+ format: options.forWordCount ? "wordCount" : "skip"
24358
+ },
24359
+ ...options.forWordCount ? [{
24360
+ selector: "hr",
24361
+ format: "wordCount"
24362
+ }] : []
24363
+ ]
24350
24364
  });
24351
24365
  }
24352
24366
  /**
@@ -24755,22 +24769,25 @@ async function parseCommentForAdmin(comments, caps) {
24755
24769
  * 语义对齐)。
24756
24770
  *
24757
24771
  * 链路(COMMENT_SUBMIT):
24758
- * 1. preCheckSpam 预检(长度 / 屏蔽词 / 人工审核标记 / 违禁词)——同步快速路径;
24772
+ * 1. preCheckSpam 预检(长度 / 屏蔽词 / 人工审核标记 / 违禁词)——按需加载纯文本转换器;
24759
24773
  * 2. checkCaptcha 验证码(Turnstile / Geetest / Cap 内嵌或外部);
24760
24774
  * 3. limitFilter 频率限制(单 IP 与全站 10 分钟窗口);
24761
24775
  * 4. postCheckSpam 后检(腾讯云 TMS / Akismet / Jev / LLM,postSubmit 异步阶段)。
24762
24776
  */
24763
24777
  /**
24764
- * 预垃圾评论检测(1.x preCheckSpam 逐行对齐)。
24778
+ * 预垃圾评论检测;长度限制按 HTML 转换后的文本计算。
24765
24779
  * @param comment 待检评论字段
24766
24780
  * @param config 全量配置
24767
24781
  * @param logger 请求日志
24768
24782
  * @returns 是否标记为垃圾(MANUAL_REVIEW / 违禁词)
24769
24783
  */
24770
- function preCheckSpam(comment, config, logger) {
24784
+ async function preCheckSpam(comment, config, logger) {
24771
24785
  let limitLength = parseInt(String(config.LIMIT_LENGTH ?? ""));
24772
24786
  if (Number.isNaN(limitLength)) limitLength = 500;
24773
- if (limitLength && comment.comment.length > limitLength) throw new Error("评论内容过长");
24787
+ if (limitLength) {
24788
+ if (comment.comment.length > limitLength * 10) throw new Error("评论内容过长");
24789
+ if ((await getHtmlToText({ forWordCount: true }))(comment.comment).length > limitLength) throw new Error("评论内容过长");
24790
+ }
24774
24791
  if (config.BLOCKED_WORDS) {
24775
24792
  const commentLowerCase = comment.comment.toLowerCase();
24776
24793
  const nickLowerCase = comment.nick.toLowerCase();
@@ -26540,7 +26557,7 @@ async function parseCommentDoc(ctx) {
26540
26557
  }),
26541
26558
  pid: comment.pid ? toStr(comment.pid) : toStr(comment.rid),
26542
26559
  rid: comment.rid,
26543
- isSpam: isAdminUser ? false : preCheckSpam({
26560
+ isSpam: isAdminUser ? false : await preCheckSpam({
26544
26561
  comment: toStr(comment.comment),
26545
26562
  nick: toStr(comment.nick),
26546
26563
  link: comment.link,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twikoojs/edgeone-makers",
3
- "version": "2.0.13",
3
+ "version": "2.0.14",
4
4
  "description": "Twikoo comment system backend for Tencent EdgeOne Makers",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,19 +21,19 @@
21
21
  "dependencies": {
22
22
  "@cap.js/server": "^4.0.5",
23
23
  "@edgeone/pages-blob": "latest",
24
- "@twikoojs/common": "2.0.13",
25
- "@twikoojs/shared": "2.0.13",
24
+ "@twikoojs/common": "2.0.14",
25
+ "@twikoojs/shared": "2.0.14",
26
26
  "bowser": "^2.14.1",
27
27
  "form-data": "^4.0.6",
28
28
  "html-to-text": "^10.0.1",
29
29
  "marked": "^18.0.13",
30
30
  "pako": "^3.0.2",
31
- "pushoo": "^2.0.13",
31
+ "pushoo": "^2.0.14",
32
32
  "xml2js": "^0.6.2"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@imaegoo/node-ip2region": "^2.1.1",
36
- "@types/node": "^26.6.1"
36
+ "@types/node": "^26.6.4"
37
37
  },
38
38
  "scripts": {
39
39
  "build": "node scripts/build-ip2region-data.mjs && tsdown && node scripts/build-zip.mjs",