import { error } from '@sveltejs/kit'; import type { ZodSchema } from 'zod'; // Shared error body shape for SvelteKit `error()` calls. `issues` is set // when validateBody fails so the client can show a precise validation // hint; everywhere else only `message` is used. export type ErrorResponse = { message: string; issues?: unknown; }; /** * Parse a route param (or query param) as a positive integer (>=1). * Throws SvelteKit `error(400)` with `Missing ` when null/undefined, * or `Invalid ` when the value is not an integer >= 1. */ export function parsePositiveIntParam( raw: string | undefined | null, field: string ): number { if (raw == null) error(400, { message: `Missing ${field}` }); const n = Number(raw); if (!Number.isInteger(n) || n <= 0) error(400, { message: `Invalid ${field}` }); return n; } /** * Validate an unknown body against a Zod schema. Throws SvelteKit * `error(400, { message: 'Invalid body', issues })` on mismatch and returns * the typed parse result on success. Accepts `null` (the typical result of * `await request.json().catch(() => null)`). */ export function validateBody(body: unknown, schema: ZodSchema): T { const parsed = schema.safeParse(body); if (!parsed.success) { error(400, { message: 'Invalid body', issues: parsed.error.issues }); } return parsed.data; }