censorship-id 1.0.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 +71 -0
- package/dist/index.d.mts +38 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# censorship-id
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/censorship-id)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
A robust and simple npm package for detecting and masking Indonesian profanity, slang, and inappropriate words.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Comprehensive Dictionary**: Pre-loaded with hundreds of common Indonesian bad words.
|
|
11
|
+
- **Regex Powered**: Uses word boundaries to avoid false positives (e.g., masking "tai" but not "pantai").
|
|
12
|
+
- **Customizable**: Add your own words to the list and choose your mask character.
|
|
13
|
+
- **Keep First and Last**: Option to keep the first and last letters visible for better context.
|
|
14
|
+
- **Case-Insensitive**: Matches words regardless of their case.
|
|
15
|
+
- **Lightweight**: Zero dependencies (only uses Jest for development).
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install censorship-id
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Basic Usage
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
const { censorId } = require('censorship-id');
|
|
29
|
+
|
|
30
|
+
const text = "Dasar anjing kau, babi!";
|
|
31
|
+
const censored = censorId(text);
|
|
32
|
+
console.log(censored);
|
|
33
|
+
// Output: Dasar ****** kau, ****!
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Advanced Usage (Options)
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
const { censorId } = require('censorship-id');
|
|
40
|
+
|
|
41
|
+
const text = "Dasar anjing kau, babi!";
|
|
42
|
+
|
|
43
|
+
// 1. Using a custom mask
|
|
44
|
+
const customMask = censorId(text, { mask: '#' });
|
|
45
|
+
console.log(customMask);
|
|
46
|
+
// Output: Dasar ###### kau, ####!
|
|
47
|
+
|
|
48
|
+
// 2. Keeping first and last letters
|
|
49
|
+
const visible = censorId(text, { keepFirstAndLast: true });
|
|
50
|
+
console.log(visible);
|
|
51
|
+
// Output: Dasar a****g kau, b**i!
|
|
52
|
+
|
|
53
|
+
// 3. Adding custom words to censor
|
|
54
|
+
const customWords = censorId("Kamu sangat malas!", { customWords: ['malas'] });
|
|
55
|
+
console.log(customWords);
|
|
56
|
+
// Output: Kamu sangat *****!
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## API Reference
|
|
60
|
+
|
|
61
|
+
### `censorId(text, options)`
|
|
62
|
+
|
|
63
|
+
- **`text`** (string): The input text to be filtered.
|
|
64
|
+
- **`options`** (object): Optional configuration.
|
|
65
|
+
- **`mask`** (string): The character used to mask words (default: `*`).
|
|
66
|
+
- **`customWords`** (string[]): Additional words to censor.
|
|
67
|
+
- **`keepFirstAndLast`** (boolean): If `true`, the first and last letters of the word remain visible (default: `false`).
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT © [rheatkhs](https://github.com/rheatkhs)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for the censorship filter.
|
|
3
|
+
*/
|
|
4
|
+
interface CensorIdOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The character used to mask the words.
|
|
7
|
+
* @default '*'
|
|
8
|
+
*/
|
|
9
|
+
mask?: string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* An array of additional words to censor.
|
|
13
|
+
*/
|
|
14
|
+
customWords?: string[];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* If true, keeps the first and last letters visible (e.g., "a****g").
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
keepFirstAndLast?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Censors Indonesian profanity and inappropriate words from the given text.
|
|
25
|
+
*
|
|
26
|
+
* @param text The input text to be filtered.
|
|
27
|
+
* @param options Configuration for filtering behavior.
|
|
28
|
+
* @returns The censored text.
|
|
29
|
+
*/
|
|
30
|
+
declare function censorId(text: string, options?: CensorIdOptions): string;
|
|
31
|
+
declare function censorId<T>(text: T, options?: CensorIdOptions): T;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The default dictionary of Indonesian profanity used by the filter.
|
|
35
|
+
*/
|
|
36
|
+
declare const dictionary: string[];
|
|
37
|
+
|
|
38
|
+
export { type CensorIdOptions, censorId, dictionary };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for the censorship filter.
|
|
3
|
+
*/
|
|
4
|
+
interface CensorIdOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The character used to mask the words.
|
|
7
|
+
* @default '*'
|
|
8
|
+
*/
|
|
9
|
+
mask?: string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* An array of additional words to censor.
|
|
13
|
+
*/
|
|
14
|
+
customWords?: string[];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* If true, keeps the first and last letters visible (e.g., "a****g").
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
keepFirstAndLast?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Censors Indonesian profanity and inappropriate words from the given text.
|
|
25
|
+
*
|
|
26
|
+
* @param text The input text to be filtered.
|
|
27
|
+
* @param options Configuration for filtering behavior.
|
|
28
|
+
* @returns The censored text.
|
|
29
|
+
*/
|
|
30
|
+
declare function censorId(text: string, options?: CensorIdOptions): string;
|
|
31
|
+
declare function censorId<T>(text: T, options?: CensorIdOptions): T;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The default dictionary of Indonesian profanity used by the filter.
|
|
35
|
+
*/
|
|
36
|
+
declare const dictionary: string[];
|
|
37
|
+
|
|
38
|
+
export { type CensorIdOptions, censorId, dictionary };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var f=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var i=f((m,a)=>{var j=["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"];a.exports=j});var c=i();function y(t,e={}){if(typeof t!="string")return t;let{mask:r="*",customWords:g=[],keepFirstAndLast:l=!1}=e,u=[...new Set([...c,...g])].map(s=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),o=t;return u.forEach(s=>{let d=new RegExp(`(?<=\\s|^|[^a-zA-Z0-9])${s}(?=\\s|$|[^a-zA-Z0-9])`,"gi");o=o.replace(d,n=>{if(l&&n.length>2){let k=n[0],p=n[n.length-1],b=r.repeat(n.length-2);return k+b+p}return r.repeat(n.length)})}),o}module.exports={censorId:y,dictionary:c};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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 // Escape special characters in words for safety in Regex\r\n const escapedWords = wordsToCensor.map(word =>\r\n word.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\r\n );\r\n\r\n let censoredText = text;\r\n\r\n // Iterate over each word and apply masking\r\n escapedWords.forEach(word => {\r\n // Regex with word boundaries (\\b) and case-insensitive flag (i)\r\n // Note: \\b doesn't work well with non-ASCII characters, but for Indonesian it's generally fine.\r\n // However, for more robustness with various symbols, we use a pattern that matches word start/end.\r\n const regex = new RegExp(`(?<=\\\\s|^|[^a-zA-Z0-9])${word}(?=\\\\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,IAY1B,SAASC,EAASC,EAAMC,EAAU,CAAC,EAAG,CAClC,GAAI,OAAOD,GAAS,SAChB,OAAOA,EAGX,GAAM,CACF,KAAAE,EAAO,IACP,YAAAC,EAAc,CAAC,EACf,iBAAAC,EAAmB,EACvB,EAAIH,EAMEI,EAHgB,CAAC,GAAG,IAAI,IAAI,CAAC,GAAGP,EAAmB,GAAGK,CAAW,CAAC,CAAC,EAGtC,IAAIG,GACnCA,EAAK,QAAQ,sBAAuB,MAAM,CAC9C,EAEIC,EAAeP,EAGnB,OAAAK,EAAa,QAAQC,GAAQ,CAIzB,IAAME,EAAQ,IAAI,OAAO,0BAA0BF,CAAI,yBAA0B,IAAI,EAErFC,EAAeA,EAAa,QAAQC,EAAQC,GAAU,CAClD,GAAIL,GAAoBK,EAAM,OAAS,EAAG,CACtC,IAAMC,EAAQD,EAAM,CAAC,EACfE,EAAOF,EAAMA,EAAM,OAAS,CAAC,EAC7BG,EAASV,EAAK,OAAOO,EAAM,OAAS,CAAC,EAC3C,OAAOC,EAAQE,EAASD,CAC5B,CACA,OAAOT,EAAK,OAAOO,EAAM,MAAM,CACnC,CAAC,CACL,CAAC,EAEMF,CACX,CAEA,OAAO,QAAU,CACb,SAAAR,EACA,WAAYD,CAChB","names":["require_dictionary","__commonJSMin","exports","module","dictionary","defaultDictionary","censorId","text","options","mask","customWords","keepFirstAndLast","escapedWords","word","censoredText","regex","match","first","last","middle"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var a=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var c=a((A,i)=>{var y=["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"];i.exports=y});var $=a((T,l)=>{var g=c();function w(t,e={}){if(typeof t!="string")return t;let{mask:r="*",customWords:u=[],keepFirstAndLast:d=!1}=e,k=[...new Set([...g,...u])].map(s=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),o=t;return k.forEach(s=>{let p=new RegExp(`(?<=\\s|^|[^a-zA-Z0-9])${s}(?=\\s|$|[^a-zA-Z0-9])`,"gi");o=o.replace(p,n=>{if(d&&n.length>2){let b=n[0],f=n[n.length-1],j=r.repeat(n.length-2);return b+j+f}return r.repeat(n.length)})}),o}l.exports={censorId:w,dictionary:g}});export default $();
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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 // Escape special characters in words for safety in Regex\r\n const escapedWords = wordsToCensor.map(word =>\r\n word.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\r\n );\r\n\r\n let censoredText = text;\r\n\r\n // Iterate over each word and apply masking\r\n escapedWords.forEach(word => {\r\n // Regex with word boundaries (\\b) and case-insensitive flag (i)\r\n // Note: \\b doesn't work well with non-ASCII characters, but for Indonesian it's generally fine.\r\n // However, for more robustness with various symbols, we use a pattern that matches word start/end.\r\n const regex = new RegExp(`(?<=\\\\s|^|[^a-zA-Z0-9])${word}(?=\\\\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,IAY1B,SAASC,EAASC,EAAMC,EAAU,CAAC,EAAG,CAClC,GAAI,OAAOD,GAAS,SAChB,OAAOA,EAGX,GAAM,CACF,KAAAE,EAAO,IACP,YAAAC,EAAc,CAAC,EACf,iBAAAC,EAAmB,EACvB,EAAIH,EAMEI,EAHgB,CAAC,GAAG,IAAI,IAAI,CAAC,GAAGP,EAAmB,GAAGK,CAAW,CAAC,CAAC,EAGtC,IAAIG,GACnCA,EAAK,QAAQ,sBAAuB,MAAM,CAC9C,EAEIC,EAAeP,EAGnB,OAAAK,EAAa,QAAQC,GAAQ,CAIzB,IAAME,EAAQ,IAAI,OAAO,0BAA0BF,CAAI,yBAA0B,IAAI,EAErFC,EAAeA,EAAa,QAAQC,EAAQC,GAAU,CAClD,GAAIL,GAAoBK,EAAM,OAAS,EAAG,CACtC,IAAMC,EAAQD,EAAM,CAAC,EACfE,EAAOF,EAAMA,EAAM,OAAS,CAAC,EAC7BG,EAASV,EAAK,OAAOO,EAAM,OAAS,CAAC,EAC3C,OAAOC,EAAQE,EAASD,CAC5B,CACA,OAAOT,EAAK,OAAOO,EAAM,MAAM,CACnC,CAAC,CACL,CAAC,EAEMF,CACX,CAEAV,EAAO,QAAU,CACb,SAAAE,EACA,WAAYD,CAChB","names":["require_dictionary","__commonJSMin","exports","module","dictionary","require_index","__commonJSMin","exports","module","defaultDictionary","censorId","text","options","mask","customWords","keepFirstAndLast","escapedWords","word","censoredText","regex","match","first","last","middle"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "censorship-id",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A robust Indonesian profanity filter for detecting and masking inappropriate words.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"require": "./dist/index.js",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"test": "jest",
|
|
22
|
+
"lint": "eslint ."
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"indonesia",
|
|
26
|
+
"profanity",
|
|
27
|
+
"filter",
|
|
28
|
+
"sensor",
|
|
29
|
+
"kata kasar",
|
|
30
|
+
"censorship",
|
|
31
|
+
"bahasa-indonesia",
|
|
32
|
+
"slang"
|
|
33
|
+
],
|
|
34
|
+
"author": "rheatkhs",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=12.0.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"jest": "^29.7.0",
|
|
41
|
+
"tsup": "^8.5.1",
|
|
42
|
+
"typescript": "^6.0.2"
|
|
43
|
+
}
|
|
44
|
+
}
|