UNPKG

@whatwg-node/node-fetch

Version:

Fetch API implementation for Node

139 lines (138 loc) 4.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PonyfillFormData = void 0; exports.getStreamFromFormData = getStreamFromFormData; const node_buffer_1 = require("node:buffer"); const IteratorObject_js_1 = require("./IteratorObject.js"); const ReadableStream_js_1 = require("./ReadableStream.js"); class PonyfillFormData { map = new Map(); append(name, value, fileName) { let values = this.map.get(name); if (!values) { values = []; this.map.set(name, values); } const entry = isBlob(value) ? getNormalizedFile(name, value, fileName) : value; values.push(entry); } delete(name) { this.map.delete(name); } get(name) { const values = this.map.get(name); return values ? values[0] : null; } getAll(name) { return this.map.get(name) || []; } has(name) { return this.map.has(name); } set(name, value, fileName) { const entry = isBlob(value) ? getNormalizedFile(name, value, fileName) : value; this.map.set(name, [entry]); } [Symbol.iterator]() { return this._entries(); } *_entries() { for (const [key, values] of this.map) { for (const value of values) { yield [key, value]; } } } entries() { return new IteratorObject_js_1.PonyfillIteratorObject(this._entries(), 'FormDataIterator'); } _keys() { return this.map.keys(); } keys() { return new IteratorObject_js_1.PonyfillIteratorObject(this._keys(), 'FormDataIterator'); } *_values() { for (const values of this.map.values()) { for (const value of values) { yield value; } } } values() { return new IteratorObject_js_1.PonyfillIteratorObject(this._values(), 'FormDataIterator'); } forEach(callback) { for (const [key, value] of this) { callback(value, key, this); } } } exports.PonyfillFormData = PonyfillFormData; function getStreamFromFormData(formData, boundary = '---') { const entries = []; let sentInitialHeader = false; return new ReadableStream_js_1.PonyfillReadableStream({ start: controller => { formData.forEach((value, key) => { if (!sentInitialHeader) { controller.enqueue(node_buffer_1.Buffer.from(`--${boundary}\r\n`)); sentInitialHeader = true; } entries.push([key, value]); }); if (!sentInitialHeader) { controller.enqueue(node_buffer_1.Buffer.from(`--${boundary}--\r\n`)); controller.close(); } }, pull: async (controller) => { const entry = entries.shift(); if (entry) { const [key, value] = entry; if (typeof value === 'string') { controller.enqueue(node_buffer_1.Buffer.from(`Content-Disposition: form-data; name="${key}"\r\n\r\n`)); controller.enqueue(node_buffer_1.Buffer.from(value)); } else { let filenamePart = ''; if (value.name) { filenamePart = `; filename="${value.name}"`; } controller.enqueue(node_buffer_1.Buffer.from(`Content-Disposition: form-data; name="${key}"${filenamePart}\r\n`)); controller.enqueue(node_buffer_1.Buffer.from(`Content-Type: ${value.type || 'application/octet-stream'}\r\n\r\n`)); const entryStream = value.stream(); for await (const chunk of entryStream) { controller.enqueue(chunk); } } if (entries.length === 0) { controller.enqueue(node_buffer_1.Buffer.from(`\r\n--${boundary}--\r\n`)); controller.close(); } else { controller.enqueue(node_buffer_1.Buffer.from(`\r\n--${boundary}\r\n`)); } } else { controller.enqueue(node_buffer_1.Buffer.from(`\r\n--${boundary}--\r\n`)); controller.close(); } }, }); } function getNormalizedFile(name, blob, fileName) { Object.defineProperty(blob, 'name', { configurable: true, enumerable: true, value: fileName || blob.name || name, }); return blob; } function isBlob(value) { return value?.arrayBuffer != null; }