UNPKG

@shopify/cli

Version:

A CLI tool to build for the Shopify platform

195 lines (193 loc) • 8.6 kB
import { FormData, file_default } from "./chunk-25IMI7TH.js"; import { init_cjs_shims } from "./chunk-PKR7KJ6P.js"; // ../../node_modules/.pnpm/node-fetch@3.3.2/node_modules/node-fetch/src/utils/multipart-parser.js init_cjs_shims(); var s = 0, S = { START_BOUNDARY: s++, HEADER_FIELD_START: s++, HEADER_FIELD: s++, HEADER_VALUE_START: s++, HEADER_VALUE: s++, HEADER_VALUE_ALMOST_DONE: s++, HEADERS_ALMOST_DONE: s++, PART_DATA_START: s++, PART_DATA: s++, END: s++ }, f = 1, F = { PART_BOUNDARY: f, LAST_BOUNDARY: f *= 2 }, LF = 10, CR = 13, SPACE = 32, HYPHEN = 45, COLON = 58, A = 97, Z = 122, lower = (c) => c | 32, noop = () => { }, MultipartParser = class { /** * @param {string} boundary */ constructor(boundary) { this.index = 0, this.flags = 0, this.onHeaderEnd = noop, this.onHeaderField = noop, this.onHeadersEnd = noop, this.onHeaderValue = noop, this.onPartBegin = noop, this.onPartData = noop, this.onPartEnd = noop, this.boundaryChars = {}, boundary = `\r --` + boundary; let ui8a = new Uint8Array(boundary.length); for (let i = 0; i < boundary.length; i++) ui8a[i] = boundary.charCodeAt(i), this.boundaryChars[ui8a[i]] = !0; this.boundary = ui8a, this.lookbehind = new Uint8Array(this.boundary.length + 8), this.state = S.START_BOUNDARY; } /** * @param {Uint8Array} data */ write(data) { let i = 0, length_ = data.length, previousIndex = this.index, { lookbehind, boundary, boundaryChars, index, state, flags } = this, boundaryLength = this.boundary.length, boundaryEnd = boundaryLength - 1, bufferLength = data.length, c, cl, mark = (name) => { this[name + "Mark"] = i; }, clear = (name) => { delete this[name + "Mark"]; }, callback = (callbackSymbol, start, end, ui8a) => { (start === void 0 || start !== end) && this[callbackSymbol](ui8a && ui8a.subarray(start, end)); }, dataCallback = (name, clear2) => { let markSymbol = name + "Mark"; markSymbol in this && (clear2 ? (callback(name, this[markSymbol], i, data), delete this[markSymbol]) : (callback(name, this[markSymbol], data.length, data), this[markSymbol] = 0)); }; for (i = 0; i < length_; i++) switch (c = data[i], state) { case S.START_BOUNDARY: if (index === boundary.length - 2) { if (c === HYPHEN) flags |= F.LAST_BOUNDARY; else if (c !== CR) return; index++; break; } else if (index - 1 === boundary.length - 2) { if (flags & F.LAST_BOUNDARY && c === HYPHEN) state = S.END, flags = 0; else if (!(flags & F.LAST_BOUNDARY) && c === LF) index = 0, callback("onPartBegin"), state = S.HEADER_FIELD_START; else return; break; } c !== boundary[index + 2] && (index = -2), c === boundary[index + 2] && index++; break; case S.HEADER_FIELD_START: state = S.HEADER_FIELD, mark("onHeaderField"), index = 0; // falls through case S.HEADER_FIELD: if (c === CR) { clear("onHeaderField"), state = S.HEADERS_ALMOST_DONE; break; } if (index++, c === HYPHEN) break; if (c === COLON) { if (index === 1) return; dataCallback("onHeaderField", !0), state = S.HEADER_VALUE_START; break; } if (cl = lower(c), cl < A || cl > Z) return; break; case S.HEADER_VALUE_START: if (c === SPACE) break; mark("onHeaderValue"), state = S.HEADER_VALUE; // falls through case S.HEADER_VALUE: c === CR && (dataCallback("onHeaderValue", !0), callback("onHeaderEnd"), state = S.HEADER_VALUE_ALMOST_DONE); break; case S.HEADER_VALUE_ALMOST_DONE: if (c !== LF) return; state = S.HEADER_FIELD_START; break; case S.HEADERS_ALMOST_DONE: if (c !== LF) return; callback("onHeadersEnd"), state = S.PART_DATA_START; break; case S.PART_DATA_START: state = S.PART_DATA, mark("onPartData"); // falls through case S.PART_DATA: if (previousIndex = index, index === 0) { for (i += boundaryEnd; i < bufferLength && !(data[i] in boundaryChars); ) i += boundaryLength; i -= boundaryEnd, c = data[i]; } if (index < boundary.length) boundary[index] === c ? (index === 0 && dataCallback("onPartData", !0), index++) : index = 0; else if (index === boundary.length) index++, c === CR ? flags |= F.PART_BOUNDARY : c === HYPHEN ? flags |= F.LAST_BOUNDARY : index = 0; else if (index - 1 === boundary.length) if (flags & F.PART_BOUNDARY) { if (index = 0, c === LF) { flags &= ~F.PART_BOUNDARY, callback("onPartEnd"), callback("onPartBegin"), state = S.HEADER_FIELD_START; break; } } else flags & F.LAST_BOUNDARY && c === HYPHEN ? (callback("onPartEnd"), state = S.END, flags = 0) : index = 0; if (index > 0) lookbehind[index - 1] = c; else if (previousIndex > 0) { let _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength); callback("onPartData", 0, previousIndex, _lookbehind), previousIndex = 0, mark("onPartData"), i--; } break; case S.END: break; default: throw new Error(`Unexpected state entered: ${state}`); } dataCallback("onHeaderField"), dataCallback("onHeaderValue"), dataCallback("onPartData"), this.index = index, this.state = state, this.flags = flags; } end() { if (this.state === S.HEADER_FIELD_START && this.index === 0 || this.state === S.PART_DATA && this.index === this.boundary.length) this.onPartEnd(); else if (this.state !== S.END) throw new Error("MultipartParser.end(): stream ended unexpectedly"); } }; function _fileName(headerValue) { let m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i); if (!m) return; let match = m[2] || m[3] || "", filename = match.slice(match.lastIndexOf("\\") + 1); return filename = filename.replace(/%22/g, '"'), filename = filename.replace(/&#(\d{4});/g, (m2, code) => String.fromCharCode(code)), filename; } async function toFormData(Body, ct) { if (!/multipart/i.test(ct)) throw new TypeError("Failed to fetch"); let m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i); if (!m) throw new TypeError("no or bad content-type header, no multipart boundary"); let parser = new MultipartParser(m[1] || m[2]), headerField, headerValue, entryValue, entryName, contentType, filename, entryChunks = [], formData = new FormData(), onPartData = (ui8a) => { entryValue += decoder.decode(ui8a, { stream: !0 }); }, appendToFile = (ui8a) => { entryChunks.push(ui8a); }, appendFileToFormData = () => { let file = new file_default(entryChunks, filename, { type: contentType }); formData.append(entryName, file); }, appendEntryToFormData = () => { formData.append(entryName, entryValue); }, decoder = new TextDecoder("utf-8"); decoder.decode(), parser.onPartBegin = function() { parser.onPartData = onPartData, parser.onPartEnd = appendEntryToFormData, headerField = "", headerValue = "", entryValue = "", entryName = "", contentType = "", filename = null, entryChunks.length = 0; }, parser.onHeaderField = function(ui8a) { headerField += decoder.decode(ui8a, { stream: !0 }); }, parser.onHeaderValue = function(ui8a) { headerValue += decoder.decode(ui8a, { stream: !0 }); }, parser.onHeaderEnd = function() { if (headerValue += decoder.decode(), headerField = headerField.toLowerCase(), headerField === "content-disposition") { let m2 = headerValue.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i); m2 && (entryName = m2[2] || m2[3] || ""), filename = _fileName(headerValue), filename && (parser.onPartData = appendToFile, parser.onPartEnd = appendFileToFormData); } else headerField === "content-type" && (contentType = headerValue); headerValue = "", headerField = ""; }; for await (let chunk of Body) parser.write(chunk); return parser.end(), formData; } export { toFormData }; //# sourceMappingURL=multipart-parser-WSNBP656.js.map