New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@2toad/profanity

Package Overview
Dependencies
Maintainers
0
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@2toad/profanity - npm Package Compare versions

Comparing version 2.5.0 to 3.0.0

supported-languages.md

3

dist/benchmark/benchmark.js

@@ -58,2 +58,5 @@ "use strict";

const partialMatchProfanity = new __1.Profanity({ wholeWord: false });
// Pre-cache regexes
defaultProfanity.exists("foo");
partialMatchProfanity.exists("bar");
// Benchmark exists() function

@@ -60,0 +63,0 @@ suite

2

dist/data/profane-words.d.ts

@@ -1,1 +0,1 @@

export declare const profaneWords: readonly string[];
export declare const profaneWords: Map<string, string[]>;

@@ -6,453 +6,869 @@ "use strict";

exports.profaneWords = void 0;
exports.profaneWords = [
"4r5e",
"5h1t",
"5hit",
"a55",
"anal",
"anus",
"ar5e",
"arrse",
"arse",
"arses",
"ass",
"ass-fucker",
"asses",
"assfucker",
"assfukka",
"asshole",
"assholes",
"asswhole",
"a_s_s",
"a$$",
"as$",
"a$s",
"b!tch",
"b00bs",
"b17ch",
"b1tch",
"ballbag",
"balls",
"ballsack",
"bastard",
"beastial",
"beastiality",
"bellend",
"bestial",
"bestiality",
"bi+ch",
"biatch",
"bitch",
"bitchboy",
"bitcher",
"bitchers",
"bitches",
"bitchin",
"bitching",
"bloody",
"blow job",
"blowjob",
"blowjobs",
"boiolas",
"bollock",
"bollok",
"boner",
"boob",
"boobs",
"booobs",
"boooobs",
"booooobs",
"booooooobs",
"breasts",
"buceta",
"bugger",
"bullshit",
"bum",
"butt",
"butts",
"butthole",
"buttmuch",
"buttplug",
"c0ck",
"c0cksucker",
"carpet muncher",
"cawk",
"chink",
"cipa",
"cl1t",
"clit",
"clitoris",
"clits",
"cnut",
"cock",
"cock-sucker",
"cockface",
"cockhead",
"cockmunch",
"cockmuncher",
"cocks",
"cocksuck",
"cocksucked",
"cocksucker",
"cocksucking",
"cocksucks",
"cocksuka",
"cocksukka",
"cok",
"cokmuncher",
"coksucka",
"coon",
"cox",
"crap",
"cum",
"cummer",
"cumming",
"cums",
"cumshot",
"cunilingus",
"cunillingus",
"cunnilingus",
"cunt",
"cuntlick",
"cuntlicker",
"cuntlicking",
"cunts",
"cyalis",
"cyberfuc",
"cyberfuck",
"cyberfucked",
"cyberfucker",
"cyberfuckers",
"cyberfucking",
"d1ck",
"damn",
"dick",
"dickhead",
"dildo",
"dildos",
"dink",
"dinks",
"dirsa",
"dlck",
"dog-fucker",
"doggin",
"dogging",
"donkeyribber",
"doosh",
"duche",
"dyke",
"ejaculate",
"ejaculated",
"ejaculates",
"ejaculating",
"ejaculatings",
"ejaculation",
"ejakulate",
"f u c k",
"f u c k e r",
"f4nny",
"fag",
"fagging",
"faggitt",
"faggot",
"faggs",
"fagot",
"fagots",
"fags",
"fanny",
"fannyflaps",
"fannyfucker",
"fanyy",
"fatass",
"fcuk",
"fcuker",
"fcuking",
"feck",
"fecker",
"felching",
"fellate",
"fellatio",
"fingerfuck",
"fingerfucked",
"fingerfucker",
"fingerfuckers",
"fingerfucking",
"fingerfucks",
"fistfuck",
"fistfucked",
"fistfucker",
"fistfuckers",
"fistfucking",
"fistfuckings",
"fistfucks",
"flange",
"fook",
"fooker",
"fuck",
"fucka",
"fucked",
"fucker",
"fuckers",
"fuckhead",
"fuckheads",
"fuckin",
"fucking",
"fuckings",
"fuckingshitmotherfucker",
"fuckme",
"fucks",
"fuckwhit",
"fuckwit",
"fudge packer",
"fudgepacker",
"fuk",
"fuker",
"fukker",
"fukkin",
"fuks",
"fukwhit",
"fukwit",
"fux",
"fux0r",
"f_u_c_k",
"gangbang",
"gangbanged",
"gangbangs",
"gaylord",
"gaysex",
"goatse",
"god-dam",
"god-damned",
"goddamn",
"goddamned",
"hardcoresex",
"headass",
"hoar",
"hoare",
"hoer",
"hoes",
"homo",
"hore",
"horniest",
"horny",
"hotsex",
"jack-off",
"jackoff",
"jap",
"jerk-off",
"jism",
"jiz",
"jizm",
"jizz",
"kawk",
"knobead",
"knobed",
"knobend",
"knobhead",
"knobjocky",
"knobjokey",
"kock",
"kondum",
"kondums",
"kum",
"kummer",
"kumming",
"kums",
"kunilingus",
"l3i+ch",
"l3itch",
"labia",
"lust",
"lusting",
"m0f0",
"m0fo",
"m45terbate",
"ma5terb8",
"ma5terbate",
"masochist",
"master-bate",
"masterb8",
"masterbat*",
"masterbat3",
"masterbate",
"masterbation",
"masterbations",
"masturbate",
"mo-fo",
"mof0",
"mofo",
"mothafuck",
"mothafucka",
"mothafuckas",
"mothafuckaz",
"mothafucked",
"mothafucker",
"mothafuckers",
"mothafuckin",
"mothafucking",
"mothafuckings",
"mothafucks",
"motherfuck",
"motherfucked",
"motherfucker",
"motherfuckers",
"motherfuckin",
"motherfucking",
"motherfuckings",
"motherfuckka",
"motherfucks",
"muff",
"muthafecker",
"muthafuckker",
"mutherfucker",
"n1gga",
"n1gger",
"nazi",
"nigg3r",
"nigg4h",
"nigga",
"niggah",
"niggas",
"niggaz",
"nigger",
"niggers",
"nob",
"nob jokey",
"nobhead",
"nobjocky",
"nobjokey",
"numbnuts",
"nutsack",
"orgasim",
"orgasims",
"orgasm",
"orgasms",
"p0rn",
"pawn",
"pecker",
"penis",
"penisfucker",
"phonesex",
"phuck",
"phuk",
"phuked",
"phuking",
"phukked",
"phukking",
"phuks",
"phuq",
"pigfucker",
"pimpis",
"piss",
"pissed",
"pisser",
"pissers",
"pisses",
"pissflaps",
"pissin",
"pissing",
"pissoff",
"poop",
"porn",
"porno",
"pornography",
"pornos",
"prick",
"pricks",
"pron",
"pube",
"pusse",
"pussi",
"pussies",
"pussy",
"pussys",
"rectum",
"retard",
"rimjaw",
"rimming",
"s hit",
"s.o.b.",
"sadist",
"schlong",
"screwing",
"scroat",
"scrote",
"scrotum",
"semen",
"sex",
"sh!+",
"sh!t",
"sh1t",
"shag",
"shagger",
"shaggin",
"shagging",
"shemale",
"shi+",
"shit",
"shitdick",
"shite",
"shited",
"shitey",
"shitfuck",
"shitfull",
"shithead",
"shiting",
"shitings",
"shits",
"shitted",
"shitter",
"shitters",
"shitting",
"shittings",
"shitty",
"skank",
"slut",
"sluts",
"smegma",
"smut",
"snatch",
"son-of-a-bitch",
"spac",
"spunk",
"s_h_i_t",
"t1tt1e5",
"t1tties",
"teets",
"teez",
"testical",
"testicle",
"tit",
"titfuck",
"tits",
"titt",
"tittie5",
"tittiefucker",
"titties",
"tittyfuck",
"tittywank",
"titwank",
"tosser",
"turd",
"tw4t",
"twat",
"twathead",
"twatty",
"twunt",
"twunter",
"v14gra",
"v1gra",
"vagina",
"viagra",
"vulva",
"w00se",
"wang",
"wank",
"wanker",
"wanky",
"whoar",
"whore",
"willies",
"willy",
];
exports.profaneWords = new Map([
[
"de",
[
"abspritzen",
"abstand",
"abtreiben",
"abtreibung",
"anal",
"anus",
"arsch",
"arschficker",
"arschloch",
"arschlöcher",
"balltasche",
"bastard",
"bellend",
"beschissen",
"besoffen",
"bestial",
"bestialität",
"blasen",
"blutig",
"bollok",
"boob",
"brüste",
"buceta",
"busen",
"bälle",
"cipa",
"cunillingus",
"deich",
"dildo",
"dildos",
"dink",
"duche",
"dödel",
"ejakulation",
"ejakulieren",
"ejakuliert",
"esel",
"fagging",
"fanny",
"felching",
"fellatio",
"ficken",
"ficker",
"fickt",
"flansch",
"fotze",
"fotzen",
"fuck",
"fudge packer",
"gammler",
"gefickt",
"geil",
"geschissen",
"gott verdammt",
"gottverdammt",
"hintern",
"hoden",
"hodensack",
"hore",
"hundeficker",
"hure",
"hurensohn",
"hölle",
"hündin",
"hündinnen",
"kacke",
"kacken",
"kippe",
"klitoris",
"kock",
"lust",
"lüstern",
"masochist",
"masturbieren",
"mist",
"muschi",
"muschis",
"mutter ficker",
"nazi",
"nigger",
"nutte",
"nutten",
"onanieren",
"orgasim",
"orgasmen",
"orgasmus",
"pecker",
"penis",
"piss",
"pisse",
"pissen",
"pisser",
"pissoff",
"pisst",
"poop",
"porno",
"pornographie",
"prostituierte",
"pube",
"rektum",
"rimming",
"sadist",
"samen",
"schamlippen",
"scheisse",
"scheiße",
"scheißen",
"schlampe",
"schlampen",
"schluchzen",
"schmutz",
"schnappen",
"schrauben",
"schwanz",
"schwanzlutscher",
"schwuchtel",
"schwuchteln",
"schwänze",
"sex",
"shag",
"shagging",
"smegma",
"spalt",
"sperma",
"stechen",
"stiche",
"teppichmuncher",
"tit",
"titt",
"titte",
"titten",
"transen",
"turd",
"vagina",
"verdammt",
"vergewaltigen",
"vergewaltiger",
"verzögern",
"viagra",
"vulva",
"wang",
"waschbär",
"wichsen",
"x bewertet",
"xxx",
],
],
[
"en",
[
"4r5e",
"5h1t",
"5hit",
"a55",
"anal",
"anus",
"ar5e",
"arrse",
"arse",
"arses",
"ass",
"ass-fucker",
"asses",
"assfucker",
"assfukka",
"asshole",
"assholes",
"asswhole",
"a_s_s",
"a$$",
"as$",
"a$s",
"b!tch",
"b00bs",
"b17ch",
"b1tch",
"ballbag",
"balls",
"ballsack",
"bastard",
"beastial",
"beastiality",
"bellend",
"bestial",
"bestiality",
"bi+ch",
"biatch",
"bitch",
"bitchboy",
"bitcher",
"bitchers",
"bitches",
"bitchin",
"bitching",
"bloody",
"blow job",
"blowjob",
"blowjobs",
"boiolas",
"bollock",
"bollok",
"boner",
"boob",
"boobs",
"booobs",
"boooobs",
"booooobs",
"booooooobs",
"breasts",
"buceta",
"bugger",
"bullshit",
"bum",
"butt",
"butts",
"butthole",
"buttmuch",
"buttplug",
"c0ck",
"c0cksucker",
"carpet muncher",
"cawk",
"chink",
"cipa",
"cl1t",
"clit",
"clitoris",
"clits",
"cnut",
"cock",
"cock-sucker",
"cockface",
"cockhead",
"cockmunch",
"cockmuncher",
"cocks",
"cocksuck",
"cocksucked",
"cocksucker",
"cocksucking",
"cocksucks",
"cocksuka",
"cocksukka",
"cok",
"cokmuncher",
"coksucka",
"coon",
"cox",
"crap",
"cum",
"cummer",
"cumming",
"cums",
"cumshot",
"cunilingus",
"cunillingus",
"cunnilingus",
"cunt",
"cuntlick",
"cuntlicker",
"cuntlicking",
"cunts",
"cyalis",
"cyberfuc",
"cyberfuck",
"cyberfucked",
"cyberfucker",
"cyberfuckers",
"cyberfucking",
"d1ck",
"damn",
"dick",
"dickhead",
"dildo",
"dildos",
"dink",
"dinks",
"dirsa",
"dlck",
"dog-fucker",
"doggin",
"dogging",
"donkeyribber",
"doosh",
"duche",
"dyke",
"ejaculate",
"ejaculated",
"ejaculates",
"ejaculating",
"ejaculatings",
"ejaculation",
"ejakulate",
"f u c k",
"f u c k e r",
"f4nny",
"fag",
"fagging",
"faggitt",
"faggot",
"faggs",
"fagot",
"fagots",
"fags",
"fanny",
"fannyflaps",
"fannyfucker",
"fanyy",
"fatass",
"fcuk",
"fcuker",
"fcuking",
"feck",
"fecker",
"felching",
"fellate",
"fellatio",
"fingerfuck",
"fingerfucked",
"fingerfucker",
"fingerfuckers",
"fingerfucking",
"fingerfucks",
"fistfuck",
"fistfucked",
"fistfucker",
"fistfuckers",
"fistfucking",
"fistfuckings",
"fistfucks",
"flange",
"fook",
"fooker",
"fuck",
"fucka",
"fucked",
"fucker",
"fuckers",
"fuckhead",
"fuckheads",
"fuckin",
"fucking",
"fuckings",
"fuckingshitmotherfucker",
"fuckme",
"fucks",
"fuckwhit",
"fuckwit",
"fudge packer",
"fudgepacker",
"fuk",
"fuker",
"fukker",
"fukkin",
"fuks",
"fukwhit",
"fukwit",
"fux",
"fux0r",
"f_u_c_k",
"gangbang",
"gangbanged",
"gangbangs",
"gaylord",
"gaysex",
"goatse",
"god-dam",
"god-damned",
"goddamn",
"goddamned",
"hardcoresex",
"headass",
"hoar",
"hoare",
"hoer",
"hoes",
"homo",
"hore",
"horniest",
"horny",
"hotsex",
"jack-off",
"jackoff",
"jap",
"jerk-off",
"jism",
"jiz",
"jizm",
"jizz",
"kawk",
"knobead",
"knobed",
"knobend",
"knobhead",
"knobjocky",
"knobjokey",
"kock",
"kondum",
"kondums",
"kum",
"kummer",
"kumming",
"kums",
"kunilingus",
"l3i+ch",
"l3itch",
"labia",
"lust",
"lusting",
"m0f0",
"m0fo",
"m45terbate",
"ma5terb8",
"ma5terbate",
"masochist",
"master-bate",
"masterb8",
"masterbat*",
"masterbat3",
"masterbate",
"masterbation",
"masterbations",
"masturbate",
"mo-fo",
"mof0",
"mofo",
"mothafuck",
"mothafucka",
"mothafuckas",
"mothafuckaz",
"mothafucked",
"mothafucker",
"mothafuckers",
"mothafuckin",
"mothafucking",
"mothafuckings",
"mothafucks",
"motherfuck",
"motherfucked",
"motherfucker",
"motherfuckers",
"motherfuckin",
"motherfucking",
"motherfuckings",
"motherfuckka",
"motherfucks",
"muff",
"muthafecker",
"muthafuckker",
"mutherfucker",
"n1gga",
"n1gger",
"nazi",
"nigg3r",
"nigg4h",
"nigga",
"niggah",
"niggas",
"niggaz",
"nigger",
"niggers",
"nob",
"nob jokey",
"nobhead",
"nobjocky",
"nobjokey",
"numbnuts",
"nutsack",
"orgasim",
"orgasims",
"orgasm",
"orgasms",
"p0rn",
"pawn",
"pecker",
"penis",
"penisfucker",
"phonesex",
"phuck",
"phuk",
"phuked",
"phuking",
"phukked",
"phukking",
"phuks",
"phuq",
"pigfucker",
"pimpis",
"piss",
"pissed",
"pisser",
"pissers",
"pisses",
"pissflaps",
"pissin",
"pissing",
"pissoff",
"poop",
"porn",
"porno",
"pornography",
"pornos",
"prick",
"pricks",
"pron",
"pube",
"pusse",
"pussi",
"pussies",
"pussy",
"pussys",
"rectum",
"retard",
"rimjaw",
"rimming",
"s hit",
"s.o.b.",
"sadist",
"schlong",
"screwing",
"scroat",
"scrote",
"scrotum",
"semen",
"sex",
"sh!+",
"sh!t",
"sh1t",
"shag",
"shagger",
"shaggin",
"shagging",
"shemale",
"shi+",
"shit",
"shitdick",
"shite",
"shited",
"shitey",
"shitfuck",
"shitfull",
"shithead",
"shiting",
"shitings",
"shits",
"shitted",
"shitter",
"shitters",
"shitting",
"shittings",
"shitty",
"skank",
"slut",
"sluts",
"smegma",
"smut",
"snatch",
"son-of-a-bitch",
"spac",
"spunk",
"s_h_i_t",
"t1tt1e5",
"t1tties",
"teets",
"teez",
"testical",
"testicle",
"tit",
"titfuck",
"tits",
"titt",
"tittie5",
"tittiefucker",
"titties",
"tittyfuck",
"tittywank",
"titwank",
"tosser",
"turd",
"tw4t",
"twat",
"twathead",
"twatty",
"twunt",
"twunter",
"v14gra",
"v1gra",
"vagina",
"viagra",
"vulva",
"w00se",
"wang",
"wank",
"wanker",
"wanky",
"whoar",
"whore",
"willies",
"willy",
],
],
[
"es",
[
"aborto",
"anal",
"ano",
"culo",
"follador de culo",
"culos",
"estúpido",
"bolsa de pelota",
"bolas",
"bastardo",
"campana",
"bestial",
"bestialidad",
"perra",
"perras",
"quejas",
"sangriento",
"mamada",
"bollok",
"teta",
"tetas",
"los pechos",
"buceta",
"extremo",
"muncher alfombra",
"grieta",
"cipa",
"clítoris",
"polla",
"chupar la polla",
"gallos",
"mapache",
"mierda",
"semen",
"corrida",
"cunillingus",
"coño",
"maldita sea",
"consolador",
"consoladores",
"tonto",
"perro follador",
"duche",
"dique",
"eyacular",
"eyaculado",
"eyacula",
"eyaculación",
"maricón",
"fagging",
"maricones",
"felching",
"felación",
"brida",
"follada",
"cabron",
"folladores",
"maldito",
"carajo",
"folla",
"fudge packer",
"maldito sea",
"infierno",
"hore",
"córneo",
"tirón",
"kock",
"labios vaginales",
"lujuria",
"masoquista",
"masturbarse",
"madre folladora",
"nazi",
"negro",
"niggers",
"orgasimo",
"orgasmo",
"orgasmos",
"pájaro carpintero",
"pene",
"mear",
"molesto",
"pisser",
"orinando",
"enojado",
"pornografía",
"porno",
"pinchazo",
"pinchazos",
"pube",
"coños",
"violación",
"violador",
"recto",
"retardar",
"rimming",
"sádico",
"atornillar",
"escroto",
"sexo",
"pelusa",
"follar",
"transexual",
"cagadas",
"cagado",
"cagando",
"de mierda",
"skank",
"puta",
"putas",
"smegma",
"tizón",
"arrebatar",
"hijo de puta",
"espacio",
"agallas",
"testículo",
"zurullo",
"vagina",
"viagra",
"vulva",
"wang",
"hacerse una paja",
"x clasificado",
"xxx",
],
],
[
"fr",
[
"avortement",
"anal",
"anus",
"cul",
"enculer",
"culs",
"connard",
"connards",
"sac de billes",
"des balles",
"bellend",
"bestial",
"bestialité",
"chienne",
"chiennes",
"salope",
"sanglant",
"pipe",
"bollok",
"boob",
"seins",
"les seins",
"buceta",
"clochard",
"bout",
"tapis muncher",
"fente",
"cipa",
"clitoris",
"coq",
"suceuse",
"coqs",
"nègre",
"merde",
"sperme",
"éjaculation",
"cunillingus",
"chatte",
"zut",
"queue",
"godemiché",
"godes",
"tremper",
"baiseur de chien",
"duché",
"digue",
"éjaculer",
"éjaculé",
"éjacule",
"éjaculant",
"pédé",
"fagging",
"fagot",
"fagots",
"penchant",
"fellation",
"bride",
"baisée",
"enfoiré",
"baiseurs",
"putain de",
"fuckings",
"baise",
"emballeur de fudge",
"damné",
"putain",
"enfer",
"hore",
"corné",
"se branler",
"kock",
"les lèvres",
"luxure",
"convoitise",
"masochiste",
"masturber",
"mère enculée",
"nazi",
"nègres",
"orgasim",
"orgasme",
"orgasmes",
"quéquette",
"pénis",
"pisse",
"bourré",
"pisser",
"faire chier",
"caca",
"porno",
"pornographie",
"piquer",
"piqûres",
"pube",
"chattes",
"râpé",
"violeur",
"rectum",
"retard",
"rimming",
"sadique",
"scrotum",
"sexe",
"baiser",
"transexuelle",
"chier",
"chié",
"merdique",
"skank",
"salopes",
"smegma",
"cochonneries",
"arracher",
"fils de pute",
"espacer",
"cran",
"testicule",
"mésange",
"titt",
"vagin",
"viagra",
"vulve",
"wang",
"branler",
"x évalué",
"xxx",
],
],
]);
//# sourceMappingURL=profane-words.js.map
export declare class List {
words: string[];
words: Set<string>;
onListChanged: () => void;

@@ -4,0 +4,0 @@ get empty(): boolean;

@@ -6,14 +6,14 @@ "use strict";

get empty() {
return !this.words.length;
return this.words.size === 0;
}
constructor(onListChanged) {
this.onListChanged = onListChanged;
this.words = [];
this.words = new Set();
}
removeWords(words) {
this.words = this.words.filter((x) => !words.includes(x));
words.forEach((word) => this.words.delete(word));
this.onListChanged();
}
addWords(words) {
this.words = this.words.concat(words.map((word) => word.toLowerCase()));
words.forEach((word) => this.words.add(word.toLowerCase()));
this.onListChanged();

@@ -20,0 +20,0 @@ }

@@ -5,3 +5,4 @@ export declare class ProfanityOptions {

grawlixChar: string;
languages: string[];
constructor(options?: Partial<ProfanityOptions>);
}

@@ -6,6 +6,7 @@ "use strict";

constructor(options = {}) {
var _a, _b, _c;
var _a, _b, _c, _d;
this.wholeWord = (_a = options.wholeWord) !== null && _a !== void 0 ? _a : true;
this.grawlix = (_b = options.grawlix) !== null && _b !== void 0 ? _b : "@#$%&!";
this.grawlixChar = (_c = options.grawlixChar) !== null && _c !== void 0 ? _c : "*";
this.languages = (_d = options.languages) !== null && _d !== void 0 ? _d : ["en"];
}

@@ -12,0 +13,0 @@ }

