Skip to main content
Module

x/opine/src/router/layer.ts

Minimalist web framework for Deno ported from ExpressJS.
Latest
File
import { pathToRegexp } from "../utils/pathToRegex.ts";import type { NextFunction, OpineRequest, OpineResponse } from "../types.ts";
export const Layer: any = function Layer( this: any, path: any, options: any = {}, fn: any,) { if (!(this instanceof Layer)) { return new (Layer as any)(path, options, fn); }
(this as any).handle = fn; (this as any).name = fn.name || "<anonymous>"; (this as any).params = undefined; (this as any).path = undefined; (this as any).regexp = pathToRegexp(path, (this as any).keys = [], options);
// set fast path flags (this as any).regexp.fast_star = path === "*"; (this as any).regexp.fast_slash = path === "/" && options.end === false;};
/** * Handle the error for the layer. * * @param {Error|string} error * @param {OpineRequest} req * @param {OpineResponse} res * @param {NextFunction} next * @private */
Layer.prototype.handle_error = async function handle_error( error: any, req: OpineRequest, res: OpineResponse, next: NextFunction,) { let fn = this.handle;
if (fn.length !== 4) { // not a standard error handler return next(error); }
try { await fn(error, req, res, next); } catch (err) { next(err); }};
/** * Handle the request for the layer. * * @param {OpineRequest} req * @param {OpineResponse} res * @param {NextFunction} next * @private */Layer.prototype.handle_request = async function handle( req: OpineRequest, res: OpineResponse, next: NextFunction,) { let fn = this.handle;
if (fn.length > 3) { // not a standard request handler return next(); }
try { await fn(req, res, next); } catch (err) { next(err); }};
/** * Check if this route matches `path`, if so * populate `.params`. * * @param {String} path * @return {Boolean} * @private */Layer.prototype.match = function match(path: any) { let match;
if (path != null) { // fast path non-ending match for / (any path matches) if (this.regexp.fast_slash) { this.params = {}; this.path = ""; return true; }
// fast path for * (everything matched in a param) if (this.regexp.fast_star) { this.params = { "0": decode_param(path) }; this.path = path; return true; }
// match the path match = this.regexp.exec(path); }
if (!match) { this.params = undefined; this.path = undefined; return false; }
// store values this.params = {}; this.path = match[0];
let keys = this.keys; let params = this.params;
for (let i = 1; i < match.length; i++) { let key = keys[i - 1]; let prop = key.name; let val = decode_param(match[i]);
if ( val !== undefined || !(Object.prototype.hasOwnProperty.call(params, prop)) ) { params[prop] = val; } }
return true;};
/** * Decode param value. * * @param {string} val * @return {string} * @private */function decode_param(val: any) { if (typeof val !== "string" || val.length === 0) { return val; }
try { return decodeURIComponent(val); } catch (err) { if (err instanceof URIError) { err.message = "Failed to decode param '" + val + "'"; (err as any).status = 400; }
throw err; }}