From fb20753c9d0c6a7a4dac73720ab7c5c20808b723 Mon Sep 17 00:00:00 2001 From: sianida26 Date: Fri, 1 Mar 2024 20:57:55 +0700 Subject: [PATCH] Added utils --- src/core/utils/jsonToFormData.ts | 33 +++++++++++++++++++ .../utils/onlyAllowFollowingContentType.ts | 31 +++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/core/utils/jsonToFormData.ts create mode 100644 src/core/utils/onlyAllowFollowingContentType.ts diff --git a/src/core/utils/jsonToFormData.ts b/src/core/utils/jsonToFormData.ts new file mode 100644 index 0000000..0a34ac0 --- /dev/null +++ b/src/core/utils/jsonToFormData.ts @@ -0,0 +1,33 @@ +/** + * Converts a JSON object to FormData. + * + * @param json - The JSON object to be converted into FormData. The object can + * include nested objects and arrays. Nested objects are flattened according + * to the FormData encoding conventions, with keys indicating the path to each + * value and arrays being treated with indices. + * @returns A FormData object containing the keys and values from the input JSON. + * Each key in the JSON object is represented in the FormData, with its corresponding + * value. Nested objects and arrays are handled by appending square brackets to the key + * names to indicate the structure in the FormData. + */ +export default function jsonToFormData(json: Record): FormData { + const formData = new FormData(); + Object.keys(json).forEach((key) => { + const value = json[key]; + if (Array.isArray(value)) { + // Handle array values by appending each item with an index + value.forEach((item, index) => { + formData.append(`${key}[${index}]`, item); + }); + } else if (typeof value === "object" && value !== null) { + // Handle nested objects by appending each sub-key + Object.keys(value).forEach((subKey) => { + formData.append(`${key}[${subKey}]`, value[subKey]); + }); + } else { + // Handle simple types (strings, numbers, etc.) + formData.append(key, value); + } + }); + return formData; +} diff --git a/src/core/utils/onlyAllowFollowingContentType.ts b/src/core/utils/onlyAllowFollowingContentType.ts new file mode 100644 index 0000000..b63b9c7 --- /dev/null +++ b/src/core/utils/onlyAllowFollowingContentType.ts @@ -0,0 +1,31 @@ +import { headers } from "next/headers"; +import BaseError from "../error/BaseError"; + +/** + * Ensures that the current request's content type is one of the allowed types. + * This function is intended to be used in Next.js API routes to validate request content types. + * + * @param contentTypes - A single content type string or an array of allowed content type strings. + * @throws {BaseError} Throws a BaseError if the current request's content type is not in the allowed content types. + */ +export default function onlyAllowFollowingContentType( + contentTypes: string | string[] +) { + // Retrieve the current request's content type. + const currentContentType = headers().get("Content-Type"); + + // Normalize the input parameter to an array to simplify the inclusion check. + const allowedContentTypes = Array.isArray(contentTypes) + ? contentTypes + : [contentTypes]; + + // Check if the current content type is not among the allowed ones and throw an error if so. + if (!allowedContentTypes.includes(currentContentType ?? "")) { + throw new BaseError({ + errorCode: "UNSUPPORTED_CONTENT_TYPE", + message: + "This content type is not supported. Please use one of the supported content types instead.", + statusCode: 400, + }); + } +}