first commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# `range/range-strict-frame.ts`
|
||||
|
||||
## Purpose
|
||||
|
||||
`parseRangeLine` is the per-line framer used by `streamParseRangeBody`.
|
||||
It enforces the documented Pwned Passwords line shape (`/^[0-9A-F]{35}:[0-9]+$/`)
|
||||
in strict mode, throwing `HIBP.MALFORMED_RESPONSE` with the offending
|
||||
line index on any deviation. In off-mode it accepts lowercase hex,
|
||||
defaults an unparseable count to `0`, and still rejects structurally
|
||||
broken lines (missing colon, wrong suffix length, non-hex characters).
|
||||
|
||||
## Features
|
||||
|
||||
- Strict mode default — uppercase hex, single colon, decimal count.
|
||||
- Off mode tolerant of lowercase hex and unparseable counts (defaults
|
||||
to `0`), still rejecting non-hex suffixes or wrong lengths.
|
||||
- Throws carry `context.lineIndex` so callers can surface a precise
|
||||
diagnostic.
|
||||
- Pure synchronous function — no allocations beyond the returned
|
||||
`{ suffix, count }` record.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { parseRangeLine } from "@suaveplan/hibp";
|
||||
|
||||
const { suffix, count } = parseRangeLine(rawLine, 0, true);
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { HibpError, parseRangeLine } from "@suaveplan/hibp";
|
||||
|
||||
function parseTolerant(lines: string[]): Array<{ suffix: string; count: number }> {
|
||||
const out: Array<{ suffix: string; count: number }> = [];
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
try {
|
||||
out.push(parseRangeLine(lines[i] as string, i, false));
|
||||
} catch (err) {
|
||||
if (err instanceof HibpError) continue;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `RangeLine` — `{ suffix: string; count: number }`.
|
||||
- `parseRangeLine(raw, lineIndex, strict): RangeLine` — throws
|
||||
`HibpError(HIBP.MALFORMED_RESPONSE)` on rejection.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The strict pattern uses a tight regex check before the colon split so
|
||||
mismatches are rejected before any allocation. Off-mode counts default
|
||||
to `0` rather than `NaN` so consumers can rely on integer semantics
|
||||
throughout. The function avoids `try`/`catch` internally — every
|
||||
branch is explicit so a future contributor can reason about the
|
||||
failure paths without tracing exception flow. Strict mode is the
|
||||
default because the documented Pwned Passwords contract is precise;
|
||||
opting out should be a deliberate operational decision, not the
|
||||
silent fallback.
|
||||
Reference in New Issue
Block a user