Files
skills/docs/security-stack/security/hibp/src/schemas/paste.schema.md
2026-05-29 08:20:56 +01:00

2.0 KiB

schemas/paste.schema.ts

Purpose

PasteSchema validates the HIBP v3 Paste payload 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

import { PasteSchema } from "@suaveplan/hibp";

const paste = PasteSchema.parse({
    Source: "Pastebin",
    Id: "ABC",
    EmailCount: 100,
});

Usage: Advanced Example

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.