/* Inspired by: - https://github.com/RobinTail/express-zod-api (API simplicity) - https://github.com/blomqma/next-rest-framework (response type checking) */ import type { IncomingMessage, ServerResponse } from "node:http"; import { type InferOutput, type ObjectEntries, type ObjectSchema, StringSchema, } from "valibot"; export type MethodServer = Record< string, { handler(req: IncomingMessage, res: ServerResponse): void; input: ObjectSchema; outputs: Record< number, ObjectSchema | StringSchema >; } >; export type ServerEndpoint = < Input extends ObjectEntries, Status extends number, Output extends ObjectEntries, Outputs extends Record< Status, ObjectSchema | StringSchema >, RouteType extends { input: ObjectSchema; outputs: Outputs; }, >( routeType: RouteType, handler: (req: { input: InferOutput; }) => Promise< ServerOutput< InferOutput, keyof RouteType["outputs"] > >, ) => { handler(req: IncomingMessage, res: ServerResponse): void; input: typeof input; outputs: Outputs; }; export type ServerJson = (output: Output) => ServerOutput; export type ServerRedirect = ( location: string, status: Status, init?: { cookies: ServerCookies }, ) => ServerOutput; export type ServerText = ( text: string, status: Status, ) => ServerOutput; type Assign = Omit & U; type KnownContentType = "application/json" | "application/x-www-form-urlencoded" | "text/plain"; type ServerCookies = Record; type ServerHeaders = Assign< Record, Partial> >; interface ServerOutput { contentType: ContentType; cookies?: ServerCookies | undefined; headers?: ServerHeaders; output: Output; status: Status; } interface ServerResponseInit< Status extends number, ContentType extends KnownContentType, > { headers?: ServerHeaders; status: Status; }