@sec-ant/gm-fetch
Version:
A fetch API for GM_xmlhttpRequest / GM.xmlHttpRequest
123 lines (122 loc) • 3.48 kB
JavaScript
var M = "__monkeyWindow-" + (() => {
try {
return new URL(import.meta.url).origin;
} catch {
return location.origin;
}
})(), y = document[M] ?? window, g = y.GM, v = y.GM_xmlhttpRequest;
function k(l) {
var e;
const t = new Headers(), a = l.replace(/\r?\n[\t ]+/g, " ");
for (const d of a.split(/\r?\n/)) {
const i = d.split(":"), o = (e = i.shift()) == null ? void 0 : e.trim();
if (o) {
const r = i.join(":").trim();
try {
t.append(o, r);
} catch (c) {
console.warn(`Response ${c.message}`);
}
}
}
return t;
}
const H = async (l, t) => {
const a = v || g.xmlHttpRequest;
if (typeof a != "function")
throw new DOMException(
"GM_xmlhttpRequest or GM.xmlHttpRequest is not granted.",
"NotFoundError"
);
const e = new Request(l, t);
if (e.signal.aborted)
throw new DOMException("Network request aborted.", "AbortError");
const d = await e.blob(), i = Object.fromEntries(e.headers);
return new Headers(t == null ? void 0 : t.headers).forEach((o, r) => {
i[r] = o;
}), new Promise((o, r) => {
let c = !1;
const R = new Promise((n) => {
const { abort: h } = a({
method: e.method.toUpperCase(),
url: e.url || location.href,
headers: i,
data: d.size ? d : void 0,
redirect: e.redirect,
binary: !0,
nocache: e.cache === "no-store",
revalidate: e.cache === "reload",
timeout: 3e5,
responseType: a.RESPONSE_TYPE_STREAM ?? "blob",
overrideMimeType: e.headers.get("Content-Type") ?? void 0,
anonymous: e.credentials === "omit",
onload: ({ response: s }) => {
if (c) {
n(null);
return;
}
n(s);
},
async onreadystatechange({
readyState: s,
responseHeaders: p,
status: b,
statusText: q,
finalUrl: w,
response: E
}) {
if (s === XMLHttpRequest.DONE)
e.signal.removeEventListener("abort", h);
else if (s !== XMLHttpRequest.HEADERS_RECEIVED)
return;
if (c) {
n(null);
return;
}
const u = k(p), f = e.url !== w, m = new Response(
E instanceof ReadableStream ? E : await R,
{
headers: u,
status: b,
statusText: q
}
);
Object.defineProperties(m, {
url: {
value: w
},
type: {
value: "basic"
},
...m.redirected !== f ? {
redirected: {
value: f
}
} : {},
// https://fetch.spec.whatwg.org/#forbidden-response-header-name
...u.has("set-cookie") || u.has("set-cookie2") ? {
headers: {
value: u
}
} : {}
}), o(m), c = !0;
},
onerror: ({ statusText: s, error: p }) => {
r(
new TypeError(s || p || "Network request failed.")
), n(null);
},
ontimeout() {
r(new TypeError("Network request timeout.")), n(null);
},
onabort() {
r(new DOMException("Network request aborted.", "AbortError")), n(null);
}
});
e.signal.addEventListener("abort", h);
});
});
};
export {
H as default
};