5.3 KiB
validate-graph — keyboard graph integrity guard
(no submodules)
- azerty — (no submodules)- dvorak — (no submodules) - dvorak — (no submodules)- qwerty — (no submodules) - qwerty — (no submodules)- validate-graph — (no submodules)- azerty — (no submodules)…
- azerty — (no submodules)- dvorak — (no submodules)- dvorak — (no submodules)- qwerty — (no submodules)- qwerty — (no submodules)- validate-graph — (no submodules)- azerty — (no submodules)- dvorak — (no submodules)- dvorak — (no submodules)- qwerty — (no submodules)- qwerty — (no submodules)- validate-graph — (no submodules)- azerty — <!-- begin:auto-doc…
- azerty — (no submodules)- dvorak — (no submodules)- dvorak — (no submodules)- qwerty — (no submodules)- qwerty — (no submodules)- validate-graph — (no submodules)- azerty — (no submodules)…
- azerty — (no submodules)- dvorak — (no submodules) - dvorak — (no submodules)- qwerty — (no submodules) - qwerty — (no submodules)- validate-graph — (no submodules)
Purpose
Validates that a user-supplied keyboard adjacency graph is well-formed
before the keyboardMatch matcher walks it. A malformed graph would
either produce nonsensical matches (self-loops) or cause inconsistent
guess estimates across users typing the same word.
Features
- Detects self-adjacency (a key listed as adjacent to itself)
- Detects asymmetric edges (
alistsbbutbdoes not lista) - Throws
PasswordStrengthErrorwith codePWSTRENGTH.GRAPH_INVALID - Pure data validation; no side effects
Usage: Basic Example
import { validateGraph } from "@suaveplan/password-strength";
import { QWERTY_GRAPH } from "@suaveplan/password-strength/graphs/qwerty";
validateGraph("qwerty", QWERTY_GRAPH); // returns; throws if malformed
Usage: Advanced Example
import { validateGraph, PWSTRENGTH_CODES, PasswordStrengthError } from "@suaveplan/password-strength";
const broken = { q: ["q"] };
try {
validateGraph("broken", broken);
} catch (e) {
if (e instanceof PasswordStrengthError && e.code === PWSTRENGTH_CODES.GRAPH_INVALID) {
console.log("graph rejected");
}
}
API Reference
validateGraph(name: string, graph: KeyboardGraph): void- Throws
PasswordStrengthErrorwith codePWSTRENGTH.GRAPH_INVALIDwhen the graph contains a self-loop or an asymmetric edge. The error message names the offending key for fast debugging.
- Throws
Implementation Notes
The symmetry check is one-directional per pair — if a claims adjacency to
b, then b's adjacency slot list must contain a in at least one of its
slots' character pairs (covering both the shifted and unshifted halves).
Slots set to null are skipped. The walk is O(n) over the number of
edges in the graph; running it on a 60-key graph is negligible.
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.