mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-22 15:06:32 +00:00
8e01dbb92f
shared gains the response schemas these routes answer with (rows in their storage spelling, as the routes have always sent them) plus the common success and empty answers, all exported for the client to type its calls with. Every JSON handler in the four controllers carries its @ResponseContract; the file download, which streams, is marked exempt. The files e2e fixture table gains the note_id column the real one has.
30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
/**
|
|
* Primitive, domain-agnostic building blocks shared by every contract.
|
|
* Domain schemas (trips, places, ...) live in their own folders and reuse these.
|
|
*/
|
|
|
|
/** TREK uses auto-increment integer primary keys. */
|
|
export const idSchema = z.number().int().positive();
|
|
export type Id = z.infer<typeof idSchema>;
|
|
|
|
/**
|
|
* Numeric id coming from a URL param / query string. Express hands these over
|
|
* as strings, so we coerce, then enforce a positive integer.
|
|
*/
|
|
export const idParamSchema = z.coerce.number().int().positive();
|
|
|
|
/** Non-empty, trimmed string. */
|
|
export const nonEmptyString = z.string().trim().min(1);
|
|
|
|
/** ISO-8601 timestamp string (the shape TREK serialises dates as in JSON). */
|
|
export const isoDateTime = z.string().datetime({ offset: true });
|
|
|
|
/** The `{ success: true }` body a write answers with when it has nothing else to say. */
|
|
export const successResponseSchema = z.object({ success: z.literal(true) });
|
|
export type SuccessResponse = z.infer<typeof successResponseSchema>;
|
|
|
|
/** A 204 answer: the handler returns nothing, so no body goes out. */
|
|
export const emptyResponseSchema = z.undefined();
|