@@ -7,11 +7,37 @@ import { ProfanityOptions } from "./profanity-options";

private blacklist;
private regex;
private removed;
private regexes;
constructor(options?: ProfanityOptions | Partial<ProfanityOptions>);
exists(text: string): boolean;
censor(text: string, censorType?: CensorType): string;
exists(text: string, languages?: string[]): boolean;
censor(text: string, censorType?: CensorType, languages?: string[]): string;
private replaceProfanity;
addWords(words: string[]): void;
removeWords(words: string[]): void;
/**
* Determines the list of languages to use, either from the provided list or falling back to default languages.
* @param languages - An optional list of languages to use.
* @returns The list of languages to be used.
*/
private resolveLanguages;
/**
* Retrieves or constructs a regular expression for detecting profanity in the specified languages.
* This method first checks if a regex for the given combination of languages already exists in the cache.
*
* @param languages - An array of languages to include in the regex.
* @throws {Error} If no languages are provided.
* @returns A RegExp object for detecting profanity in the specified languages.
*/
private getRegex;
/**
* Constructs a regular expression for detecting profane words.
*
* @param words - An array of profane words to be included in the regex.
* @returns A RegExp that matches any of the profane or blacklisted words.
*/
private buildRegex;
/**
* Clear the cached regexes.
*/
private clearRegexes;
}
export declare const profanity: Profanity;

