@shopify/cli
Version:
A CLI tool to build for the Shopify platform
195 lines (193 loc) • 8.6 kB
JavaScript
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