Skip to content

Commit 88d273b

Browse files
committed
refactor(*): move code from lib -> src
moves all source files to src folder. also types for everything. better documented everything as well #166, #147
1 parent f9af397 commit 88d273b

File tree

5 files changed

+607
-91
lines changed

5 files changed

+607
-91
lines changed

lib/badwords.js

-89
This file was deleted.

src/badwords.ts

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { localList } from './lang.js'
2+
import { array as baseList } from 'badwords-list'
3+
4+
/**
5+
* Constructor options for Filter class.
6+
*
7+
* @property {boolean} emptyList - Instantiate filter with no blocklist
8+
* @property {array} list - Instantiate filter with custom list
9+
* @property {string} placeHolder - Character used to replace profane words.
10+
* @property {string} regex - Regular expression used to sanitize words before comparing them to blocklist.
11+
* @property {string} replaceRegex - Regular expression used to replace profane words with placeHolder.
12+
* @property {string} splitRegex - Regular expression used to split a string into words.
13+
*/
14+
export interface FilterOptions {
15+
emptyList?: boolean
16+
list?: string[]
17+
exclude?: string[]
18+
placeHolder?: string
19+
regex?: RegExp
20+
replaceRegex?: RegExp
21+
splitRegex?: RegExp
22+
}
23+
24+
/**
25+
* Local list of profane words.
26+
*
27+
* @property {array} words - List of profane words.
28+
*/
29+
export type LocalList = {
30+
words: string[]
31+
}
32+
33+
/**
34+
* Profanity Filter class.
35+
* @public
36+
*/
37+
export class Filter {
38+
/**
39+
* List of words to filter.
40+
* @type {array} list - List of words to filter.
41+
*/
42+
list: string[] = []
43+
/**
44+
* List of words to exclude from filter.
45+
* @type {array} exclude - List of words to exclude from filter.
46+
*/
47+
exclude: string[] = []
48+
/**
49+
* Character used to replace profane words.
50+
* @type {string} placeHolder - Character used to replace profane words.
51+
*/
52+
placeHolder: string = '*'
53+
/**
54+
* Regular expression used to sanitize words before comparing them to blocklist.
55+
* @type {string} regex - Regular expression used to sanitize words before comparing them to blocklist.
56+
*/
57+
regex: RegExp = /[^a-zA-Z0-9|$|@]|\^/g
58+
/**
59+
* Regular expression used to replace profane words with placeHolder.
60+
* @type {string} replaceRegex - Regular expression used to replace profane words with placeHolder.
61+
*/
62+
replaceRegex: RegExp = /\w/g
63+
/**
64+
* Regular expression used to split a string into words.
65+
* @type {string} splitRegex - Regular expression used to split a string into words.
66+
*/
67+
splitRegex: RegExp = /\b|_/g
68+
69+
/**
70+
* Filter constructor.
71+
*
72+
* @param {FilterOptions} options - Constructor options for Filter class.
73+
*/
74+
constructor(options: FilterOptions = {}) {
75+
Object.assign(this, {
76+
list:
77+
(options.emptyList && []) ||
78+
Array.prototype.concat.apply(localList, [baseList, options.list || []]),
79+
exclude: options.exclude || [],
80+
splitRegex: options.splitRegex || /\b|_/g,
81+
placeHolder: options.placeHolder || '*',
82+
regex: options.regex || /[^a-zA-Z0-9|$|@]|\^/g,
83+
replaceRegex: options.replaceRegex || /\w/g,
84+
})
85+
}
86+
87+
/**
88+
* Determine if a string contains profane language.
89+
* @param {string} string - String to evaluate for profanity.
90+
*/
91+
isProfane(string: string): boolean {
92+
return (
93+
this.list.filter((word) => {
94+
const wordExp = new RegExp(
95+
`\\b${word.replace(/(\W)/g, '\\$1')}\\b`,
96+
'gi',
97+
)
98+
return (
99+
!this.exclude.includes(word.toLowerCase()) && wordExp.test(string)
100+
)
101+
}).length > 0 || false
102+
)
103+
}
104+
105+
/**
106+
* Replace a word with placeHolder characters;
107+
* @param {string} string - String to replace.
108+
*/
109+
replaceWord(string: string): string {
110+
return string
111+
.replace(this.regex, '')
112+
.replace(this.replaceRegex, this.placeHolder)
113+
}
114+
115+
/**
116+
* Evaluate a string for profanity and return an edited version.
117+
* @param {string} input - String to filter.
118+
*/
119+
clean(input: string): string {
120+
const delimiter = this.splitRegex.exec(input)
121+
122+
if (!input || !delimiter) {
123+
return input
124+
}
125+
126+
return input
127+
.split(this.splitRegex)
128+
.map((word) => {
129+
return this.isProfane(word) ? this.replaceWord(word) : word
130+
})
131+
.join(delimiter[0])
132+
}
133+
134+
/**
135+
* Add word(s) to blocklist filter / remove words from whitelist filter
136+
* @param {...string} words - Word(s) to add to blocklist
137+
*/
138+
addWords(...words: string[]): void {
139+
this.list.push(...words)
140+
141+
words
142+
.map((word) => word.toLowerCase())
143+
.forEach((word) => {
144+
if (this.exclude.includes(word)) {
145+
this.exclude.splice(this.exclude.indexOf(word), 1)
146+
}
147+
})
148+
}
149+
150+
/**
151+
* Add words to allowlist filter
152+
* @param {...string} words - Word(s) to add to allowlist.
153+
*/
154+
removeWords(...words: string[]): void {
155+
this.exclude.push(...words.map((word) => word.toLowerCase()))
156+
}
157+
}

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Filter, FilterOptions, LocalList } from './badwords.js'

lib/lang.json src/lang.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"words":[
2+
"words": [
33
"ahole",
44
"anus",
55
"ash0le",
@@ -188,7 +188,6 @@
188188
"pussy",
189189
"puuke",
190190
"puuker",
191-
"qweir",
192191
"recktum",
193192
"rectum",
194193
"retard",

0 commit comments

Comments
 (0)