@@ -11,15 +11,17 @@ "use strict";

this.options = options ? { ...new profanity_options_1.ProfanityOptions(), ...options } : new profanity_options_1.ProfanityOptions();
this.whitelist = new models_1.List(() => this.buildRegex());
this.blacklist = new models_1.List(() => this.buildRegex());
this.blacklist.addWords(data_1.profaneWords);
this.whitelist = new models_1.List(() => this.clearRegexes());
this.blacklist = new models_1.List(() => this.clearRegexes());
this.removed = new models_1.List(() => this.clearRegexes());
this.regexes = new Map();
}
exists(text) {
exists(text, languages) {
if (typeof text !== "string") {
return false;
}
this.regex.lastIndex = 0;
const regex = this.getRegex(this.resolveLanguages(languages));
regex.lastIndex = 0;
const lowercaseText = text.toLowerCase();
let match;
do {
match = this.regex.exec(lowercaseText);
match = regex.exec(lowercaseText);
if (match !== null) {

@@ -29,18 +31,25 @@ const matchStart = match.index;

// Check if the matched word is part of a whitelisted word
const isWhitelisted = this.whitelist.words.some((whitelistedWord) => {
let isWhitelisted = false;
this.whitelist.words.forEach((whitelistedWord) => {
const whitelistedIndex = lowercaseText.indexOf(whitelistedWord, Math.max(0, matchStart - whitelistedWord.length + 1));
if (whitelistedIndex === -1)
return false;
const whitelistedEnd = whitelistedIndex + whitelistedWord.length;
if (this.options.wholeWord) {
// For whole word matching, ensure the whitelisted word exactly matches the profane word
// and is not part of a hyphenated or underscore-separated word
return (matchStart === whitelistedIndex &&
matchEnd === whitelistedEnd &&
(matchStart === 0 || !/[\w-_]/.test(lowercaseText[matchStart - 1])) &&
// eslint-disable-next-line security/detect-object-injection
(matchEnd === lowercaseText.length || !/[\w-_]/.test(lowercaseText[matchEnd])));
if (whitelistedIndex !== -1) {
const whitelistedEnd = whitelistedIndex + whitelistedWord.length;
if (this.options.wholeWord) {
// For whole word matching, ensure the whitelisted word exactly matches the profane word
// and is not part of a hyphenated or underscore-separated word
if (matchStart === whitelistedIndex &&
matchEnd === whitelistedEnd &&
(matchStart === 0 || !/[\w-_]/.test(lowercaseText[matchStart - 1])) &&
// eslint-disable-next-line security/detect-object-injection
(matchEnd === lowercaseText.length || !/[\w-_]/.test(lowercaseText[matchEnd]))) {
isWhitelisted = true;
}
}
else {
// For partial matching, check if the profane word is contained within the whitelisted word
if ((matchStart >= whitelistedIndex && matchStart < whitelistedEnd) || (matchEnd > whitelistedIndex && matchEnd <= whitelistedEnd)) {
isWhitelisted = true;
}
}
}
// For partial matching, check if the profane word is contained within the whitelisted word
return (matchStart >= whitelistedIndex && matchStart < whitelistedEnd) || (matchEnd > whitelistedIndex && matchEnd <= whitelistedEnd);
});

@@ -54,10 +63,12 @@ if (!isWhitelisted) {

}
censor(text, censorType = models_1.CensorType.Word) {
censor(text, censorType = models_1.CensorType.Word, languages) {
if (typeof text !== "string") {
return text;
}
const regex = this.getRegex(this.resolveLanguages(languages));
regex.lastIndex = 0;
const lowercaseText = text.toLowerCase();
switch (censorType) {
case models_1.CensorType.Word:
return text.replace(this.regex, (match) => {
return text.replace(regex, (match) => {
const underscore = match.includes("_") ? "_" : "";

@@ -67,3 +78,3 @@ return this.options.grawlix + underscore;

case models_1.CensorType.FirstChar: {
return this.replaceProfanity(text, lowercaseText, (word) => this.options.grawlixChar + word.slice(1));
return this.replaceProfanity(text, lowercaseText, (word) => this.options.grawlixChar + word.slice(1), regex);
}

@@ -73,3 +84,3 @@ case models_1.CensorType.FirstVowel:

const vowelRegex = new RegExp("[aeiou]", censorType === models_1.CensorType.FirstVowel ? "i" : "ig");
return this.replaceProfanity(text, lowercaseText, (word) => word.replace(vowelRegex, this.options.grawlixChar));
return this.replaceProfanity(text, lowercaseText, (word) => word.replace(vowelRegex, this.options.grawlixChar), regex);
}

@@ -80,9 +91,8 @@ default:

}
replaceProfanity(text, lowercaseText, replacer) {
replaceProfanity(text, lowercaseText, replacer, regex) {
let result = text;
let offset = 0;
this.regex.lastIndex = 0;
let match;
do {
match = this.regex.exec(lowercaseText);
match = regex.exec(lowercaseText);
if (match !== null) {

@@ -100,13 +110,94 @@ const matchStart = match.index;

addWords(words) {
this.blacklist.addWords(words);
const removedWords = [];
const blacklistWords = [];
words.forEach((word) => {
const lowerCaseWord = word.toLowerCase();
if (this.removed.words.has(lowerCaseWord)) {
removedWords.push(lowerCaseWord);
}
else {
blacklistWords.push(lowerCaseWord);
}
});
if (removedWords.length) {
this.removed.removeWords(removedWords);
}
if (blacklistWords.length) {
this.blacklist.addWords(blacklistWords);
}
}
removeWords(words) {
this.blacklist.removeWords(words.map((word) => word.toLowerCase()));
const blacklistedWords = [];
const removeWords = [];
words.forEach((word) => {
const lowerCaseWord = word.toLowerCase();
if (this.blacklist.words.has(lowerCaseWord)) {
blacklistedWords.push(lowerCaseWord);
}
else {
removeWords.push(lowerCaseWord);
}
});
if (blacklistedWords.length) {
this.blacklist.removeWords(blacklistedWords);
}
if (removeWords.length) {
this.removed.addWords(removeWords);
}
}
buildRegex() {
const escapedBlacklistWords = this.blacklist.words.map(utils_1.escapeRegExp);
const profanityPattern = `${this.options.wholeWord ? "(?:\\b|_)" : ""}(${escapedBlacklistWords.join("|")})${this.options.wholeWord ? "(?:\\b|_)" : ""}`;
/**
* Determines the list of languages to use, either from the provided list or falling back to default languages.
* @param languages - An optional list of languages to use.
* @returns The list of languages to be used.
*/
resolveLanguages(languages) {
return (languages === null || languages === void 0 ? void 0 : languages.length) ? languages : this.options.languages;
}
/**
* Retrieves or constructs a regular expression for detecting profanity in the specified languages.
* This method first checks if a regex for the given combination of languages already exists in the cache.
*
* @param languages - An array of languages to include in the regex.
* @throws {Error} If no languages are provided.
* @returns A RegExp object for detecting profanity in the specified languages.
*/
getRegex(languages) {
if (!languages.length) {
throw new Error("At least one language must be provided");
}
const uniqueLanguages = [...new Set(languages.map((language) => language.trim().toLowerCase()))];
const regexKey = uniqueLanguages.sort().join(",");
if (this.regexes.has(regexKey)) {
return this.regexes.get(regexKey);
}
const allWords = uniqueLanguages.flatMap((language) => {
const words = data_1.profaneWords.get(language);
if (!words) {
throw new Error(`Invalid language: "${language}"`);
}
return words.filter((word) => !this.removed.words.has(word));
});
const regex = this.buildRegex(allWords);
this.regexes.set(regexKey, regex);
return regex;
}
/**
* Constructs a regular expression for detecting profane words.
*
* @param words - An array of profane words to be included in the regex.
* @returns A RegExp that matches any of the profane or blacklisted words.
*/
buildRegex(words) {
const allProfaneWords = [...words, ...this.blacklist.words];
const escapedProfaneWords = allProfaneWords.map(utils_1.escapeRegExp);
const profanityPattern = `${this.options.wholeWord ? "(?:\\b|_)" : ""}(${escapedProfaneWords.join("|")})${this.options.wholeWord ? "(?:\\b|_)" : ""}`;
// eslint-disable-next-line security/detect-non-literal-regexp
this.regex = new RegExp(profanityPattern, "gi");
return new RegExp(profanityPattern, "gi");
}
/**
* Clear the cached regexes.
*/
clearRegexes() {
this.regexes.clear();
}
}

@@ -113,0 +204,0 @@ exports.Profanity = Profanity;

{
"name": "@2toad/profanity",
"version": "2.5.0",
"description": "A JavaScript profanity filter",
"version": "3.0.0",
"description": "A multi-language profanity filter with full TypeScript support",
"homepage": "https://github.com/2Toad/Profanity",

@@ -20,3 +20,3 @@ "author": "2Toad",

"test:watch": "npm run test -- --watch",
"benchmark": "ts-node src/benchmark/benchmark.ts",
"benchmark": "docker-compose -f ./src/benchmark/docker-compose.yml up --build",
"lint": "eslint . --cache",

@@ -57,2 +57,5 @@ "lint:fix": "eslint . --fix",

"@types/chai": "^4.3.19",
"@types/eslint__js": "^8.42.3",
"@types/eslint-config-prettier": "^6.11.3",
"@types/eslint-plugin-security": "^3.0.0",
"@types/mocha": "^10.0.7",

@@ -59,0 +62,0 @@ "@types/node": "^22.5.2",

@@ -7,3 +7,3 @@ # Profanity 🧼

A JavaScript profanity filter (with TypeScript support)
A multi-language profanity filter with full TypeScript support

@@ -49,2 +49,3 @@ ## Getting Started

const profanity = new Profanity({
languages: ['de'],
wholeWord: false,

@@ -56,2 +57,24 @@ grawlix: '*****',

### languages
By default, this is set to `['en']` (English). You can change the default to any [supported language](./supported-languages.md), including multiple languages:
```JavaScript
const profanity = new Profanity({
languages: ["en", "de"],
});
```
You can override this option by specifying the languages in `exists` or `censor`:
```JavaScript
profanity.exists('Je suis un connard', ["fr"]);
// true
profanity.censor('I like big butts and je suis un connard', CensorType.Word, ["en", "de", "fr"]);
// I like big @#$%&! and je suis un @#$%&!
```
If no languages are specified in the method call, it will use the languages specified in the options.
### wholeWord

@@ -118,3 +141,2 @@

## Customize the word list

@@ -121,0 +143,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc