uploadthing
Version:
Learn more: [docs.uploadthing.com](https://docs.uploadthing.com)
87 lines (85 loc) • 3.24 kB
JavaScript
import { UploadThingError } from "@uploadthing/shared";
import * as Effect from "effect/Effect";
import * as Config from "effect/Config";
import * as Data from "effect/Data";
//#region src/_internal/to-web-request.ts
var InvalidURL = class extends Data.Error {
_tag = "InvalidURL";
name = "InvalidURLError";
constructor(attemptedUrl, base) {
Effect.runSync(Effect.logError(`Failed to parse URL from request. '${attemptedUrl}' is not a valid URL with base '${base}'.`));
super({ reason: `Failed to parse URL from request. '${attemptedUrl}' is not a valid URL with base '${base}'.` });
}
};
const parseURL = (req) => {
const headers = req.headers;
let relativeUrl = req.url ?? "/";
if ("baseUrl" in req && typeof req.baseUrl === "string") relativeUrl = req.baseUrl + relativeUrl;
const proto = headers?.["x-forwarded-proto"] ?? "http";
const host = headers?.["x-forwarded-host"] ?? headers?.host;
const baseUrl = Config.string("url").pipe(Config.withDefault(`${proto.toString()}://${host?.toString()}`));
return Effect.flatMap(baseUrl, (baseUrl$1) => Effect.try({
try: () => new URL(relativeUrl, baseUrl$1),
catch: () => new InvalidURL(relativeUrl, baseUrl$1)
})).pipe(Effect.catchTag("ConfigError", () => Effect.fail(new InvalidURL(relativeUrl))));
};
const isBodyAllowed = (method) => [
"POST",
"PUT",
"PATCH"
].includes(method);
const getPostBody = (opts) => Effect.async((resume) => {
const { req } = opts;
if (!req.method || !isBodyAllowed(req.method)) return resume(Effect.succeed(void 0));
const contentType = req.headers?.["content-type"];
if ("body" in req) {
if (contentType !== "application/json") {
Effect.runSync(Effect.logError("Expected JSON content type, got:", contentType));
return resume(new UploadThingError({
code: "BAD_REQUEST",
message: "INVALID_CONTENT_TYPE"
}));
}
if (typeof req.body !== "object") {
Effect.runSync(Effect.logError("Expected body to be of type 'object', got:", typeof req.body));
return resume(new UploadThingError({
code: "BAD_REQUEST",
message: "INVALID_BODY"
}));
}
Effect.runSync(Effect.logDebug("Body parsed successfully.", req.body));
return resume(Effect.succeed(req.body));
}
let body = "";
req.on("data", (data) => body += data);
req.on("end", () => {
const parsedBody = Effect.try({
try: () => JSON.parse(body),
catch: (err) => new UploadThingError({
code: "BAD_REQUEST",
message: "INVALID_JSON",
cause: err
})
});
return resume(parsedBody);
});
});
const toWebRequest = (req, body) => {
body ??= req.body;
const bodyStr = typeof body === "string" ? body : JSON.stringify(body);
const method = req.method ?? "GET";
const allowsBody = isBodyAllowed(method);
const headers = new Headers();
for (const [key, value] of Object.entries(req.headers ?? [])) {
if (typeof value === "string") headers.set(key, value);
if (Array.isArray(value)) headers.set(key, value.join(","));
}
return parseURL(req).pipe(Effect.catchTag("InvalidURL", (e) => Effect.die(e)), Effect.andThen((url) => new Request(url, {
method,
headers,
...allowsBody ? { body: bodyStr } : {}
})));
};
//#endregion
export { getPostBody, toWebRequest };
//# sourceMappingURL=to-web-request-DhP0wXG-.js.map