refactor(webhook): load route map from env
Build and Deploy / build-and-deploy (push) Successful in 5m5s
Build and Deploy / build-and-deploy (push) Successful in 5m5s
This commit is contained in:
@@ -32,6 +32,8 @@ spec:
|
|||||||
envFrom:
|
envFrom:
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: enka-env
|
name: enka-env
|
||||||
|
- configMapRef:
|
||||||
|
name: enka-route-map
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /health
|
path: /health
|
||||||
|
|||||||
@@ -7,4 +7,3 @@ type: Opaque
|
|||||||
stringData:
|
stringData:
|
||||||
PRIVATE_API_KEY: "key is not needed"
|
PRIVATE_API_KEY: "key is not needed"
|
||||||
PUBLIC_API_KEY: "key is not needed"
|
PUBLIC_API_KEY: "key is not needed"
|
||||||
WH_ROUTE_MAP: "https://cdn.astrxl.dev/sec/a2f43a3d249a-routes.json"
|
|
||||||
|
|||||||
+27
-8
@@ -1,11 +1,9 @@
|
|||||||
import type { App } from "@";
|
import type { App } from "@";
|
||||||
import { env } from "bun";
|
import { env } from "bun";
|
||||||
import { status, t } from "elysia";
|
import { status, t } from "elysia";
|
||||||
import { TTLCache } from "enka.ts";
|
|
||||||
|
|
||||||
import { createLogger } from "@/lib/logger";
|
import { createLogger } from "@/lib/logger";
|
||||||
|
|
||||||
const routesCache = new TTLCache();
|
|
||||||
type Pending = {
|
type Pending = {
|
||||||
data: unknown;
|
data: unknown;
|
||||||
timer: ReturnType<typeof setTimeout>;
|
timer: ReturnType<typeof setTimeout>;
|
||||||
@@ -15,6 +13,7 @@ type Pending = {
|
|||||||
const pending = new Map<string, Pending>();
|
const pending = new Map<string, Pending>();
|
||||||
|
|
||||||
const log = createLogger("WH");
|
const log = createLogger("WH");
|
||||||
|
const routes = parseRouteMap(env.WH_ROUTE_MAP);
|
||||||
|
|
||||||
export function webhookMerger(app: App) {
|
export function webhookMerger(app: App) {
|
||||||
return app.post(
|
return app.post(
|
||||||
@@ -72,15 +71,35 @@ export function webhookMerger(app: App) {
|
|||||||
type RouteMap = [string, string, number][];
|
type RouteMap = [string, string, number][];
|
||||||
|
|
||||||
async function getRoutes(): Promise<RouteMap> {
|
async function getRoutes(): Promise<RouteMap> {
|
||||||
const cached = routesCache.get(".");
|
return routes;
|
||||||
|
}
|
||||||
|
|
||||||
if (cached) return cached as RouteMap;
|
function parseRouteMap(raw: string): RouteMap {
|
||||||
|
const parsed = JSON.parse(raw) as unknown;
|
||||||
|
|
||||||
const res = await fetch(env.WH_ROUTE_MAP).then((r) => r.ok && r.json());
|
if (!Array.isArray(parsed)) throw new Error("WH_ROUTE_MAP must be a JSON array");
|
||||||
|
|
||||||
if (!res) throw new Error("cant get route map");
|
for (const [index, route] of parsed.entries()) {
|
||||||
routesCache.set(".", res, 900);
|
if (!Array.isArray(route) || route.length !== 3) {
|
||||||
return res;
|
throw new Error(`WH_ROUTE_MAP route ${index} must be [id, url, bufferTime]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [id, url, bufferTime] = route;
|
||||||
|
|
||||||
|
if (typeof id !== "string" || !id) {
|
||||||
|
throw new Error(`WH_ROUTE_MAP route ${index} has invalid id`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof url !== "string" || !url) {
|
||||||
|
throw new Error(`WH_ROUTE_MAP route ${index} has invalid url`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Number.isFinite(bufferTime)) {
|
||||||
|
throw new Error(`WH_ROUTE_MAP route ${index} has invalid bufferTime`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed as RouteMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_FIELD_LENGTH = Number(env.MAX_FIELD_LENGTH) || 4000;
|
const MAX_FIELD_LENGTH = Number(env.MAX_FIELD_LENGTH) || 4000;
|
||||||
|
|||||||
Reference in New Issue
Block a user