347 lines
12 KiB
JavaScript
347 lines
12 KiB
JavaScript
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
|
|
};
|