UNPKG

kequapp

Version:

A minimal, zero-magic Node web framework built on native APIs

60 lines (59 loc) 2.08 kB
import { unknownToEx } from "../built-in/tools/ex.js"; import { findErrorHandler, findRenderer } from "./find.js"; export async function renderRoute(route, bundle) { const { res, methods } = bundle; const { actions, method, renderers } = route; let payload; if (methods.includes('OPTIONS')) { res.setHeader('Access-Control-Allow-Origin', '*'); } if (method === 'OPTIONS') { res.statusCode = 204; addOptionsHeaders(bundle); } else { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); } for (const action of actions) { payload = await action(bundle); if (res.writableEnded || payload !== undefined) { break; } } await finalize(renderers, bundle, payload); } export async function renderError(route, bundle, error) { const { errorHandlers, renderers } = route; const { res, logger } = bundle; const errorHandler = findErrorHandler(errorHandlers, getContentType(bundle)); const ex = unknownToEx(error); res.statusCode = ex.statusCode; const payload = await errorHandler(ex, bundle); await finalize(renderers, bundle, payload); if (res.statusCode === 500) { logger.error(error); } } function getContentType({ res }) { return String(res.getHeader('Content-Type') ?? 'text/plain'); } function addOptionsHeaders({ req, res, methods }) { const allowMethods = methods.join(', '); const allowHeaders = req.headers['access-control-request-headers']; if (allowMethods) { res.setHeader('Valid', allowMethods); res.setHeader('Access-Control-Allow-Methods', allowMethods); } if (allowHeaders) { res.setHeader('Access-Control-Allow-Headers', allowHeaders); } res.setHeader('Content-Length', 0); } async function finalize(renderers, bundle, payload) { const { res } = bundle; if (!res.writableEnded && payload !== undefined) { const renderer = findRenderer(renderers, getContentType(bundle)); await renderer(payload, bundle); } }