import type { Arg, Promisable } from "@libs/typing/types"
import type { Logger } from "@logtape/logtape"
import { is } from "@libs/is"
export { Status } from "@libs/testing"
export { faker } from "@libs/testing/faker"
export * from "@libs/is"
export type { Logger, Promisable }
export type ResponseInitWithBody = ResponseInit & { body?: BodyInit | Record<PropertyKey, unknown> | unknown[] }
export type Handler<Schema extends is.ZodType = is.ZodType> = (input: is.infer<Schema>, request: Request, _: { log: Logger; paths: string[] }) => Promisable<Response | ResponseInitWithBody>
export function mock(response: ResponseInitWithBody): (request: Request) => Response
export function mock<Schema extends is.ZodType = is.ZodType>(response: Handler<Schema>): (request: Request) => Promise<Response>
export function mock<Schema extends is.ZodType = is.ZodType>(schema: Schema, handler: Handler<Schema>): (request: Request) => Promise<Response>
export function mock<Shape extends is.ZodRawShape = is.ZodRawShape>(schema: Shape, handler: Handler<is.ZodObject<Shape>>): (request: Request) => Promise<Response>
export function mock<SchemaOrShape extends (is.ZodType | is.ZodRawShape), Schema extends is.ZodType = SchemaOrShape extends is.ZodType ? SchemaOrShape : never>(arg0: ResponseInitWithBody | SchemaOrShape | Handler<Schema>, handler?: Handler<Schema>) {
if (typeof arg0 === "function") {
handler = arg0 as Handler<Schema>
arg0 = is.any() as unknown as SchemaOrShape
}
if (handler) {
const schema = arg0 as SchemaOrShape
return async function (request: Request, options: Arg<Handler, 2>) {
const input = request.body ? await request.clone().json() : undefined
const init = await handler(("_zod" in schema ? (schema as is.ZodType) : is.object(schema as is.ZodRawShape)).parse(input) as is.infer<Schema>, request, options)
return init instanceof Response ? init : respond(init as ResponseInitWithBody)
}
}
const init = arg0 as ResponseInitWithBody
return function (_: Request) {
return respond(init)
}
}
function respond(init: ResponseInitWithBody): Response {
if ((init?.body) && ((typeof init.body === "string") || ([Uint8Array, FormData, URLSearchParams].some((type) => init.body instanceof type))))
return new Response(init.body as BodyInit, init)
return new Response(init?.body ? JSON.stringify(init.body) : null, init)
}
|