censorship-id 1.0.0 → 1.1.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.
- package/README.md +12 -1
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,7 +7,8 @@ A robust and simple npm package for detecting and masking Indonesian profanity,
|
|
|
7
7
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
|
-
- **
|
|
10
|
+
- **Smart Detection**: Optional `smartMode` to handle leetspeak (e.g., `4njing`), repeated characters (e.g., `baaaaaabiii`), and punctuation insertion (e.g., `a.n.j.i.n.g`).
|
|
11
|
+
- **Comprehensive Dictionary**: Pre-loaded with common Indonesian bad words.
|
|
11
12
|
- **Regex Powered**: Uses word boundaries to avoid false positives (e.g., masking "tai" but not "pantai").
|
|
12
13
|
- **Customizable**: Add your own words to the list and choose your mask character.
|
|
13
14
|
- **Keep First and Last**: Option to keep the first and last letters visible for better context.
|
|
@@ -54,6 +55,15 @@ console.log(visible);
|
|
|
54
55
|
const customWords = censorId("Kamu sangat malas!", { customWords: ['malas'] });
|
|
55
56
|
console.log(customWords);
|
|
56
57
|
// Output: Kamu sangat *****!
|
|
58
|
+
|
|
59
|
+
// 4. Smart Mode (handles leetspeak & repeats)
|
|
60
|
+
const smart = censorId("D4s4r 4njing!", { smartMode: true });
|
|
61
|
+
console.log(smart);
|
|
62
|
+
// Output: D4s4r ******!
|
|
63
|
+
|
|
64
|
+
const repeats = censorId("baaaaaaaabiiiiii", { smartMode: true });
|
|
65
|
+
console.log(repeats);
|
|
66
|
+
// Output: ****************
|
|
57
67
|
```
|
|
58
68
|
|
|
59
69
|
## API Reference
|
|
@@ -65,6 +75,7 @@ console.log(customWords);
|
|
|
65
75
|
- **`mask`** (string): The character used to mask words (default: `*`).
|
|
66
76
|
- **`customWords`** (string[]): Additional words to censor.
|
|
67
77
|
- **`keepFirstAndLast`** (boolean): If `true`, the first and last letters of the word remain visible (default: `false`).
|
|
78
|
+
- **`smartMode`** (boolean): If `true`, detects leetspeak and repeated characters (default: `false`).
|
|
68
79
|
|
|
69
80
|
## License
|
|
70
81
|
|
package/dist/index.d.mts
CHANGED
|
@@ -18,6 +18,12 @@ interface CensorIdOptions {
|
|
|
18
18
|
* @default false
|
|
19
19
|
*/
|
|
20
20
|
keepFirstAndLast?: boolean;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* If true, handles leetspeak (e.g., "4njing") and repeated characters (e.g., "baaaaaaabiii").
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
smartMode?: boolean;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,12 @@ interface CensorIdOptions {
|
|
|
18
18
|
* @default false
|
|
19
19
|
*/
|
|
20
20
|
keepFirstAndLast?: boolean;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* If true, handles leetspeak (e.g., "4njing") and repeated characters (e.g., "baaaaaaabiii").
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
smartMode?: boolean;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var x=(n,t)=>()=>(t||n((t={exports:{}}).exports,t),t.exports);var k=x((P,u)=>{var C=["anjing","asu","babi","bangsat","bajing","bajingan","bedebah","berak","bejat","brengsek","buto","cuk","dancuk","entot","goblok","itil","jancuk","jembut","kontol","kunyuk","lonte","memek","monyet","ngentot","pantat","perek","puki","setan","siak","sinting","tai","tolol"];u.exports=C});var b=k(),p={4:"a",3:"e",1:"i",0:"o",5:"s",7:"t",8:"b",9:"g","@":"a",$:"s","!":"i","(":"c"};function w(n,t={}){if(typeof n!="string")return n;let{mask:g="*",customWords:f=[],keepFirstAndLast:d=!1,smartMode:h=!1}=t,j=[...new Set([...b,...f])].sort((s,r)=>r.length-s.length),o=n;return j.forEach(s=>{let r;h?r=Array.from(s).map((i,c)=>{let a=i.toLowerCase(),y=Object.keys(p).filter(l=>p[l]===a),m=[a,...y].map(l=>l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),A=c===s.length-1?"+":"+[^a-zA-Z0-9]*";return`[${m.join("")}]${A}`}).join(""):r=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");let $=new RegExp(`(?<=\\s|^|[^a-zA-Z0-9])${r}(?=\\s|$|[^a-zA-Z0-9])`,"gi");o=o.replace($,e=>{if(d&&e.length>2){let i=e[0],c=e[e.length-1],a=g.repeat(e.length-2);return i+a+c}return g.repeat(e.length)})}),o}module.exports={censorId:w,dictionary:b};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../dictionary.js","../index.js"],"sourcesContent":["/**\r\n * A comprehensive list of common Indonesian profanity, slang, and inappropriate words.\r\n */\r\nconst dictionary = [\r\n \"anjing\",\r\n \"asu\",\r\n \"babi\",\r\n \"bangsat\",\r\n \"bajing\",\r\n \"bajingan\",\r\n \"bedebah\",\r\n \"berak\",\r\n \"bejat\",\r\n \"brengsek\",\r\n \"buto\",\r\n \"cuk\",\r\n \"dancuk\",\r\n \"entot\",\r\n \"goblok\",\r\n \"itil\",\r\n \"jancuk\",\r\n \"jembut\",\r\n \"kontol\",\r\n \"kunyuk\",\r\n \"lonte\",\r\n \"memek\",\r\n \"monyet\",\r\n \"ngentot\",\r\n \"pantat\",\r\n \"perek\",\r\n \"puki\",\r\n \"setan\",\r\n \"siak\",\r\n \"sinting\",\r\n \"tai\",\r\n \"tolol\"\r\n];\r\n\r\nmodule.exports = dictionary;\r\n","const defaultDictionary = require(\"./dictionary\");\r\n\r\n/**\r\n * Censor Indonesian profanity and inappropriate words.\r\n *\r\n * @param {string} text - The input text to be filtered.\r\n * @param {object} options - Filtering options.\r\n * @param {string} options.mask - The character used to mask the words (default is '*').\r\n * @param {string[]} options.customWords - An array of additional words to censor.\r\n * @param {boolean} options.keepFirstAndLast - If true, keeps the first and last letters visible (default is false).\r\n * @returns {string} - The censored text.\r\n */\r\nfunction censorId(text, options = {}) {\r\n if (typeof text !== \"string\") {\r\n return text;\r\n }\r\n\r\n const {\r\n mask = \"*\",\r\n customWords = [],\r\n keepFirstAndLast = false\r\n } = options;\r\n\r\n // Merge default dictionary with custom words\r\n const wordsToCensor = [...new Set([...defaultDictionary, ...customWords])];\r\n\r\n
|
|
1
|
+
{"version":3,"sources":["../dictionary.js","../index.js"],"sourcesContent":["/**\r\n * A comprehensive list of common Indonesian profanity, slang, and inappropriate words.\r\n */\r\nconst dictionary = [\r\n \"anjing\",\r\n \"asu\",\r\n \"babi\",\r\n \"bangsat\",\r\n \"bajing\",\r\n \"bajingan\",\r\n \"bedebah\",\r\n \"berak\",\r\n \"bejat\",\r\n \"brengsek\",\r\n \"buto\",\r\n \"cuk\",\r\n \"dancuk\",\r\n \"entot\",\r\n \"goblok\",\r\n \"itil\",\r\n \"jancuk\",\r\n \"jembut\",\r\n \"kontol\",\r\n \"kunyuk\",\r\n \"lonte\",\r\n \"memek\",\r\n \"monyet\",\r\n \"ngentot\",\r\n \"pantat\",\r\n \"perek\",\r\n \"puki\",\r\n \"setan\",\r\n \"siak\",\r\n \"sinting\",\r\n \"tai\",\r\n \"tolol\"\r\n];\r\n\r\nmodule.exports = dictionary;\r\n","const defaultDictionary = require(\"./dictionary\");\r\n\r\n// Leetspeak mapping\r\nconst leetMap = {\r\n \"4\": \"a\",\r\n \"3\": \"e\",\r\n \"1\": \"i\",\r\n \"0\": \"o\",\r\n \"5\": \"s\",\r\n \"7\": \"t\",\r\n \"8\": \"b\",\r\n \"9\": \"g\",\r\n \"@\": \"a\",\r\n \"$\": \"s\",\r\n \"!\": \"i\",\r\n \"(\": \"c\"\r\n};\r\n\r\n/**\r\n * Censor Indonesian profanity and inappropriate words.\r\n *\r\n * @param {string} text - The input text to be filtered.\r\n * @param {object} options - Filtering options.\r\n * @param {string} options.mask - The character used to mask the words (default is '*').\r\n * @param {string[]} options.customWords - An array of additional words to censor.\r\n * @param {boolean} options.keepFirstAndLast - If true, keeps the first and last letters visible (default is false).\r\n * @param {boolean} options.smartMode - If true, handles leetspeak and repeated characters (default is false).\r\n * @returns {string} - The censored text.\r\n */\r\nfunction censorId(text, options = {}) {\r\n if (typeof text !== \"string\") {\r\n return text;\r\n }\r\n\r\n const {\r\n mask = \"*\",\r\n customWords = [],\r\n keepFirstAndLast = false,\r\n smartMode = false\r\n } = options;\r\n\r\n // Merge default dictionary with custom words and sort by length descending\r\n const wordsToCensor = [...new Set([...defaultDictionary, ...customWords])].sort((a, b) => b.length - a.length);\r\n\r\n let censoredText = text;\r\n\r\n // Iterate over each word and apply masking\r\n wordsToCensor.forEach(word => {\r\n let searchPattern;\r\n if (smartMode) {\r\n // Create a pattern that allows:\r\n // 1. Any number of repeats for each character (e.g., a+n+j+i+n+g+)\r\n // 2. Optional non-alphanumeric characters between letters (e.g., a[...]*n[...]*j)\r\n // 3. Mapping of leetspeak characters\r\n\r\n const charPatterns = Array.from(word).map((char, index) => {\r\n const lowerChar = char.toLowerCase();\r\n const leetChars = Object.keys(leetMap).filter(key => leetMap[key] === lowerChar);\r\n const variants = [lowerChar, ...leetChars].map(c => c.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\r\n\r\n // Only allow non-alphanumeric between characters, not after the last one\r\n const suffix = index === word.length - 1 ? \"+\" : \"+[^a-zA-Z0-9]*\";\r\n return `[${variants.join(\"\")}]${suffix}`;\r\n });\r\n\r\n searchPattern = charPatterns.join(\"\");\r\n } else {\r\n // Standard escaping for regex\r\n searchPattern = word.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n }\r\n\r\n const regex = new RegExp(`(?<=\\\\s|^|[^a-zA-Z0-9])${searchPattern}(?=\\\\s|$|[^a-zA-Z0-9])`, \"gi\");\r\n\r\n censoredText = censoredText.replace(regex, (match) => {\r\n if (keepFirstAndLast && match.length > 2) {\r\n const first = match[0];\r\n const last = match[match.length - 1];\r\n const middle = mask.repeat(match.length - 2);\r\n return first + middle + last;\r\n }\r\n return mask.repeat(match.length);\r\n });\r\n });\r\n\r\n return censoredText;\r\n}\r\n\r\nmodule.exports = {\r\n censorId,\r\n dictionary: defaultDictionary\r\n};\r\n"],"mappings":"8DAAA,IAAAA,EAAAC,EAAA,CAAAC,EAAAC,IAAA,CAGA,IAAMC,EAAa,CACjB,SACA,MACA,OACA,UACA,SACA,WACA,UACA,QACA,QACA,WACA,OACA,MACA,SACA,QACA,SACA,OACA,SACA,SACA,SACA,SACA,QACA,QACA,SACA,UACA,SACA,QACA,OACA,QACA,OACA,UACA,MACA,OACF,EAEAD,EAAO,QAAUC,ICtCjB,IAAMC,EAAoB,IAGpBC,EAAU,CACZ,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,IAAK,IACL,EAAK,IACL,IAAK,IACL,IAAK,GACT,EAaA,SAASC,EAASC,EAAMC,EAAU,CAAC,EAAG,CAClC,GAAI,OAAOD,GAAS,SAChB,OAAOA,EAGX,GAAM,CACF,KAAAE,EAAO,IACP,YAAAC,EAAc,CAAC,EACf,iBAAAC,EAAmB,GACnB,UAAAC,EAAY,EAChB,EAAIJ,EAGEK,EAAgB,CAAC,GAAG,IAAI,IAAI,CAAC,GAAGT,EAAmB,GAAGM,CAAW,CAAC,CAAC,EAAE,KAAK,CAACI,EAAGC,IAAMA,EAAE,OAASD,EAAE,MAAM,EAEzGE,EAAeT,EAGnB,OAAAM,EAAc,QAAQI,GAAQ,CAC1B,IAAIC,EACAN,EAgBAM,EAVqB,MAAM,KAAKD,CAAI,EAAE,IAAI,CAACE,EAAMC,IAAU,CACvD,IAAMC,EAAYF,EAAK,YAAY,EAC7BG,EAAY,OAAO,KAAKjB,CAAO,EAAE,OAAOkB,GAAOlB,EAAQkB,CAAG,IAAMF,CAAS,EACzEG,EAAW,CAACH,EAAW,GAAGC,CAAS,EAAE,IAAIG,GAAKA,EAAE,QAAQ,sBAAuB,MAAM,CAAC,EAGtFC,EAASN,IAAUH,EAAK,OAAS,EAAI,IAAM,iBACjD,MAAO,IAAIO,EAAS,KAAK,EAAE,CAAC,IAAIE,CAAM,EAC1C,CAAC,EAE4B,KAAK,EAAE,EAGpCR,EAAgBD,EAAK,QAAQ,sBAAuB,MAAM,EAG9D,IAAMU,EAAQ,IAAI,OAAO,0BAA0BT,CAAa,yBAA0B,IAAI,EAE9FF,EAAeA,EAAa,QAAQW,EAAQC,GAAU,CAClD,GAAIjB,GAAoBiB,EAAM,OAAS,EAAG,CACtC,IAAMC,EAAQD,EAAM,CAAC,EACfE,EAAOF,EAAMA,EAAM,OAAS,CAAC,EAC7BG,EAAStB,EAAK,OAAOmB,EAAM,OAAS,CAAC,EAC3C,OAAOC,EAAQE,EAASD,CAC5B,CACA,OAAOrB,EAAK,OAAOmB,EAAM,MAAM,CACnC,CAAC,CACL,CAAC,EAEMZ,CACX,CAEA,OAAO,QAAU,CACb,SAAAV,EACA,WAAYF,CAChB","names":["require_dictionary","__commonJSMin","exports","module","dictionary","defaultDictionary","leetMap","censorId","text","options","mask","customWords","keepFirstAndLast","smartMode","wordsToCensor","a","b","censoredText","word","searchPattern","char","index","lowerChar","leetChars","key","variants","c","suffix","regex","match","first","last","middle"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var u=(n,t)=>()=>(t||n((t={exports:{}}).exports,t),t.exports);var p=u((E,k)=>{var w=["anjing","asu","babi","bangsat","bajing","bajingan","bedebah","berak","bejat","brengsek","buto","cuk","dancuk","entot","goblok","itil","jancuk","jembut","kontol","kunyuk","lonte","memek","monyet","ngentot","pantat","perek","puki","setan","siak","sinting","tai","tolol"];k.exports=w});var P=u((L,d)=>{var f=p(),b={4:"a",3:"e",1:"i",0:"o",5:"s",7:"t",8:"b",9:"g","@":"a",$:"s","!":"i","(":"c"};function z(n,t={}){if(typeof n!="string")return n;let{mask:g="*",customWords:h=[],keepFirstAndLast:j=!1,smartMode:$=!1}=t,y=[...new Set([...f,...h])].sort((s,r)=>r.length-s.length),o=n;return y.forEach(s=>{let r;$?r=Array.from(s).map((i,c)=>{let a=i.toLowerCase(),A=Object.keys(b).filter(l=>b[l]===a),x=[a,...A].map(l=>l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),C=c===s.length-1?"+":"+[^a-zA-Z0-9]*";return`[${x.join("")}]${C}`}).join(""):r=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");let m=new RegExp(`(?<=\\s|^|[^a-zA-Z0-9])${r}(?=\\s|$|[^a-zA-Z0-9])`,"gi");o=o.replace(m,e=>{if(j&&e.length>2){let i=e[0],c=e[e.length-1],a=g.repeat(e.length-2);return i+a+c}return g.repeat(e.length)})}),o}d.exports={censorId:z,dictionary:f}});export default P();
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../dictionary.js","../index.js"],"sourcesContent":["/**\r\n * A comprehensive list of common Indonesian profanity, slang, and inappropriate words.\r\n */\r\nconst dictionary = [\r\n \"anjing\",\r\n \"asu\",\r\n \"babi\",\r\n \"bangsat\",\r\n \"bajing\",\r\n \"bajingan\",\r\n \"bedebah\",\r\n \"berak\",\r\n \"bejat\",\r\n \"brengsek\",\r\n \"buto\",\r\n \"cuk\",\r\n \"dancuk\",\r\n \"entot\",\r\n \"goblok\",\r\n \"itil\",\r\n \"jancuk\",\r\n \"jembut\",\r\n \"kontol\",\r\n \"kunyuk\",\r\n \"lonte\",\r\n \"memek\",\r\n \"monyet\",\r\n \"ngentot\",\r\n \"pantat\",\r\n \"perek\",\r\n \"puki\",\r\n \"setan\",\r\n \"siak\",\r\n \"sinting\",\r\n \"tai\",\r\n \"tolol\"\r\n];\r\n\r\nmodule.exports = dictionary;\r\n","const defaultDictionary = require(\"./dictionary\");\r\n\r\n/**\r\n * Censor Indonesian profanity and inappropriate words.\r\n *\r\n * @param {string} text - The input text to be filtered.\r\n * @param {object} options - Filtering options.\r\n * @param {string} options.mask - The character used to mask the words (default is '*').\r\n * @param {string[]} options.customWords - An array of additional words to censor.\r\n * @param {boolean} options.keepFirstAndLast - If true, keeps the first and last letters visible (default is false).\r\n * @returns {string} - The censored text.\r\n */\r\nfunction censorId(text, options = {}) {\r\n if (typeof text !== \"string\") {\r\n return text;\r\n }\r\n\r\n const {\r\n mask = \"*\",\r\n customWords = [],\r\n keepFirstAndLast = false\r\n } = options;\r\n\r\n // Merge default dictionary with custom words\r\n const wordsToCensor = [...new Set([...defaultDictionary, ...customWords])];\r\n\r\n
|
|
1
|
+
{"version":3,"sources":["../dictionary.js","../index.js"],"sourcesContent":["/**\r\n * A comprehensive list of common Indonesian profanity, slang, and inappropriate words.\r\n */\r\nconst dictionary = [\r\n \"anjing\",\r\n \"asu\",\r\n \"babi\",\r\n \"bangsat\",\r\n \"bajing\",\r\n \"bajingan\",\r\n \"bedebah\",\r\n \"berak\",\r\n \"bejat\",\r\n \"brengsek\",\r\n \"buto\",\r\n \"cuk\",\r\n \"dancuk\",\r\n \"entot\",\r\n \"goblok\",\r\n \"itil\",\r\n \"jancuk\",\r\n \"jembut\",\r\n \"kontol\",\r\n \"kunyuk\",\r\n \"lonte\",\r\n \"memek\",\r\n \"monyet\",\r\n \"ngentot\",\r\n \"pantat\",\r\n \"perek\",\r\n \"puki\",\r\n \"setan\",\r\n \"siak\",\r\n \"sinting\",\r\n \"tai\",\r\n \"tolol\"\r\n];\r\n\r\nmodule.exports = dictionary;\r\n","const defaultDictionary = require(\"./dictionary\");\r\n\r\n// Leetspeak mapping\r\nconst leetMap = {\r\n \"4\": \"a\",\r\n \"3\": \"e\",\r\n \"1\": \"i\",\r\n \"0\": \"o\",\r\n \"5\": \"s\",\r\n \"7\": \"t\",\r\n \"8\": \"b\",\r\n \"9\": \"g\",\r\n \"@\": \"a\",\r\n \"$\": \"s\",\r\n \"!\": \"i\",\r\n \"(\": \"c\"\r\n};\r\n\r\n/**\r\n * Censor Indonesian profanity and inappropriate words.\r\n *\r\n * @param {string} text - The input text to be filtered.\r\n * @param {object} options - Filtering options.\r\n * @param {string} options.mask - The character used to mask the words (default is '*').\r\n * @param {string[]} options.customWords - An array of additional words to censor.\r\n * @param {boolean} options.keepFirstAndLast - If true, keeps the first and last letters visible (default is false).\r\n * @param {boolean} options.smartMode - If true, handles leetspeak and repeated characters (default is false).\r\n * @returns {string} - The censored text.\r\n */\r\nfunction censorId(text, options = {}) {\r\n if (typeof text !== \"string\") {\r\n return text;\r\n }\r\n\r\n const {\r\n mask = \"*\",\r\n customWords = [],\r\n keepFirstAndLast = false,\r\n smartMode = false\r\n } = options;\r\n\r\n // Merge default dictionary with custom words and sort by length descending\r\n const wordsToCensor = [...new Set([...defaultDictionary, ...customWords])].sort((a, b) => b.length - a.length);\r\n\r\n let censoredText = text;\r\n\r\n // Iterate over each word and apply masking\r\n wordsToCensor.forEach(word => {\r\n let searchPattern;\r\n if (smartMode) {\r\n // Create a pattern that allows:\r\n // 1. Any number of repeats for each character (e.g., a+n+j+i+n+g+)\r\n // 2. Optional non-alphanumeric characters between letters (e.g., a[...]*n[...]*j)\r\n // 3. Mapping of leetspeak characters\r\n\r\n const charPatterns = Array.from(word).map((char, index) => {\r\n const lowerChar = char.toLowerCase();\r\n const leetChars = Object.keys(leetMap).filter(key => leetMap[key] === lowerChar);\r\n const variants = [lowerChar, ...leetChars].map(c => c.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\r\n\r\n // Only allow non-alphanumeric between characters, not after the last one\r\n const suffix = index === word.length - 1 ? \"+\" : \"+[^a-zA-Z0-9]*\";\r\n return `[${variants.join(\"\")}]${suffix}`;\r\n });\r\n\r\n searchPattern = charPatterns.join(\"\");\r\n } else {\r\n // Standard escaping for regex\r\n searchPattern = word.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n }\r\n\r\n const regex = new RegExp(`(?<=\\\\s|^|[^a-zA-Z0-9])${searchPattern}(?=\\\\s|$|[^a-zA-Z0-9])`, \"gi\");\r\n\r\n censoredText = censoredText.replace(regex, (match) => {\r\n if (keepFirstAndLast && match.length > 2) {\r\n const first = match[0];\r\n const last = match[match.length - 1];\r\n const middle = mask.repeat(match.length - 2);\r\n return first + middle + last;\r\n }\r\n return mask.repeat(match.length);\r\n });\r\n });\r\n\r\n return censoredText;\r\n}\r\n\r\nmodule.exports = {\r\n censorId,\r\n dictionary: defaultDictionary\r\n};\r\n"],"mappings":"8DAAA,IAAAA,EAAAC,EAAA,CAAAC,EAAAC,IAAA,CAGA,IAAMC,EAAa,CACjB,SACA,MACA,OACA,UACA,SACA,WACA,UACA,QACA,QACA,WACA,OACA,MACA,SACA,QACA,SACA,OACA,SACA,SACA,SACA,SACA,QACA,QACA,SACA,UACA,SACA,QACA,OACA,QACA,OACA,UACA,MACA,OACF,EAEAD,EAAO,QAAUC,ICtCjB,IAAAC,EAAAC,EAAA,CAAAC,EAAAC,IAAA,KAAMC,EAAoB,IAGpBC,EAAU,CACZ,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,IAAK,IACL,EAAK,IACL,IAAK,IACL,IAAK,GACT,EAaA,SAASC,EAASC,EAAMC,EAAU,CAAC,EAAG,CAClC,GAAI,OAAOD,GAAS,SAChB,OAAOA,EAGX,GAAM,CACF,KAAAE,EAAO,IACP,YAAAC,EAAc,CAAC,EACf,iBAAAC,EAAmB,GACnB,UAAAC,EAAY,EAChB,EAAIJ,EAGEK,EAAgB,CAAC,GAAG,IAAI,IAAI,CAAC,GAAGT,EAAmB,GAAGM,CAAW,CAAC,CAAC,EAAE,KAAK,CAACI,EAAGC,IAAMA,EAAE,OAASD,EAAE,MAAM,EAEzGE,EAAeT,EAGnB,OAAAM,EAAc,QAAQI,GAAQ,CAC1B,IAAIC,EACAN,EAgBAM,EAVqB,MAAM,KAAKD,CAAI,EAAE,IAAI,CAACE,EAAMC,IAAU,CACvD,IAAMC,EAAYF,EAAK,YAAY,EAC7BG,EAAY,OAAO,KAAKjB,CAAO,EAAE,OAAOkB,GAAOlB,EAAQkB,CAAG,IAAMF,CAAS,EACzEG,EAAW,CAACH,EAAW,GAAGC,CAAS,EAAE,IAAIG,GAAKA,EAAE,QAAQ,sBAAuB,MAAM,CAAC,EAGtFC,EAASN,IAAUH,EAAK,OAAS,EAAI,IAAM,iBACjD,MAAO,IAAIO,EAAS,KAAK,EAAE,CAAC,IAAIE,CAAM,EAC1C,CAAC,EAE4B,KAAK,EAAE,EAGpCR,EAAgBD,EAAK,QAAQ,sBAAuB,MAAM,EAG9D,IAAMU,EAAQ,IAAI,OAAO,0BAA0BT,CAAa,yBAA0B,IAAI,EAE9FF,EAAeA,EAAa,QAAQW,EAAQC,GAAU,CAClD,GAAIjB,GAAoBiB,EAAM,OAAS,EAAG,CACtC,IAAMC,EAAQD,EAAM,CAAC,EACfE,EAAOF,EAAMA,EAAM,OAAS,CAAC,EAC7BG,EAAStB,EAAK,OAAOmB,EAAM,OAAS,CAAC,EAC3C,OAAOC,EAAQE,EAASD,CAC5B,CACA,OAAOrB,EAAK,OAAOmB,EAAM,MAAM,CACnC,CAAC,CACL,CAAC,EAEMZ,CACX,CAEAb,EAAO,QAAU,CACb,SAAAG,EACA,WAAYF,CAChB","names":["require_dictionary","__commonJSMin","exports","module","dictionary","require_index","__commonJSMin","exports","module","defaultDictionary","leetMap","censorId","text","options","mask","customWords","keepFirstAndLast","smartMode","wordsToCensor","a","b","censoredText","word","searchPattern","char","index","lowerChar","leetChars","key","variants","c","suffix","regex","match","first","last","middle"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "censorship-id",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A robust Indonesian profanity filter for detecting and masking inappropriate words.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -41,4 +41,4 @@
|
|
|
41
41
|
"tsup": "^8.5.1",
|
|
42
42
|
"typescript": "^6.0.2"
|
|
43
43
|
}
|
|
44
|
-
}
|
|
44
|
+
}
|