import { serve } from "bun"; import packages from "../database/database/packages.json"; import programs from "../database/database/programs.json"; // Pre-sort data for indexDetails endpoints const packagesLatestRepos = [...packages].sort( (a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime() ); const packagesMostUsed = [...packages].sort( (a, b) => (b.usage_count || 0) - (a.usage_count || 0) ); const programsLatestRepos = [...programs].sort( (a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime() ); const programsMostUsed = [...programs].sort( (a, b) => (b.usage_count || 0) - (a.usage_count || 0) ); serve({ port: 7860, fetch(req) { const url = new URL(req.url); const pathname = url.pathname; const q = url.searchParams.get("q")?.trim().toLowerCase(); const filter = url.searchParams.get("filter")?.trim().toLowerCase(); const corsHeaders = { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*", }; // CORS preflight handling if (req.method === "OPTIONS") { return new Response(null, { status: 204, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type", }, }); } if (pathname === "/api/searchPackages") { const results = packages.filter( ({ name, full_name, description, topics }) => { if ( filter && !topics?.some((t: string) => t.toLowerCase() === filter) ) return false; if (!q) return true; return [name, full_name, description, ...(topics || [])].some( (field: string) => field?.toLowerCase().includes(q), ); }, ); return new Response(JSON.stringify(results.slice(0, 25)), { status: 200, headers: corsHeaders, }); } if (pathname === "/api/searchPrograms") { const results = programs.filter(({ full_name, description, topics }) => { if (filter && !topics?.some((t: string) => t.toLowerCase() === filter)) return false; if (!q) return true; return [full_name, description, ...(topics || [])].some( (field: string) => field?.toLowerCase().includes(q), ); }); return new Response(JSON.stringify(results.slice(0, 25)), { status: 200, headers: corsHeaders, }); } if (pathname === "/api/infiniteScrollPackages") { const pageNumberParam = url.searchParams.get("pageNumber"); const pageNumber = parseInt(pageNumberParam || "0", 10); if (isNaN(pageNumber) || pageNumber < 0) { return new Response(JSON.stringify({ error: "Invalid page number" }), { status: 400, headers: corsHeaders, }); } const lowerLimit = pageNumber * 10; const scrollResults = packages.slice(lowerLimit, lowerLimit + 10); return new Response(JSON.stringify(scrollResults), { status: 200, headers: corsHeaders, }); } if (pathname === "/api/infiniteScrollPrograms") { const pageNumberParam = url.searchParams.get("pageNumber"); const pageNumber = parseInt(pageNumberParam || "0", 10); if (isNaN(pageNumber) || pageNumber < 0) { return new Response(JSON.stringify({ error: "Invalid page number" }), { status: 400, headers: corsHeaders, }); } const lowerLimit = pageNumber * 10; const scrollResults = programs.slice(lowerLimit, lowerLimit + 10); return new Response(JSON.stringify(scrollResults), { status: 200, headers: corsHeaders, }); } // New: Get program by owner and repo name const programMatch = pathname.match(/^\/api\/programs\/([^\/]+)\/([^\/]+)$/); if (programMatch) { const [, owner, repo] = programMatch; const program = programs.find( (p) => p.owner?.toLowerCase() === owner.toLowerCase() && p.name?.toLowerCase() === repo.toLowerCase() ); if (program) { return new Response(JSON.stringify(program), { status: 200, headers: corsHeaders, }); } return new Response(JSON.stringify({ error: "Program not found" }), { status: 404, headers: corsHeaders, }); } // New: Get package by owner and repo name const packageMatch = pathname.match(/^\/api\/packages\/([^\/]+)\/([^\/]+)$/); if (packageMatch) { const [, owner, repo] = packageMatch; const pkg = packages.find( (p) => p.owner?.toLowerCase() === owner.toLowerCase() && p.name?.toLowerCase() === repo.toLowerCase() ); if (pkg) { return new Response(JSON.stringify(pkg), { status: 200, headers: corsHeaders, }); } return new Response(JSON.stringify({ error: "Package not found" }), { status: 404, headers: corsHeaders, }); } // Helper to parse range string like "0..100" function parseRange(rangeStr: string | null, max: number) { if (!rangeStr) return [0, Math.min(10, max)]; const match = rangeStr.match(/^(\d+)\.\.(\d+)$/); if (!match) return [0, Math.min(10, max)]; const start = Math.max(0, parseInt(match[1], 10)); const end = Math.min(max, parseInt(match[2], 10)); return [start, end]; } // /api/indexDetailsPackages if (pathname === "/api/indexDetailsPackages") { const section = url.searchParams.get("section"); const rangeStr = url.searchParams.get("range"); let data = packages; if (section === "latestRepos") { data = packagesLatestRepos; } else if (section === "mostUsed") { data = packagesMostUsed; } const [start, end] = parseRange(rangeStr, data.length); return new Response(JSON.stringify(data.slice(start, end)), { status: 200, headers: corsHeaders, }); } // /api/indexDetailsPrograms if (pathname === "/api/indexDetailsPrograms") { const section = url.searchParams.get("section"); const rangeStr = url.searchParams.get("range"); let data = programs; if (section === "latestRepos") { data = programsLatestRepos; } else if (section === "mostUsed") { data = programsMostUsed; } const [start, end] = parseRange(rangeStr, data.length); return new Response(JSON.stringify(data.slice(start, end)), { status: 200, headers: corsHeaders, }); } return new Response("Not Found", { status: 404, headers: { "Access-Control-Allow-Origin": "*" }, }); }, });