UNPKG

url-route-handler

Version:

The library provides a flexible and efficient way to map URL patterns to their respective handler methods. By defining a set of URL patterns and the corresponding handler functions, this package allows seamless routing, ensuring that each url is processed

136 lines (131 loc) 3.79 kB
'use strict'; var pathToRegexp = require('path-to-regexp'); class RouteLayer { handle; name; params; path; regexp; keys; constructor(path, options, callback) { options = options || {}; this.handle = callback; this.name = callback.name || '<anonymous>'; const { regexp, keys } = pathToRegexp.pathToRegexp(path, options); this.regexp = regexp; this.keys = keys; } match(path) { let match; if (path != null) { if (path === '/') { this.params = {}; this.path = ''; return true; } if (path === '/*') { this.params = { '0': decodeParam(path) }; this.path = path; return true; } match = this.regexp.exec(path); } if (!match) { this.params = undefined; this.path = undefined; return false; } this.params = {}; this.path = match[0]; var keys = this.keys; var params = this.params; for (var i = 1; i < match.length; i++) { var key = keys[i - 1]; var prop = key.name; var val = decodeParam(match[i]); if (val !== undefined || !(Object.hasOwnProperty.call(params, prop))) { params[prop] = val; } } return true; } handleError(err) { return { status: 'error', message: err.message, }; } handleRequest(urlObj, ...args) { try { const result = this.handle(urlObj, ...args); if (isPromise(result)) { return result.then((res) => { return { status: 'success', data: res, }; }).catch((err) => { return this.handleError(err); }); } return { status: 'success', data: result, }; } catch (err) { return this.handleError(err); } } } function isPromise(obj) { return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; } function decodeParam(val) { 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.status = 400; } throw err; } } class Router { layers = []; use(path, callback) { this.layers.push(new RouteLayer(path, {}, callback)); } handle(url, ...args) { const urlObj = new URL(url, 'http://localhost'); for (const layer of this.layers) { if (layer.match(urlObj.pathname)) { const queryParam = {}; urlObj.searchParams?.forEach((value, key) => { queryParam[key] = value; }); return layer.handleRequest({ url: urlObj.href, host: urlObj.host, origin: urlObj.origin, pathname: urlObj.pathname, protocol: urlObj.protocol, query: queryParam, params: { ...layer.params }, hash: urlObj.hash?.slice(1), }, ...args); } } return { status: 'error', message: 'No route found', }; } } exports.Router = Router; //# sourceMappingURL=index.cjs.map