
Security News
Open Source Maintainers Feeling the Weight of the EUโs Cyber Resilience Act
The EU Cyber Resilience Act is prompting compliance requests that open source maintainers may not be obligated or equipped to handle.
word-sensor
Advanced tools
A powerful and flexible word filtering library for JavaScript/TypeScript with advanced features like regex patterns, statistics, and batch processing
WordSensor is a powerful and flexible word filtering library for JavaScript/TypeScript. It helps you detect, replace, or remove forbidden words from text with advanced features like regex patterns, statistics, batch processing, and more.
npm install word-sensor
or
yarn add word-sensor
import { WordSensor } from 'word-sensor';
// Create a sensor with forbidden words
const sensor = new WordSensor({
words: ['badword', 'offensive', 'rude'],
maskChar: '*',
caseInsensitive: true,
logDetections: true
});
// Filter text
const result = sensor.filter('This is a badword test.');
console.log(result); // "This is a ******* test."
import { createProfanityFilter, createSpamFilter, createPhishingFilter } from 'word-sensor';
// Create specialized filters
const profanityFilter = createProfanityFilter();
const spamFilter = createSpamFilter();
const phishingFilter = createPhishingFilter();
// Use them
console.log(profanityFilter.filter('This is badword content.')); // "This is ******* content."
console.log(spamFilter.filter('Buy now! Free money!')); // "#### now! #### money!"
new WordSensor(config?: WordSensorConfig)
Configuration Options:
words?: string[]
- Initial list of forbidden wordsmaskChar?: string
- Character used for masking (default: "*")caseInsensitive?: boolean
- Case-insensitive matching (default: true)logDetections?: boolean
- Enable detection logging (default: false)enableRegex?: boolean
- Enable regex pattern support (default: false)wordBoundary?: boolean
- Use word boundaries (default: true)customReplacer?: (word: string, context: string) => string
- Custom replacement functionfilter(text: string, mode?: "replace" | "remove" | "highlight", maskType?: "full" | "partial" | "smart"): string
Filter text with specified mode and masking type.
// Replace with full masking
sensor.filter('This is badword.'); // "This is *******."
// Remove forbidden words
sensor.filter('This is badword.', 'remove'); // "This is ."
// Highlight forbidden words
sensor.filter('This is badword.', 'highlight'); // "This is [FILTERED: badword]."
// Smart masking
sensor.filter('This is badword.', 'replace', 'smart'); // "This is b****d."
detect(text: string): string[]
Detect all forbidden words in text.
const detected = sensor.detect('This contains badword and offensive content.');
console.log(detected); // ["badword", "offensive"]
detectWithPositions(text: string): Array<{word: string, start: number, end: number}>
Detect forbidden words with their positions.
const positions = sensor.detectWithPositions('This badword is offensive.');
console.log(positions);
// [
// { word: "badword", start: 5, end: 12 },
// { word: "offensive", start: 16, end: 25 }
// ]
// Add words
sensor.addWord('newbadword', '###'); // With custom mask
sensor.addWords(['word1', 'word2']);
// Remove words
sensor.removeWord('badword');
sensor.removeWords(['word1', 'word2']);
// Check words
sensor.hasWord('badword'); // true/false
sensor.getWords(); // Get all forbidden words
sensor.clearWords(); // Clear all words
// Enable regex support
const regexSensor = new WordSensor({ enableRegex: true });
// Add regex patterns
regexSensor.addRegexPattern('\\b\\w+@\\w+\\.\\w+\\b', '[EMAIL]');
regexSensor.addRegexPattern('\\b\\d{4}-\\d{4}-\\d{4}-\\d{4}\\b', '[CARD]');
// Filter with regex
const result = regexSensor.filter('Contact me at test@example.com');
console.log(result); // "Contact me at [EMAIL]"
// Get detection statistics
const stats = sensor.getStats();
console.log(stats);
// {
// totalDetections: 5,
// uniqueWords: ["badword", "offensive"],
// detectionCounts: { "badword": 3, "offensive": 2 },
// lastDetectionTime: Date
// }
// Get detection logs
const logs = sensor.getDetectionLogs();
console.log(logs); // ["badword", "offensive", "badword", ...]
// Reset statistics
sensor.resetStats();
// Update configuration
sensor.setMaskChar('#');
sensor.setCaseInsensitive(false);
sensor.setLogDetections(true);
sensor.setCustomReplacer((word) => `[${word.toUpperCase()}]`);
// Check if text is clean
sensor.isClean('This is clean text.'); // true
sensor.isClean('This has badword.'); // false
// Get clean percentage
sensor.getCleanPercentage('This badword is offensive.'); // 50
// Sanitize text (quick filter)
sensor.sanitizeText('This is badword.'); // "This is *******."
import {
createProfanityFilter,
createSpamFilter,
createPhishingFilter,
PRESET_WORDS
} from 'word-sensor';
// Create specialized filters
const profanityFilter = createProfanityFilter('*');
const spamFilter = createSpamFilter('#');
const phishingFilter = createPhishingFilter('!');
// Access preset word lists
console.log(PRESET_WORDS.profanity);
console.log(PRESET_WORDS.spam);
console.log(PRESET_WORDS.phishing);
import { batchFilter, batchDetect, getBatchStats } from 'word-sensor';
const texts = [
'This is bad.',
'This is offensive.',
'This is clean.'
];
// Batch filter
const filtered = batchFilter(texts, sensor);
console.log(filtered);
// ["This is ***.", "This is *********.", "This is clean."]
// Batch detect
const detected = batchDetect(texts, sensor);
console.log(detected);
// [
// { text: "This is bad.", detected: ["bad"] },
// { text: "This is offensive.", detected: ["offensive"] },
// { text: "This is clean.", detected: [] }
// ]
// Get batch statistics
const stats = getBatchStats(texts, sensor);
console.log(stats);
// {
// totalTexts: 3,
// cleanTexts: 1,
// dirtyTexts: 2,
// totalDetections: 2,
// averageCleanPercentage: 66.67
// }
import { createCustomReplacer, createEmojiReplacer } from 'word-sensor';
// Create custom replacer
const customReplacer = createCustomReplacer({
'bad': 'good',
'offensive': 'appropriate',
'rude': 'polite'
});
// Create emoji replacer
const emojiReplacer = createEmojiReplacer();
// Use with sensor
sensor.setCustomReplacer(customReplacer);
sensor.setCustomReplacer(emojiReplacer);
import { validateRegexPattern, escapeRegexSpecialChars } from 'word-sensor';
// Validate regex pattern
validateRegexPattern('\\b\\w+\\b'); // true
validateRegexPattern('invalid['); // false
// Escape special characters
escapeRegexSpecialChars('test.com'); // "test\\.com"
escapeRegexSpecialChars('test*test'); // "test\\*test"
import { loadForbiddenWordsFromAPI, loadWordsFromFile } from 'word-sensor';
// Load from API
await loadForbiddenWordsFromAPI(
'https://api.example.com/forbidden-words',
'data.words',
sensor
);
// Load from file (browser)
const fileInput = document.getElementById('file') as HTMLInputElement;
const file = fileInput.files[0];
if (file) {
const words = await loadWordsFromFile(file);
sensor.addWords(words);
}
import { WordSensor, createProfanityFilter, createSpamFilter } from 'word-sensor';
class ContentModerator {
private profanityFilter: WordSensor;
private spamFilter: WordSensor;
private customFilter: WordSensor;
constructor() {
this.profanityFilter = createProfanityFilter();
this.spamFilter = createSpamFilter();
this.customFilter = new WordSensor({
enableRegex: true,
wordBoundary: false
});
// Add custom patterns
this.customFilter.addRegexPattern('\\b\\w+@\\w+\\.\\w+\\b', '[EMAIL]');
this.customFilter.addRegexPattern('\\b\\d{10,}\\b', '[PHONE]');
}
moderateContent(content: string): {
isClean: boolean;
filteredContent: string;
violations: string[];
stats: any;
} {
// Apply all filters
let filteredContent = content;
const violations: string[] = [];
// Check profanity
const profanityDetected = this.profanityFilter.detect(content);
if (profanityDetected.length > 0) {
violations.push('profanity');
filteredContent = this.profanityFilter.filter(filteredContent);
}
// Check spam
const spamDetected = this.spamFilter.detect(content);
if (spamDetected.length > 0) {
violations.push('spam');
filteredContent = this.spamFilter.filter(filteredContent);
}
// Apply custom filters
filteredContent = this.customFilter.filter(filteredContent);
return {
isClean: violations.length === 0,
filteredContent,
violations,
stats: {
profanity: this.profanityFilter.getStats(),
spam: this.spamFilter.getStats(),
custom: this.customFilter.getStats()
}
};
}
}
// Usage
const moderator = new ContentModerator();
const result = moderator.moderateContent('This is badword spam content with test@example.com');
console.log(result);
import { WordSensor, createEmojiReplacer } from 'word-sensor';
class ChatFilter {
private sensor: WordSensor;
private messageHistory: string[] = [];
constructor() {
this.sensor = new WordSensor({
words: ['badword', 'offensive'],
logDetections: true,
customReplacer: createEmojiReplacer()
});
}
processMessage(message: string, userId: string): {
filteredMessage: string;
isClean: boolean;
warning: string | null;
} {
const filteredMessage = this.sensor.filter(message);
const isClean = this.sensor.isClean(message);
// Check user history
const userViolations = this.messageHistory.filter(msg =>
msg.includes(userId) && !this.sensor.isClean(msg)
).length;
let warning = null;
if (!isClean) {
if (userViolations >= 3) {
warning = 'You have been warned multiple times. Further violations may result in a ban.';
} else {
warning = 'Please keep the chat appropriate.';
}
}
// Log message
this.messageHistory.push(`${userId}: ${message}`);
return { filteredMessage, isClean, warning };
}
getModerationStats() {
return this.sensor.getStats();
}
}
import { WordSensor, batchDetect, getBatchStats } from 'word-sensor';
class ContentAnalyzer {
private sensor: WordSensor;
constructor() {
this.sensor = new WordSensor({
words: ['inappropriate', 'spam', 'offensive'],
logDetections: true
});
}
analyzeBatch(contentList: string[]): {
summary: any;
details: Array<{
content: string;
isClean: boolean;
detectedWords: string[];
cleanPercentage: number;
}>;
} {
const batchResults = batchDetect(contentList, this.sensor);
const batchStats = getBatchStats(contentList, this.sensor);
const details = contentList.map((content, index) => ({
content,
isClean: batchResults[index].detected.length === 0,
detectedWords: batchResults[index].detected,
cleanPercentage: this.sensor.getCleanPercentage(content)
}));
return {
summary: {
...batchStats,
sensorStats: this.sensor.getStats()
},
details
};
}
}
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
# Build for production
npm run build
# Build in watch mode
npm run dev
# Clean build artifacts
npm run clean
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/amazing-feature
)git commit -m 'Add some amazing feature'
)git push origin feature/amazing-feature
)This project is licensed under the MIT License - see the LICENSE file for details.
Developed by Asrul Harahap.
โญ Star this repository if you find it useful!
FAQs
A powerful and flexible word filtering library for JavaScript/TypeScript with advanced features like regex patterns, statistics, and batch processing
The npm package word-sensor receives a total of 8 weekly downloads. As such, word-sensor popularity was classified as not popular.
We found that word-sensor demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The EU Cyber Resilience Act is prompting compliance requests that open source maintainers may not be obligated or equipped to handle.
Security News
Crates.io adds Trusted Publishing support, enabling secure GitHub Actions-based crate releases without long-lived API tokens.
Research
/Security News
Undocumented protestware found in 28 npm packages disrupts UI for Russian-language users visiting Russian and Belarusian domains.