@q78kg/koishi-plugin-text-censor 1.0.15 → 1.1.0-beta.1
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/lib/index.cjs +2 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.mjs +2 -0
- package/package.json +18 -4
- package/lib/index.js +0 -2
package/lib/index.cjs
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
var W=Object.create;var u=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var E=(e,r)=>{for(var o in r)u(e,o,{get:r[o],enumerable:!0})},w=(e,r,o,g)=>{if(r&&typeof r=="object"||typeof r=="function")for(let f of D(r))!j.call(e,f)&&f!==o&&u(e,f,{get:()=>r[f],enumerable:!(g=S(r,f))||g.enumerable});return e};var M=(e,r,o)=>(o=e!=null?W($(e)):{},w(r||!e||!e.__esModule?u(o,"default",{value:e,enumerable:!0}):o,e)),A=e=>w(u({},"__esModule",{value:!0}),e);var R={};E(R,{Config:()=>T,apply:()=>I,name:()=>F});module.exports=A(R);var i=require("koishi"),v=require("node:fs"),m=require("node:fs/promises"),x=require("node:path"),C=require("@q78kg/mint-filter"),b=M(require("@koishijs/censor"),1),F="text-censor",T=i.Schema.intersect([i.Schema.object({textDatabase:i.Schema.array(i.Schema.string()).description("\u654F\u611F\u8BCD\u5E93\u7684\u6587\u4EF6\u8DEF\u5F84").default(["data/text-censor/censor.txt"]),regexPatterns:i.Schema.array(i.Schema.string()).description("\u6B63\u5219\u8868\u8FBE\u5F0F\u5339\u914D\u6A21\u5F0F\u5217\u8868\uFF08\u8F93\u5165\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\u4E0D\u8981\u643A\u5E26\u4FEE\u9970\u7B26\uFF09").default([])}),i.Schema.object({removeWords:i.Schema.boolean().description("\u662F\u5426\u76F4\u63A5\u5220\u9664\u654F\u611F\u8BCD").default(!1)})]);function I(e,r){let o=new Set,g=async()=>{await Promise.all(r.textDatabase.map(async n=>{let t=(0,x.resolve)(e.baseDir,n);try{(0,v.existsSync)(t)||(e.logger.warn(`dictionary file not found: ${t}, creating a new one.`),await(0,m.mkdir)((0,x.dirname)(t),{recursive:!0}),await(0,m.writeFile)(t,"")),(await(0,m.readFile)(t,"utf8")).split(`
|
2
|
+
`).map(s=>s.trim()).filter(s=>s&&!/^[/#]/.test(s)).forEach(s=>o.add(s))}catch(l){e.logger.error(`Error loading dictionary ${t}:`,l)}}))},f=r.regexPatterns.map(n=>{try{return new RegExp(String.raw`${n}`,"gs")}catch(t){return e.logger.warn(`Invalid regex pattern: ${n}, error: ${t.message}`),null}}).filter(n=>n!==null),h=new Map,P=n=>{if(h.has(n))return h.get(n);let t=n,l=[];for(let c of f)for(let s of t.matchAll(c))l.push({start:s.index,end:s.index+s[0].length});if(l.length>0){l.sort((a,d)=>a.start-d.start);let c=l.reduce((a,d)=>{let p=a[a.length-1];return!p||p.end<d.start?a.push(d):p.end=Math.max(p.end,d.end),a},[]),s=[],y=0;for(let{start:a,end:d}of c)s.push(t.slice(y,a)),s.push(r.removeWords?"":"*".repeat(d-a)),y=d;s.push(t.slice(y)),t=s.join("")}return h.set(n,t),t};e.plugin(b.default.default??b.default),e.get("censor").intercept({async text(n){let t=P(n.content);if(o.size>0){let c=(0,C.createMintFilter)([...o],{customCharacter:"*"}).filter(t,{replace:!r.removeWords});return!c||typeof c.text!="string"?[]:(r.removeWords&&(t=c.text.split("").filter(s=>s!=="*").join("")),[t.trim()])}return[t]}}),g()}0&&(module.exports={Config,apply,name});
|
package/lib/index.d.ts
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
2
|
+
export declare const name = "text-censor";
|
3
|
+
export interface Config {
|
4
|
+
textDatabase: string[];
|
5
|
+
removeWords: boolean;
|
6
|
+
regexPatterns: string[];
|
7
|
+
}
|
8
|
+
export declare const Config: Schema<Config>;
|
9
|
+
export declare function apply(ctx: Context, config: Config): void;
|
10
|
+
|
package/lib/index.mjs
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
import{Schema as i}from"koishi";import{existsSync as y}from"node:fs";import{mkdir as b,writeFile as w,readFile as v}from"node:fs/promises";import{dirname as C,resolve as P}from"node:path";import{createMintFilter as W}from"@q78kg/mint-filter";import p from"@koishijs/censor";var F="text-censor",T=i.intersect([i.object({textDatabase:i.array(i.string()).description("\u654F\u611F\u8BCD\u5E93\u7684\u6587\u4EF6\u8DEF\u5F84").default(["data/text-censor/censor.txt"]),regexPatterns:i.array(i.string()).description("\u6B63\u5219\u8868\u8FBE\u5F0F\u5339\u914D\u6A21\u5F0F\u5217\u8868\uFF08\u8F93\u5165\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\u4E0D\u8981\u643A\u5E26\u4FEE\u9970\u7B26\uFF09").default([])}),i.object({removeWords:i.boolean().description("\u662F\u5426\u76F4\u63A5\u5220\u9664\u654F\u611F\u8BCD").default(!1)})]);function I(l,c){let f=new Set,u=async()=>{await Promise.all(c.textDatabase.map(async r=>{let e=P(l.baseDir,r);try{y(e)||(l.logger.warn(`dictionary file not found: ${e}, creating a new one.`),await b(C(e),{recursive:!0}),await w(e,"")),(await v(e,"utf8")).split(`
|
2
|
+
`).map(t=>t.trim()).filter(t=>t&&!/^[/#]/.test(t)).forEach(t=>f.add(t))}catch(n){l.logger.error(`Error loading dictionary ${e}:`,n)}}))},x=c.regexPatterns.map(r=>{try{return new RegExp(String.raw`${r}`,"gs")}catch(e){return l.logger.warn(`Invalid regex pattern: ${r}, error: ${e.message}`),null}}).filter(r=>r!==null),m=new Map,h=r=>{if(m.has(r))return m.get(r);let e=r,n=[];for(let o of x)for(let t of e.matchAll(o))n.push({start:t.index,end:t.index+t[0].length});if(n.length>0){n.sort((s,a)=>s.start-a.start);let o=n.reduce((s,a)=>{let d=s[s.length-1];return!d||d.end<a.start?s.push(a):d.end=Math.max(d.end,a.end),s},[]),t=[],g=0;for(let{start:s,end:a}of o)t.push(e.slice(g,s)),t.push(c.removeWords?"":"*".repeat(a-s)),g=a;t.push(e.slice(g)),e=t.join("")}return m.set(r,e),e};l.plugin(p.default??p),l.get("censor").intercept({async text(r){let e=h(r.content);if(f.size>0){let o=W([...f],{customCharacter:"*"}).filter(e,{replace:!c.removeWords});return!o||typeof o.text!="string"?[]:(c.removeWords&&(e=o.text.split("").filter(t=>t!=="*").join("")),[e.trim()])}return[e]}}),u()}export{T as Config,I as apply,F as name};
|
package/package.json
CHANGED
@@ -1,14 +1,25 @@
|
|
1
1
|
{
|
2
2
|
"name": "@q78kg/koishi-plugin-text-censor",
|
3
3
|
"description": "A text censor provider for Koishi",
|
4
|
-
"version": "1.0.
|
5
|
-
"main": "lib/index.
|
4
|
+
"version": "1.1.0-beta.1",
|
5
|
+
"main": "lib/index.cjs",
|
6
|
+
"module": "lib/index.mjs",
|
7
|
+
"types": "lib/index.d.ts",
|
8
|
+
"type": "module",
|
9
|
+
"exports": {
|
10
|
+
".": {
|
11
|
+
"types": "./lib/index.d.ts",
|
12
|
+
"require": "./lib/index.cjs",
|
13
|
+
"import": "./lib/index.mjs"
|
14
|
+
},
|
15
|
+
"./package.json": "./package.json"
|
16
|
+
},
|
6
17
|
"files": [
|
7
18
|
"lib"
|
8
19
|
],
|
9
20
|
"license": "MIT",
|
10
21
|
"scripts": {
|
11
|
-
"build": "
|
22
|
+
"build": "kumoya build",
|
12
23
|
"lint": "eslint src",
|
13
24
|
"lint-fix": "eslint src --fix"
|
14
25
|
},
|
@@ -45,6 +56,8 @@
|
|
45
56
|
},
|
46
57
|
"devDependencies": {
|
47
58
|
"@types/node": "^20.11.30",
|
59
|
+
"@typescript-eslint/eslint-plugin": "^8.22.0",
|
60
|
+
"@typescript-eslint/parser": "^8.22.0",
|
48
61
|
"esbuild": "^0.18.20",
|
49
62
|
"esbuild-register": "^3.5.0",
|
50
63
|
"eslint": "^9.12.0",
|
@@ -55,12 +68,13 @@
|
|
55
68
|
"eslint-plugin-prettier": "^5.2.1",
|
56
69
|
"eslint-plugin-promise": "^7.1.0",
|
57
70
|
"koishi": "^4.17.9",
|
71
|
+
"kumoya": "^1.2.0",
|
58
72
|
"prettier": "^3.3.3",
|
59
73
|
"typescript": "^5.5.3",
|
60
74
|
"yml-register": "^1.2.5"
|
61
75
|
},
|
62
76
|
"dependencies": {
|
63
77
|
"@koishijs/censor": "^1.0.1",
|
64
|
-
"mint-filter": "^
|
78
|
+
"@q78kg/mint-filter": "^1.0.1"
|
65
79
|
}
|
66
80
|
}
|
package/lib/index.js
DELETED
@@ -1,2 +0,0 @@
|
|
1
|
-
var P=Object.create;var x=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var M=Object.getPrototypeOf,T=Object.prototype.hasOwnProperty;var j=(e,t)=>{for(var a in t)x(e,a,{get:t[a],enumerable:!0})},y=(e,t,a,m)=>{if(t&&typeof t=="object"||typeof t=="function")for(let d of D(t))!T.call(e,d)&&d!==a&&x(e,d,{get:()=>t[d],enumerable:!(m=W(t,d))||m.enumerable});return e};var b=(e,t,a)=>(a=e!=null?P(M(e)):{},y(t||!e||!e.__esModule?x(a,"default",{value:e,enumerable:!0}):a,e)),k=e=>y(x({},"__esModule",{value:!0}),e);var E={};j(E,{Config:()=>I,apply:()=>$,name:()=>F});module.exports=k(E);var c=require("koishi"),f=require("node:fs"),u=require("node:path"),w=b(require("mint-filter")),S=b(require("@koishijs/censor")),F="text-censor",I=c.Schema.intersect([c.Schema.object({textDatabase:c.Schema.array(c.Schema.tuple([c.Schema.string().default("data/text-censor/censor.txt")])).description("\u654F\u611F\u8BCD\u5E93\u7684\u6587\u4EF6\u8DEF\u5F84").default([["data/text-censor/censor.txt"]]),regexPatterns:c.Schema.array(c.Schema.string()).description("\u6B63\u5219\u8868\u8FBE\u5F0F\u5339\u914D\u6A21\u5F0F\u5217\u8868").default([])}),c.Schema.object({removeWords:c.Schema.boolean().description("\u662F\u5426\u76F4\u63A5\u5220\u9664\u654F\u611F\u8BCD").default(!1),caseStrategy:c.Schema.union(["none","lower","capital"]).description("\u654F\u611F\u8BCD\u5904\u7406\u65F6\u7684\u5927\u5C0F\u5199\u7B56\u7565").default("none")})]);function $(e,t){let a=[];for(let[h]of t.textDatabase){let n=(0,u.resolve)(e.baseDir,h);if(!(0,f.existsSync)(n)){e.logger.warn(`dictionary file not found: ${n}, creating a new one.`);let s=(0,u.dirname)(n);(0,f.existsSync)(s)||(0,f.mkdirSync)(s,{recursive:!0}),(0,f.writeFileSync)(n,"")}let i=(0,f.readFileSync)(n,"utf8").split(`
|
2
|
-
`).map(s=>s.trim()).filter(s=>s&&!s.startsWith("//")&&!s.startsWith("#"));a=a.concat(i)}if(a.length===0){e.logger.warn("no sensitive words found");return}let m={transform:t.caseStrategy},d=new w.default(a,m);e.plugin(S.default),e.get("censor").intercept({async text(h){let n=h.content,p=[];for(let r of t.regexPatterns)try{let l=new RegExp(r,"gs"),o;for(;(o=l.exec(n))!==null;)p.push({start:o.index,end:o.index+o[0].length})}catch{e.logger.warn(`Invalid regex pattern: ${r}`)}p.sort((r,l)=>r.start-l.start);let i=[];for(let r of p)i.length===0||i[i.length-1].end<r.start?i.push(r):i[i.length-1].end=Math.max(i[i.length-1].end,r.end);for(let r=i.length-1;r>=0;r--){let{start:l,end:o}=i[r],g=n.slice(l,o);t.removeWords?n=n.slice(0,l)+n.slice(o):n=n.slice(0,l)+"*".repeat(g.length)+n.slice(o)}let s=await d.filter(n);if(typeof s.text!="string")return[];if(t.removeWords){let r=n,l=0;for(let o=0;o<s.text.length;o++)if(s.text[o]==="*"){let g=0;for(;o+g<s.text.length&&s.text[o+g]==="*";)g++;let v=r.slice(0,l),C=r.slice(l+g);r=v+C,o+=g-1}else l++;return[r.trim()]}else return[s.text]}})}0&&(module.exports={Config,apply,name});
|