first commit
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# `schemas` — Zod boundary schemas
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
Declares every Zod schema validating the package's public boundaries:
|
||||
`AssessOptions`, `FeedbackOptions`, `AssessReactiveOptions`,
|
||||
`CrackTimeOptions`, `Match` (discriminated union over all six pattern
|
||||
types), `StrengthResult`, and `DictionarySet`. Every public function
|
||||
Zod-parses its options before any other work, so a malformed input throws
|
||||
`PWSTRENGTH.INVALID_OPTIONS` with the original `ZodError` preserved on
|
||||
`cause`.
|
||||
|
||||
## Features
|
||||
|
||||
- Discriminated `MatchSchema` over six pattern types
|
||||
- Stable `StrengthResultSchema` exported for downstream consumers
|
||||
- Strict refinements on numeric ranges (e.g. `debounceMs ∈ [0, 5000]`)
|
||||
- AbortSignal and function-typed fields validated via `z.custom`
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { AssessOptionsSchema } from "@suaveplan/password-strength/schemas";
|
||||
|
||||
const parsed = AssessOptionsSchema.parse({ userInputs: ["alice@example.com"] });
|
||||
console.log(parsed);
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { MatchSchema, StrengthResultSchema } from "@suaveplan/password-strength/schemas";
|
||||
|
||||
const match = MatchSchema.parse({
|
||||
pattern: "dictionary",
|
||||
i: 0,
|
||||
j: 7,
|
||||
token: "password",
|
||||
matchedWord: "password",
|
||||
rank: 1,
|
||||
dictionaryName: "passwords",
|
||||
reversed: false,
|
||||
l33t: false,
|
||||
});
|
||||
console.log(match.pattern); // narrowed to "dictionary"
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `AssessOptionsSchema` — options accepted by `assess`.
|
||||
- `FeedbackOptionsSchema` — options accepted by `feedback`.
|
||||
- `AssessReactiveOptionsSchema` — options accepted by `assessReactive`.
|
||||
- `CrackTimeOptionsSchema` — re-exported from `scoring/crack-times`.
|
||||
- `MatchSchema` — discriminated union over all six pattern types.
|
||||
- `StrengthResultSchema` — the canonical `StrengthResult` shape.
|
||||
- `DictionarySetSchema` — `Record<string, Map<string, number>>`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`MatchSchema` uses `z.discriminatedUnion` on the `pattern` field so callers
|
||||
parsing untrusted JSON get type-narrowed output. Function-typed and
|
||||
`AbortSignal`-typed fields use `z.custom` since Zod has no built-in for
|
||||
either. The `baseMatch` partial is spread into each variant to keep
|
||||
position-tracking fields (`i`, `j`, `token`) consistent across the union
|
||||
without duplication.
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user