@npio/filesystem
Version:
A free visual website editor, powered with your own SolidJS components.
71 lines (62 loc) • 1.99 kB
text/typescript
import {
FileHandler,
FileInfo as FileInfo_,
FormDataParserOptions,
parseMultipartFormData as parseMultipartFormData_,
} from "@lufrai/multipart";
import type { FetchEvent } from "@solidjs/start/server";
import { getRequestEvent } from "solid-js/web";
import { Readable } from "stream";
import { assertBodySize, contentType } from "./utils";
interface FileInfo extends Omit<FileInfo_, "body"> {
body: Readable;
}
interface Options<T> extends Omit<FormDataParserOptions<T>, "handleFile"> {
handleFile: (fileInfo: FileInfo, fields: Parameters<FileHandler<T>>[1]) => T;
}
export const parseFormData = async ({
maxSize,
event = getRequestEvent()!,
}: { maxSize?: number; event?: FetchEvent } = {}) => {
if (maxSize != null) {
assertBodySize({ maxSize: maxSize, event });
}
return await event.request.formData();
};
const defaultMaxSize = 1024 * 1024 * 1024 * 10;
export const parseFormDataStream = async function <T>(
options: Options<T> & { maxSize?: number },
event = getRequestEvent()!,
): Promise<FormData> {
if (options.maxSize != null) {
assertBodySize({ maxSize: options.maxSize, event });
}
const promise = parseMultipartFormData_(event.request, {
maxFileSize: defaultMaxSize,
maxTotalFileSize: defaultMaxSize,
...options,
handleFile(fileInfo, fields) {
fileInfo.contentType = contentType(fileInfo.contentType);
return new Promise((res, rej) => {
const body = Readable.fromWeb(fileInfo.body as any);
body.on("error", rej);
Promise.resolve(
options.handleFile(
{
...fileInfo,
body,
},
fields,
),
)
.then(res)
.catch(rej);
}).catch((error) => {
console.error("Unhandled error during file upload", error);
console.log(fileInfo);
});
},
});
promise.finally(() => event.nativeEvent.node.req.destroy());
return (await promise) as any;
};