@cleverbrush/server 4.3.1 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -2
- package/dist/ActionResult.d.ts +25 -0
- package/dist/ContentNegotiator.d.ts +11 -0
- package/dist/Endpoint.d.ts +4 -4
- package/dist/Server.d.ts +8 -0
- package/dist/{chunk-BNRQFILU.js → chunk-LWRLB46M.js} +1 -1
- package/dist/chunk-LWRLB46M.js.map +1 -0
- package/dist/contract.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-BNRQFILU.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as Se,b as Re,c as ve,d as we,e as ie,f as Pe,g as Te,h as Ce,i as Be,j as xe,k as Ae,l as Me,m as Ee,n as ke,o as _e}from"./chunk-BNRQFILU.js";var C=class{static ok(e,t){return new P(e,200,t)}static created(e,t,r){let n={...r};return t&&(n.location=t),new P(e,201,n)}static accepted(e,t){return new P(e,202,t)}static noContent(){return new I}static badRequest(e,t){return new P(e,400,t)}static unauthorized(e,t){return new P(e,401,t)}static forbidden(e,t){return new P(e,403,t)}static notFound(e,t){return new P(e,404,t)}static conflict(e,t){return new P(e,409,t)}static redirect(e,t=!1){return new D(e,t)}static json(e,t=200,r){return new P(e,t,r)}static file(e,t,r="application/octet-stream"){return new H(e,t,r)}static content(e,t,r=200){return new N(e,t,r)}static stream(e,t,r){return new O(e,t,r)}static status(e,t){return new F(e,t)}},P=class extends C{body;status;headers;constructor(e,t=200,r){super(),this.body=e,this.status=t,this.headers=r??{}}async executeAsync(e,t,r){for(let[n,o]of Object.entries(this.headers))t.setHeader(n,o);if(this.body===null||this.body===void 0){t.writeHead(this.status),t.end();return}t.writeHead(this.status,{"content-type":"application/json"}),t.end(JSON.stringify(this.body))}},H=class extends C{content;fileName;contentType;constructor(e,t,r="application/octet-stream"){super(),this.content=e,this.fileName=t,this.contentType=r}async executeAsync(e,t,r){let n=this.fileName,o=n.replace(/[^\x20-\x7E]/g,"_"),s=o===n?`attachment; filename="${n}"`:`attachment; filename="${o}"; filename*=UTF-8''${encodeURIComponent(n)}`;t.writeHead(200,{"content-type":this.contentType,"content-disposition":s,"content-length":String(this.content.byteLength)}),t.end(this.content)}},N=class extends C{body;contentType;status;constructor(e,t,r=200){super(),this.body=e,this.contentType=t,this.status=r}async executeAsync(e,t,r){t.writeHead(this.status,{"content-type":this.contentType}),t.end(this.body)}},O=class extends C{readable;contentType;fileName;constructor(e,t,r){super(),this.readable=e,this.contentType=t,this.fileName=r}async executeAsync(e,t,r){let n={"content-type":this.contentType};this.fileName&&(n["content-disposition"]=`attachment; filename="${this.fileName}"`),t.writeHead(200,n),await new Promise((o,s)=>{this.readable.on("error",s),t.on("error",s),this.readable.on("end",o),this.readable.pipe(t,{end:!0})})}},F=class extends C{status;headers;constructor(e,t){super(),this.status=e,this.headers=t??{}}async executeAsync(e,t,r){t.writeHead(this.status,this.headers),t.end()}},D=class extends C{url;permanent;constructor(e,t=!1){super(),this.url=e,this.permanent=t}async executeAsync(e,t,r){t.writeHead(this.permanent?301:302,{location:this.url}),t.end()}},I=class extends C{async executeAsync(e,t,r){t.writeHead(204),t.end()}};var je={400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",409:"Conflict",415:"Unsupported Media Type",422:"Unprocessable Content",500:"Internal Server Error",503:"Service Unavailable"};function S(i,e,t,r){return{type:`https://httpstatuses.com/${i}`,status:i,title:e??je[i]??"Error",...t!==void 0?{detail:t}:{},...r}}function G(i){return S(400,"Bad Request","One or more validation errors occurred.",{errors:i})}function v(i){return JSON.stringify(i)}var w="application/problem+json";var T=class extends Error{status;title;detail;extensions;constructor(e,t,r,n){super(r??t??`HTTP ${e}`),this.name="HttpError",this.status=e,this.title=t??`HTTP ${e}`,this.detail=r,this.extensions=n}toProblemDetails(){return S(this.status,this.title,this.detail,this.extensions)}},X=class extends T{constructor(e){super(404,"Not Found",e),this.name="NotFoundError"}},K=class extends T{constructor(e){super(400,"Bad Request",e),this.name="BadRequestError"}},Y=class extends T{constructor(e){super(401,"Unauthorized",e),this.name="UnauthorizedError"}},Z=class extends T{constructor(e){super(403,"Forbidden",e),this.name="ForbiddenError"}},Q=class extends T{constructor(e){super(409,"Conflict",e),this.name="ConflictError"}};function qe(i){return["POST","PUT","DELETE","PATCH"].includes(i.toUpperCase())}var He=6e4;function Ne(i={}){let{ttl:e=864e5,headerName:t="x-idempotency-key",skip:r=s=>!qe(s.method)}=i,n=new Map,o=setInterval(()=>{let s=Date.now();for(let[c,d]of n)d.expiresAt<=s&&n.delete(c)},He);return o.unref&&o.unref(),async(s,c)=>{if(r(s))return c();let d=s.headers[t]??s.headers[t.toLowerCase()];if(!d||typeof d!="string"||d.length===0)return c();let a=n.get(d);if(a)if(a.expiresAt<=Date.now())n.delete(d);else{let u=s.response;u.writeHead(a.status,a.headers),u.end(a.body),s.responded=!0;return}let f=s.response.writeHead.bind(s.response),m=s.response.end.bind(s.response),p=200,y={},h=[];if(s.response.writeHead=function(u,...l){return p=u,l.length>0&&(y=l[0]),f(u,...l)},s.response.end=function(u,...l){return u&&h.push(Buffer.isBuffer(u)?u:Buffer.from(u)),m(u,...l)},await c(),p>=200&&p<500){let u=Buffer.concat(h);n.set(d,{status:p,headers:y,body:u,expiresAt:Date.now()+e})}}}function Oe(i){return["POST","PUT","DELETE","PATCH"].includes(i.toUpperCase())}function ae(i,e){return i.map(t=>{let r=[];for(let[n,o]of Object.entries(t.properties).sort(([s],[c])=>s.localeCompare(c))){let s=o.getValue(e);s.success&&s.value!==void 0&&r.push(`${n}=${String(s.value)}`)}return r.length>0?`${t.name}:${r.join(",")}`:t.name})}function Fe(i={}){let{ttlByTag:e={},defaultTtl:t=6e4}=i,r=new Map;return async(n,o)=>{let c=n.items.get("__endpoint_meta")?.cacheTags??[];if(c.length===0)return o();if(Oe(n.method)){if(await o(),n.response.statusCode>=200&&n.response.statusCode<300){let d=n.items.get("__raw_body"),a={params:n.pathParams??{},body:d,query:n.queryParams??{},headers:n.headers??{}},f=ae(c,a);for(let m of c){for(let[p]of r)(f.includes(p)||f.some(y=>p.startsWith(m.name)))&&r.delete(p);for(let[p]of r)p.startsWith(m.name)&&r.delete(p)}}return}if(n.method==="GET"){let d={params:n.pathParams??{},body:void 0,query:n.queryParams??{},headers:n.headers??{}},a=ae(c,d);for(let u of a){let l=r.get(u);if(l&&l.expiresAt>Date.now()){let g=n.response;g.writeHead(l.status,l.headers),g.end(l.body),n.responded=!0;return}l&&r.delete(u)}let f=n.response.writeHead.bind(n.response),m=n.response.end.bind(n.response),p=200,y={},h=[];if(n.response.writeHead=function(u,...l){return p=u,l.length>0&&(y=l[0]),f(u,...l)},n.response.end=function(u,...l){return u&&h.push(Buffer.isBuffer(u)?u:Buffer.from(u)),m(u,...l)},await o(),p>=200&&p<300){let u=Buffer.concat(h),l=c.reduce((g,R)=>{let b=e[R.name]!==void 0?e[R.name]:t;return b>g?b:g},0);if(l>0)for(let g of a)r.set(g,{status:p,headers:y,body:u,expiresAt:Date.now()+l})}return}return o()}}import{URL as De}from"url";import{any as te,boolean as Ie,func as de,object as ze,promise as ce,record as re,string as A}from"@cleverbrush/schema";function B(i){return JSON.parse(i,(e,t)=>{if(!(e==="__proto__"||e==="constructor"))return t})}function x(i,e=64){ee(i,0,e)}function ee(i,e,t){if(!(i===null||typeof i!="object")){if(e>=t)throw new Error(`JSON nesting depth exceeds maximum of ${t}`);if(Array.isArray(i))for(let r of i)ee(r,e+1,t);else for(let r of Object.values(i))ee(r,e+1,t)}}var Je=ze({method:A(),url:A(),pathParams:re(A(),A()),queryParams:re(A(),A()),headers:re(A(),A()),items:te(),body:de().hasReturnType(ce(te())),json:de().hasReturnType(ce(te())),responded:Ie()}),j=5*1024*1024,E=class{request;response;url;method;headers;items=new Map;maxBodySize;#e={};_queryParams;#t;#r=null;#s=!1;#o=void 0;#d=!1;responded=!1;principal=void 0;constructor(e,t,r){this.request=e,this.response=t,this.method=(e.method??"GET").toUpperCase(),this.maxBodySize=r??j;let n=e.url??"/";this.url=new De(n,`http://${e.headers.host??"localhost"}`);let o={};for(let[s,c]of Object.entries(e.headers))typeof c=="string"?o[s]=c:Array.isArray(c)&&(o[s]=c.join(", "));this.headers=o}get pathParams(){return this.#e}set pathParams(e){this.#e=e}get queryParams(){if(this._queryParams)return this._queryParams;let e={};for(let[t,r]of this.url.searchParams)e[t]=r;return e}get services(){return this.#t}set services(e){this.#t=e}async body(){return this.#s?this.#r:(this.#r=await new Promise((e,t)=>{let r=[],n=0;this.request.on("data",o=>{if(n+=o.length,n>this.maxBodySize){this.request.destroy(),t(new T(413,"Payload Too Large"));return}r.push(o)}),this.request.on("end",()=>e(Buffer.concat(r))),this.request.on("error",t)}),this.#s=!0,this.#r)}async json(){if(this.#d)return this.#o;let t=(await this.body()).toString("utf-8");return t.length>0&&(this.#o=B(t),x(this.#o)),this.#d=!0,this.#o}};import*as V from"http";import*as ge from"https";import{AuthorizationService as Ve,PolicyBuilder as Ge,Principal as q,parseCookies as Xe,requireRole as Ke}from"@cleverbrush/auth";import{ServiceCollection as Ye}from"@cleverbrush/di";import{Busboy as Ze}from"@fastify/busboy";import{WebSocketServer as Qe}from"ws";var Ue={mimeType:"application/json",serialize(i){return JSON.stringify(i)},deserialize(i){let e=B(i);return x(e),e}};function We(i){return i.split(",").map(e=>{let t=e.trim(),[r,...n]=t.split(";").map(s=>s.trim()),o=1;for(let s of n){let[c,d]=s.split("=");c?.trim()==="q"&&d&&(o=parseFloat(d),Number.isNaN(o)&&(o=1))}return{mimeType:r.toLowerCase(),quality:o}}).sort((e,t)=>t.quality-e.quality)}var z=class{#e=new Map;constructor(){this.register(Ue)}register(e){this.#e.set(e.mimeType.toLowerCase(),e)}selectResponseHandler(e){if(!e)return this.#e.get("application/json")??null;let t=We(e);for(let{mimeType:r}of t){if(r==="*/*")return this.#e.get("application/json")??null;let n=this.#e.get(r);if(n)return n}return null}selectRequestHandler(e){if(!e)return null;let t=e.split(";")[0].trim().toLowerCase();return this.#e.get(t)??null}};var k=class{#e=[];add(e){this.#e.push(e)}async execute(e,t){let r=0,n=async()=>{if(r<this.#e.length){let o=this.#e[r++];await o(e,n)}else await t()};await n()}};function le(i){return i.bodySchema!=null}async function ue(i,e,t,r){let n=[],o={};if(o.context=t,i.authRoles!==null&&t.principal!==void 0&&(o.principal=t.principal),e&&Object.keys(e).length>0&&(o.params=e),i.bodySchema){let s=await i.bodySchema.validateAsync(r,{doNotStopOnFirstError:!0});if(s.valid)o.body=s.object;else{let c=typeof s.getInvalidProperties=="function"?s.getInvalidProperties:null,d=!1;if(c)for(let a of c()){let f=a.descriptor.toJsonPointer();for(let m of a.errors)n.push({pointer:`/body${f}`,detail:m}),d=!0}if(!d)for(let a of s.errors??[])n.push({pointer:"/body",detail:a.message})}}if(i.querySchema){let s=i.querySchema.introspect();if(s.type!=="object"||!s.properties)throw new Error("Endpoint query schema must be an object schema whose properties map to query parameter names.");let c=s.properties,d={};for(let[a,f]of Object.entries(c)){let m=t.queryParams[a],p=await f.validateAsync(m,{doNotStopOnFirstError:!0});if(p.valid)d[a]=p.object;else for(let y of p.errors??[])n.push({pointer:`/query/${a}`,detail:y.message})}o.query=d}if(i.headerSchema){let s=i.headerSchema.introspect();if(s.type!=="object"||!s.properties)throw new Error("Endpoint headers schema must be an object schema whose properties map to header names.");let c=s.properties,d={};for(let[a,f]of Object.entries(c)){let m=t.headers[a.toLowerCase()],p=await f.validateAsync(m,{doNotStopOnFirstError:!0});if(p.valid)d[a]=p.object;else for(let y of p.errors??[])n.push({pointer:`/headers/${a}`,detail:y.message})}o.headers=d}if(n.length>0)return{valid:!1,problemDetails:G(n)};if(i.serviceSchemas){if(!t.services)throw new Error("Endpoint declares .inject() dependencies but no service provider is available. Register services via createServer().services() before handling this endpoint.");let s={};for(let[c,d]of Object.entries(i.serviceSchemas))s[c]=t.services.get(d);return{valid:!0,args:[o,s]}}return{valid:!0,args:[o]}}function _(i){let e=decodeURI(i);return e.length>1&&e.endsWith("/")?e.slice(0,-1):e}function pe(i){return typeof i!="string"&&typeof i.validate=="function"}var J=class{#e=new Map;#t=[];addRoute(e){let{method:t,basePath:r,pathTemplate:n}=e.endpoint,o=t.toUpperCase(),c={basePath:_(r),routePath:n,registration:e};this.#e.has(o)||this.#e.set(o,[]),this.#e.get(o).push(c)}match(e,t){let r;try{r=_(t)}catch{return{match:null,methodNotAllowed:!1,badRequest:!0}}let n=e.toUpperCase(),o=this.#e.get(n);if(o)for(let c of o){let d=this.#r(c,r);if(d)return{match:d,methodNotAllowed:!1}}let s=[];for(let[c,d]of this.#e)if(c!==n){for(let a of d)if(this.#r(a,r)){s.push(c);break}}return s.length>0?{match:null,methodNotAllowed:!0,allowedMethods:s}:{match:null,methodNotAllowed:!1}}#r(e,t){let{basePath:r,routePath:n}=e;if(r&&!t.startsWith(r))return null;let o=r?t.slice(r.length):t;if(pe(n)){let d=n.validate(o);return d.valid?{registration:e.registration,parsedPath:d.object}:null}let s=_(n);return(o.length===0?"/":o)===s?{registration:e.registration,parsedPath:null}:null}addSubscriptionRoute(e){let{basePath:t,pathTemplate:r}=e.endpoint,n=_(t);this.#t.push({basePath:n,routePath:r,registration:e})}matchSubscription(e){let t;try{t=_(e)}catch{return null}for(let r of this.#t){let{basePath:n,routePath:o}=r;if(n&&!t.startsWith(n))continue;let s=n?t.slice(n.length):t;if(pe(o)){let a=o.validate(s);if(a.valid)return{registration:r.registration,parsedPath:a.object};continue}let c=_(o);if((s.length===0?"/":s)===c)return{registration:r.registration,parsedPath:null}}return null}};import{Readable as Le,Writable as $e}from"stream";var U=class extends Le{method;url;headers;__cleverbrushBatchSubrequest;socket=null;#e;#t=!1;constructor(e){super(),this.method=e.method,this.url=e.url;let t={};for(let[r,n]of Object.entries(e.headers??{}))t[r.toLowerCase()]=n;this.headers={host:"localhost",...t},this.#e=e.body!=null&&e.body.length>0?Buffer.from(e.body,"utf-8"):Buffer.alloc(0)}_read(){this.#t||(this.#t=!0,this.#e.length>0&&this.push(this.#e),this.push(null))}},W=class extends $e{statusCode=200;headersSent=!1;#e=[];#t={};#r=200;_write(e,t,r){this.#e.push(Buffer.isBuffer(e)?e:Buffer.from(e)),r()}writeHead(e,t){if(this.#r=e,this.statusCode=e,t!=null&&typeof t=="object"&&!Array.isArray(t))for(let[r,n]of Object.entries(t))this.#t[r.toLowerCase()]=Array.isArray(n)?n.join(", "):String(n);return this.headersSent=!0,this}setHeader(e,t){return this.#t[e.toLowerCase()]=Array.isArray(t)?t.join(", "):String(t),this}getHeader(e){return this.#t[e.toLowerCase()]}end(e,...t){if(e!=null&&typeof e!="function"){let r=Buffer.isBuffer(e)||e instanceof Uint8Array?Buffer.from(e):Buffer.from(String(e),"utf-8");this.#e.push(r),super.end(...t)}else typeof e=="function"?super.end(e):super.end(...t);return this}toResult(){return{status:this.#r,headers:{...this.#t},body:Buffer.concat(this.#e).toString("utf-8")}}};function he(i){return{type:"message",data:i}}function fe(i,e){return{type:"tracked",id:i,data:e}}function me(){return{type:"pong"}}function M(i,e){return{type:"error",code:i,message:e}}function ye(i){let e;try{e=B(i),x(e)}catch{return null}if(typeof e!="object"||e===null)return null;let t=e;return t.type==="ping"?{type:"ping"}:t.type==="message"&&"data"in t?{type:"message",data:t.data}:null}async function et(i,e){let t=e.maxFileCount??10,r=e.maxFileSize??10*1024*1024,n=e.allowedMimeTypes;return new Promise((o,s)=>{let c={},d={},a=[],f=0,m=Ze({headers:i.headers,limits:{fileSize:r,files:t}});m.on("field",(p,y)=>{c[p]=y}),m.on("file",(p,y,h,u,l)=>{if(f>=t){a.push({filename:h,mimeType:l,reason:`Exceeded max file count (${t})`}),y.resume();return}if(n&&!n.some(b=>b.endsWith("/*")?l.startsWith(b.slice(0,-1)):l===b)){a.push({filename:h,mimeType:l,reason:`MIME type "${l}" not allowed (allowed: ${n.join(", ")})`}),y.resume();return}f++;let g=[];y.on("data",R=>{g.push(R)}),y.on("end",()=>{let R=Buffer.concat(g);d[p]={filename:h,mimeType:l,buffer:R,size:R.length}}),y.on("error",s)}),m.on("error",s),m.on("finish",()=>o({fields:c,files:d,rejectedFiles:a})),i.pipe(m)})}var L=class{#e=new Ye;#t=[];#r=[];#s=[];#o=[];#d=new z;#i;#a=null;#n=null;#c=!1;#l=null;constructor(e={}){this.#i=e}services(e){return e(this.#e),this}use(e){return this.#o.push(e),this}contentType(e){return this.#d.register(e),this}useAuthentication(e){return this.#a=e,this}useAuthorization(e){return this.#n=e??{},this}withHealthcheck(){return this.#c=!0,this}useBatching(e={}){return this.#l=e,this}handle(e,t,r){return this.#t.push({endpoint:e.introspect(),handler:t,middlewares:r?.middlewares}),this}handleAll(e){for(let t of e._entries)this.#t.push({endpoint:t.endpoint.introspect(),handler:t.handler,middlewares:t.middlewares});for(let t of e._subscriptions)this.#r.push({endpoint:t.endpoint.introspect(),handler:t.handler,middlewares:t.middlewares});return this}getRegistrations(){return[...this.#t]}getSubscriptionRegistrations(){return[...this.#r]}webhook(e){return this.#s.push(e),this}getWebhooks(){return[...this.#s]}getAuthenticationConfig(){return this.#a}async listen(e,t){let r=new J;for(let f of this.#t)r.addRoute(f);for(let f of this.#r)r.addSubscriptionRoute(f);let n=this.#e.buildServiceProvider({validateScopes:!1}),o=[];if(this.#a&&o.push(st(this.#a)),this.#n!==null){let f=new Map;if(this.#n.policies)for(let[p,y]of Object.entries(this.#n.policies)){let h=new Ge;y(h),f.set(p,h.build(p))}let m=new Ve(f);o.push(ot(m,this.#a))}let s=[...o,...this.#o],c=new $(r,n,this.#d,s,this.#c,this.#r.length>0,this.#l,this.#i.maxBodySize),d=e??this.#i.port??3e3,a=t??this.#i.host??"0.0.0.0";return await c.start(d,a,this.#i),c}},tt=1024,$=class{#e;#t;#r;#s;#o;#d;#i;#a;#n=null;#c=null;#l=new Set;constructor(e,t,r,n,o=!1,s=!1,c=null,d=j){this.#e=e,this.#t=t,this.#r=r,this.#s=n,this.#o=o,this.#d=s,this.#i=c,this.#a=d}async start(e,t,r){let n=(o,s)=>{this.#u(o,s).catch(c=>{s.headersSent||(s.writeHead(500,{"content-type":w}),s.end(v(S(500))))})};r.https?this.#n=ge.createServer({key:r.https.key,cert:r.https.cert},n):this.#n=V.createServer(n),await new Promise(o=>{this.#n.listen(e,t,o)}),this.#d&&(this.#c=new Qe({noServer:!0,maxPayload:this.#a}),this.#n.on("upgrade",(o,s,c)=>{let d=new URL(o.url??"/",`http://${o.headers.host??"localhost"}`).pathname,a=this.#e.matchSubscription(d);if(!a){s.write(`HTTP/1.1 404 Not Found\r
|
|
1
|
+
import{a as we,b as Pe,c as Te,d as Ce,e as ae,f as xe,g as Ae,h as Be,i as Me,j as ke,k as Ee,l as _e,m as je,n as He,o as qe}from"./chunk-LWRLB46M.js";var C=class{static ok(e,t){return new P(e,200,t)}static created(e,t,r){let n={...r};return t&&(n.location=t),new P(e,201,n)}static accepted(e,t){return new P(e,202,t)}static noContent(){return new z}static badRequest(e,t){return new P(e,400,t)}static unauthorized(e,t){return new P(e,401,t)}static forbidden(e,t){return new P(e,403,t)}static notFound(e,t){return new P(e,404,t)}static conflict(e,t){return new P(e,409,t)}static redirect(e,t=!1){return new I(e,t)}static json(e,t=200,r){return new P(e,t,r)}static file(e,t,r="application/octet-stream"){return new N(e,t,r)}static content(e,t,r=200){return new O(e,t,r)}static stream(e,t,r){return new F(e,t,r)}static raw(e){return new q(e)}static status(e,t){return new D(e,t)}},q=class extends C{handler;constructor(e){super(),this.handler=e}async executeAsync(e,t,r){await this.handler(e,t)}},P=class extends C{body;status;headers;constructor(e,t=200,r){super(),this.body=e,this.status=t,this.headers=r??{}}async executeAsync(e,t,r){for(let[n,i]of Object.entries(this.headers))t.setHeader(n,i);if(this.body===null||this.body===void 0){t.writeHead(this.status),t.end();return}t.writeHead(this.status,{"content-type":"application/json"}),t.end(JSON.stringify(this.body))}},N=class extends C{content;fileName;contentType;constructor(e,t,r="application/octet-stream"){super(),this.content=e,this.fileName=t,this.contentType=r}async executeAsync(e,t,r){let n=this.fileName,i=n.replace(/[^\x20-\x7E]/g,"_"),o=i===n?`attachment; filename="${n}"`:`attachment; filename="${i}"; filename*=UTF-8''${encodeURIComponent(n)}`;t.writeHead(200,{"content-type":this.contentType,"content-disposition":o,"content-length":String(this.content.byteLength)}),t.end(this.content)}},O=class extends C{body;contentType;status;constructor(e,t,r=200){super(),this.body=e,this.contentType=t,this.status=r}async executeAsync(e,t,r){t.writeHead(this.status,{"content-type":this.contentType}),t.end(this.body)}},F=class extends C{readable;contentType;fileName;constructor(e,t,r){super(),this.readable=e,this.contentType=t,this.fileName=r}async executeAsync(e,t,r){let n={"content-type":this.contentType};this.fileName&&(n["content-disposition"]=`attachment; filename="${this.fileName}"`),t.writeHead(200,n),await new Promise((i,o)=>{this.readable.on("error",o),t.on("error",o),this.readable.on("end",i),this.readable.pipe(t,{end:!0})})}},D=class extends C{status;headers;constructor(e,t){super(),this.status=e,this.headers=t??{}}async executeAsync(e,t,r){t.writeHead(this.status,this.headers),t.end()}},I=class extends C{url;permanent;constructor(e,t=!1){super(),this.url=e,this.permanent=t}async executeAsync(e,t,r){t.writeHead(this.permanent?301:302,{location:this.url}),t.end()}},z=class extends C{async executeAsync(e,t,r){t.writeHead(204),t.end()}};function x(s){return JSON.parse(s,(e,t)=>{if(!(e==="__proto__"||e==="constructor"))return t})}function A(s,e=64){K(s,0,e)}function K(s,e,t){if(!(s===null||typeof s!="object")){if(e>=t)throw new Error(`JSON nesting depth exceeds maximum of ${t}`);if(Array.isArray(s))for(let r of s)K(r,e+1,t);else for(let r of Object.values(s))K(r,e+1,t)}}var de={mimeType:"application/json",serialize(s){return JSON.stringify(s)},deserialize(s){let e=x(s);return A(e),e}},ce={mimeType:"application/x-www-form-urlencoded",serialize(s){let e=new URLSearchParams;if(s&&typeof s=="object"){for(let[t,r]of Object.entries(s))if(r!=null)if(Array.isArray(r))for(let n of r)e.append(t,String(n));else e.append(t,String(r))}return e.toString()},deserialize(s){let e={},t=new URLSearchParams(s);for(let[r,n]of t){if(Ne(r))continue;let i=e[r];i===void 0?e[r]=n:Array.isArray(i)?i.push(n):e[r]=[i,n]}return e}};function Ne(s){return s==="__proto__"||s==="constructor"||s==="prototype"}function Oe(s){return s.split(",").map(e=>{let t=e.trim(),[r,...n]=t.split(";").map(o=>o.trim()),i=1;for(let o of n){let[c,d]=o.split("=");c?.trim()==="q"&&d&&(i=parseFloat(d),Number.isNaN(i)&&(i=1))}return{mimeType:r.toLowerCase(),quality:i}}).sort((e,t)=>t.quality-e.quality)}var j=class{#e=new Map;constructor(){this.register(de),this.register(ce)}register(e){this.#e.set(e.mimeType.toLowerCase(),e)}selectResponseHandler(e){if(!e)return this.#e.get("application/json")??null;let t=Oe(e);for(let{mimeType:r}of t){if(r==="*/*")return this.#e.get("application/json")??null;let n=this.#e.get(r);if(n)return n}return null}selectRequestHandler(e){if(!e)return null;let t=e.split(";")[0].trim().toLowerCase();return this.#e.get(t)??null}};var Fe={400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",409:"Conflict",415:"Unsupported Media Type",422:"Unprocessable Content",500:"Internal Server Error",503:"Service Unavailable"};function R(s,e,t,r){return{type:`https://httpstatuses.com/${s}`,status:s,title:e??Fe[s]??"Error",...t!==void 0?{detail:t}:{},...r}}function X(s){return R(400,"Bad Request","One or more validation errors occurred.",{errors:s})}function v(s){return JSON.stringify(s)}var w="application/problem+json";var T=class extends Error{status;title;detail;extensions;constructor(e,t,r,n){super(r??t??`HTTP ${e}`),this.name="HttpError",this.status=e,this.title=t??`HTTP ${e}`,this.detail=r,this.extensions=n}toProblemDetails(){return R(this.status,this.title,this.detail,this.extensions)}},Y=class extends T{constructor(e){super(404,"Not Found",e),this.name="NotFoundError"}},Z=class extends T{constructor(e){super(400,"Bad Request",e),this.name="BadRequestError"}},Q=class extends T{constructor(e){super(401,"Unauthorized",e),this.name="UnauthorizedError"}},ee=class extends T{constructor(e){super(403,"Forbidden",e),this.name="ForbiddenError"}},te=class extends T{constructor(e){super(409,"Conflict",e),this.name="ConflictError"}};function De(s){return["POST","PUT","DELETE","PATCH"].includes(s.toUpperCase())}var Ie=6e4;function ze(s={}){let{ttl:e=864e5,headerName:t="x-idempotency-key",skip:r=o=>!De(o.method)}=s,n=new Map,i=setInterval(()=>{let o=Date.now();for(let[c,d]of n)d.expiresAt<=o&&n.delete(c)},Ie);return i.unref&&i.unref(),async(o,c)=>{if(r(o))return c();let d=o.headers[t]??o.headers[t.toLowerCase()];if(!d||typeof d!="string"||d.length===0)return c();let a=n.get(d);if(a)if(a.expiresAt<=Date.now())n.delete(d);else{let u=o.response;u.writeHead(a.status,a.headers),u.end(a.body),o.responded=!0;return}let f=o.response.writeHead.bind(o.response),m=o.response.end.bind(o.response),p=200,y={},h=[];if(o.response.writeHead=function(u,...l){return p=u,l.length>0&&(y=l[0]),f(u,...l)},o.response.end=function(u,...l){return u&&h.push(Buffer.isBuffer(u)?u:Buffer.from(u)),m(u,...l)},await c(),p>=200&&p<500){let u=Buffer.concat(h);n.set(d,{status:p,headers:y,body:u,expiresAt:Date.now()+e})}}}function Je(s){return["POST","PUT","DELETE","PATCH"].includes(s.toUpperCase())}function le(s,e){return s.map(t=>{let r=[];for(let[n,i]of Object.entries(t.properties).sort(([o],[c])=>o.localeCompare(c))){let o=i.getValue(e);o.success&&o.value!==void 0&&r.push(`${n}=${String(o.value)}`)}return r.length>0?`${t.name}:${r.join(",")}`:t.name})}function Ue(s={}){let{ttlByTag:e={},defaultTtl:t=6e4}=s,r=new Map;return async(n,i)=>{let c=n.items.get("__endpoint_meta")?.cacheTags??[];if(c.length===0)return i();if(Je(n.method)){if(await i(),n.response.statusCode>=200&&n.response.statusCode<300){let d=n.items.get("__raw_body"),a={params:n.pathParams??{},body:d,query:n.queryParams??{},headers:n.headers??{}},f=le(c,a);for(let m of c){for(let[p]of r)(f.includes(p)||f.some(y=>p.startsWith(m.name)))&&r.delete(p);for(let[p]of r)p.startsWith(m.name)&&r.delete(p)}}return}if(n.method==="GET"){let d={params:n.pathParams??{},body:void 0,query:n.queryParams??{},headers:n.headers??{}},a=le(c,d);for(let u of a){let l=r.get(u);if(l&&l.expiresAt>Date.now()){let g=n.response;g.writeHead(l.status,l.headers),g.end(l.body),n.responded=!0;return}l&&r.delete(u)}let f=n.response.writeHead.bind(n.response),m=n.response.end.bind(n.response),p=200,y={},h=[];if(n.response.writeHead=function(u,...l){return p=u,l.length>0&&(y=l[0]),f(u,...l)},n.response.end=function(u,...l){return u&&h.push(Buffer.isBuffer(u)?u:Buffer.from(u)),m(u,...l)},await i(),p>=200&&p<300){let u=Buffer.concat(h),l=c.reduce((g,S)=>{let b=e[S.name]!==void 0?e[S.name]:t;return b>g?b:g},0);if(l>0)for(let g of a)r.set(g,{status:p,headers:y,body:u,expiresAt:Date.now()+l})}return}return i()}}import{URL as We}from"url";import{any as re,boolean as Le,func as ue,object as $e,promise as pe,record as ne,string as B}from"@cleverbrush/schema";var Ve=$e({method:B(),url:B(),pathParams:ne(B(),B()),queryParams:ne(B(),B()),headers:ne(B(),B()),items:re(),body:ue().hasReturnType(pe(re())),json:ue().hasReturnType(pe(re())),responded:Le()}),H=5*1024*1024,k=class{request;response;url;method;headers;items=new Map;maxBodySize;#e={};_queryParams;#t;#r=null;#s=!1;#o=void 0;#d=!1;responded=!1;principal=void 0;constructor(e,t,r){this.request=e,this.response=t,this.method=(e.method??"GET").toUpperCase(),this.maxBodySize=r??H;let n=e.url??"/";this.url=new We(n,`http://${e.headers.host??"localhost"}`);let i={};for(let[o,c]of Object.entries(e.headers))typeof c=="string"?i[o]=c:Array.isArray(c)&&(i[o]=c.join(", "));this.headers=i}get pathParams(){return this.#e}set pathParams(e){this.#e=e}get queryParams(){if(this._queryParams)return this._queryParams;let e={};for(let[t,r]of this.url.searchParams)e[t]=r;return e}get services(){return this.#t}set services(e){this.#t=e}async body(){return this.#s?this.#r:(this.#r=await new Promise((e,t)=>{let r=[],n=0;this.request.on("data",i=>{if(n+=i.length,n>this.maxBodySize){this.request.destroy(),t(new T(413,"Payload Too Large"));return}r.push(i)}),this.request.on("end",()=>e(Buffer.concat(r))),this.request.on("error",t)}),this.#s=!0,this.#r)}async json(){if(this.#d)return this.#o;let t=(await this.body()).toString("utf-8");return t.length>0&&(this.#o=x(t),A(this.#o)),this.#d=!0,this.#o}};import*as G from"http";import*as Se from"https";import{AuthorizationService as Xe,PolicyBuilder as Ye,Principal as L,parseCookies as Ze,requireRole as Qe}from"@cleverbrush/auth";import{ServiceCollection as et}from"@cleverbrush/di";import{Busboy as tt}from"@fastify/busboy";import{WebSocketServer as rt}from"ws";var E=class{#e=[];add(e){this.#e.push(e)}async execute(e,t){let r=0,n=async()=>{if(r<this.#e.length){let i=this.#e[r++];await i(e,n)}else await t()};await n()}};function he(s){return s.bodySchema!=null}async function fe(s,e,t,r){let n=[],i={};if(i.context=t,s.authRoles!==null&&t.principal!==void 0&&(i.principal=t.principal),e&&Object.keys(e).length>0&&(i.params=e),s.bodySchema){let o=await s.bodySchema.validateAsync(r,{doNotStopOnFirstError:!0});if(o.valid)i.body=o.object;else{let c=typeof o.getInvalidProperties=="function"?o.getInvalidProperties:null,d=!1;if(c)for(let a of c()){let f=a.descriptor.toJsonPointer();for(let m of a.errors)n.push({pointer:`/body${f}`,detail:m}),d=!0}if(!d)for(let a of o.errors??[])n.push({pointer:"/body",detail:a.message})}}if(s.querySchema){let o=s.querySchema.introspect();if(o.type!=="object"||!o.properties)throw new Error("Endpoint query schema must be an object schema whose properties map to query parameter names.");let c=o.properties,d={};for(let[a,f]of Object.entries(c)){let m=t.queryParams[a],p=await f.validateAsync(m,{doNotStopOnFirstError:!0});if(p.valid)d[a]=p.object;else for(let y of p.errors??[])n.push({pointer:`/query/${a}`,detail:y.message})}i.query=d}if(s.headerSchema){let o=s.headerSchema.introspect();if(o.type!=="object"||!o.properties)throw new Error("Endpoint headers schema must be an object schema whose properties map to header names.");let c=o.properties,d={};for(let[a,f]of Object.entries(c)){let m=t.headers[a.toLowerCase()],p=await f.validateAsync(m,{doNotStopOnFirstError:!0});if(p.valid)d[a]=p.object;else for(let y of p.errors??[])n.push({pointer:`/headers/${a}`,detail:y.message})}i.headers=d}if(n.length>0)return{valid:!1,problemDetails:X(n)};if(s.serviceSchemas){if(!t.services)throw new Error("Endpoint declares .inject() dependencies but no service provider is available. Register services via createServer().services() before handling this endpoint.");let o={};for(let[c,d]of Object.entries(s.serviceSchemas))o[c]=t.services.get(d);return{valid:!0,args:[i,o]}}return{valid:!0,args:[i]}}function _(s){let e=decodeURI(s);return e.length>1&&e.endsWith("/")?e.slice(0,-1):e}function me(s){return typeof s!="string"&&typeof s.validate=="function"}var J=class{#e=new Map;#t=[];addRoute(e){let{method:t,basePath:r,pathTemplate:n}=e.endpoint,i=t.toUpperCase(),c={basePath:_(r),routePath:n,registration:e};this.#e.has(i)||this.#e.set(i,[]),this.#e.get(i).push(c)}match(e,t){let r;try{r=_(t)}catch{return{match:null,methodNotAllowed:!1,badRequest:!0}}let n=e.toUpperCase(),i=this.#e.get(n);if(i)for(let c of i){let d=this.#r(c,r);if(d)return{match:d,methodNotAllowed:!1}}let o=[];for(let[c,d]of this.#e)if(c!==n){for(let a of d)if(this.#r(a,r)){o.push(c);break}}return o.length>0?{match:null,methodNotAllowed:!0,allowedMethods:o}:{match:null,methodNotAllowed:!1}}#r(e,t){let{basePath:r,routePath:n}=e;if(r&&!t.startsWith(r))return null;let i=r?t.slice(r.length):t;if(me(n)){let d=n.validate(i);return d.valid?{registration:e.registration,parsedPath:d.object}:null}let o=_(n);return(i.length===0?"/":i)===o?{registration:e.registration,parsedPath:null}:null}addSubscriptionRoute(e){let{basePath:t,pathTemplate:r}=e.endpoint,n=_(t);this.#t.push({basePath:n,routePath:r,registration:e})}matchSubscription(e){let t;try{t=_(e)}catch{return null}for(let r of this.#t){let{basePath:n,routePath:i}=r;if(n&&!t.startsWith(n))continue;let o=n?t.slice(n.length):t;if(me(i)){let a=i.validate(o);if(a.valid)return{registration:r.registration,parsedPath:a.object};continue}let c=_(i);if((o.length===0?"/":o)===c)return{registration:r.registration,parsedPath:null}}return null}};import{Readable as Ge,Writable as Ke}from"stream";var U=class extends Ge{method;url;headers;__cleverbrushBatchSubrequest;socket=null;#e;#t=!1;constructor(e){super(),this.method=e.method,this.url=e.url;let t={};for(let[r,n]of Object.entries(e.headers??{}))t[r.toLowerCase()]=n;this.headers={host:"localhost",...t},this.#e=e.body!=null&&e.body.length>0?Buffer.from(e.body,"utf-8"):Buffer.alloc(0)}_read(){this.#t||(this.#t=!0,this.#e.length>0&&this.push(this.#e),this.push(null))}},W=class extends Ke{statusCode=200;headersSent=!1;#e=[];#t={};#r=200;_write(e,t,r){this.#e.push(Buffer.isBuffer(e)?e:Buffer.from(e)),r()}writeHead(e,t){if(this.#r=e,this.statusCode=e,t!=null&&typeof t=="object"&&!Array.isArray(t))for(let[r,n]of Object.entries(t))this.#t[r.toLowerCase()]=Array.isArray(n)?n.join(", "):String(n);return this.headersSent=!0,this}setHeader(e,t){return this.#t[e.toLowerCase()]=Array.isArray(t)?t.join(", "):String(t),this}getHeader(e){return this.#t[e.toLowerCase()]}end(e,...t){if(e!=null&&typeof e!="function"){let r=Buffer.isBuffer(e)||e instanceof Uint8Array?Buffer.from(e):Buffer.from(String(e),"utf-8");this.#e.push(r),super.end(...t)}else typeof e=="function"?super.end(e):super.end(...t);return this}toResult(){return{status:this.#r,headers:{...this.#t},body:Buffer.concat(this.#e).toString("utf-8")}}};function ye(s){return{type:"message",data:s}}function ge(s,e){return{type:"tracked",id:s,data:e}}function be(){return{type:"pong"}}function M(s,e){return{type:"error",code:s,message:e}}function Re(s){let e;try{e=x(s),A(e)}catch{return null}if(typeof e!="object"||e===null)return null;let t=e;return t.type==="ping"?{type:"ping"}:t.type==="message"&&"data"in t?{type:"message",data:t.data}:null}async function nt(s,e){let t=e.maxFileCount??10,r=e.maxFileSize??10*1024*1024,n=e.allowedMimeTypes;return new Promise((i,o)=>{let c={},d={},a=[],f=0,m=tt({headers:s.headers,limits:{fileSize:r,files:t}});m.on("field",(p,y)=>{c[p]=y}),m.on("file",(p,y,h,u,l)=>{if(f>=t){a.push({filename:h,mimeType:l,reason:`Exceeded max file count (${t})`}),y.resume();return}if(n&&!n.some(b=>b.endsWith("/*")?l.startsWith(b.slice(0,-1)):l===b)){a.push({filename:h,mimeType:l,reason:`MIME type "${l}" not allowed (allowed: ${n.join(", ")})`}),y.resume();return}f++;let g=[];y.on("data",S=>{g.push(S)}),y.on("end",()=>{let S=Buffer.concat(g);d[p]={filename:h,mimeType:l,buffer:S,size:S.length}}),y.on("error",o)}),m.on("error",o),m.on("finish",()=>i({fields:c,files:d,rejectedFiles:a})),s.pipe(m)})}var $=class{#e=new et;#t=[];#r=[];#s=[];#o=[];#d=new j;#i;#a=null;#n=null;#c=!1;#l=null;constructor(e={}){this.#i=e}services(e){return e(this.#e),this}use(e){return this.#o.push(e),this}contentType(e){return this.#d.register(e),this}useAuthentication(e){return this.#a=e,this}useAuthorization(e){return this.#n=e??{},this}withHealthcheck(){return this.#c=!0,this}useBatching(e={}){return this.#l=e,this}handle(e,t,r){return this.#t.push({endpoint:e.introspect(),handler:t,middlewares:r?.middlewares}),this}handleAll(e){for(let t of e._entries)this.#t.push({endpoint:t.endpoint.introspect(),handler:t.handler,middlewares:t.middlewares});for(let t of e._subscriptions)this.#r.push({endpoint:t.endpoint.introspect(),handler:t.handler,middlewares:t.middlewares});return this}getRegistrations(){return[...this.#t]}getSubscriptionRegistrations(){return[...this.#r]}webhook(e){return this.#s.push(e),this}getWebhooks(){return[...this.#s]}getAuthenticationConfig(){return this.#a}async listen(e,t){let r=new J;for(let f of this.#t)r.addRoute(f);for(let f of this.#r)r.addSubscriptionRoute(f);let n=this.#e.buildServiceProvider({validateScopes:!1}),i=[];if(this.#a&&i.push(at(this.#a)),this.#n!==null){let f=new Map;if(this.#n.policies)for(let[p,y]of Object.entries(this.#n.policies)){let h=new Ye;y(h),f.set(p,h.build(p))}let m=new Xe(f);i.push(dt(m,this.#a))}let o=[...i,...this.#o],c=new V(r,n,this.#d,o,this.#c,this.#r.length>0,this.#l,this.#i.maxBodySize),d=e??this.#i.port??3e3,a=t??this.#i.host??"0.0.0.0";return await c.start(d,a,this.#i),c}},st=1024,V=class{#e;#t;#r;#s;#o;#d;#i;#a;#n=null;#c=null;#l=new Set;constructor(e,t,r,n,i=!1,o=!1,c=null,d=H){this.#e=e,this.#t=t,this.#r=r,this.#s=n,this.#o=i,this.#d=o,this.#i=c,this.#a=d}async start(e,t,r){let n=(i,o)=>{this.#u(i,o).catch(c=>{o.headersSent||(o.writeHead(500,{"content-type":w}),o.end(v(R(500))))})};r.https?this.#n=Se.createServer({key:r.https.key,cert:r.https.cert},n):this.#n=G.createServer(n),await new Promise(i=>{this.#n.listen(e,t,i)}),this.#d&&(this.#c=new rt({noServer:!0,maxPayload:this.#a}),this.#n.on("upgrade",(i,o,c)=>{let d=new URL(i.url??"/",`http://${i.headers.host??"localhost"}`).pathname,a=this.#e.matchSubscription(d);if(!a){o.write(`HTTP/1.1 404 Not Found\r
|
|
2
2
|
\r
|
|
3
|
-
`),
|
|
3
|
+
`),o.destroy();return}this.#c.handleUpgrade(i,o,c,f=>{this.#f(f,i,a.registration,a.parsedPath)})}))}async close(){for(let e of this.#l)e.close(1001,"Server shutting down");this.#l.clear(),this.#c&&(await new Promise((e,t)=>{this.#c.close(r=>{r?t(r):e()})}),this.#c=null),this.#n&&(await new Promise((e,t)=>{this.#n.close(r=>{r?t(r):e()})}),this.#n=null)}get address(){let e=this.#n?.address();return!e||typeof e=="string"?null:{port:e.port,host:e.address}}async#u(e,t){let r=this.#t.createScope();try{let n=new k(e,t,this.#a),i=n.url.pathname,o=n.method,c=e.__cleverbrushBatchSubrequest;if(c&&n.items.set("__batch_subrequest",c),this.#o&&o==="GET"&&i==="/health"){t.writeHead(200),t.end();return}if(this.#i!==null&&o==="POST"&&i===(this.#i.path??"/__batch")){n.services=r.serviceProvider;let y=new E;for(let h of this.#s)y.add(h);await y.execute(n,async()=>{n.responded||(await this.#p(e,t),n.responded=!0)});return}let d=this.#e.match(o,i);if(!d.match){if(d.badRequest){let h=R(400);t.writeHead(400,{"content-type":w}),t.end(v(h));return}if(d.methodNotAllowed){let h=R(405,"Method Not Allowed");t.writeHead(405,{"content-type":w,allow:d.allowedMethods.join(", ")}),t.end(v(h));return}let y=R(404);t.writeHead(404,{"content-type":w}),t.end(v(y));return}let{registration:a,parsedPath:f}=d.match,m=a.endpoint;if(f){let y={};se(f,"",y),n.pathParams=y}n.services=r.serviceProvider,n.items.set("__endpoint_meta",m);let p=new E;for(let y of this.#s)p.add(y);if(a.middlewares)for(let y of a.middlewares)p.add(y);await p.execute(n,async()=>{if(n.responded)return;let y,h,u;if(he(m)){let S=e.headers["content-type"]??"";if(m.fileUpload&&S.startsWith("multipart/form-data"))try{let b=await nt(e,m.fileUpload);y=b.fields,h=b.files,u=b.rejectedFiles}catch{let b=R(400,"Malformed multipart request");t.writeHead(400,{"content-type":w}),t.end(v(b)),n.responded=!0;return}else if(m.fileUpload){let b=R(400,"File upload endpoint requires multipart/form-data content type");t.writeHead(400,{"content-type":w}),t.end(v(b)),n.responded=!0;return}else{let b=this.#r.selectRequestHandler(S);if(b){let ie=(await n.body()).toString("utf-8");if(ie.length>0)try{y=b.deserialize(ie)}catch{let ve=R(400,"Malformed request body");t.writeHead(400,{"content-type":w}),t.end(v(ve)),n.responded=!0;return}}else if(S){let oe=R(415);t.writeHead(415,{"content-type":w}),t.end(v(oe)),n.responded=!0;return}}}let l=await fe(m,f,n,y);if(!l.valid){t.writeHead(400,{"content-type":w}),t.end(v(l.problemDetails)),n.responded=!0;return}if(h&&l.args.length>0){let S=l.args[0];S.files=h,u&&u.length>0&&(S.rejectedFiles=u)}let g=a.handler(...l.args);g instanceof Promise&&(g=await g),!n.responded&&(await this.#h(e,t,g),n.responded=!0)})}catch(n){if(t.headersSent)return;if(n instanceof T){let i=n.toProblemDetails();t.writeHead(i.status,{"content-type":w}),t.end(v(i))}else{console.error("[server] Unhandled error:",n);let i=R(500);t.writeHead(500,{"content-type":w}),t.end(v(i))}}finally{try{await r.asyncDispose()}catch{}}}async#p(e,t){let r=this.#i,n=r.maxSize??20,i=r.parallel??!0,o;try{let a=await it(e,this.#a),f=x(a.toString("utf-8"));if(A(f),o=f,!Array.isArray(o?.requests))throw new Error("requests must be an array")}catch(a){if(a instanceof T&&a.status===413){let m=R(413,"Payload Too Large");t.writeHead(413,{"content-type":w}),t.end(v(m));return}let f=R(400,"Invalid batch request body");t.writeHead(400,{"content-type":w}),t.end(v(f));return}if(o.requests.length>n){let a=R(400,`Batch size ${o.requests.length} exceeds maximum of ${n}`);t.writeHead(400,{"content-type":w}),t.end(v(a));return}let c=async(a,f)=>{let m=new U({method:(a.method??"GET").toUpperCase(),url:a.url,headers:a.headers??{},body:a.body});m.__cleverbrushBatchSubrequest={index:f,size:o.requests.length,path:r.path??"/__batch"};let p=new W;return await this.#u(m,p),p.toResult()},d;if(i)d=await Promise.all(o.requests.map(c));else{d=[];for(let a=0;a<o.requests.length;a++)d.push(await c(o.requests[a],a))}t.writeHead(200,{"content-type":"application/json"}),t.end(JSON.stringify({responses:d}))}async#h(e,t,r){r instanceof C?await r.executeAsync(e,t,this.#r):r==null?(t.writeHead(204),t.end()):await new P(r,200).executeAsync(e,t,this.#r)}#f(e,t,r,n){this.#l.add(e);let i=this.#t.createScope(),o=new AbortController,c=r.endpoint,d=new G.ServerResponse(t),a=new k(t,d);if(n){let m={};se(n,"",m),a.pathParams=m}a.services=i.serviceProvider,a.items.set("__endpoint_meta",c);let f=new E;for(let m of this.#s)f.add(m);if(r.middlewares)for(let m of r.middlewares)f.add(m);f.execute(a,async()=>{if(a.responded){e.close(1008,"Unauthorized");return}this.#m(e,a,c,r.handler,n,i,o)}).catch(()=>{e.close(1011,"Internal Server Error")}),e.on("close",()=>{this.#l.delete(e),o.abort(),i.asyncDispose().catch(()=>{})}),e.on("error",()=>{this.#l.delete(e),o.abort(),i.asyncDispose().catch(()=>{})})}#m(e,t,r,n,i,o,c){let d=[],a=null,f=!1,m={[Symbol.asyncIterator](){return{next(){return d.length>0?Promise.resolve({value:d.shift(),done:!1}):f?Promise.resolve({value:void 0,done:!0}):new Promise(h=>{a=()=>{a=null,d.length>0?h({value:d.shift(),done:!1}):h({value:void 0,done:!0})}})},return(){return f=!0,Promise.resolve({value:void 0,done:!0})}}}};e.on("message",h=>{let u=typeof h=="string"?h:h.toString("utf-8"),l=Re(u);if(!l){e.send(JSON.stringify(M(400,"Invalid frame format")));return}if(l.type==="ping"){e.send(JSON.stringify(be()));return}if(d.length>=st){e.send(JSON.stringify(M(429,"Message queue full \u2014 slow down or reconnect"))),e.close(1008,"Message queue overflow");return}if(r.incomingSchema){let g=r.incomingSchema.validate(l.data);if(!g.valid){let S=(g.errors??[]).map(b=>b.message).join("; ");e.send(JSON.stringify(M(422,`Validation failed: ${S}`)));return}d.push(g.object)}else d.push(l.data);a&&a()}),e.on("close",()=>{f=!0,a&&a()});let p={context:t,signal:c.signal};if(i&&Object.keys(i).length>0&&(p.params=i),r.querySchema){let h={};for(let[l,g]of t.url.searchParams.entries())h[l]=g;let u=r.querySchema.validate(h);if(!u.valid){let l=(u.errors??[]).map(g=>g.message).join("; ");e.close(1002,`Query validation failed: ${l}`);return}p.query=u.object}if(r.headerSchema){let h=r.headerSchema.validate(t.headers);if(!h.valid){let u=(h.errors??[]).map(l=>l.message).join("; ");e.close(1002,`Header validation failed: ${u}`);return}p.headers=h.object}t.principal!==void 0&&(p.principal=t.principal),r.incomingSchema,p.incoming=m;let y=[p];if(r.serviceSchemas){let h={};for(let[u,l]of Object.entries(r.serviceSchemas))h[u]=o.serviceProvider.get(l);y.push(h)}(async()=>{try{let h=n(...y);for await(let u of h){if(e.readyState!==e.OPEN)break;let l;if(ae(u)){let g=r.outgoingSchema?r.outgoingSchema.validate(u.data):{valid:!0,object:u.data};if(!g.valid){e.send(JSON.stringify(M(500,"Outgoing validation failed")));continue}l=JSON.stringify(ge(u.id,g.object))}else{let g=r.outgoingSchema?r.outgoingSchema.validate(u):{valid:!0,object:u};if(!g.valid){e.send(JSON.stringify(M(500,"Outgoing validation failed")));continue}l=JSON.stringify(ye(g.object))}e.send(l)}}catch(h){e.readyState===e.OPEN&&(h instanceof Error&&console.error("[server] Subscription handler error:",h),e.send(JSON.stringify(M(500,"Internal error"))),e.close(1011,"Handler error"))}})()}};function ot(s){return new $(s)}function it(s,e=H){return new Promise((t,r)=>{let n=[],i=0;s.on("data",o=>{if(i+=o.length,i>e){s.destroy(),r(new T(413,"Payload Too Large"));return}n.push(o)}),s.on("end",()=>t(Buffer.concat(n))),s.on("error",r)})}function se(s,e,t){for(let[r,n]of Object.entries(s)){let i=e?`${e}.${r}`:r;n!==null&&typeof n=="object"&&!Array.isArray(n)?se(n,i,t):t[i]=String(n)}}function at(s){let e=new Map;for(let r of s.schemes)e.set(r.name,r);let t;return s.trySchemes==="all"?t=s.schemes:t=(s.trySchemes&&s.trySchemes.length>0?s.trySchemes:[s.defaultScheme]).map(n=>e.get(n)).filter(n=>n!==void 0),async(r,n)=>{if(r.items.get("__endpoint_meta")?.authRoles===null){r.principal=L.anonymous(),await n();return}let o={headers:r.headers,cookies:Ze(r.headers.cookie??""),items:r.items};r.principal=L.anonymous();for(let c of t){let d=await c.authenticate(o);if(d.succeeded){r.principal=d.principal;break}}await n()}}function dt(s,e){let t={};if(e){for(let r of e.schemes)if(r.challenge){let n=r.challenge();t[n.headerName.toLowerCase()]=n.headerValue}}return async(r,n)=>{let i=r.items.get("__endpoint_meta");if(!i||i.authRoles===null){await n();return}let o=r.principal;if(!o||!(o instanceof L)||!o.isAuthenticated){let c=R(401,"Unauthorized"),d={"content-type":w,...t};r.response.writeHead(401,d),r.response.end(v(c)),r.responded=!0;return}if(i.authRoles.length>0&&!(await s.authorize(o,[Qe(...i.authRoles)])).allowed){let d=R(403,"Forbidden");r.response.writeHead(403,{"content-type":w}),r.response.end(v(d)),r.responded=!0;return}o instanceof L&&(r.principal=o.value),await n()}}function ct(s,e){return{name:s,...e}}export{C as ActionResult,Z as BadRequestError,te as ConflictError,j as ContentNegotiator,O as ContentResult,H as DEFAULT_MAX_BODY_SIZE,Be as EndpointBuilder,N as FileResult,ee as ForbiddenError,T as HttpError,Ve as IRequestContext,P as JsonResult,z as NoContentResult,Y as NotFoundError,q as RawResult,I as RedirectResult,k as RequestContext,V as Server,$ as ServerBuilder,D as StatusCodeResult,F as StreamResult,xe as SubscriptionBuilder,Q as UnauthorizedError,Ue as cacheResponse,Te as computeCacheKey,we as createCacheTagTree,Me as createEndpoints,R as createProblemDetails,ot as createServer,X as createValidationProblemDetails,_e as defineApi,ct as defineWebhook,ke as endpoint,ce as formUrlEncodedContentTypeHandler,ze as idempotency,de as jsonContentTypeHandler,Ae as mapHandlers,je as mergeContracts,qe as omitGroups,He as pickGroups,Ee as route,Pe as serializeTag,Ce as tracked};
|
|
4
4
|
//# sourceMappingURL=index.js.map
|