mirror of
https://github.com/hanzoai/ventures.git
synced 2026-10-30 18:18:25 +00:00
40 lines
1.5 KiB
JavaScript
40 lines
1.5 KiB
JavaScript
// The gates measure the EXPORT, so they need something that serves the export
|
|
// the way the Sites plane does: directory indexes, and a real 404 for a path
|
|
// with no file. Twenty lines of node beats a dependency.
|
|
import { createServer } from 'node:http'
|
|
import { readFile, stat } from 'node:fs/promises'
|
|
import { join, extname, normalize } from 'node:path'
|
|
|
|
const root = new URL('../out/', import.meta.url).pathname
|
|
const port = Number(process.env.PORT || 4321)
|
|
|
|
const TYPES = {
|
|
'.html': 'text/html; charset=utf-8',
|
|
'.js': 'text/javascript; charset=utf-8',
|
|
'.css': 'text/css; charset=utf-8',
|
|
'.txt': 'text/plain; charset=utf-8',
|
|
'.xml': 'application/xml; charset=utf-8',
|
|
'.json': 'application/json; charset=utf-8',
|
|
'.woff2': 'font/woff2',
|
|
'.svg': 'image/svg+xml',
|
|
}
|
|
|
|
createServer(async (req, res) => {
|
|
// normalize() collapses `..`, so a crafted path cannot climb out of out/.
|
|
const rel = normalize(decodeURIComponent(req.url.split('?')[0])).replace(/^(\.\.[/\\])+/, '')
|
|
let file = join(root, rel)
|
|
try {
|
|
if ((await stat(file)).isDirectory()) file = join(file, 'index.html')
|
|
} catch {
|
|
file = extname(file) ? file : `${file}/index.html`
|
|
}
|
|
try {
|
|
const body = await readFile(file)
|
|
res.writeHead(200, { 'content-type': TYPES[extname(file)] || 'application/octet-stream' })
|
|
res.end(body)
|
|
} catch {
|
|
res.writeHead(404, { 'content-type': 'text/plain' })
|
|
res.end('not found')
|
|
}
|
|
}).listen(port, () => console.log(`serving out/ on http://127.0.0.1:${port}`))
|