2.8 KiB
regex — regex pattern matcher
(no submodules)
Purpose
Recognises substrings matching a set of regex patterns per Wheeler 2016
section 3.6. The default registry covers a recent_year pattern matching
19xx and 20xx. Callers extend the registry to flag additional patterns
(hex strings, phone-number shapes, project-specific identifiers) without
forking the scorer.
Features
- Default
recent_yearregex matches19xxand20xx - Registry-pluggable: callers can register their own named regexes
- Global-flag enforced internally so every occurrence is reported
- Every match carries the full
RegExpMatchArrayfor downstream inspection
Usage: Basic Example
import { regexMatch } from "@suaveplan/password-strength/matchers/regex";
const matches = regexMatch("login1985");
console.log(matches[0].regexName); // "recent_year"
console.log(matches[0].token); // "1985"
Usage: Advanced Example
import { regexMatch } from "@suaveplan/password-strength/matchers/regex";
const matches = regexMatch("token=ABCDEF", { regexes: { hex: /[0-9A-F]+/g } });
for (const m of matches) {
console.log(m.regexName, m.token);
}
API Reference
regexMatch(password: string, opts?: RegexMatchOptions): RegexMatch[]opts.regexes:Record<string, RegExp>— the registry. Defaults toDEFAULT_REGEXES.
DEFAULT_REGEXES: Readonly<Record<string, RegExp>>— frozen default registry (currentlyrecent_year).RegexMatchOptions:{ regexes?: Record<string, RegExp> }
Implementation Notes
The matcher copies each registered regex with the g flag forced on so a
global walk over the password emits every occurrence. The walk uses
String.prototype.matchAll rather than mutating lastIndex so zero-width
matches do not loop. The full RegExpMatchArray is preserved on each
output record so callers can read capture groups when their regex uses
them.
Additional Implementation Notes
The implementation follows the canonical zxcvbn algorithm from Wheeler 2016 with
the suaveplan-style additions described in the package proposal: structured error
codes via the defineCodes registry, Zod boundaries at every public entry
point, OTel histograms and counters keyed to low-cardinality attributes, and
a strict input-length guard at 200 characters. Consumers integrate with their
existing observability stack by installing a meter provider before importing
the package, and with their i18n stack via the MessageResolver callback type
declared in @suaveplan/types. The bundled data tables are intentionally
small to keep the package bundle compact; production deployments should swap
in fuller frequency-ranked tables via loadDictionaries. The default English
dictionary set is a frozen DictionarySet that the matcher never mutates;
caller-supplied dictionaries override defaults by name.