#!./run // Automated bundle server import { Response, serve, ServerRequest, } from "https://deno.land/std@0.103.0/http/server.ts"; export async function processRequest( req: ServerRequest, hostpath: string, runner = Deno.run, ): Promise { if (req.method != "GET") { return { status: 405 }; } const params = req.url.split("/").filter((x) => !!x); if (params.length < 2) { return { status: 404 }; } const [lib, version] = params[0].split("@", 2); const file = params.slice(1).join("/"); const branch = version || "master"; const path = `https://${hostpath}/${lib}/raw/${branch}/${file}`; if (!isName(lib) || !isName(branch) || !isPath(file)) { return { status: 400, body: `console.error("bundler error - Invalid path ${path}");`, }; } if (path.endsWith(".js")) { return await bundle(path.slice(0, -3) + ".ts", runner); } else { return { status: 301, headers: new Headers({ Location: path }), }; } } async function bundle( path: string, runner: typeof Deno.run, ): Promise { const process = runner({ cmd: ["deno", "bundle", path], stdout: "piped", }); const output = await process.output(); const status = await process.status(); if (status.success) { return { body: output }; } else { return { status: 500, body: `console.error("bundler error - Failed to bundle ${path}");`, }; } } export async function serveBundles(hostpath: string, port: number) { const listen = { hostname: "0.0.0.0", port }; const server = serve(listen); console.log( `Serving ${hostpath} bundles on ${listen.hostname}:${listen.port} ...`, ); for await (const req of server) { try { const response = await processRequest(req, hostpath); await req.respond(response); } catch (err) { // console.error(err); await req.respond({ status: 500 }); } } } function isName(input: string): boolean { return !!input.match(/^[a-zA-Z0-9_\-\.]+$/); } function isPath(input: string): boolean { return !input.split("/").some((part) => !isName(part)); } export type { Response }; if (import.meta.main) { if (Deno.args.length >= 1 && Deno.args.length <= 2) { await serveBundles(Deno.args[0], parseInt(Deno.args[1] || "8000")); } else { console.error("Usage: server.ts yourgithosting.net/namespace [port]"); } }