badgen.net/index.ts

88 wiersze
2.1 KiB
TypeScript

import fs from 'fs'
import path from 'path'
import http from 'http'
import matchRoute from 'my-way'
import serveHandler from 'serve-handler'
import serve404 from './libs/serve-404'
const sendError = (res: http.ServerResponse, error: Error) => {
res.statusCode = 500
res.end(error.message)
}
const sendRedirection = (res: http.ServerResponse, code: number, dest: string) => {
res.statusCode = code
res.setHeader('Location', dest)
res.end()
}
const badgeNames = fs.readdirSync(path.join(__dirname, 'endpoints'))
.filter(name => /\.[jt]s$/.test(name))
.map(name => name.replace(/\.[jt]s$/, ''))
const isStatic = (url) => {
if (url === '/') return true
if (url.startsWith('/_next/')) return true
if (url.startsWith('/static/')) return true
if (url.startsWith('/builder')) return true
return false
}
const serveStaticHeaders = [
{
source: '**/*',
headers: [{
key: 'Cache-Control',
value: 'public, max-age=86400, s-maxage=604800, stale-while-revalidate=86400'
}]
}
]
const { PUB_DIR = '.' } = process.env
const server = http.createServer(async (req, res) => {
const url = req.url || '/'
// handle statics
if (isStatic(url)) {
return serveHandler(req, res, {
public: path.resolve(__dirname, PUB_DIR),
headers: serveStaticHeaders
})
}
// redirects `/docs/:name` to `/:name`
if (url.startsWith('/docs/')) {
return sendRedirection(res, 301, url.replace('/docs', ''))
}
// handle endpoints
const handlerName = badgeNames.find(h => matchRoute(`/${h}/:path*`, url))
try {
if (handlerName) {
const handlerPath = path.join(__dirname, 'endpoints', handlerName)
const { default: handler } = await import(handlerPath)
return handler(req, res, handlerName)
}
} catch (error) {
console.error(error)
return sendError(res, error)
}
return serve404(req, res)
})
// Auto run
if (require.main === module) {
const port = process.env.PORT || 3000
server.listen(port)
console.log(`Badgen listening on port ${port}`)
}
process.on('unhandledRejection', e => {
console.error('REJECTION', e)
})
export default server