Email address and obfuscated-email filtering for composable text moderation.
Add the GitHub Packages registry for the @textfilters scope in a project .npmrc or user npm config:
@textfilters:registry=https://npm.pkg.github.comInstall with GitHub npm authentication configured. GitHub Packages requires authentication for npm installs, including public packages.
npm install @textfilters/core @textfilters/emailimport { createEmailFilter } from "@textfilters/email";
const emailFilter = createEmailFilter({ maskChar: "#" });
const safeText = emailFilter.censor("contact user@example.com");import { createEmailFilter } from "@textfilters/email";
const emailOnlyFilter = createEmailFilter({ matchObfuscated: false });
const safeText = emailOnlyFilter.censor("contact user@example.com");import { createEmailFilter } from "@textfilters/email";
const emailFilter = createEmailFilter({
excludeDomains: ["example.com"],
excludeUsernames: ["support"],
});import { filter } from "@textfilters/email";
const safeText = filter.censor("contact user [at] example [dot] com");import { createTextPipeline } from "@textfilters/core";
import { filter as emailFilter } from "@textfilters/email";
const pipeline = createTextPipeline().use(emailFilter);
const result = pipeline.censor("contact user@example.com");The default shared instance is exported as filter. It has stable name: "email".
The package detects direct email addresses such as user@example.com, tagged local parts, mixed-case input, subdomains, and common fullwidth symbol variants after NFKC normalization.
It also detects common obfuscated forms such as user [at] example [dot] com, user(at)example(dot)com, user at example dot com, and user [@] example [.] com.
Set matchObfuscated: false to keep only direct user@example.com matching.
Configured exclusions can leave selected full email addresses, local-part usernames, or domains unmasked. Domain exclusions match the exact domain and its subdomains after normalization.
censor() preserves JavaScript string length for matched spans where practical and is idempotent. Masking is applied over code points so surrogate pairs are not split.
False-positive guards avoid package scopes, social handles, prose-only at and dot words, version-like text, IP addresses, incomplete domains, and single-label domains by default.
See docs/architecture.md for the scanner flow, module map, and change guide.
Releases are managed by Release Please from Conventional Commit history on main. When a Release Please release is created, the workflow runs npm run check and publishes the package to GitHub Packages. Release tags keep the v* pattern.
The package is prepared for publication to GitHub Packages, not the public npm registry.
MIT