Skip to content

Commit e0b4bee

Browse files
authored
Create badword.ts
1 parent 535773a commit e0b4bee

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed

badword.ts

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
function isNodeEnvironment(): boolean {
2+
return typeof exports === 'object' && typeof module !== 'undefined';
3+
}
4+
5+
function escapeRegExp(strings: string): string {
6+
let data = strings.trim().toLowerCase().split("|").filter(Boolean);
7+
for (let index = 0; index < data.length; index++) {
8+
const element = data[index];
9+
if (!((element.includes("(") && element.includes(")")) ||
10+
(element.includes("[") && element.includes("]")))) {
11+
data[index] = data[index]
12+
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
13+
.replace(/[a4]/g, "[a4]")
14+
.replace(/[s5]/g, "[s5]")
15+
.replace("i", "[i1]")
16+
.replace("l", "[l1]")
17+
.replace(/[o0]/g, "[o0]")
18+
.replace(/[e3]/g, "[e3]")
19+
.replace(/[b8]/g, "[b8]")
20+
.replace(/[kx]/g, "[kx]");
21+
}
22+
}
23+
return new RegExp(data.join("|")).source;
24+
}
25+
26+
function validateInput(type: string, value: string): boolean {
27+
let regex: RegExp;
28+
29+
switch (type) {
30+
case 'email':
31+
regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.(com|net|org|edu|gov|mil|co|info|io|biz|id|us|uk|ca|au|de|fr|es|it|jp|cn|br|in|ru|mx|kr|za|nl|se|no|fi|dk|pl|pt|ar|ch|hk|sg|my|th|vn|ae|at|be|cz|hu|ro|bg|gr|lt|lv|sk|si|ee|cy)(\.[a-zA-Z]{2,})?$/;
32+
break;
33+
case 'phone':
34+
regex = /^(?:\+?(\d{1,3}))?[-. ]?(\(?\d{1,4}?\)?)[-.\s]?(\d{1,4})[-.\s]?(\d{1,4})[-.\s]?(\d{1,9})$/;
35+
break;
36+
case 'url':
37+
regex = /^(https?:\/\/)?(www\.)?([a-zA-Z0-9-]+\.[a-zA-Z]{2,})(\/[^\s]*)?$/;
38+
break;
39+
default:
40+
return false; // Invalid type
41+
}
42+
43+
return regex.test(value);
44+
}
45+
46+
class FilterBadWord {
47+
protected _text: string; // Changed to protected to allow access in subclasses
48+
protected _filt: RegExp; // Changed to protected
49+
protected _subfilter: RegExp; // Changed to protected
50+
51+
constructor(text: string = "", customFilter: string = "", customSubFilter: string = "") {
52+
this._text = text;
53+
this._filt = /[b8][[a4][s5]hfu[l1][l1]*|k[i1][l1][l1]*|fuck*|dr[uo]g*|d[i1]ck*|fk/gi;
54+
this._subfilter = /[a4][s5][s5]|[l1][i1]p|pu[s5][s5]y[*]?|[s5]uck[*]?|m[o0]th[e3]r[*]?|m[o0]m[*]?|d[o0]g[*]?|l[o0]w[*]?|s[e3]x[*]?/gi;
55+
56+
if (customFilter.length > 3) {
57+
this._filt = new RegExp(this._filt.source + "|" + escapeRegExp(customFilter), "gi");
58+
}
59+
if (customSubFilter.length > 3) {
60+
this._subfilter = new RegExp(this._subfilter.source + "|" + escapeRegExp(customSubFilter), "gi");
61+
}
62+
}
63+
64+
private getBoundPosition(position: number): string {
65+
let paragraph = this._text;
66+
while (position > 0 && paragraph[position] === " ") position--;
67+
position = paragraph.lastIndexOf(" ", position) + 1;
68+
let end = paragraph.indexOf(" ", position);
69+
if (end === -1) {
70+
end = paragraph.length;
71+
}
72+
return paragraph.substring(position, end);
73+
}
74+
75+
private positionStatic(): number[] {
76+
const wordList = this._text.toLowerCase().split(' ');
77+
const positions: number[] = [];
78+
79+
wordList.forEach((word, index) => {
80+
if (word.match(this._filt)) {
81+
positions.push(index);
82+
}
83+
});
84+
85+
return positions;
86+
}
87+
88+
public position(): number[] {
89+
return this.positionStatic();
90+
}
91+
92+
public get thisToxic(): (string | number)[] | false {
93+
const check = this.position();
94+
const arry: (string | number)[] = [];
95+
96+
if (check.length > 0) {
97+
const word = this._text.toLowerCase();
98+
99+
for (const index of check) {
100+
const wordBoundary = this.getBoundPosition(index);
101+
const before = word.substring(0, word.indexOf(wordBoundary)).trim().split(" ");
102+
const after = word.substring(word.indexOf(wordBoundary) + wordBoundary.length).trim().split(" ");
103+
104+
if (before.length && before[before.length - 1].match(this._subfilter)) {
105+
arry.push("Toxic", 1, before[before.length - 1]);
106+
return arry;
107+
}
108+
109+
if (after.length && after[0].match(this._subfilter)) {
110+
arry.push("Toxic", 1, after[0]);
111+
return arry;
112+
}
113+
114+
if (after.length > 1 && after[1].match(this._subfilter)) {
115+
arry.push("Toxic", 1, after[1]);
116+
return arry;
117+
}
118+
}
119+
120+
arry.push("Notoxic", 0);
121+
return arry;
122+
}
123+
124+
return false;
125+
}
126+
127+
set thisToxic(key: any) {
128+
throw key;
129+
}
130+
131+
public clean(position: number[]): string {
132+
let words = this._text.split(" ");
133+
const sensor = "*";
134+
135+
position.forEach((number) => {
136+
const getWord = this.getBoundPosition(number);
137+
words = words.map(word => word.replace(getWord, sensor.repeat(getWord.length)));
138+
});
139+
140+
return words.join(" ");
141+
}
142+
}
143+
144+
class filters_badword extends FilterBadWord {
145+
private cl: boolean;
146+
private st: boolean;
147+
148+
public text_o(text: string): void {
149+
this._text = text.toString();
150+
}
151+
152+
public config(cl: boolean = true, smart: boolean = true, customFilter: string = "", customSubFilter: string = ""): void {
153+
this.cl = cl;
154+
this.st = smart;
155+
156+
if (customFilter.length > 3) {
157+
this._filt = new RegExp(this._filt.source + "|" + escapeRegExp(customFilter), "gi");
158+
}
159+
if (customSubFilter.length > 3) {
160+
this._subfilter = new RegExp(this._subfilter.source + "|" + escapeRegExp(customSubFilter), "gi");
161+
}
162+
}
163+
164+
public get cleans(): string {
165+
if (this.cl) {
166+
if (this.thisToxic[1] === 1 && this.thisToxic.length > 2) {
167+
if (this.st) {
168+
const sensore = "*".repeat(this.thisToxic[2].length);
169+
return this.clean(this.position()).replace(this.thisToxic[2], sensore);
170+
}
171+
return this.clean(this.position());
172+
}
173+
return this.clean(this.position());
174+
} else {
175+
return this._text.trim();
176+
}
177+
}
178+
179+
set cleans(value: string) {
180+
throw value;
181+
}
182+
}
183+
184+
export {
185+
/**
186+
* FilterBadWord class: class for filtering bad words
187+
*@param {string} text - The text to filter
188+
*@param {string} customFilter - List of bad words
189+
*@param {string} customSubFilter - List of bad sub words
190+
*/
191+
FilterBadWord,
192+
/**
193+
* filters_badword class: a simpler class to filter bad words
194+
* which uses the FilterBadWord class. To use it you have to call the config function
195+
*/
196+
filters_badword
197+
};

0 commit comments

Comments
 (0)