Files
OmniRoute/src/lib/api/proxyRegistryRouteHandlers.ts
Webman 2463781e00 fix(barrel): migrate src/lib/ off the localDb barrel to direct db imports (#59) (#12052)
Boarded together with Phases 2, 4, 5 (#12051, #12053, #12055) and validated in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles, check-db-rules all green. Mechanical import-path migration only, no behavior change. Thanks for the phased, well-tested cleanup.
2026-08-30 02:27:25 -03:00

149 lines
4.6 KiB
TypeScript

import {
createProxy,
createProxyAndAssign,
deleteProxyById,
getProxyById,
getProxyWhereUsed,
updateProxy,
updateProxyAndAssign,
} from "@/lib/db/proxies";
import { createErrorResponse, createErrorResponseFromUnknown } from "@/lib/api/errorResponse";
import { createProxyRegistrySchema, updateProxyRegistrySchema } from "@/shared/validation/schemas";
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
import { clearDispatcherCache } from "@omniroute/open-sse/utils/proxyDispatcher";
async function readJsonBody(request: Request) {
try {
return { ok: true as const, body: await request.json() };
} catch {
return {
ok: false as const,
response: createErrorResponse({
status: 400,
message: "Invalid JSON body",
type: "invalid_request",
}),
};
}
}
export async function resolveProxyLookupResponse(
searchParams: URLSearchParams,
whereUsedParam: string
): Promise<Response | null> {
const id = searchParams.get("id");
const whereUsed = searchParams.get(whereUsedParam) === "1";
if (id && whereUsed) {
const usage = await getProxyWhereUsed(id);
return Response.json(usage);
}
if (!id) {
return null;
}
const proxy = await getProxyById(id, { includeSecrets: false });
if (!proxy) {
return createErrorResponse({ status: 404, message: "Proxy not found", type: "not_found" });
}
return Response.json(proxy);
}
export async function handleProxyCreate(request: Request) {
const parsed = await readJsonBody(request);
if (!parsed.ok) return parsed.response;
try {
const validation = validateBody(createProxyRegistrySchema, parsed.body);
if (isValidationFailure(validation)) {
return createErrorResponse({
status: 400,
message: validation.error.message,
details: validation.error.details,
type: "invalid_request",
});
}
const { assignment, ...proxyFields } = validation.data;
if (assignment) {
const result = await createProxyAndAssign(proxyFields, assignment);
clearDispatcherCache();
return Response.json({ ...result.proxy, assignment: result.assignment }, { status: 201 });
}
const created = await createProxy(proxyFields);
return Response.json(created, { status: 201 });
} catch (error) {
return createErrorResponseFromUnknown(error, "Failed to create proxy");
}
}
export async function handleProxyUpdate(request: Request) {
const parsed = await readJsonBody(request);
if (!parsed.ok) return parsed.response;
try {
const validation = validateBody(updateProxyRegistrySchema, parsed.body);
if (isValidationFailure(validation)) {
return createErrorResponse({
status: 400,
message: validation.error.message,
details: validation.error.details,
type: "invalid_request",
});
}
const { id, assignment, ...rawChanges } = validation.data;
// Strip keys the client didn't send — .partial() resolves absent fields to
// undefined, which would silently overwrite DB values via the spread merge
// in updateProxyRow. Only include keys the client explicitly provided.
const changes = Object.fromEntries(
Object.entries(rawChanges).filter(([_, v]) => v !== undefined)
);
if (assignment) {
const result = await updateProxyAndAssign(id, changes, assignment);
if (!result?.proxy) {
return createErrorResponse({ status: 404, message: "Proxy not found", type: "not_found" });
}
clearDispatcherCache();
return Response.json({ ...result.proxy, assignment: result.assignment });
}
const updated = await updateProxy(id, changes);
if (!updated) {
return createErrorResponse({ status: 404, message: "Proxy not found", type: "not_found" });
}
return Response.json(updated);
} catch (error) {
return createErrorResponseFromUnknown(error, "Failed to update proxy");
}
}
export async function handleProxyDelete(request: Request) {
try {
const { searchParams } = new URL(request.url);
const id = searchParams.get("id");
const force = searchParams.get("force") === "1";
if (!id) {
return createErrorResponse({
status: 400,
message: "id is required",
type: "invalid_request",
});
}
const deleted = await deleteProxyById(id, { force });
if (!deleted) {
return createErrorResponse({ status: 404, message: "Proxy not found", type: "not_found" });
}
return Response.json({ success: true });
} catch (error) {
return createErrorResponseFromUnknown(error, "Failed to delete proxy");
}
}