@sideid/id-profanity-filter 1.1.0 → 1.9.5

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.
Files changed (41) hide show
  1. package/dist/config/options.d.ts +258 -0
  2. package/dist/constants/categories/insult.d.ts +1 -1
  3. package/dist/constants/categories/sexual.d.ts +1 -1
  4. package/dist/constants/regions/batak.d.ts +1 -1
  5. package/dist/constants/regions/betawi.d.ts +1 -1
  6. package/dist/constants/regions/general.d.ts +1 -1
  7. package/dist/constants/regions/jawa.d.ts +1 -1
  8. package/dist/constants/regions/sunda.d.ts +1 -1
  9. package/dist/constants/wordList.d.ts +1 -1
  10. package/dist/core/analyzer.d.ts +4 -4
  11. package/dist/core/filter.d.ts +1 -1
  12. package/dist/core/matcher.d.ts +5 -5
  13. package/dist/index.d.ts +30 -42
  14. package/dist/index.esm.js +1070 -432
  15. package/dist/index.esm.js.map +1 -1
  16. package/dist/index.js +1101 -429
  17. package/dist/index.js.map +1 -1
  18. package/dist/types/index.d.ts +29 -41
  19. package/dist/utils/regexUtils.d.ts +64 -0
  20. package/dist/utils/similarityUtils.d.ts +57 -0
  21. package/dist/utils/stringUtils.d.ts +79 -0
  22. package/package.json +1 -1
  23. package/src/config/options.ts +178 -0
  24. package/src/constants/categories/index.ts +31 -31
  25. package/src/constants/categories/insult.ts +114 -114
  26. package/src/constants/categories/sexual.ts +99 -100
  27. package/src/constants/regions/batak.ts +17 -17
  28. package/src/constants/regions/betawi.ts +39 -39
  29. package/src/constants/regions/general.ts +111 -111
  30. package/src/constants/regions/index.ts +62 -62
  31. package/src/constants/regions/jawa.ts +102 -102
  32. package/src/constants/regions/sunda.ts +35 -35
  33. package/src/constants/wordList.ts +125 -125
  34. package/src/core/analyzer.ts +225 -204
  35. package/src/core/filter.ts +129 -129
  36. package/src/core/matcher.ts +259 -267
  37. package/src/index.ts +188 -133
  38. package/src/types/index.ts +88 -115
  39. package/src/utils/regexUtils.ts +203 -0
  40. package/src/utils/similarityUtils.ts +195 -0
  41. package/src/utils/stringUtils.ts +213 -0
