UNPKG

workery

Version:

Modern web framework for building APIs on Cloudflare Workers.

2 lines (1 loc) 5.58 kB
"use strict";var e=require("zod"),t=require("./responses.cjs"),s=require("./parameters.cjs");const r=new Set(["accept-encoding","accept-language","accept","authorization","connection","content-length","content-type","cookie","host","if-modified-since","if-none-match","keep-alive","origin","proxy-authenticate","proxy-authorization","referer","set-cookie","transfer-encoding","upgrade","user-agent","cf-connecting-ip","cf-ipcountry","cf-ray","cf-visitor","x-forwarded-for","x-real-ip","cf-pseudo-ipv4","cf-connecting-ipv6","cdn-loop","cf-worker"]);function i(e){return 0==e.length||"/"==e?"/":("/"!==e[0]&&(e="/"+e),e.startsWith("//")&&(e=e.slice(1)),"/"===e[e.length-1]&&(e=e.slice(0,-1)),e)}function o(e,t){return[{GET:"Read",POST:"Create",PUT:"Update",PATCH:"Modify",DELETE:"Delete",HEAD:"Head",OPTIONS:"Check",TRACE:"Trace"}[e],...t.split("/").map((e=>e&&e[0].toUpperCase()+e.slice(1))).filter((e=>e&&!(e.startsWith("{")&&e.endsWith("}"))))].join(" ")}class n{method;path;name;tags;summary;description;deprecated;responses;security;statusCode;includeInSchema;responseClass;middleware;parameters;handle;constructor(e){this.method=e.method,this.path=i(e.path),this.name=e.name,this.tags=e.tags??[],this.summary=e.summary??o(this.method,this.path),this.description=e.description??"",this.deprecated=e.deprecated??!1,this.responses=e.responses??{},this.security=e.security,this.includeInSchema=e.includeInSchema??!0,this.statusCode=e.statusCode??200,this.responseClass=e.responseClass??t.JSONResponse,this.middleware=e.middleware??[],this.parameters=e.parameters,this.handle=e.handle}openapi(){const t={},s=e=>{for(const[r,i]of Object.entries(e))"$depends"==i.location?s(i.dependency.parameters):t[r]=i};let i;s(this.parameters);const o={path:{},query:{},header:{},cookie:{}};for(const[e,s]of Object.entries(t))void 0===s.options.includeInSchema&&("header"==s.location&&r.has(e.replace(/_/g,"-").toLowerCase())?s.options.includeInSchema=!1:s.options.includeInSchema=!0),s.options.includeInSchema&&("body"==s.location?i=s:"header"==s.location?o[s.location][s.options.altName??e.replace(/_/g,"-")]=s.schema:o[s.location][s.options.altName??e]=s.schema);let n;return i&&(n=i.schemaOr?{description:i.options.description,content:{[i.options?.mediaType]:{schema:i.schemaOr===String?{type:"string"}:{type:"string",format:"binary"}}}}:{description:i.options.description??i.schema?._def.openapi?.metadata?.description,content:{[i.options?.mediaType]:{schema:i.schema}}}),{method:this.method.toLowerCase(),path:this.path,tags:this.tags,summary:this.summary,description:this.description,security:this.security,deprecated:this.deprecated,request:{body:n,params:e.z.object(o.path),query:e.z.object(o.query),headers:e.z.object(o.header),cookies:e.z.object(o.cookie)},responses:this.responses}}}class a{inner;name;routes;middleware;paramNames;constructor(e){this.inner={},this.name=e,this.routes={},this.paramNames=[],this.middleware=[]}touch(e){return this.inner[e]||=new a(e),this.inner[e]}match(e){return this.inner[e]??this.inner["{}"]}}class c{routes;tree;constructor(){this.routes=[],this.tree=new a("")}*[Symbol.iterator](){for(const e of this.routes)yield e}get length(){return this.routes.length}get(e){const t=i(e).split("/").slice(1);let s=this.tree;const r=[];for(let[e,i]of t.entries())if("{"==i[0]&&"}"==i[i.length-1]&&(r.push(i.slice(1,-1)),i="{}"),s=s.touch(i),e==t.length-1)return s.paramNames=r,s;return s}set(e,t){let s;return s=null===e?this.tree:this.get(e),t.middleware&&(s.middleware=t.middleware),s}push(...e){this.routes.push(...e);for(const t of e){this.get(t.path).routes[t.method]=t}return this.length}match(e,t){const s=i(t).split("/").slice(1),r=[],o=[...this.tree.middleware];let n=this.tree;for(const[t,i]of s.entries()){let a=n.match(i);if(!a)return[void 0,{},o];if(n=a,o.push(...n.middleware),"{}"==n.name&&r.push(i),t==s.length-1){if(!n.routes[e])return 0==Object.keys(n.routes).length?[void 0,{},o]:[null,{allow:Object.keys(n.routes).join(", ")},o];const t={};for(let e=0;e<n.paramNames.length;e++)t[n.paramNames[e]]=r[e];return o.push(...n.routes[e].middleware),[n.routes[e],t,o]}}return[void 0,{},o]}}exports.Route=n,exports.RouteMatcher=c,exports.RouteNode=a,exports.Router=class{tags;deprecated;includeInSchema;responses;security;defaultResponseClass;middleware;routeMatcher;constructor(r){this.tags=r.tags??[],this.deprecated=r.deprecated??!1,this.includeInSchema=r.includeInSchema??!0,this.defaultResponseClass=r.defaultResponseClass??t.JSONResponse,this.middleware=r.middleware??[],this.responses=r.responses??{422:s.Responds(e.z.object({detail:e.z.array(e.z.object({location:e.z.string(),name:e.z.string(),issues:e.z.array(e.z.any())}))}),{description:"Validation Error",mediaType:"application/json"})},this.security=r.security,this.routeMatcher=new c}get(e,t){return this.route("GET",e,t)}post(e,t){return this.route("POST",e,t)}put(e,t){return this.route("PUT",e,t)}delete(e,t){return this.route("DELETE",e,t)}patch(e,t){return this.route("PATCH",e,t)}head(e,t){return this.route("HEAD",e,t)}trace(e,t){return this.route("TRACE",e,t)}options(e,t){return this.route("OPTIONS",e,t)}route(e,t,s){const r=new n({method:e,path:t,deprecated:this.deprecated,includeInSchema:this.includeInSchema,responseClass:this.defaultResponseClass,security:this.security,...s,tags:[...this.tags,...s.tags??[]],responses:{...this.responses,...s.responses}});return this.routeMatcher.push(r),r}},exports.fixPathSlashes=i,exports.generateRouteSummary=o,exports.searchParamsToQueries=function(e){const t={};for(const[s,r]of e.entries())t[s]||=[],t[s].push(r);return t};