more modularization

This commit is contained in:
KingKDot
2026-05-29 20:14:31 -05:00
parent b975907b20
commit 3102a00e8c
13 changed files with 497 additions and 453 deletions
@@ -10,9 +10,6 @@ import {
getBuild,
countBuildsForUser,
getOldestBuildForUser,
listBuildProfilesForUser,
saveBuildProfileForUser,
deleteBuildProfileForUser,
setBuildBlocked,
listClientIdsByBuildTag,
countBuildClaimsBatch,
@@ -29,7 +26,8 @@ import { addBuildToBanlist, removeBuildFromBanlist } from "../build-signing";
import path from "path";
import fs from "fs";
import { resolveRuntimeRoot } from "../runtime-paths";
import { createUploadPull } from "./file-download-routes";
import { createUploadPull } from "../file-transfer-state";
import { handleBuildProfileRoutes } from "./build-profile-routes";
type RequestIpProvider = {
requestIP: (req: Request) => { address?: string } | null | undefined;
@@ -426,89 +424,8 @@ export async function handleBuildRoutes(
return Response.json({ builds: enriched });
}
if (req.method === "GET" && url.pathname === "/api/build/profiles") {
requirePermission(user, "clients:build");
const profiles = listBuildProfilesForUser(user.userId).map((p) => {
let parsedConfig: any = {};
try {
parsedConfig = JSON.parse(p.profileJson);
} catch {
parsedConfig = {};
}
return {
name: p.name,
config: parsedConfig,
createdAt: p.createdAt,
updatedAt: p.updatedAt,
};
});
return Response.json({ profiles });
}
if (req.method === "POST" && url.pathname === "/api/build/profiles") {
requirePermission(user, "clients:build");
const body = await req.json();
const name = typeof body?.name === "string" ? body.name.trim() : "";
const config = body?.config;
if (!name || name.length > 64 || !/^[A-Za-z0-9 _.-]+$/.test(name)) {
return Response.json(
{ error: "Invalid profile name (1-64 chars, letters/numbers/space/._-)" },
{ status: 400 },
);
}
if (!config || typeof config !== "object" || Array.isArray(config)) {
return Response.json({ error: "Invalid profile config" }, { status: 400 });
}
const MAX_PROFILES_PER_USER = 50;
const existingProfiles = listBuildProfilesForUser(user.userId);
const hasExistingWithSameName = existingProfiles.some((p) => p.name === name);
if (!hasExistingWithSameName && existingProfiles.length >= MAX_PROFILES_PER_USER) {
return Response.json(
{ error: `Profile limit reached (${MAX_PROFILES_PER_USER} max)` },
{ status: 400 },
);
}
let profileJson = "{}";
try {
profileJson = JSON.stringify(config);
} catch {
return Response.json({ error: "Profile config must be JSON serializable" }, { status: 400 });
}
if (profileJson.length > 512 * 1024) {
return Response.json({ error: "Profile config too large (max 512KB)" }, { status: 400 });
}
saveBuildProfileForUser(user.userId, name, profileJson);
return Response.json({ success: true });
}
if (req.method === "DELETE" && url.pathname.match(/^\/api\/build\/profiles\/.+$/)) {
requirePermission(user, "clients:build");
const encodedName = url.pathname.split("/api/build/profiles/")[1] || "";
let name = "";
try {
name = decodeURIComponent(encodedName).trim();
} catch {
return Response.json({ error: "Invalid profile name" }, { status: 400 });
}
if (!name) {
return Response.json({ error: "Invalid profile name" }, { status: 400 });
}
const deleted = deleteBuildProfileForUser(user.userId, name);
if (!deleted) {
return Response.json({ error: "Profile not found" }, { status: 404 });
}
return Response.json({ success: true });
}
const profileResult = await handleBuildProfileRoutes(req, url, user);
if (profileResult) return profileResult;
if (req.method === "DELETE" && url.pathname.match(/^\/api\/build\/(.+)\/delete$/)) {
requirePermission(user, "clients:build");