@web-std/form-data
Version:
Web API compatible Form Data implementation
1 lines • 15 kB
Source Map (JSON)
{"version":3,"file":"form-data.cjs","sources":["../../src/form-data.js"],"sourcesContent":["/**\n * @implements {globalThis.FormData}\n */\nexport class FormData {\n /**\n * @param {HTMLFormElement} [form]\n */\n constructor(form) {\n /**\n * @private\n * @readonly\n * @type {Array<[string, FormDataEntryValue]>}\n */\n this._entries = []\n\n Object.defineProperty(this, \"_entries\", { enumerable: false })\n\n if (isHTMLFormElement(form)) {\n for (const element of form.elements) {\n if (isSelectElement(element)) {\n for (const option of element.options) {\n if (option.selected) {\n this.append(element.name, option.value);\n }\n }\n } else if (\n isInputElement(element) &&\n (element.checked || ![\"radio\", \"checkbox\"].includes(element.type)) &&\n element.name\n ) {\n this.append(element.name, element.value);\n }\n }\n }\n }\n get [Symbol.toStringTag]() {\n return \"FormData\"\n }\n\n /**\n * Appends a new value onto an existing key inside a FormData object, or adds\n * the key if it does not already exist.\n *\n * The difference between `set` and `append` is that if the specified key\n * already exists, `set` will overwrite all existing values with the new one,\n * whereas `append` will append the new value onto the end of the existing\n * set of values.\n *\n * @param {string} name\n * @param {string|Blob|File} value - The name of the field whose data is\n * contained in value.\n * @param {string} [filename] - The filename reported to the server, when a\n * value is a `Blob` or a `File`. The default filename for a `Blob` objects is\n * `\"blob\"`. The default filename for a `File` is the it's name.\n */\n append(\n name,\n value = panic(\n new TypeError(\"FormData.append: requires at least 2 arguments\")\n ),\n filename\n ) {\n this._entries.push([name, toEntryValue(value, filename)])\n }\n\n /**\n * Deletes a key and all its values from a FormData object.\n *\n * @param {string} name\n */\n delete(\n name = panic(new TypeError(\"FormData.delete: requires string argument\"))\n ) {\n const entries = this._entries\n let index = 0\n while (index < entries.length) {\n const [entryName] = /** @type {[string, FormDataEntryValue]}*/ (\n entries[index]\n )\n if (entryName === name) {\n entries.splice(index, 1)\n } else {\n index++\n }\n }\n }\n\n /**\n * Returns the first value associated with a given key from within a\n * FormData object.\n *\n * @param {string} name\n * @returns {FormDataEntryValue|null}\n */\n\n get(name = panic(new TypeError(\"FormData.get: requires string argument\"))) {\n for (const [entryName, value] of this._entries) {\n if (entryName === name) {\n return value\n }\n }\n return null\n }\n\n /**\n * Returns an array of all the values associated with a given key from within\n * a FormData.\n *\n * @param {string} name\n * @returns {FormDataEntryValue[]}\n */\n getAll(\n name = panic(new TypeError(\"FormData.getAll: requires string argument\"))\n ) {\n const values = []\n for (const [entryName, value] of this._entries) {\n if (entryName === name) {\n values.push(value)\n }\n }\n return values\n }\n\n /**\n * Returns a boolean stating whether a FormData object contains a certain key.\n *\n * @param {string} name\n */\n\n has(name = panic(new TypeError(\"FormData.has: requires string argument\"))) {\n for (const [entryName] of this._entries) {\n if (entryName === name) {\n return true\n }\n }\n return false\n }\n\n /**\n * Sets a new value for an existing key inside a FormData object, or adds the\n * key/value if it does not already exist.\n *\n * @param {string} name\n * @param {string|Blob|File} value\n * @param {string} [filename]\n */\n\n set(\n name,\n value = panic(new TypeError(\"FormData.set: requires at least 2 arguments\")),\n filename\n ) {\n let index = 0\n const { _entries: entries } = this\n const entryValue = toEntryValue(value, filename)\n let wasSet = false\n while (index < entries.length) {\n const entry = /** @type {[string, FormDataEntryValue]}*/ (entries[index])\n if (entry[0] === name) {\n if (wasSet) {\n entries.splice(index, 1)\n } else {\n wasSet = true\n entry[1] = entryValue\n index++\n }\n } else {\n index++\n }\n }\n\n if (!wasSet) {\n entries.push([name, entryValue])\n }\n }\n\n /**\n * Method returns an iterator allowing to go through all key/value pairs\n * contained in this object.\n */\n entries() {\n return this._entries.values()\n }\n\n /**\n * Returns an iterator allowing to go through all keys of the key/value pairs\n * contained in this object.\n *\n * @returns {IterableIterator<string>}\n */\n *keys() {\n for (const [name] of this._entries) {\n yield name\n }\n }\n\n /**\n * Returns an iterator allowing to go through all values contained in this\n * object.\n *\n * @returns {IterableIterator<FormDataEntryValue>}\n */\n *values() {\n for (const [_, value] of this._entries) {\n yield value\n }\n }\n\n [Symbol.iterator]() {\n return this._entries.values()\n }\n\n /**\n * @param {(value: FormDataEntryValue, key: string, parent: globalThis.FormData) => void} fn\n * @param {any} [thisArg]\n * @returns {void}\n */\n forEach(fn, thisArg) {\n for (const [key, value] of this._entries) {\n fn.call(thisArg, value, key, this)\n }\n }\n}\n\n/**\n * @param {any} value\n * @returns {value is HTMLFormElement}\n */\nconst isHTMLFormElement = value =>\n Object.prototype.toString.call(value) === \"[object HTMLFormElement]\"\n\n/**\n * @param {string|Blob|File} value\n * @param {string} [filename]\n * @returns {FormDataEntryValue}\n */\nconst toEntryValue = (value, filename) => {\n if (isFile(value)) {\n return filename != null ? new BlobFile([value], filename, value) : value\n } else if (isBlob(value)) {\n return new BlobFile([value], filename != null ? filename : \"blob\")\n } else {\n if (filename != null && filename != \"\") {\n throw new TypeError(\n \"filename is only supported when value is Blob or File\"\n )\n }\n return `${value}`\n }\n}\n\n/**\n * @param {any} value\n * @returns {value is File}\n */\nconst isFile = value =>\n Object.prototype.toString.call(value) === \"[object File]\" &&\n typeof value.name === \"string\"\n\n/**\n * @param {any} value\n * @returns {value is Blob}\n */\nconst isBlob = value =>\n Object.prototype.toString.call(value) === \"[object Blob]\"\n\n/**\n * Simple `File` implementation that just wraps a given blob.\n * @implements {globalThis.File}\n */\nconst BlobFile = class File {\n /**\n * @param {[Blob]} parts\n * @param {string} name\n * @param {FilePropertyBag} [options]\n */\n constructor([blob], name, { lastModified = Date.now() } = {}) {\n this.blob = blob\n this.name = name\n this.lastModified = lastModified\n }\n get webkitRelativePath() {\n return \"\"\n }\n get size() {\n return this.blob.size\n }\n get type() {\n return this.blob.type\n }\n /**\n *\n * @param {number} [start]\n * @param {number} [end]\n * @param {string} [contentType]\n */\n slice(start, end, contentType) {\n return this.blob.slice(start, end, contentType)\n }\n stream() {\n return this.blob.stream()\n }\n text() {\n return this.blob.text()\n }\n arrayBuffer() {\n return this.blob.arrayBuffer()\n }\n get [Symbol.toStringTag]() {\n return \"File\"\n }\n}\n\n/**\n * @param {*} error\n * @returns {never}\n */\nconst panic = error => {\n throw error\n}\n\n/**\n *\n * @param {Element} element\n * @returns {element is HTMLSelectElement}\n */\nfunction isSelectElement(element) {\n return element.tagName === \"SELECT\";\n}\n\n/**\n *\n * @param {Element} element\n * @returns {element is HTMLInputElement}\n */\nfunction isInputElement(element) {\n return element.tagName === \"INPUT\" || element.tagName === \"TEXTAREA\";\n}\n"],"names":[],"mappings":"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"}