UNPKG

@zodios/express

Version:
114 lines (109 loc) 7.88 kB
import express, { Request, Response, RouterOptions } from 'express'; import { ZodObject, ZodAny, z } from 'zod'; import { ZodiosEndpointDefinitions, Method, ZodiosPathsByMethod, ZodiosPathParamsByPath, ZodiosBodyByPath, ZodiosQueryParamsByPath, ZodiosResponseByPath, ZodiosEndpointDefinition, ZodiosErrorByPath } from '@zodios/core'; import { IfEquals, Narrow } from '@zodios/core/lib/utils.types'; import http from 'http'; type ZodiosSuccessCodes = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226; type WithZodiosContext<T, Context extends ZodObject<any>> = Context extends ZodAny ? T : T & z.infer<Context>; interface ZodiosRequestHandler<Api extends ZodiosEndpointDefinitions, Context extends ZodObject<any>, M extends Method, Path extends ZodiosPathsByMethod<Api, M>, ReqPath = ZodiosPathParamsByPath<Api, M, Path, false>, ReqBody = ZodiosBodyByPath<Api, M, Path, false>, ReqQuery = ZodiosQueryParamsByPath<Api, M, Path, false>, Res = ZodiosResponseByPath<Api, M, Path, false>> { (req: WithZodiosContext<express.Request<ReqPath, Res, ReqBody, ReqQuery>, Context>, res: Omit<express.Response<Res>, "status"> & { status<StatusCode extends number, API extends ZodiosEndpointDefinition[] = Api, METHOD extends Method = M, PATH extends ZodiosPathsByMethod<Api, M> = Path>(status: StatusCode): StatusCode extends ZodiosSuccessCodes ? express.Response<Res> : express.Response<ZodiosErrorByPath<API, METHOD, PATH, StatusCode, false>>; }, next: express.NextFunction): void; } type ZodiosHandler<Router, Context extends ZodObject<any>, Api extends ZodiosEndpointDefinitions, M extends Method> = <Path extends ZodiosPathsByMethod<Api, M>>(path: Path, ...handlers: Array<ZodiosRequestHandler<Api, Context, M, Path>>) => Router; type ZodiosRouterContextRequestHandler<Context extends ZodObject<any>> = (req: WithZodiosContext<express.Request, Context>, res: express.Response, next: express.NextFunction) => void; type ZodiosRouterContextErrorHandler<Context extends ZodObject<any>> = (error: any, req: WithZodiosContext<express.Request, Context>, res: express.Response, next: express.NextFunction) => void; type ZodiosRouterValidationErrorHandler<Context extends ZodObject<any>> = (error: { context: string; error: z.ZodIssue[]; }, req: WithZodiosContext<express.Request, Context>, res: express.Response, next: express.NextFunction) => void; interface ZodiosUse<Context extends ZodObject<any>> { use(...handlers: Array<ZodiosRouterContextRequestHandler<Context>>): this; use(handlers: Array<ZodiosRouterContextRequestHandler<Context>>): this; use(errorHandler: ZodiosRouterContextErrorHandler<Context>): this; use(path: string, ...handlers: Array<ZodiosRouterContextRequestHandler<Context>>): this; use(path: string, handlers: Array<ZodiosRouterContextRequestHandler<Context>>): this; } interface ZodiosHandlers<Api extends ZodiosEndpointDefinitions, Context extends ZodObject<any>> extends ZodiosUse<Context> { get: ZodiosHandler<this, Context, Api, "get">; post: ZodiosHandler<this, Context, Api, "post">; put: ZodiosHandler<this, Context, Api, "put">; patch: ZodiosHandler<this, Context, Api, "patch">; delete: ZodiosHandler<this, Context, Api, "delete">; options: ZodiosHandler<this, Context, Api, "options">; head: ZodiosHandler<this, Context, Api, "head">; } interface ZodiosValidationOptions { /** * validate request parameters - default is true */ validate?: boolean; /** * transform request parameters - default is false */ transform?: boolean; } interface ZodiosAppOptions<Context extends ZodObject<any>> extends ZodiosValidationOptions { /** * express app intance - default is express() */ express?: ReturnType<typeof express>; /** * enable express json body parser - default is true */ enableJsonBodyParser?: boolean; context?: Context; validationErrorHandler?: ZodiosRouterValidationErrorHandler<Context>; } interface ZodiosRouterOptions<Context extends ZodObject<any>> extends ZodiosValidationOptions { /** * express router instance - default is express.Router */ router?: ReturnType<typeof express.Router>; context?: Context; validationErrorHandler?: ZodiosRouterValidationErrorHandler<Context>; } interface ZodiosUnknownApp<Context extends ZodObject<any>> extends Omit<ReturnType<typeof express>, "use">, ZodiosUse<Context> { (req: Request | http.IncomingMessage, res: Response | http.ServerResponse): any; } interface ZodiosApiApp<Api extends ZodiosEndpointDefinition[], Context extends ZodObject<any>> extends Omit<ReturnType<typeof express>, Method | "use">, ZodiosHandlers<Api, Context> { (req: Request | http.IncomingMessage, res: Response | http.ServerResponse): any; } type ZodiosApp<Api extends ZodiosEndpointDefinitions, Context extends ZodObject<any>> = IfEquals<Api, any, ZodiosUnknownApp<Context>, ZodiosApiApp<Api, Context>>; type ZodiosRouter<Api extends ZodiosEndpointDefinitions, Context extends ZodObject<any>> = IfEquals<Api, any, Omit<ReturnType<typeof express.Router>, "use"> & ZodiosUse<Context> & ZodiosRouterContextRequestHandler<Context>, Omit<ReturnType<typeof express.Router>, Method | "use"> & ZodiosHandlers<Api, Context> & ZodiosRouterContextRequestHandler<Context>>; /** * create a zodios app based on the given api and express * @param api - api definition * @param options - options to configure the app * @returns */ declare function zodiosApp<Api extends ZodiosEndpointDefinitions = any, Context extends ZodObject<any> = ZodObject<any>>(api?: Narrow<Api>, options?: ZodiosAppOptions<Context>): ZodiosApp<Api, Context>; /** * create a zodios router based on the given api and express router * @param api - api definition * @param options - options to configure the router * @returns */ declare function zodiosRouter<Api extends ZodiosEndpointDefinitions, Context extends ZodObject<any> = ZodObject<any>>(api: Narrow<Api>, options?: RouterOptions & ZodiosRouterOptions<Context>): ZodiosRouter<Api, Context>; /** * create a zodios app for nextjs * @param options - options to configure the app * @returns - a zodios app */ declare function zodiosNextApp<Api extends ZodiosEndpointDefinitions = any, Context extends ZodObject<any> = ZodObject<any>>(api?: Narrow<Api>, options?: ZodiosAppOptions<Context>): ZodiosApp<Api, Context>; declare class ZodiosContext<Context extends ZodObject<any>> { context?: Context | undefined; constructor(context?: Context | undefined); app<Api extends ZodiosEndpointDefinitions = any>(api?: Narrow<Api>, options?: ZodiosAppOptions<Context>): ZodiosApp<Api, Context>; nextApp<Api extends ZodiosEndpointDefinitions = any>(api?: Narrow<Api>, options?: ZodiosAppOptions<Context>): ZodiosApp<Api, Context>; router<Api extends ZodiosEndpointDefinitions>(api: Narrow<Api>, options?: RouterOptions & ZodiosRouterOptions<Context>): ZodiosRouter<Api, Context>; } declare function zodiosContext<Context extends ZodObject<any> = ZodObject<any>>(context?: Context): ZodiosContext<Context>; type MapPrefixPath<T extends readonly unknown[], PrefixValue extends string, ACC extends unknown[] = []> = T extends readonly [infer Head, ...infer Tail] ? MapPrefixPath<Tail, PrefixValue, [ ...ACC, { [K in keyof Head]: K extends "path" ? Head[K] extends string ? `${PrefixValue}${Head[K]}` : Head[K] : Head[K]; } ]> : ACC; declare function prefixApi<Prefix extends string, Api extends readonly any[]>(prefix: Prefix, api: Api): MapPrefixPath<Api, Prefix, []>; export { WithZodiosContext, ZodiosApp, ZodiosAppOptions, ZodiosContext, ZodiosHandler, ZodiosHandlers, ZodiosRequestHandler, ZodiosRouter, ZodiosRouterContextRequestHandler, ZodiosRouterOptions, ZodiosSuccessCodes, ZodiosUse, ZodiosValidationOptions, prefixApi, zodiosApp, zodiosContext, zodiosNextApp, zodiosRouter };