server/utils/request.ts

74 lines
2 KiB
TypeScript
Raw Normal View History

2023-09-15 03:22:27 +02:00
/**
* Takes a request, and turns FormData or query parameters
* into a JSON object as would be returned by req.json()
* This is a translation layer that allows clients to use
* either FormData, query parameters, or JSON in the request
* @param request The request to parse
*/
export async function parseRequest<T>(request: Request): Promise<Partial<T>> {
const query = new URL(request.url).searchParams;
2023-09-23 04:46:52 +02:00
// Parse SearchParams arrays into JSON arrays
const arrayKeys = [...query.keys()].filter(key => key.endsWith("[]"));
for (const key of arrayKeys) {
const value = query.getAll(key);
query.delete(key);
query.append(key, JSON.stringify(value));
}
2023-11-12 09:28:06 +01:00
// If body is empty
if (request.body === null) {
return {};
}
2023-09-15 03:22:27 +02:00
// if request contains a JSON body
if (request.headers.get("Content-Type")?.includes("application/json")) {
return (await request.json()) as T;
}
// If request contains FormData
if (request.headers.get("Content-Type")?.includes("multipart/form-data")) {
2023-09-22 03:09:14 +02:00
const formData = await request.formData();
2023-09-15 03:22:27 +02:00
if ([...formData.entries()].length > 0) {
const data: Record<string, string | File> = {};
for (const [key, value] of formData.entries()) {
// If object, parse as JSON
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-base-to-string
data[key] = JSON.parse(value.toString());
} catch {
// If a file, set as a file
if (value instanceof File) {
data[key] = value;
} else {
// Otherwise, set as a string
// eslint-disable-next-line @typescript-eslint/no-base-to-string
data[key] = value.toString();
2023-09-15 03:22:27 +02:00
}
}
}
return data as T;
}
}
if ([...query.entries()].length > 0) {
2023-09-23 04:46:52 +02:00
const data: Record<string, string | string[]> = {};
2023-09-15 03:22:27 +02:00
for (const [key, value] of query.entries()) {
2023-09-23 04:46:52 +02:00
try {
data[key] = JSON.parse(value) as string[];
} catch {
data[key] = value.toString();
}
2023-09-15 03:22:27 +02:00
}
return data as T;
}
return {};
}