prasi-bun/app/web/src/base/load/proxy.ts

128 lines
3.1 KiB
TypeScript

(BigInt.prototype as any).toJSON = function (): string {
return `BigInt::` + this.toString();
};
let w = window as any;
export const fetchViaProxy = async (
url: string,
data?: any,
_headers?: any
) => {
const headers = { ..._headers };
let body = data;
let isFile = false;
const formatSingle = async (data: any) => {
if (!(data instanceof w.FormData || data instanceof w.File)) {
headers["content-type"] = "application/json";
} else {
if (data instanceof w.File) {
isFile = true;
let ab = await new Promise<ArrayBuffer | undefined>((resolve) => {
const reader = new FileReader();
reader.addEventListener("load", (e) => {
resolve(e.target?.result as ArrayBuffer);
});
reader.readAsArrayBuffer(data);
});
if (ab) {
data = new File([ab], data.name);
}
}
}
return data;
};
if (Array.isArray(data)) {
body = await Promise.all(data.map((e) => formatSingle(e)));
} else {
body = await formatSingle(data);
}
if (!isFile) {
body = JSON.stringify(body);
}
const cur = new URL(location.href);
const base = new URL(url);
if (cur.host === base.host) {
const res = await fetch(
base.pathname,
data
? {
method: "POST",
body,
headers,
}
: undefined
);
const raw = await res.text();
try {
return JSON.parse(raw);
} catch (e) {
return raw;
}
} else {
if (
data instanceof File ||
(Array.isArray(data) && data[0] instanceof File)
) {
const target = new URL(url);
_headers["content-type"] = "multipart/form-data";
if (data instanceof File) {
const formData = new FormData();
formData.append("file", data);
const res = await fetch(target.pathname, {
body: formData,
method: "POST",
headers: _headers,
});
return await res.text();
} else {
const formData = new FormData();
let idx = 1;
for (const file of data) {
formData.append("file-" + idx++, file);
}
const res = await fetch(target.pathname, {
body: formData,
method: "POST",
headers: _headers,
});
return await res.text();
}
} else {
const res = await fetch(`${w.basehost ? w.basehost : ""}/_proxy`, {
method: "POST",
body: JSON.stringify([
{
url,
body,
headers,
},
]),
headers: { "content-type": "application/json" },
});
let text = "";
try {
text = await res.text();
return JSON.parse(text);
} catch (e) {
let formatted_body = null;
try {
formatted_body = JSON.stringify(JSON.parse(body), null, 2);
} catch (e) {}
console.warn(
`\n\n⚡ Failed to JSON.parse fetch result of ${url}:\n\n${JSON.stringify(
text
)} \n\nwith params:\n${formatted_body}`
);
return text;
}
}
}
};