package/src/index.ts CHANGED
@@ -1,133 +1,188 @@
1
- export * from './types';
2
- export * from './core/matcher';
3
- export * from './core/filter';
4
- export * from './core/analyzer';
5
-
6
- import { filter, isProfane } from './core/filter';
7
- import {
8
- analyze,
9
- batchAnalyze,
10
- analyzeBySentence,
11
- analyzeWithContext,
12
- } from './core/analyzer';
13
- import { FilterOptions, FilterResult, AnalysisResult } from './types';
14
-
15
- export class IDProfanityFilter {
16
- private options: FilterOptions;
17
-
18
- /**
19
- * Membuat instance filter baru
20
- * @param options Opsi untuk filter
21
- */
22
- constructor(options: FilterOptions = {}) {
23
- this.options = options;
24
- }
25
-
26
- /**
27
- * Menyensor teks yang diberikan
28
- * @param text Teks yang akan disensor
29
- * @returns Hasil filter
30
- */
31
- filter(text: string): FilterResult {
32
- return filter(text, this.options);
33
- }
34
-
35
- /**
36
- * Memeriksa apakah teks mengandung kata kotor
37
- * @param text Teks yang akan diperiksa
38
- * @returns Boolean apakah teks mengandung kata kotor
39
- */
40
- isProfane(text: string): boolean {
41
- return isProfane(text, this.options);
42
- }
43
-
44
- /**
45
- * Menganalisis teks untuk kata kotor
46
- * @param text Teks yang akan dianalisis
47
- * @returns Hasil analisis
48
- */
49
- analyze(text: string): AnalysisResult {
50
- return analyze(text, this.options);
51
- }
52
-
53
- /**
54
- * Menganalisis batch teks untuk kata kotor
55
- * @param texts Array dari teks yang akan dianalisis
56
- * @returns Hasil analisis batch
57
- */
58
- batchAnalyze(texts: string[]) {
59
- return batchAnalyze(texts, this.options);
60
- }
61
-
62
- /**
63
- * Menganalisis teks per-kalimat
64
- * @param text Teks yang akan dianalisis
65
- * @returns Array hasil analisis per-kalimat
66
- */
67
- analyzeBySentence(text: string) {
68
- return analyzeBySentence(text, this.options);
69
- }
70
-
71
- /**
72
- * Menganalisis teks dengan konteks di sekitar kata kotor
73
- * @param text Teks yang akan dianalisis
74
- * @param contextWindowSize Jumlah kata konteks
75
- * @returns Konteks di dekat kata kotor
76
- */
77
- analyzeWithContext(text: string, contextWindowSize: number = 5) {
78
- return analyzeWithContext(text, contextWindowSize, this.options);
79
- }
80
-
81
- /**
82
- * Mengubah opsi filter
83
- * @param options Opsi baru untuk filter
84
- */
85
- setOptions(options: Partial<FilterOptions>) {
86
- this.options = {
87
- ...this.options,
88
- ...options,
89
- };
90
- }
91
-
92
- /**
93
- * Menetapkan daftar kata kustom
94
- * @param wordList Daftar kata untuk digunakan
95
- */
96
- setWordList(wordList: string[]) {
97
- this.options.wordList = wordList;
98
- }
99
-
100
- /**
101
- * Menambahkan kata ke whitelist
102
- * @param word Kata yang akan diabaikan
103
- */
104
- addToWhitelist(word: string) {
105
- this.options.whitelist = [
106
- ...(this.options.whitelist || []),
107
- word.toLowerCase(),
108
- ];
109
- }
110
-
111
- /**
112
- * Menghapus kata dari whitelist
113
- * @param word Kata yang akan dihapus dari whitelist
114
- */
115
- removeFromWhitelist(word: string) {
116
- if (!this.options.whitelist) return;
117
-
118
- this.options.whitelist = this.options.whitelist.filter(
119
- (w) => w.toLowerCase() !== word.toLowerCase(),
120
- );
121
- }
122
- }
123
-
124
- export default IDProfanityFilter;
125
-
126
- export const idFilter = {
127
- filter: (text: string, options?: FilterOptions) => filter(text, options),
128
- isProfane: (text: string, options?: FilterOptions) =>
129
- isProfane(text, options),
130
- analyze: (text: string, options?: FilterOptions) => analyze(text, options),
131
- batchAnalyze: (texts: string[], options?: FilterOptions) =>
132
- batchAnalyze(texts, options),
133
- };
1
+ export * from "./types";
2
+ export * from "./core/matcher";
3
+ export * from "./core/filter";
4
+ export * from "./core/analyzer";
5
+ export * from "./utils/stringUtils";
6
+ export * from "./utils/regexUtils";
7
+ export * from "./utils/similarityUtils";
8
+ export * from "./config/options";
9
+
10
+ import { filter, isProfane } from "./core/filter";
11
+ import {
12
+ analyze,
13
+ batchAnalyze,
14
+ analyzeBySentence,
15
+ analyzeWithContext,
16
+ } from "./core/analyzer";
17
+ import { FilterOptions, FilterResult, AnalysisResult } from "./types";
18
+ import {
19
+ DEFAULT_OPTIONS,
20
+ FILTER_PRESETS,
21
+ CATEGORY_PRESETS,
22
+ REGION_PRESETS,
23
+ getPresetOptions,
24
+ makeRandomGrawlixString,
25
+ } from "./config/options";
26
+
27
+ export class IDProfanityFilter {
28
+ private options: FilterOptions;
29
+
30
+ /**
31
+ * Membuat instance filter baru
32
+ * @param options Opsi untuk filter
33
+ */
34
+ constructor(options: FilterOptions = {}) {
35
+ this.options = { ...DEFAULT_OPTIONS, ...options };
36
+ }
37
+
38
+ /**
39
+ * Menyensor teks yang diberikan
40
+ * @param text Teks yang akan disensor
41
+ * @returns Hasil filter
42
+ */
43
+ filter(text: string): FilterResult {
44
+ return filter(text, this.options);
45
+ }
46
+
47
+ /**
48
+ * Memeriksa apakah teks mengandung kata kotor
49
+ * @param text Teks yang akan diperiksa
50
+ * @returns Boolean apakah teks mengandung kata kotor
51
+ */
52
+ isProfane(text: string): boolean {
53
+ return isProfane(text, this.options);
54
+ }
55
+
56
+ /**
57
+ * Menganalisis teks untuk kata kotor
58
+ * @param text Teks yang akan dianalisis
59
+ * @returns Hasil analisis
60
+ */
61
+ analyze(text: string): AnalysisResult {
62
+ return analyze(text, this.options);
63
+ }
64
+
65
+ /**
66
+ * Menganalisis batch teks untuk kata kotor
67
+ * @param texts Array dari teks yang akan dianalisis
68
+ * @returns Hasil analisis batch
69
+ */
70
+ batchAnalyze(texts: string[]) {
71
+ return batchAnalyze(texts, this.options);
72
+ }
73
+
74
+ /**
75
+ * Menganalisis teks per-kalimat
76
+ * @param text Teks yang akan dianalisis
77
+ * @returns Array hasil analisis per-kalimat
78
+ */
79
+ analyzeBySentence(text: string) {
80
+ return analyzeBySentence(text, this.options);
81
+ }
82
+
83
+ /**
84
+ * Menganalisis teks dengan konteks di sekitar kata kotor
85
+ * @param text Teks yang akan dianalisis
86
+ * @param contextWindowSize Jumlah kata konteks
87
+ * @returns Konteks di dekat kata kotor
88
+ */
89
+ analyzeWithContext(text: string, contextWindowSize: number = 5) {
90
+ return analyzeWithContext(text, contextWindowSize, this.options);
91
+ }
92
+
93
+ /**
94
+ * Mengubah opsi filter
95
+ * @param options Opsi baru untuk filter
96
+ */
97
+ setOptions(options: Partial<FilterOptions>) {
98
+ this.options = {
99
+ ...this.options,
100
+ ...options,
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Menggunakan preset yang telah ditentukan
106
+ * @param presetName Nama preset yang akan digunakan
107
+ * @param additionalOptions Opsi tambahan untuk override
108
+ */
109
+ usePreset(
110
+ presetName: string,
111
+ additionalOptions: Partial<FilterOptions> = {},
112
+ ) {
113
+ this.options = getPresetOptions(presetName, additionalOptions);
114
+ }
115
+
116
+ /**
117
+ * Menetapkan daftar kata kustom
118
+ * @param wordList Daftar kata untuk digunakan
119
+ */
120
+ setWordList(wordList: string[]) {
121
+ this.options.wordList = wordList;
122
+ }
123
+
124
+ /**
125
+ * Menambahkan kata ke whitelist
126
+ * @param word Kata yang akan diabaikan
127
+ */
128
+ addToWhitelist(word: string) {
129
+ this.options.whitelist = [
130
+ ...(this.options.whitelist || []),
131
+ word.toLowerCase(),
132
+ ];
133
+ }
134
+
135
+ /**
136
+ * Menghapus kata dari whitelist
137
+ * @param word Kata yang akan dihapus dari whitelist
138
+ */
139
+ removeFromWhitelist(word: string) {
140
+ if (!this.options.whitelist) return;
141
+
142
+ this.options.whitelist = this.options.whitelist.filter(
143
+ (w) => w.toLowerCase() !== word.toLowerCase(),
144
+ );
145
+ }
146
+
147
+ /**
148
+ * Mengaktifkan deteksi variasi ejaan Indonesia
149
+ */
150
+ enableIndonesianVariations() {
151
+ this.options.indonesianVariation = true;
152
+ }
153
+
154
+ /**
155
+ * Mengaktifkan deteksi kata yang dipisah
156
+ */
157
+ enableSplitWordDetection() {
158
+ this.options.detectSplit = true;
159
+ }
160
+
161
+ /**
162
+ * Mengaktifkan deteksi berdasarkan kesamaan
163
+ * @param threshold Threshold kesamaan (0-1)
164
+ */
165
+ enableSimilarityDetection(threshold: number = 0.8) {
166
+ this.options.detectSimilarity = true;
167
+ this.options.similarityThreshold = threshold;
168
+ }
169
+ }
170
+
171
+ export default IDProfanityFilter;
172
+
173
+ export const idFilter = {
174
+ filter: (text: string, options?: FilterOptions) =>
175
+ filter(text, { ...DEFAULT_OPTIONS, ...options }),
176
+ isProfane: (text: string, options?: FilterOptions) =>
177
+ isProfane(text, { ...DEFAULT_OPTIONS, ...options }),
178
+ analyze: (text: string, options?: FilterOptions) =>
179
+ analyze(text, { ...DEFAULT_OPTIONS, ...options }),
180
+ batchAnalyze: (texts: string[], options?: FilterOptions) =>
181
+ batchAnalyze(texts, { ...DEFAULT_OPTIONS, ...options }),
182
+ getPresetOptions,
183
+ presets: {
184
+ filter: FILTER_PRESETS,
185
+ category: CATEGORY_PRESETS,
186
+ region: REGION_PRESETS,
187
+ },
188
+ };
@@ -1,115 +1,88 @@
1
- export type ProfanityCategory =
2
- | 'sexual' // Kata-kata berbau seksual
3
- | 'insult' // Kata-kata penghinaan
4
- | 'profanity' // Umpatan umum
5
- | 'slur' // Perkataan merendahkan berdasarkan identitas
6
- | 'drugs' // Terkait narkoba
7
- | 'disgusting' // Kata-kata menjijikkan
8
- | 'blasphemy'; // Penistaan agama
9
-
10
-
11
- export type Region =
12
- | 'general' // Umum di Indonesia
13
- | 'jawa'
14
- | 'sunda'
15
- | 'betawi'
16
- | 'batak'
17
- | 'minang'
18
- | 'bali'
19
- | 'madura'
20
- | 'bugis'
21
- | 'aceh'
22
- | 'ambon'
23
- | 'papua'
24
- | 'manado'
25
- | 'banjar'
26
- | 'palembang'
27
- | 'lampung'
28
- | 'ntt'
29
- | 'ntb';
30
-
31
- /**
32
- * Definisi kata kotor
33
- */
34
- export interface ProfanityWord {
35
- word: string; // Kata kotor
36
- category: ProfanityCategory; // Kategori kata
37
- region: Region; // Daerah asal kata
38
- severity: number; // Tingkat keparahan (0-1)
39
- aliases?: string[]; // Variasi kata atau alias
40
- description?: string; // Deskripsi atau makna kata
41
- context?: string; // Konteks penggunaan kata
42
- }
43
-
44
- /**
45
- * Opsi untuk konfigurasi filter
46
- */
47
- export interface FilterOptions {
48
- /** List kata yang ingin difilter */
49
- wordList?: string[];
50
-
51
- /** Karakter pengganti untuk kata yang disensor */
52
- replaceWith?: string;
53
-
54
- /** Apakah harus menyensor seluruh kata atau hanya sebagian */
55
- fullWordCensor?: boolean;
56
-
57
- /** Apakah harus mendeteksi kata dengan variasi penulisan */
58
- detectLeetSpeak?: boolean;
59
-
60
- /** Mengabaikan kata-kata dalam konteks tertentu (misalnya nama) */
61
- whitelist?: string[];
62
-
63
- /** Apakah harus memeriksa substring (lebih ketat) */
64
- checkSubstring?: boolean;
65
-
66
- /** Kategori kata yang ingin difilter */
67
- categories?: ProfanityCategory[];
68
-
69
- /** Daerah yang ingin difilter katanya */
70
- regions?: Region[];
71
-
72
- /** Tingkat keparahan minimum yang akan difilter (0-1) */
73
- severityThreshold?: number;
74
- }
75
-
76
- /**
77
- * Hasil analisis dari teks
78
- */
79
- export interface AnalysisResult {
80
- /** Apakah teks mengandung kata kotor */
81
- hasProfanity: boolean;
82
-
83
- /** Daftar kata kotor yang ditemukan */
84
- matches: string[];
85
-
86
- /** Daftar kata kotor lengkap dengan metadata */
87
- matchDetails: ProfanityWord[];
88
-
89
- /** Daftar kategori kata kotor yang ditemukan */
90
- categories: ProfanityCategory[];
91
-
92
- /** Daftar daerah asal kata kotor yang ditemukan */
93
- regions: Region[];
94
-
95
- /** Tingkat keparahan (0-1) berdasarkan jumlah dan jenis kata */
96
- severityScore: number;
97
- }
98
-
99
- /**
100
- * Hasil filter dari teks
101
- */
102
- export interface FilterResult {
103
- /** Teks hasil filter */
104
- filtered: string;
105
-
106
- /** Jumlah kata yang disensor */
107
- censored: number;
108
-
109
- /** Kata asli yang disensor dan penggantinya */
110
- replacements: Array<{
111
- original: string;
112
- censored: string;
113
- metadata?: ProfanityWord;
114
- }>;
115
- }
1
+ export type ProfanityCategory =
2
+ | "sexual"
3
+ | "insult"
4
+ | "profanity"
5
+ | "slur"
6
+ | "drugs"
7
+ | "disgusting"
8
+ | "blasphemy";
9
+
10
+ export type Region =
11
+ | "general"
12
+ | "jawa"
13
+ | "sunda"
14
+ | "betawi"
15
+ | "batak"
16
+ | "minang"
17
+ | "bali"
18
+ | "madura"
19
+ | "bugis"
20
+ | "aceh"
21
+ | "ambon"
22
+ | "papua"
23
+ | "manado"
24
+ | "banjar"
25
+ | "palembang"
26
+ | "lampung"
27
+ | "ntt"
28
+ | "ntb";
29
+
30
+ export interface ProfanityWord {
31
+ word: string;
32
+ category: ProfanityCategory;
33
+ region: Region;
34
+ severity: number;
35
+ aliases?: string[];
36
+ description?: string;
37
+ context?: string;
38
+ }
39
+
40
+ export interface FilterOptions {
41
+ replaceWith?: string;
42
+ fullWordCensor?: boolean;
43
+ detectLeetSpeak?: boolean;
44
+ checkSubstring?: boolean;
45
+ wordList?: string[];
46
+ whitelist?: string[];
47
+ categories?: ProfanityCategory[];
48
+ regions?: Region[];
49
+ severityThreshold?: number;
50
+ useRandomGrawlix?: boolean;
51
+ keepFirstAndLast?: boolean;
52
+ indonesianVariation?: boolean;
53
+ detectSimilarity?: boolean;
54
+ similarityThreshold?: number;
55
+ detectSplit?: boolean;
56
+ }
57
+
58
+ export interface FilterResult {
59
+ filtered: string;
60
+ censored: number;
61
+ replacements: Array<{
62
+ original: string;
63
+ censored: string;
64
+ metadata?: ProfanityWord;
65
+ }>;
66
+ }
67
+
68
+ export interface AnalysisResult {
69
+ hasProfanity: boolean;
70
+ matches: string[];
71
+ matchDetails: ProfanityWord[];
72
+ categories: ProfanityCategory[];
73
+ regions: Region[];
74
+ severityScore: number;
75
+ similarWords?: Array<{
76
+ word: string;
77
+ original: string;
78
+ similarity: number;
79
+ }>;
80
+ }
81
+
82
+ export interface RegexOptions {
83
+ wholeWord?: boolean;
84
+ caseSensitive?: boolean;
85
+ leetSpeak?: boolean;
86
+ detectSplit?: boolean;
87
+ indonesianVariation?: boolean;
88
+ }