glin-profanity 1.1.8 → 2.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/lib/cjs/data/english.json +43 -15
- package/lib/cjs/data/globalWhitelist.json +31 -0
- package/lib/cjs/filters/Filter.d.ts +6 -3
- package/lib/cjs/filters/Filter.js +74 -69
- package/lib/cjs/filters/Filter.js.map +1 -1
- package/lib/cjs/hooks/useProfanityChecker.d.ts +3 -0
- package/lib/cjs/hooks/useProfanityChecker.js +17 -1
- package/lib/cjs/hooks/useProfanityChecker.js.map +1 -1
- package/lib/cjs/types/types.d.ts +6 -1
- package/lib/cjs/types/types.js +8 -0
- package/lib/cjs/types/types.js.map +1 -1
- package/lib/esm/data/english.json +43 -15
- package/lib/esm/data/globalWhitelist.json +31 -0
- package/lib/esm/filters/Filter.d.ts +6 -3
- package/lib/esm/filters/Filter.js +74 -69
- package/lib/esm/filters/Filter.js.map +1 -1
- package/lib/esm/hooks/useProfanityChecker.d.ts +3 -0
- package/lib/esm/hooks/useProfanityChecker.js +15 -2
- package/lib/esm/hooks/useProfanityChecker.js.map +1 -1
- package/lib/esm/types/types.d.ts +6 -1
- package/lib/esm/types/types.js +7 -1
- package/lib/esm/types/types.js.map +1 -1
- package/package.json +73 -54
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"words": [
|
|
3
|
-
"testbad01",
|
|
4
|
-
"2g1c",
|
|
5
3
|
"2 girls 1 cup",
|
|
4
|
+
"2g1c",
|
|
5
|
+
"a$$",
|
|
6
6
|
"acrotomophilia",
|
|
7
7
|
"alabama hot pocket",
|
|
8
8
|
"alaskan pipeline",
|
|
@@ -12,10 +12,13 @@
|
|
|
12
12
|
"apeshit",
|
|
13
13
|
"arsehole",
|
|
14
14
|
"ass",
|
|
15
|
+
"asshat",
|
|
15
16
|
"asshole",
|
|
16
17
|
"assmunch",
|
|
18
|
+
"asswipe",
|
|
17
19
|
"auto erotic",
|
|
18
20
|
"autoerotic",
|
|
21
|
+
"b!tch",
|
|
19
22
|
"babeland",
|
|
20
23
|
"baby batter",
|
|
21
24
|
"baby juice",
|
|
@@ -30,6 +33,7 @@
|
|
|
30
33
|
"barely legal",
|
|
31
34
|
"barenaked",
|
|
32
35
|
"bastard",
|
|
36
|
+
"bastardized",
|
|
33
37
|
"bastardo",
|
|
34
38
|
"bastinado",
|
|
35
39
|
"bbw",
|
|
@@ -50,9 +54,9 @@
|
|
|
50
54
|
"black cock",
|
|
51
55
|
"blonde action",
|
|
52
56
|
"blonde on blonde action",
|
|
53
|
-
"blowjob",
|
|
54
57
|
"blow job",
|
|
55
58
|
"blow your load",
|
|
59
|
+
"blowjob",
|
|
56
60
|
"blue waffle",
|
|
57
61
|
"blumpkin",
|
|
58
62
|
"bollocks",
|
|
@@ -63,6 +67,7 @@
|
|
|
63
67
|
"booty call",
|
|
64
68
|
"brown showers",
|
|
65
69
|
"brunette action",
|
|
70
|
+
"bs",
|
|
66
71
|
"bukkake",
|
|
67
72
|
"bulldyke",
|
|
68
73
|
"bullet vibe",
|
|
@@ -88,11 +93,12 @@
|
|
|
88
93
|
"clusterfuck",
|
|
89
94
|
"cock",
|
|
90
95
|
"cocks",
|
|
96
|
+
"cocksucker",
|
|
97
|
+
"coon",
|
|
98
|
+
"coons",
|
|
91
99
|
"coprolagnia",
|
|
92
100
|
"coprophilia",
|
|
93
101
|
"cornhole",
|
|
94
|
-
"coon",
|
|
95
|
-
"coons",
|
|
96
102
|
"creampie",
|
|
97
103
|
"cum",
|
|
98
104
|
"cumming",
|
|
@@ -106,15 +112,16 @@
|
|
|
106
112
|
"dendrophilia",
|
|
107
113
|
"dick",
|
|
108
114
|
"dildo",
|
|
109
|
-
"dingleberry",
|
|
110
115
|
"dingleberries",
|
|
116
|
+
"dingleberry",
|
|
117
|
+
"dipshit",
|
|
111
118
|
"dirty pillows",
|
|
112
119
|
"dirty sanchez",
|
|
120
|
+
"dog style",
|
|
113
121
|
"doggie style",
|
|
114
122
|
"doggiestyle",
|
|
115
123
|
"doggy style",
|
|
116
124
|
"doggystyle",
|
|
117
|
-
"dog style",
|
|
118
125
|
"dolcett",
|
|
119
126
|
"domination",
|
|
120
127
|
"dominatrix",
|
|
@@ -124,6 +131,7 @@
|
|
|
124
131
|
"double penetration",
|
|
125
132
|
"dp action",
|
|
126
133
|
"dry hump",
|
|
134
|
+
"dumbass",
|
|
127
135
|
"dvda",
|
|
128
136
|
"eat my ass",
|
|
129
137
|
"ecchi",
|
|
@@ -132,6 +140,8 @@
|
|
|
132
140
|
"erotism",
|
|
133
141
|
"escort",
|
|
134
142
|
"eunuch",
|
|
143
|
+
"f*ck",
|
|
144
|
+
"f@ck",
|
|
135
145
|
"faggot",
|
|
136
146
|
"fecal",
|
|
137
147
|
"felch",
|
|
@@ -148,12 +158,16 @@
|
|
|
148
158
|
"frotting",
|
|
149
159
|
"fuck",
|
|
150
160
|
"fuck buttons",
|
|
161
|
+
"fucker",
|
|
162
|
+
"fuckface",
|
|
151
163
|
"fuckin",
|
|
152
164
|
"fucking",
|
|
153
165
|
"fucktards",
|
|
154
166
|
"fudge packer",
|
|
155
167
|
"fudgepacker",
|
|
168
|
+
"fuq",
|
|
156
169
|
"futanari",
|
|
170
|
+
"g-spot",
|
|
157
171
|
"gang bang",
|
|
158
172
|
"gay sex",
|
|
159
173
|
"genitals",
|
|
@@ -166,18 +180,18 @@
|
|
|
166
180
|
"god damn",
|
|
167
181
|
"gokkun",
|
|
168
182
|
"golden shower",
|
|
169
|
-
"goodpoop",
|
|
170
183
|
"goo girl",
|
|
184
|
+
"goodpoop",
|
|
171
185
|
"goregasm",
|
|
172
186
|
"grope",
|
|
173
187
|
"group sex",
|
|
174
|
-
"g-spot",
|
|
175
188
|
"guro",
|
|
176
189
|
"hand job",
|
|
177
190
|
"handjob",
|
|
178
191
|
"hard core",
|
|
179
192
|
"hardcore",
|
|
180
193
|
"hentai",
|
|
194
|
+
"hoe",
|
|
181
195
|
"homoerotic",
|
|
182
196
|
"honkey",
|
|
183
197
|
"hooker",
|
|
@@ -190,6 +204,7 @@
|
|
|
190
204
|
"incest",
|
|
191
205
|
"intercourse",
|
|
192
206
|
"jack off",
|
|
207
|
+
"jackass",
|
|
193
208
|
"jail bait",
|
|
194
209
|
"jailbait",
|
|
195
210
|
"jelly donut",
|
|
@@ -207,12 +222,14 @@
|
|
|
207
222
|
"leather restraint",
|
|
208
223
|
"leather straight jacket",
|
|
209
224
|
"lemon party",
|
|
225
|
+
"lmfao",
|
|
210
226
|
"lolita",
|
|
211
227
|
"lovemaking",
|
|
212
228
|
"make me come",
|
|
213
229
|
"male squirting",
|
|
214
230
|
"masturbate",
|
|
215
231
|
"menage a trois",
|
|
232
|
+
"mf",
|
|
216
233
|
"milf",
|
|
217
234
|
"missionary position",
|
|
218
235
|
"motherfucker",
|
|
@@ -224,9 +241,9 @@
|
|
|
224
241
|
"nawashi",
|
|
225
242
|
"negro",
|
|
226
243
|
"neonazi",
|
|
244
|
+
"nig nog",
|
|
227
245
|
"nigga",
|
|
228
246
|
"nigger",
|
|
229
|
-
"nig nog",
|
|
230
247
|
"nimphomania",
|
|
231
248
|
"nipple",
|
|
232
249
|
"nipples",
|
|
@@ -236,6 +253,7 @@
|
|
|
236
253
|
"nympho",
|
|
237
254
|
"nymphomania",
|
|
238
255
|
"octopussy",
|
|
256
|
+
"omfg",
|
|
239
257
|
"omorashi",
|
|
240
258
|
"one cup two girls",
|
|
241
259
|
"one guy one jar",
|
|
@@ -251,8 +269,9 @@
|
|
|
251
269
|
"penis",
|
|
252
270
|
"phone sex",
|
|
253
271
|
"piece of shit",
|
|
254
|
-
"pissing",
|
|
255
272
|
"piss pig",
|
|
273
|
+
"pissed",
|
|
274
|
+
"pissing",
|
|
256
275
|
"pisspig",
|
|
257
276
|
"playboy",
|
|
258
277
|
"pleasure chest",
|
|
@@ -261,7 +280,6 @@
|
|
|
261
280
|
"poof",
|
|
262
281
|
"poon",
|
|
263
282
|
"poontang",
|
|
264
|
-
"punany",
|
|
265
283
|
"poop chute",
|
|
266
284
|
"poopchute",
|
|
267
285
|
"porn",
|
|
@@ -270,6 +288,7 @@
|
|
|
270
288
|
"prince albert piercing",
|
|
271
289
|
"pthc",
|
|
272
290
|
"pubes",
|
|
291
|
+
"punany",
|
|
273
292
|
"pussy",
|
|
274
293
|
"queaf",
|
|
275
294
|
"queef",
|
|
@@ -280,12 +299,15 @@
|
|
|
280
299
|
"raping",
|
|
281
300
|
"rapist",
|
|
282
301
|
"rectum",
|
|
302
|
+
"retard",
|
|
303
|
+
"retarded",
|
|
283
304
|
"reverse cowgirl",
|
|
284
305
|
"rimjob",
|
|
285
306
|
"rimming",
|
|
286
307
|
"rosy palm",
|
|
287
308
|
"rosy palm and her 5 sisters",
|
|
288
309
|
"rusty trombone",
|
|
310
|
+
"s&m",
|
|
289
311
|
"sadism",
|
|
290
312
|
"santorum",
|
|
291
313
|
"scat",
|
|
@@ -295,19 +317,22 @@
|
|
|
295
317
|
"sex",
|
|
296
318
|
"sexo",
|
|
297
319
|
"sexy",
|
|
320
|
+
"sh!t",
|
|
298
321
|
"shaved beaver",
|
|
299
322
|
"shaved pussy",
|
|
300
323
|
"shemale",
|
|
301
324
|
"shibari",
|
|
302
325
|
"shit",
|
|
303
326
|
"shitblimp",
|
|
327
|
+
"shithead",
|
|
328
|
+
"shitshow",
|
|
304
329
|
"shitty",
|
|
305
330
|
"shota",
|
|
306
331
|
"shrimping",
|
|
332
|
+
"simp",
|
|
307
333
|
"skeet",
|
|
308
334
|
"slanteye",
|
|
309
335
|
"slut",
|
|
310
|
-
"s&m",
|
|
311
336
|
"smut",
|
|
312
337
|
"snatch",
|
|
313
338
|
"snowballing",
|
|
@@ -319,6 +344,7 @@
|
|
|
319
344
|
"spooge",
|
|
320
345
|
"spread legs",
|
|
321
346
|
"spunk",
|
|
347
|
+
"stfu",
|
|
322
348
|
"strap on",
|
|
323
349
|
"strapon",
|
|
324
350
|
"strappado",
|
|
@@ -333,6 +359,7 @@
|
|
|
333
359
|
"tainted love",
|
|
334
360
|
"taste my",
|
|
335
361
|
"tea bagging",
|
|
362
|
+
"testbad01",
|
|
336
363
|
"threesome",
|
|
337
364
|
"throating",
|
|
338
365
|
"tied up",
|
|
@@ -366,17 +393,18 @@
|
|
|
366
393
|
"voyeur",
|
|
367
394
|
"vulva",
|
|
368
395
|
"wank",
|
|
369
|
-
"wetback",
|
|
370
396
|
"wet dream",
|
|
397
|
+
"wetback",
|
|
371
398
|
"white power",
|
|
372
399
|
"wrapping men",
|
|
373
400
|
"wrinkled starfish",
|
|
401
|
+
"wtf",
|
|
374
402
|
"xx",
|
|
375
403
|
"xxx",
|
|
376
404
|
"yaoi",
|
|
377
405
|
"yellow showers",
|
|
378
406
|
"yiffy",
|
|
379
407
|
"zoophilia",
|
|
380
|
-
"
|
|
408
|
+
"\ud83d\udd95"
|
|
381
409
|
]
|
|
382
410
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"whitelist": [
|
|
3
|
+
"Document",
|
|
4
|
+
"Assume",
|
|
5
|
+
"Assistant",
|
|
6
|
+
"Assignment",
|
|
7
|
+
"Bass",
|
|
8
|
+
"Class",
|
|
9
|
+
"Grass",
|
|
10
|
+
"Pass",
|
|
11
|
+
"Analytics",
|
|
12
|
+
"Pension",
|
|
13
|
+
"Night",
|
|
14
|
+
"Butler",
|
|
15
|
+
"Canal",
|
|
16
|
+
"Election",
|
|
17
|
+
"Spreadsheet",
|
|
18
|
+
"Accountant",
|
|
19
|
+
"Cucumber",
|
|
20
|
+
"Analysis",
|
|
21
|
+
"Japan",
|
|
22
|
+
"Analytics",
|
|
23
|
+
"Manipulate",
|
|
24
|
+
"Shoot",
|
|
25
|
+
"Button",
|
|
26
|
+
"Scrutiny",
|
|
27
|
+
"Constitution",
|
|
28
|
+
"Associate",
|
|
29
|
+
"Country"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -9,6 +9,8 @@ interface FilterConfig {
|
|
|
9
9
|
severityLevels?: boolean;
|
|
10
10
|
ignoreWords?: string[];
|
|
11
11
|
logProfanity?: boolean;
|
|
12
|
+
allowObfuscatedMatch?: boolean;
|
|
13
|
+
fuzzyToleranceLevel?: number;
|
|
12
14
|
}
|
|
13
15
|
declare class Filter {
|
|
14
16
|
private words;
|
|
@@ -18,13 +20,14 @@ declare class Filter {
|
|
|
18
20
|
private severityLevels;
|
|
19
21
|
private ignoreWords;
|
|
20
22
|
private logProfanity;
|
|
23
|
+
private allowObfuscatedMatch;
|
|
24
|
+
private fuzzyToleranceLevel;
|
|
21
25
|
constructor(config?: FilterConfig);
|
|
26
|
+
private normalizeObfuscated;
|
|
22
27
|
private getRegex;
|
|
23
|
-
private
|
|
24
|
-
private isMergedMatch;
|
|
28
|
+
private isFuzzyToleranceMatch;
|
|
25
29
|
private evaluateSeverity;
|
|
26
30
|
isProfane(value: string): boolean;
|
|
27
|
-
checkProfanityInSentence(text: string): CheckProfanityResult;
|
|
28
31
|
checkProfanity(text: string): CheckProfanityResult;
|
|
29
32
|
}
|
|
30
33
|
export { Filter };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/filters/Filter.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -8,14 +7,16 @@ exports.Filter = void 0;
|
|
|
8
7
|
const dictionary_1 = __importDefault(require("../data/dictionary"));
|
|
9
8
|
class Filter {
|
|
10
9
|
constructor(config) {
|
|
11
|
-
var _a, _b, _c, _d, _e;
|
|
10
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
12
11
|
let words = [];
|
|
13
12
|
this.caseSensitive = (_a = config === null || config === void 0 ? void 0 : config.caseSensitive) !== null && _a !== void 0 ? _a : false;
|
|
14
|
-
this.
|
|
13
|
+
this.allowObfuscatedMatch = (_b = config === null || config === void 0 ? void 0 : config.allowObfuscatedMatch) !== null && _b !== void 0 ? _b : false;
|
|
14
|
+
this.wordBoundaries = (_c = config === null || config === void 0 ? void 0 : config.wordBoundaries) !== null && _c !== void 0 ? _c : !this.allowObfuscatedMatch; // Turn off word boundaries if obfuscation enabled
|
|
15
15
|
this.replaceWith = config === null || config === void 0 ? void 0 : config.replaceWith;
|
|
16
|
-
this.severityLevels = (
|
|
17
|
-
this.ignoreWords = new Set(((
|
|
18
|
-
this.logProfanity = (
|
|
16
|
+
this.severityLevels = (_d = config === null || config === void 0 ? void 0 : config.severityLevels) !== null && _d !== void 0 ? _d : false;
|
|
17
|
+
this.ignoreWords = new Set(((_e = config === null || config === void 0 ? void 0 : config.ignoreWords) === null || _e === void 0 ? void 0 : _e.map((word) => word.toLowerCase())) || []);
|
|
18
|
+
this.logProfanity = (_f = config === null || config === void 0 ? void 0 : config.logProfanity) !== null && _f !== void 0 ? _f : false;
|
|
19
|
+
this.fuzzyToleranceLevel = (_g = config === null || config === void 0 ? void 0 : config.fuzzyToleranceLevel) !== null && _g !== void 0 ? _g : 0.8;
|
|
19
20
|
if (config === null || config === void 0 ? void 0 : config.allLanguages) {
|
|
20
21
|
for (const lang in dictionary_1.default) {
|
|
21
22
|
if (dictionary_1.default.hasOwnProperty(lang)) {
|
|
@@ -27,7 +28,7 @@ class Filter {
|
|
|
27
28
|
const languages = (config === null || config === void 0 ? void 0 : config.languages) || ['english'];
|
|
28
29
|
const languagesChecks = new Set(languages);
|
|
29
30
|
if (languagesChecks.size !== 0) {
|
|
30
|
-
languagesChecks.forEach(lang => {
|
|
31
|
+
languagesChecks.forEach((lang) => {
|
|
31
32
|
words = [...words, ...dictionary_1.default[lang]];
|
|
32
33
|
});
|
|
33
34
|
}
|
|
@@ -35,96 +36,100 @@ class Filter {
|
|
|
35
36
|
if (config === null || config === void 0 ? void 0 : config.customWords) {
|
|
36
37
|
words = [...words, ...config.customWords];
|
|
37
38
|
}
|
|
38
|
-
this.words = new Map(words.map(word => [word.toLowerCase(), 1]));
|
|
39
|
+
this.words = new Map(words.map((word) => [word.toLowerCase(), 1]));
|
|
40
|
+
}
|
|
41
|
+
normalizeObfuscated(text) {
|
|
42
|
+
let normalized = text.replace(/([a-zA-Z])\1{1,}/g, '$1$1'); // allow max 2 consecutive
|
|
43
|
+
const charMap = {
|
|
44
|
+
'@': 'a',
|
|
45
|
+
$: 's',
|
|
46
|
+
'!': 'i',
|
|
47
|
+
'1': 'i',
|
|
48
|
+
'*': '',
|
|
49
|
+
};
|
|
50
|
+
normalized = normalized.replace(/[@$!1*]/g, (m) => charMap[m] || m);
|
|
51
|
+
return normalized;
|
|
39
52
|
}
|
|
40
53
|
getRegex(word) {
|
|
41
54
|
const flags = this.caseSensitive ? 'g' : 'gi';
|
|
55
|
+
const escapedWord = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
42
56
|
const boundary = this.wordBoundaries ? '\\b' : '';
|
|
43
|
-
return new RegExp(`${boundary}${
|
|
44
|
-
}
|
|
45
|
-
isFuzzyMatch(word, text) {
|
|
46
|
-
const pattern = `${word.split('').join('[^a-zA-Z]*')}`;
|
|
47
|
-
const regex = new RegExp(pattern, this.caseSensitive ? 'g' : 'gi');
|
|
48
|
-
return regex.test(text);
|
|
57
|
+
return new RegExp(`${boundary}${escapedWord}${boundary}`, flags);
|
|
49
58
|
}
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
59
|
+
isFuzzyToleranceMatch(word, text) {
|
|
60
|
+
const simplifiedText = text.toLowerCase().replace(/[^a-z]/g, '');
|
|
61
|
+
const simplifiedWord = word.toLowerCase();
|
|
62
|
+
let matchCount = 0;
|
|
63
|
+
let index = 0;
|
|
64
|
+
for (let i = 0; i < simplifiedText.length; i++) {
|
|
65
|
+
if (simplifiedText[i] === simplifiedWord[index]) {
|
|
66
|
+
matchCount++;
|
|
67
|
+
index++;
|
|
68
|
+
if (index === simplifiedWord.length)
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const score = matchCount / simplifiedWord.length;
|
|
73
|
+
return score >= this.fuzzyToleranceLevel;
|
|
54
74
|
}
|
|
55
75
|
evaluateSeverity(word, text) {
|
|
56
|
-
if (this.
|
|
57
|
-
return 1
|
|
58
|
-
}
|
|
59
|
-
else if (this.isFuzzyMatch(word, text)) {
|
|
60
|
-
return 2; // Fuzzy match
|
|
76
|
+
if (this.wordBoundaries) {
|
|
77
|
+
return this.getRegex(word).test(text) ? 1 : undefined;
|
|
61
78
|
}
|
|
62
|
-
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
-
|
|
79
|
+
if (this.getRegex(word).test(text))
|
|
80
|
+
return 1;
|
|
81
|
+
if (this.isFuzzyToleranceMatch(word, text))
|
|
82
|
+
return 2;
|
|
83
|
+
return undefined;
|
|
66
84
|
}
|
|
67
85
|
isProfane(value) {
|
|
86
|
+
let input = value;
|
|
87
|
+
if (this.allowObfuscatedMatch) {
|
|
88
|
+
input = this.normalizeObfuscated(value);
|
|
89
|
+
}
|
|
68
90
|
for (const word of this.words.keys()) {
|
|
69
|
-
if (!this.ignoreWords.has(word.toLowerCase()) &&
|
|
91
|
+
if (!this.ignoreWords.has(word.toLowerCase()) &&
|
|
92
|
+
this.evaluateSeverity(word, input) !== undefined) {
|
|
70
93
|
return true;
|
|
71
|
-
}
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
checkProfanityInSentence(text) {
|
|
75
|
-
const words = text.split(/\s+/);
|
|
76
|
-
const profaneWords = [];
|
|
77
|
-
const severityMap = {};
|
|
78
|
-
for (const word of words) {
|
|
79
|
-
for (const dictWord of this.words.keys()) {
|
|
80
|
-
const severity = this.evaluateSeverity(dictWord, word);
|
|
81
|
-
if (severity !== undefined && !this.ignoreWords.has(dictWord.toLowerCase())) {
|
|
82
|
-
profaneWords.push(word);
|
|
83
|
-
severityMap[word] = severity; // Use the actual word found in text as the key
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
let processedText = text;
|
|
88
|
-
if (this.replaceWith) {
|
|
89
|
-
for (const word of profaneWords) {
|
|
90
|
-
processedText = processedText.replace(new RegExp(word, 'gi'), this.replaceWith);
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
|
-
return
|
|
94
|
-
containsProfanity: profaneWords.length > 0,
|
|
95
|
-
profaneWords,
|
|
96
|
-
processedText: this.replaceWith ? processedText : undefined,
|
|
97
|
-
severityMap: Object.keys(severityMap).length > 0 ? severityMap : undefined, // Only return if there are valid severities
|
|
98
|
-
};
|
|
96
|
+
return false;
|
|
99
97
|
}
|
|
100
98
|
checkProfanity(text) {
|
|
101
|
-
|
|
99
|
+
let input = text;
|
|
100
|
+
if (this.allowObfuscatedMatch) {
|
|
101
|
+
input = this.normalizeObfuscated(text);
|
|
102
|
+
}
|
|
102
103
|
const profaneWords = [];
|
|
103
104
|
const severityMap = {};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
for (const dictWord of this.words.keys()) {
|
|
106
|
+
if (this.ignoreWords.has(dictWord.toLowerCase()))
|
|
107
|
+
continue;
|
|
108
|
+
const severity = this.evaluateSeverity(dictWord, input);
|
|
109
|
+
if (severity !== undefined) {
|
|
110
|
+
const regex = this.getRegex(dictWord);
|
|
111
|
+
let match;
|
|
112
|
+
while ((match = regex.exec(input)) !== null) {
|
|
113
|
+
profaneWords.push(match[0]);
|
|
114
|
+
severityMap[match[0]] = severity;
|
|
111
115
|
}
|
|
112
116
|
}
|
|
113
117
|
}
|
|
114
|
-
const sentenceResult = this.checkProfanityInSentence(text);
|
|
115
|
-
profaneWords.push(...sentenceResult.profaneWords);
|
|
116
|
-
Object.assign(severityMap, sentenceResult.severityMap);
|
|
117
118
|
let processedText = text;
|
|
118
|
-
if (this.replaceWith) {
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
if (this.replaceWith && profaneWords.length > 0) {
|
|
120
|
+
const uniqueWords = Array.from(new Set(profaneWords));
|
|
121
|
+
for (const word of uniqueWords) {
|
|
122
|
+
const escaped = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
123
|
+
processedText = processedText.replace(new RegExp(escaped, 'gi'), this.replaceWith);
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
126
|
return {
|
|
124
127
|
containsProfanity: profaneWords.length > 0,
|
|
125
128
|
profaneWords: Array.from(new Set(profaneWords)),
|
|
126
129
|
processedText: this.replaceWith ? processedText : undefined,
|
|
127
|
-
severityMap: Object.keys(severityMap).length > 0
|
|
130
|
+
severityMap: this.severityLevels && Object.keys(severityMap).length > 0
|
|
131
|
+
? severityMap
|
|
132
|
+
: undefined,
|
|
128
133
|
};
|
|
129
134
|
}
|
|
130
135
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Filter.js","sourceRoot":"","sources":["../../../src/filters/Filter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Filter.js","sourceRoot":"","sources":["../../../src/filters/Filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,11 +7,14 @@ interface ProfanityCheckerConfig {
|
|
|
7
7
|
customWords?: string[];
|
|
8
8
|
replaceWith?: string;
|
|
9
9
|
severityLevels?: boolean;
|
|
10
|
+
allowObfuscatedMatch?: boolean;
|
|
11
|
+
fuzzyToleranceLevel?: number;
|
|
10
12
|
customActions?: (result: CheckProfanityResult) => void;
|
|
11
13
|
}
|
|
12
14
|
export declare const useProfanityChecker: (config?: ProfanityCheckerConfig) => {
|
|
13
15
|
result: CheckProfanityResult;
|
|
14
16
|
checkText: (text: string) => void;
|
|
15
17
|
checkTextAsync: (text: string) => Promise<CheckProfanityResult>;
|
|
18
|
+
reset: () => void;
|
|
16
19
|
};
|
|
17
20
|
export {};
|
|
@@ -8,13 +8,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
exports.useProfanityChecker = void 0;
|
|
13
16
|
const react_1 = require("react");
|
|
14
17
|
const Filter_1 = require("../filters/Filter");
|
|
18
|
+
const globalWhitelist_json_1 = __importDefault(require("../data/globalWhitelist.json"));
|
|
15
19
|
const useProfanityChecker = (config) => {
|
|
16
20
|
const [result, setResult] = (0, react_1.useState)(null);
|
|
17
|
-
const
|
|
21
|
+
const filterConfig = (0, react_1.useMemo)(() => {
|
|
22
|
+
var _a;
|
|
23
|
+
const effectiveConfig = Object.assign(Object.assign({}, config), { ignoreWords: globalWhitelist_json_1.default.whitelist, fuzzyToleranceLevel: (_a = config === null || config === void 0 ? void 0 : config.fuzzyToleranceLevel) !== null && _a !== void 0 ? _a : 0.8 });
|
|
24
|
+
// Optional - warn developer
|
|
25
|
+
if (effectiveConfig.allowObfuscatedMatch &&
|
|
26
|
+
effectiveConfig.wordBoundaries) {
|
|
27
|
+
console.warn('[Glin-Profanity] Obfuscated match enabled → wordBoundaries will be ignored internally.');
|
|
28
|
+
}
|
|
29
|
+
return effectiveConfig;
|
|
30
|
+
}, [config]);
|
|
31
|
+
const filter = (0, react_1.useMemo)(() => new Filter_1.Filter(filterConfig), [filterConfig]);
|
|
18
32
|
const checkText = (text) => {
|
|
19
33
|
const checkResult = filter.checkProfanity(text);
|
|
20
34
|
setResult(checkResult);
|
|
@@ -32,10 +46,12 @@ const useProfanityChecker = (config) => {
|
|
|
32
46
|
resolve(checkResult);
|
|
33
47
|
});
|
|
34
48
|
});
|
|
49
|
+
const reset = () => setResult(null);
|
|
35
50
|
return {
|
|
36
51
|
result,
|
|
37
52
|
checkText,
|
|
38
53
|
checkTextAsync,
|
|
54
|
+
reset,
|
|
39
55
|
};
|
|
40
56
|
};
|
|
41
57
|
exports.useProfanityChecker = useProfanityChecker;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useProfanityChecker.js","sourceRoot":"","sources":["../../../src/hooks/useProfanityChecker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useProfanityChecker.js","sourceRoot":"","sources":["../../../src/hooks/useProfanityChecker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,iCAA0C;AAC1C,8CAA2C;AAE3C,wFAA+D;AAexD,MAAM,mBAAmB,GAAG,CAAC,MAA+B,EAAE,EAAE;IACrE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAA,gBAAQ,EAA8B,IAAI,CAAC,CAAC;IAExE,MAAM,YAAY,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;;QAChC,MAAM,eAAe,mCAChB,MAAM,KACT,WAAW,EAAE,8BAAmB,CAAC,SAAS,EAC1C,mBAAmB,EAAE,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,mBAAmB,mCAAI,GAAG,GACxD,CAAC;QAEF,4BAA4B;QAC5B,IACE,eAAe,CAAC,oBAAoB;YACpC,eAAe,CAAC,cAAc,EAC9B,CAAC;YACD,OAAO,CAAC,IAAI,CACV,wFAAwF,CACzF,CAAC;QACJ,CAAC;QAED,OAAO,eAAe,CAAC;IACzB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,MAAM,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,IAAI,eAAM,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEvE,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;QACjC,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAChD,SAAS,CAAC,WAAW,CAAC,CAAC;QACvB,IAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,EAAE,CAAC;YAC1B,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,CAAO,IAAY,EAAE,EAAE;QAC5C,OAAO,IAAI,OAAO,CAAuB,CAAC,OAAO,EAAE,EAAE;YACnD,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAChD,SAAS,CAAC,WAAW,CAAC,CAAC;YACvB,IAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,EAAE,CAAC;gBAC1B,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;YACpC,CAAC;YACD,OAAO,CAAC,WAAW,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC,CAAA,CAAC;IAEF,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEpC,OAAO;QACL,MAAM;QACN,SAAS;QACT,cAAc;QACd,KAAK;KACN,CAAC;AACJ,CAAC,CAAC;AApDW,QAAA,mBAAmB,uBAoD9B"}
|
package/lib/cjs/types/types.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
export declare enum SeverityLevel {
|
|
2
|
+
Exact = 1,
|
|
3
|
+
Fuzzy = 2,
|
|
4
|
+
Merged = 3
|
|
5
|
+
}
|
|
1
6
|
export interface CheckProfanityResult {
|
|
2
7
|
containsProfanity: boolean;
|
|
3
8
|
profaneWords: string[];
|
|
4
9
|
processedText?: string;
|
|
5
10
|
severityMap?: {
|
|
6
|
-
[word: string]:
|
|
11
|
+
[word: string]: SeverityLevel;
|
|
7
12
|
};
|
|
8
13
|
}
|
|
9
14
|
export type Language = 'arabic' | 'chinese' | 'czech' | 'danish' | 'english' | 'esperanto' | 'finnish' | 'french' | 'german' | 'hindi' | 'hungarian' | 'italian' | 'japanese' | 'korean' | 'norwegian' | 'persian' | 'polish' | 'portuguese' | 'russian' | 'turkish' | 'swedish' | 'thai';
|