UNPKG

edge-mock

Version:

types for testing an developer edge applications

82 lines (71 loc) 2.6 kB
import {EdgeFile, EdgeFormData} from './models' export function stringAsFormData(boundary: string, body: string): FormData { let start = body.indexOf(`${boundary}\r\n`) if (start == -1) { throw new Error('boundary not found anywhere in body') } const boundaryLength = boundary.length // + 2 to account for \r\n start = start + boundaryLength + 2 const form = new EdgeFormData() while (true) { const end = body.indexOf(boundary, start) if (end == -1) { return form } const sep = body.indexOf('\r\n\r\n', start) if (sep == -1 || sep > end) { throw new Error('body is not well formed, no break found between headers and body') } const header_content = body.slice(start, sep) const n = header_content.match(/name ?= ?"(.+?)"/) if (!n) { throw new Error('name not found in header') } const name = decodeURI(n[1]) let filename: string | undefined = undefined let type: string | undefined = undefined const fn = header_content.match(/filename ?= ?"(.+?)"/) if (fn) { filename = decodeURI(fn[1]) } const ct = header_content.match(/\r\nContent-Type: ?(.+)/) if (ct) { type = decodeURI(ct[1]) } let chunk_body = body.slice(sep + 4, end) chunk_body = chunk_body.substr(0, chunk_body.lastIndexOf('\r\n')) if (filename || type) { form.append(name, new EdgeFile([chunk_body], filename || 'blob', {type})) } else { form.append(name, chunk_body) } // + 2 to account for \r\n start = end + boundaryLength + 2 } } export async function formDataAsString(form: FormData, boundary?: string): Promise<[string, string]> { boundary = boundary || generateBoundary() let s = '' for (const [key, value] of form) { s += await multipartSection(boundary, key, value) } return [boundary, `${s}--${boundary}--\r\n`] } export const generateBoundary = () => [...Array(32)].map(randChar).join('') const characters = 'abcdefghijklmnopqrstuvwxyz0123456789' const randChar = () => characters.charAt(Math.floor(Math.random() * characters.length)) async function multipartSection(boundary: string, key: string, value: FormDataEntryValue): Promise<string> { let header = `Content-Disposition: form-data; name="${encodeURI(key)}"` let body: string if (typeof value == 'string') { body = value } else { header += `; filename="${encodeURI(value.name)}"` if (value.type) { header += `\r\nContent-Type: ${encodeURI(value.type)}` } body = await value.text() } return `--${boundary}\r\n${header}\r\n\r\n${body}\r\n` }