deno.land / x / hono@v4.2.5 / utils / body.ts
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103import { HonoRequest } from '../request.ts'
export type BodyData = Record<string, string | File | (string | File)[]>export type ParseBodyOptions = { /** * Parse all fields with multiple values should be parsed as an array. * @default false * @example * ```ts * const data = new FormData() * data.append('file', 'aaa') * data.append('file', 'bbb') * data.append('message', 'hello') * ``` * * If `all` is `false`: * parseBody should return `{ file: 'bbb', message: 'hello' }` * * If `all` is `true`: * parseBody should return `{ file: ['aaa', 'bbb'], message: 'hello' }` */ all?: boolean}
export const parseBody = async <T extends BodyData = BodyData>( request: HonoRequest | Request, options: ParseBodyOptions = { all: false }): Promise<T> => { const headers = request instanceof HonoRequest ? request.raw.headers : request.headers const contentType = headers.get('Content-Type')
if (isFormDataContent(contentType)) { return parseFormData<T>(request, options) }
return {} as T}
function isFormDataContent(contentType: string | null): boolean { if (contentType === null) { return false }
return ( contentType.startsWith('multipart/form-data') || contentType.startsWith('application/x-www-form-urlencoded') )}
async function parseFormData<T extends BodyData = BodyData>( request: HonoRequest | Request, options: ParseBodyOptions): Promise<T> { const formData = await (request as Request).formData()
if (formData) { return convertFormDataToBodyData<T>(formData, options) }
return {} as T}
function convertFormDataToBodyData<T extends BodyData = BodyData>( formData: FormData, options: ParseBodyOptions): T { const form: BodyData = {}
formData.forEach((value, key) => { const shouldParseAllValues = options.all || key.endsWith('[]')
if (!shouldParseAllValues) { form[key] = value } else { handleParsingAllValues(form, key, value) } })
return form as T}
const handleParsingAllValues = (form: BodyData, key: string, value: FormDataEntryValue): void => { if (form[key] && isArrayField(form[key])) { appendToExistingArray(form[key] as (string | File)[], value) } else if (form[key]) { convertToNewArray(form, key, value) } else { form[key] = value }}
function isArrayField(field: unknown): field is (string | File)[] { return Array.isArray(field)}
const appendToExistingArray = (arr: (string | File)[], value: FormDataEntryValue): void => { arr.push(value)}
const convertToNewArray = (form: BodyData, key: string, value: FormDataEntryValue): void => { form[key] = [form[key] as string | File, value]}
Version Info