feat/api-prox: add POST proxy

This commit is contained in:
Kentai Radiquum 2025-09-06 19:44:49 +05:00
parent deb92f1480
commit a24371cf24
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
6 changed files with 95 additions and 57 deletions

View file

@ -1,7 +1,7 @@
export type Hook = {
priority: number;
match: (url: URL) => boolean;
hook: (url: URL, data: any) => any;
match: (url: URL, method: "GET" | "POST") => boolean;
hook: (url: URL, data: any, method: "GET" | "POST") => any;
};
import testHook from "./test.ts";
@ -12,10 +12,10 @@ export function sortHooks(hooks: Hook[]) {
return hooks.sort((a, b) => b.priority - a.priority);
}
export function runHooks(hooks: Hook[], url: URL, data: any) {
export function runHooks(hooks: Hook[], url: URL, data: any, method: "GET" | "POST") {
for (const hook of hooks) {
if (hook.match(url)) {
data = hook.hook(data, url);
if (hook.match(url, method)) {
data = hook.hook(data, url, method);
}
}
return data;

View file

@ -1,13 +1,15 @@
function match(url: URL): boolean {
return url.pathname == "/profile/1";
const priority = 0;
function match(url: URL, method: "GET" | "POST"): boolean {
return url.pathname == "/profile/1" && method == "GET";
}
function hook(data: any, _: URL) {
function hook(data: any, _: URL, __: "GET" | "POST") {
const newUname = "Anixartiki";
if (!data.hasOwnProperty("profile") || !data.profile) return data;
data["profile"]["login"] = newUname;
return data;
}
const entrypoint = { priority: 1, match, hook }
const entrypoint = { priority, match, hook };
export default entrypoint;

View file

@ -96,7 +96,76 @@ app.get("/*", async (c) => {
return c.json(error);
}
await runHooks(hookList, url, data);
await runHooks(hookList, url, data, "GET");
//@ts-ignore
return c.json(data);
});
app.post("/*", async (c) => {
InfoLogger("index.ts", "Trying to proxy `POST` request");
const url = new URL(c.req.url);
const currentBaseURL = new URL(
BASE_URLS[Math.floor(Math.random() * BASE_URLS.length)]
);
url.protocol = currentBaseURL.protocol;
url.host = currentBaseURL.host;
url.port = currentBaseURL.port;
if (
url.searchParams.get("API-Version") == "v2" ||
c.req.header("API-Version") == "v2"
) {
ANIXART_HEADERS["Api-Version"] = "v2";
url.searchParams.delete("API-Version");
}
let reqContentType =
c.req.header("content-type") ?
c.req.header("content-type")?.split(";")[0].toLowerCase()
: "application/json";
InfoLogger("index.ts", "URL:", `${url.protocol}//${url.host}${url.pathname}`);
InfoLogger("index.ts", "Content-Type:", `${reqContentType}`);
let data = null;
let error = null;
switch (reqContentType) {
case "multipart/form-data":
({ data, error } = await tryCatchAPI(
fetch(url.toString(), {
method: "POST",
headers: ANIXART_HEADERS,
body: await c.req.formData(),
})
));
break;
case "application/x-www-form-urlencoded":
({ data, error } = await tryCatchAPI(
fetch(url.toString(), {
method: "POST",
headers: ANIXART_HEADERS,
body: null,
})
));
break;
default:
({ data, error } = await tryCatchAPI(
fetch(url.toString(), {
method: "POST",
headers: ANIXART_HEADERS,
body: await c.req.json(),
})
));
break;
}
if (error) {
return c.json(error);
}
await runHooks(hookList, url, data, "POST");
//@ts-ignore
return c.json(data);

View file

@ -1,40 +0,0 @@
// import { readdirSync } from "node:fs";
// export function loadHooks() {
// let hooks: string[] = [];
// let loadedHooks: Hook[] = [];
// try {
// hooks = readdirSync("./src/hooks");
// } catch (err) {
// console.error("'hooks' directory not found");
// }
// for (const hook of hooks) {
// try {
// console.log(hook);
// // const _import = await import(`./src/hooks/${hook}`);
// // if (_import.default) {
// // loadedHooks.push(_import.default);
// // }
// } catch (err) {
// console.error(`Failed to load hook ${hook}`);
// }
// }
// return sortHooks(loadedHooks);
// }
// export function sortHooks(hooks: Hook[]) {
// return hooks.sort((a, b) => b.priority - a.priority);
// }
// export function runHooks(hooks: Hook[], url: URL, data: any) {
// for (const hook of hooks) {
// if (hook.match(url)) {
// data = hook.hook(url, data);
// }
// }
// return data;
// }

View file

@ -1,11 +1,18 @@
function hideQueryParam(param: string, url: URL) {
if (url.searchParams.get(param)) {
url.searchParams.set(param, "***");
}
}
export const RouteLogger = (message: string) => {
const args = message.split(" ");
const direction = args[0];
const method = args[1];
const url = new URL("http://example.com" + args[2]);
if (url.searchParams.get("token")) {
url.searchParams.set("token", "***");
}
hideQueryParam("token", url);
hideQueryParam("login", url);
hideQueryParam("password", url);
if (direction == "<--") {
console.log(`--> REQ | ${method} ${url.pathname}${url.search}`);

View file

@ -3,9 +3,9 @@
"name": "anixart-serverless-api-proxy",
"main": "src/index.ts",
"compatibility_date": "2025-09-05",
"compatibility_flags": [
"nodejs_compat"
],
// "compatibility_flags": [
// "nodejs_compat"
// ],
// "vars": {
// "MY_VAR": "my-variable"
// },