UNPKG

@whatwg-node/router

Version:
138 lines (133 loc) 5.1 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const server = require('@whatwg-node/server'); const fetch = require('@whatwg-node/fetch'); const HTTP_METHODS = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH']; function createRouter(options) { var _a; const routesByMethod = new Map(); function addHandlersToMethod(method, path, ...handlers) { let methodPatternMaps = routesByMethod.get(method); if (!methodPatternMaps) { methodPatternMaps = new Map(); routesByMethod.set(method, methodPatternMaps); } const basePath = (options === null || options === void 0 ? void 0 : options.base) || '/'; let fullPath = ''; if (basePath === '/') { fullPath = path; } else if (path === '/') { fullPath = basePath; } else { fullPath = `${basePath}${path}`; } const pattern = new fetch.URLPattern({ pathname: fullPath }); methodPatternMaps.set(pattern, handlers); } async function handleRequest(request, context) { const method = request.method; let _parsedUrl; function getParsedUrl() { if (!_parsedUrl) { _parsedUrl = new URL(request.url); } return _parsedUrl; } const methodPatternMaps = routesByMethod.get(method); if (methodPatternMaps) { const queryProxy = new Proxy({}, { get(_, prop) { const parsedUrl = getParsedUrl(); const allQueries = parsedUrl.searchParams.getAll(prop.toString()); return allQueries.length === 1 ? allQueries[0] : allQueries; }, has(_, prop) { const parsedUrl = getParsedUrl(); return parsedUrl.searchParams.has(prop.toString()); }, }); for (const [pattern, handlers] of methodPatternMaps) { const match = pattern.exec(request.url); if (match) { const routerRequest = new Proxy(request, { get(target, prop) { if (prop === 'parsedUrl') { return getParsedUrl(); } if (prop === 'params') { return match.pathname.groups; } if (prop === 'query') { return queryProxy; } const targetProp = target[prop]; if (typeof targetProp === 'function') { return targetProp.bind(target); } return targetProp; }, has(target, prop) { return prop in target || prop === 'parsedUrl' || prop === 'params' || prop === 'query'; }, }); for (const handler of handlers) { const result = await handler(routerRequest, context); if (result) { return result; } } } } } } let routerBaseObject = new Proxy({}, { get(_, prop) { if (prop === 'handle') { return handleRequest; } const method = prop.toString().toLowerCase(); return function routeMethodKeyFn(path, ...handlers) { if (method === 'all') { for (const httpMethod of HTTP_METHODS) { addHandlersToMethod(httpMethod, path, ...handlers); } } else { addHandlersToMethod(method.toUpperCase(), path, ...handlers); } return this; }; }, }); (_a = options === null || options === void 0 ? void 0 : options.plugins) === null || _a === void 0 ? void 0 : _a.forEach(plugin => { routerBaseObject = plugin(routerBaseObject); }); return server.createServerAdapter(routerBaseObject, (options === null || options === void 0 ? void 0 : options.RequestCtor) || fetch.Request); } Object.defineProperty(exports, 'withCORS', { enumerable: true, get: function () { return server.withCORS; } }); Object.defineProperty(exports, 'withErrorHandling', { enumerable: true, get: function () { return server.withErrorHandling; } }); Object.defineProperty(exports, 'Response', { enumerable: true, get: function () { return fetch.Response; } }); Object.defineProperty(exports, 'URLPattern', { enumerable: true, get: function () { return fetch.URLPattern; } }); exports.createRouter = createRouter;