import bundler from "./mod.ts"; import mime from "https://esm.sh/mime@4.0.3"; import { parseArgs } from "jsr:@std/cli/parse-args"; if(Deno.mainModule == import.meta.url) { serve(parseArgs(Deno.args) as ServeArgs); } type ServeArgs = {path?:string, html?:string, port?:string|number}; function serve(settings:ServeArgs):void { let basePath = ""; const SetDirectory =(inPath:string)=>{ if(inPath.startsWith("http://")||inPath.startsWith("https://")||inPath.startsWith("file://")) { basePath = inPath; } else { basePath = new URL(inPath, new URL(`file://${Deno.cwd().replaceAll("\\", "/")}/`).toString()).href; } if(!basePath.endsWith("/")) { basePath = basePath + "/"; } console.log("Base Path:", basePath); } SetDirectory(settings.path||"./"); const transpiled:Map = new Map(); const ServeJSCode =(inText:string)=> new Response(inText, {headers:{"content-type":"application/javascript"}}); const ServeStatic =async(inPath:string)=> { try { const handle = await fetch(basePath+inPath.substring(1)); return new Response(handle.body, {headers:{"content-type": mime.getType(inPath)??""}}) } catch(_e) { console.log("404", inPath); return resp404; } }; const resp404 = new Response("404", {status:404}); let respIndex:false|Response|Promise = false; if(settings.html) { if(settings.html.indexOf("<") != -1) { respIndex= new Response(settings.html, {headers:{"content-type":"text-html"}}); } else { respIndex = ServeStatic(settings.html); } } Deno.serve({port:parseInt(settings.port as string)||8000}, async(req)=>{ const url = new URL(req.url); const index = url.pathname.lastIndexOf("."); if(index > -1) { const ext = url.pathname.substring(index+1); if(ext === "ts" || ext == "tsx" || ext == "js" || ext == "jsx") { if(ext == "js") { const lookup = transpiled.get(url.pathname); if(lookup) { return ServeJSCode(lookup); } } else { const lookup = transpiled.get(url.pathname.substring(0, index)+".js"); if(lookup) { return ServeJSCode(lookup); } } try { const results = await bundler({ entryPoints:[basePath+url.pathname], outdir:"/", entryNames: `[dir][name]`, splitting: true }, basePath); if(results.outputFiles) { results.outputFiles.forEach(output=>transpiled.set(output.path, output.text)) return ServeJSCode(results.outputFiles[0].text); } else { throw(new Error("no output")); } } catch(_e) { return resp404; } } else { return ServeStatic(url.pathname); } } if(respIndex) { return respIndex; } else { let indexLookup = url.pathname; if(!indexLookup.endsWith("/")) { indexLookup = indexLookup+"/"; } return ServeStatic(indexLookup+"index.html"); } }); } export default serve