first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
# `schemas/paste.schema.ts`
## Purpose
`PasteSchema` validates the [HIBP v3 `Paste`
payload](https://haveibeenpwned.com/API/v3#PastesForAccount) returned by
`/pasteaccount/{email}`. Older paste records can omit `Title` and `Date`,
so this schema makes them optional while still enforcing structural shape
on the required fields. Defending this boundary keeps `getPastesForAccount`
honest about its return type.
## Features
- Required: `Source`, `Id`, `EmailCount` (non-negative int).
- Optional: `Title`, `Date` (older paste records may lack metadata).
- Throws `ZodError` on type mismatch; the breach client maps that to
`HIBP.MALFORMED_RESPONSE`.
## Usage: Basic Example
```ts
import { PasteSchema } from "@suaveplan/hibp";
const paste = PasteSchema.parse({
Source: "Pastebin",
Id: "ABC",
EmailCount: 100,
});
```
## Usage: Advanced Example
```ts
import { PasteSchema, type Paste } from "@suaveplan/hibp";
export function summarisePastes(items: unknown[]): {
pastes: Paste[];
totalEmails: number;
} {
const pastes = items.map((x) => PasteSchema.parse(x));
return {
pastes,
totalEmails: pastes.reduce((n, p) => n + p.EmailCount, 0),
};
}
```
## API Reference
- `PasteSchema: ZodObject` — v3 paste shape.
- `Paste` — `z.infer<typeof PasteSchema>` type alias.
## Implementation Notes
The optional `Title` / `Date` fields are deliberately not defaulted; if
they are absent in the upstream payload, they remain `undefined` in the
parsed value so callers can branch on presence. We considered defaulting
`Date` to `null` for consistency but rejected it as a divergence from the
documented contract. The schema rejects unknown nested types eagerly: a
server-side rename like `Source` → `source` (lowercase) will surface as a
`HIBP.MALFORMED_RESPONSE` from `getPastesForAccount`, which is the
correct behaviour — a silent rename would be far worse than a typed
throw. Callers can wrap individual `parse` calls in `try` if partial
tolerance is desired, but the default policy is fail-fast.