UNPKG

elysia

Version:

Ergonomic Framework for Human

347 lines (346 loc) 12.4 kB
import { createResponseHandler, createStreamHandler, handleFile, handleSet } from "../utils.mjs"; import { isNotEmpty } from "../../utils.mjs"; import { Cookie } from "../../cookies.mjs"; import { ElysiaCustomStatusResponse } from "../../error.mjs"; const mapResponse = (response, set, request) => { if (isNotEmpty(set.headers) || set.status !== 200 || set.cookie) switch (handleSet(set), response?.constructor?.name) { case "String": return new Response(response, set); case "Array": case "Object": return Response.json(response, set); case "ElysiaFile": return handleFile(response.value, set, request); case "File": return handleFile(response, set, request); case "Blob": return handleFile(response, set, request); case "ElysiaCustomStatusResponse": return set.status = response.code, mapResponse( response.response, set, request ); case void 0: return response ? Response.json(response, set) : new Response("", set); case "Response": return handleResponse(response, set, request); case "Error": return errorToResponse(response, set); case "Promise": return response.then( (x) => mapResponse(x, set, request) ); case "Function": return mapResponse(response(), set, request); case "Number": case "Boolean": return new Response( response.toString(), set ); case "Cookie": return response instanceof Cookie ? new Response(response.value, set) : new Response(response?.toString(), set); case "FormData": return new Response(response, set); default: if (response instanceof Response) return handleResponse(response, set, request); if (response instanceof Promise) return response.then((x) => mapResponse(x, set)); if (response instanceof Error) return errorToResponse(response, set); if (response instanceof ElysiaCustomStatusResponse) return set.status = response.code, mapResponse( response.response, set, request ); if ( // @ts-expect-error typeof response?.next == "function" || response instanceof ReadableStream ) return handleStream(response, set, request); if (typeof response?.then == "function") return response.then( (x) => mapResponse(x, set) ); if (Array.isArray(response)) return Response.json(response); if (typeof response?.toResponse == "function") return mapResponse(response.toResponse(), set); if ("charCodeAt" in response) { const code = response.charCodeAt(0); if (code === 123 || code === 91) return Response.json(response, set); } return new Response(response, set); } return ( // @ts-expect-error typeof response?.next == "function" || response instanceof ReadableStream ? handleStream(response, set, request) : mapCompactResponse(response, request) ); }, mapEarlyResponse = (response, set, request) => { if (response != null) if (isNotEmpty(set.headers) || set.status !== 200 || set.cookie) switch (handleSet(set), response?.constructor?.name) { case "String": return new Response(response, set); case "Array": case "Object": return Response.json(response, set); case "ElysiaFile": return handleFile(response.value, set, request); case "File": return handleFile(response, set, request); case "Blob": return handleFile(response, set, request); case "ElysiaCustomStatusResponse": return set.status = response.code, mapEarlyResponse( response.response, set, request ); case void 0: return response ? Response.json(response, set) : void 0; case "Response": return handleResponse(response, set, request); case "Promise": return response.then( (x) => mapEarlyResponse(x, set) ); case "Error": return errorToResponse(response, set); case "Function": return mapEarlyResponse(response(), set); case "Number": case "Boolean": return new Response( response.toString(), set ); case "FormData": return new Response(response); case "Cookie": return response instanceof Cookie ? new Response(response.value, set) : new Response(response?.toString(), set); default: if (response instanceof Response) return handleResponse(response, set, request); if (response instanceof Promise) return response.then((x) => mapEarlyResponse(x, set)); if (response instanceof Error) return errorToResponse(response, set); if (response instanceof ElysiaCustomStatusResponse) return set.status = response.code, mapEarlyResponse( response.response, set, request ); if ( // @ts-expect-error typeof response?.next == "function" || response instanceof ReadableStream ) return handleStream(response, set, request); if (typeof response?.then == "function") return response.then( (x) => mapEarlyResponse(x, set) ); if (typeof response?.toResponse == "function") return mapEarlyResponse(response.toResponse(), set); if (Array.isArray(response)) return Response.json(response); if ("charCodeAt" in response) { const code = response.charCodeAt(0); if (code === 123 || code === 91) return Response.json(response, set); } return new Response(response, set); } else switch (response?.constructor?.name) { case "String": return new Response(response); case "Array": case "Object": return Response.json(response, set); case "ElysiaFile": return handleFile(response.value, set, request); case "File": return handleFile(response, set, request); case "Blob": return handleFile(response, set, request); case "ElysiaCustomStatusResponse": return set.status = response.code, mapEarlyResponse( response.response, set, request ); case void 0: return response ? Response.json(response) : new Response(""); case "Response": return response; case "Promise": return response.then((x) => { const r = mapEarlyResponse(x, set); if (r !== void 0) return r; }); case "Error": return errorToResponse(response, set); case "Function": return mapCompactResponse(response(), request); case "Number": case "Boolean": return new Response(response.toString()); case "Cookie": return response instanceof Cookie ? new Response(response.value, set) : new Response(response?.toString(), set); case "FormData": return new Response(response); default: if (response instanceof Response) return response; if (response instanceof Promise) return response.then((x) => mapEarlyResponse(x, set)); if (response instanceof Error) return errorToResponse(response, set); if (response instanceof ElysiaCustomStatusResponse) return set.status = response.code, mapEarlyResponse( response.response, set, request ); if ( // @ts-expect-error typeof response?.next == "function" || response instanceof ReadableStream ) return handleStream(response, set, request); if (typeof response?.then == "function") return response.then( (x) => mapEarlyResponse(x, set) ); if (typeof response?.toResponse == "function") return mapEarlyResponse(response.toResponse(), set); if (Array.isArray(response)) return Response.json(response); if ("charCodeAt" in response) { const code = response.charCodeAt(0); if (code === 123 || code === 91) return Response.json(response, set); } return new Response(response); } }, mapCompactResponse = (response, request) => { switch (response?.constructor?.name) { case "String": return new Response(response); case "Object": case "Array": return Response.json(response); case "ElysiaFile": return handleFile(response.value, void 0, request); case "File": return handleFile(response, void 0, request); case "Blob": return handleFile(response, void 0, request); case "ElysiaCustomStatusResponse": return mapResponse( response.response, { status: response.code, headers: {} } ); case void 0: return response ? Response.json(response) : new Response(""); case "Response": return response; case "Error": return errorToResponse(response); case "Promise": return response.then( (x) => mapCompactResponse(x, request) ); // ? Maybe response or Blob case "Function": return mapCompactResponse(response(), request); case "Number": case "Boolean": return new Response(response.toString()); case "FormData": return new Response(response); default: if (response instanceof Response) return response; if (response instanceof Promise) return response.then( (x) => mapCompactResponse(x, request) ); if (response instanceof Error) return errorToResponse(response); if (response instanceof ElysiaCustomStatusResponse) return mapResponse( response.response, { status: response.code, headers: {} } ); if ( // @ts-expect-error typeof response?.next == "function" || response instanceof ReadableStream ) return handleStream(response, void 0, request); if (typeof response?.then == "function") return response.then( (x) => mapCompactResponse(x, request) ); if (typeof response?.toResponse == "function") return mapCompactResponse(response.toResponse()); if (Array.isArray(response)) return Response.json(response); if ("charCodeAt" in response) { const code = response.charCodeAt(0); if (code === 123 || code === 91) return Response.json(response); } return new Response(response); } }, errorToResponse = (error, set) => { if (typeof error?.toResponse == "function") { const raw = error.toResponse(), targetSet = set ?? { headers: {}, status: 200, redirect: "" }, apply = (resolved) => (resolved instanceof Response && (targetSet.status = resolved.status), mapResponse(resolved, targetSet)); return typeof raw?.then == "function" ? raw.then(apply) : apply(raw); } return Response.json( { name: error?.name, message: error?.message, cause: error?.cause }, { status: set?.status !== 200 ? set?.status ?? 500 : 500, headers: set?.headers } ); }, createStaticHandler = (handle, hooks, setHeaders = {}) => { if (typeof handle == "function") return; const response = mapResponse(handle, { headers: setHeaders }); if (!hooks.parse?.length && !hooks.transform?.length && !hooks.beforeHandle?.length && !hooks.afterHandle?.length) return () => response.clone(); }, handleResponse = createResponseHandler({ mapResponse, mapCompactResponse }), handleStream = createStreamHandler({ mapResponse, mapCompactResponse }); export { createStaticHandler, errorToResponse, mapCompactResponse, mapEarlyResponse, mapResponse };