UNPKG

itty-router

Version:

A tiny, zero-dependency router, designed to make beautiful APIs in any environment.

2 lines (1 loc) 4.05 kB
const e=({base:e="",routes:t=[],...r}={})=>({__proto__:new Proxy({},{get:(r,o,a,s)=>(r,...c)=>t.push([o.toUpperCase(),RegExp(`^${(s=(e+r).replace(/\/+(\/|$)/g,"$1")).replace(/(\/?\.?):(\w+)\+/g,"($1(?<$2>*))").replace(/(\/?\.?):(\w+)/g,"($1(?<$2>[^$1/]+?))").replace(/\./g,"\\.").replace(/(\/?)\*/g,"($1.*)?")}/*$`),c,s])&&a}),routes:t,...r,async fetch(e,...r){let o,a,s=new URL(e.url),c=e.query={__proto__:null};for(let[e,t]of s.searchParams)c[e]=c[e]?[].concat(c[e],t):t;for(let[c,n,l,i]of t)if((c==e.method||"ALL"==c)&&(a=s.pathname.match(n))){e.params=a.groups||{},e.route=i;for(let t of l)if(null!=(o=await t(e.proxy??e,...r)))return o}}}),t=({base:e="",routes:t=[],...r}={})=>({__proto__:new Proxy({},{get:(r,o,a,s)=>(r,...c)=>t.push([o.toUpperCase?.(),RegExp(`^${(s=(e+r).replace(/\/+(\/|$)/g,"$1")).replace(/(\/?\.?):(\w+)\+/g,"($1(?<$2>*))").replace(/(\/?\.?):(\w+)/g,"($1(?<$2>[^$1/]+?))").replace(/\./g,"\\.").replace(/(\/?)\*/g,"($1.*)?")}/*$`),c,s])&&a}),routes:t,...r,async fetch(e,...o){let a,s,c=new URL(e.url),n=e.query={__proto__:null};for(let[e,t]of c.searchParams)n[e]=n[e]?[].concat(n[e],t):t;e:try{for(let t of r.before||[])if(null!=(a=await t(e.proxy??e,...o)))break e;t:for(let[r,n,l,i]of t)if((r==e.method||"ALL"==r)&&(s=c.pathname.match(n))){e.params=s.groups||{},e.route=i;for(let t of l)if(null!=(a=await t(e.proxy??e,...o)))break t}}catch(t){if(!r.catch)throw t;a=await r.catch(t,e.proxy??e,...o)}try{for(let t of r.finally||[])a=await t(a,e.proxy??e,...o)??a}catch(t){if(!r.catch)throw t;a=await r.catch(t,e.proxy??e,...o)}return a}}),r=(e="text/plain; charset=utf-8",t)=>(r,o={})=>{if(void 0===r||r instanceof Response)return r;const a=new Response(t?.(r)??r,o.url?void 0:o);return a.headers.set("content-type",e),a},o=r("application/json; charset=utf-8",JSON.stringify),a=e=>({400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",500:"Internal Server Error"}[e]||"Unknown Error"),s=(e=500,t)=>{if(e instanceof Error){const{message:r,...o}=e;e=e.status||500,t={error:r||a(e),...o}}return t={status:e,..."object"==typeof t?t:{error:t||a(e)}},o(t,{status:e})},c=e=>{e.proxy=new Proxy(e.proxy??e,{get:(t,r)=>t[r]?.bind?.(e)??t[r]??t?.params?.[r]})},n=({format:e=o,missing:r=(()=>s(404)),finally:a=[],before:n=[],...l}={})=>t({before:[c,...n],catch:s,finally:[(e,...t)=>e??r(...t),e,...a],...l});class l extends Error{status;constructor(e=500,t){super("object"==typeof t?t.error:t),"object"==typeof t&&Object.assign(this,t),this.status=e}}const i=(e,t)=>new Response(null,{...t,status:e}),p=r("text/plain; charset=utf-8",String),f=r("text/html"),u=r("image/jpeg"),h=r("image/png"),g=r("image/webp"),d=async e=>{e.content=e.body?await e.clone().json().catch((()=>e.clone().formData())).catch((()=>e.text())):void 0},w=e=>{e.cookies=(e.headers.get("Cookie")||"").split(/;\s*/).map((e=>e.split(/=(.+)/))).reduce(((e,[t,r])=>r?(e[t]=r,e):e),{})},y=(e={})=>{const{origin:t="*",credentials:r=!1,allowMethods:o="*",allowHeaders:a,exposeHeaders:s,maxAge:c}=e,n=e=>{const o=e?.headers.get("origin");return!0===t?o:t instanceof RegExp?t.test(o)?o:void 0:Array.isArray(t)?t.includes(o)?o:void 0:t instanceof Function?t(o):"*"==t&&r?o:t},l=(e,t)=>{for(const[r,o]of Object.entries(t))o&&e.headers.append(r,o);return e};return{corsify:(e,t)=>e?.headers?.get("access-control-allow-origin")||101==e.status?e:l(e.clone(),{"access-control-allow-origin":n(t),"access-control-allow-credentials":r}),preflight:e=>{if("OPTIONS"==e.method){const t=new Response(null,{status:204});return l(t,{"access-control-allow-origin":n(e),"access-control-allow-methods":o?.join?.(",")??o,"access-control-expose-headers":s?.join?.(",")??s,"access-control-allow-headers":a?.join?.(",")??a??e.headers.get("access-control-request-headers"),"access-control-max-age":c,"access-control-allow-credentials":r})}}}};export{n as AutoRouter,e as IttyRouter,t as Router,l as StatusError,y as cors,r as createResponse,s as error,f as html,u as jpeg,o as json,h as png,i as status,p as text,g as webp,d as withContent,w as withCookies,c as withParams};