edge-master
Version:
A Micro Framework for Edges
2 lines (1 loc) • 2.66 kB
JavaScript
"use strict";import{InterceptorType as p}from"./types/interceptor";import{and as n,httpMethod as o,pathStartWith as i}from"./Utils";export class EdgeController{constructor(){this._reqInterceptors=[],this._hasReqInterceptor=!1,this._resInterceptors=[],this._hasResInterceptor=!1,this._routes=[]}async interceptRequest(t){if(!this._hasReqInterceptor)return t.reqCtx.req;let e=new Request(t.reqCtx.req);for(const r of this._reqInterceptors)try{e=await r.intercept({...t,reqCtx:{...t.reqCtx,req:e}})}catch(s){throw console.error(`Request interceptor error: ${s}`),s}return e}async interceptResponse(t){if(!this._hasResInterceptor)return t.res;let e=t.res;for(const r of this._resInterceptors)try{e=await r.intercept({...t,res:e})}catch(s){throw console.error(`Response interceptor error: ${s}`),s}return e}async handleRoutes(t){const e=this._routes.find(r=>r.matcher(t.req));return e?e.routeHandler.execute(t):this._notFoundHandler?this._notFoundHandler(t):new Response("Not Found",{status:404})}addRoute(t,e,r=0){return this._routes.push({matcher:t,routeHandler:e,priority:r}),this._routes.sort((s,a)=>(a.priority||0)-(s.priority||0)),this}addInterceptor(t){return t.type===p.Request&&(this._reqInterceptors.push(t),this._hasReqInterceptor||(this._hasReqInterceptor=!0)),t.type===p.Response&&(this._resInterceptors.push(t),this._hasResInterceptor||(this._hasResInterceptor=!0)),this}onNotFound(t){return this._notFoundHandler=t,this}onError(t){return this._errorHandler=t,this}GET(t,e){return this.addRoute(n(o("GET"),i(t)),e)}POST(t,e){return this.addRoute(n(o("POST"),i(t)),e)}PUT(t,e){return this.addRoute(n(o("PUT"),i(t)),e)}DELETE(t,e){return this.addRoute(n(o("DELETE"),i(t)),e)}PATCH(t,e){return this.addRoute(n(o("PATCH"),i(t)),e)}HEAD(t,e){return this.addRoute(n(o("HEAD"),i(t)),e)}OPTIONS(t,e){return this.addRoute(n(o("OPTIONS"),i(t)),e)}group(t,e){const r=new EdgeController;e(r);for(const s of r._routes){const a=h=>{const u=new URL(h.url);if(u.pathname.startsWith(t)){const c=new URL(h.url);c.pathname=u.pathname.substring(t.length)||"/";const d=new Request(c,h);return s.matcher(d)}return!1};this._routes.push({matcher:a,routeHandler:s.routeHandler})}return this}async handleRequest(t){return new Promise(async e=>{const r=new Map;try{e(await this.interceptResponse({reqCtx:t,responder:e,state:r,res:await this.handleRoutes({req:await this.interceptRequest({reqCtx:t,responder:e,state:r}),reqCtx:t,responder:e,state:r})}))}catch(s){if(this._errorHandler)try{e(await this._errorHandler(s,{reqCtx:t,responder:e,state:r}))}catch{e(new Response("Internal Server Error",{status:500}))}else e(new Response("Internal Server Error",{status:500}))}})}}