47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
import type { ObjectSchema, ParseResult, SchemaDescriptor } from "./index.ts";
|
|
|
|
export class ValidationError<T = Record<string, unknown>> extends Error {
|
|
constructor(public readonly result: ParseResult<T>) {
|
|
super("Validation failed");
|
|
this.name = "ValidationError";
|
|
}
|
|
}
|
|
|
|
export function parseOrThrow<T extends object>(schema: ObjectSchema<T>, input: unknown): T {
|
|
const result = schema.parse(input);
|
|
if (!result.ok) throw new ValidationError(result);
|
|
return result.value;
|
|
}
|
|
|
|
export function validationResponse(
|
|
result: ParseResult,
|
|
options: { successStatus?: number; failureStatus?: number } = {},
|
|
): Response {
|
|
return Response.json(
|
|
result.ok
|
|
? { ok: true, value: result.value }
|
|
: { ok: false, errors: result.errors, value: result.value },
|
|
{
|
|
status: result.ok ? (options.successStatus ?? 200) : (options.failureStatus ?? 422),
|
|
headers: { "cache-control": "no-store" },
|
|
},
|
|
);
|
|
}
|
|
|
|
export function firstValidationError(errors: Record<string, string>): string | null {
|
|
return Object.values(errors).find(Boolean) ?? null;
|
|
}
|
|
|
|
export function validationSummary(
|
|
errors: Record<string, string>,
|
|
): Array<{ field: string; message: string }> {
|
|
return Object.entries(errors)
|
|
.filter(([, message]) => Boolean(message))
|
|
.map(([field, message]) => ({ field, message }));
|
|
}
|
|
|
|
export function schemaFieldNames(schema: ObjectSchema | SchemaDescriptor): string[] {
|
|
const descriptor = "describe" in schema ? schema.describe() : schema;
|
|
return Object.keys(descriptor.fields);
|
|
}
|