@virid/express 0.3.3 → 0.3.4

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/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
- * @virid/express v0.3.3
2
+ * @virid/express v0.3.4
3
3
  * Add express functionality to virid
4
4
  */
5
- var T=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Re=Object.prototype.hasOwnProperty;var Se=(r,e,t)=>e in r?T(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var o=(r,e)=>T(r,"name",{value:e,configurable:!0});var ye=(r,e)=>{for(var t in e)T(r,t,{get:e[t],enumerable:!0})},Ce=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ee(e))!Re.call(r,i)&&i!==t&&T(r,i,{get:()=>e[i],enumerable:!(s=ge(e,i))||s.enumerable});return r};var Oe=r=>Ce(T({},"__esModule",{value:!0}),r);var l=(r,e,t)=>Se(r,typeof e!="symbol"?e+"":e,t);var Ge={};ye(Ge,{BadRequest:()=>Ie,BadRequestResponse:()=>v,Body:()=>je,ConflictResponse:()=>Y,Cookies:()=>Xe,Created:()=>Te,CreatedResponse:()=>q,Ctx:()=>ze,CustomResponse:()=>Ve,CustomResponseResponse:()=>U,ExpressPlugin:()=>ce,Forbidden:()=>$e,ForbiddenResponse:()=>D,Headers:()=>Ye,HttpContext:()=>S,HttpError:()=>w,HttpRequestMessage:()=>O,HttpResponse:()=>p,HttpRoute:()=>Ue,HttpSystem:()=>Qe,InternalServerError:()=>B,InternalServerErrorResponse:()=>P,NoContent:()=>Pe,NoContentResponse:()=>V,NotFound:()=>qe,NotFoundResponse:()=>N,Ok:()=>Ae,OkResponse:()=>$,Params:()=>We,ParseBoolPipe:()=>xe,ParseIntPipe:()=>me,Query:()=>Fe,Req:()=>Le,Res:()=>Ke,Stream:()=>be,StreamFile:()=>ve,StreamFileResponse:()=>y,StreamResponse:()=>C,Unauthorized:()=>He,UnauthorizedResponse:()=>b,UnprocessableEntityResponse:()=>X,addAutoPipe:()=>De,getAutoPipe:()=>Ne,getHttpArgs:()=>de,parseRawCookie:()=>ae});module.exports=Oe(Ge);var m=require("@virid/core");var he=require("@virid/core");var L=class L{constructor(e,t,s,i,a){l(this,"id");l(this,"req");l(this,"res");l(this,"timestamp");l(this,"route");l(this,"rc",0);l(this,"isClosed",!1);this.id=e,this.req=t,this.res=s,this.timestamp=i,this.route=a}inc(){this.rc++}dec(){this.rc--,this.rc===0&&this.tryFinalize()}tryFinalize(){if(this.res.writableEnded||this.isClosed)return;this.isClosed=!0;let e=`[Virid Express] Request Orphaned: The connection was closed because all systems finished execution without sending a response.
5
+ var T=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Re=Object.prototype.hasOwnProperty;var Se=(r,e,t)=>e in r?T(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var o=(r,e)=>T(r,"name",{value:e,configurable:!0});var ye=(r,e)=>{for(var t in e)T(r,t,{get:e[t],enumerable:!0})},Ce=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ee(e))!Re.call(r,i)&&i!==t&&T(r,i,{get:()=>e[i],enumerable:!(s=ge(e,i))||s.enumerable});return r};var Oe=r=>Ce(T({},"__esModule",{value:!0}),r);var l=(r,e,t)=>Se(r,typeof e!="symbol"?e+"":e,t);var Ge={};ye(Ge,{BadRequest:()=>Ie,BadRequestResponse:()=>b,Body:()=>je,ConflictResponse:()=>Y,Cookies:()=>Xe,Created:()=>Te,CreatedResponse:()=>q,Ctx:()=>ze,CustomResponse:()=>Ve,CustomResponseResponse:()=>U,ExpressPlugin:()=>ce,Forbidden:()=>$e,ForbiddenResponse:()=>D,Headers:()=>Ye,HttpContext:()=>S,HttpError:()=>w,HttpRequestMessage:()=>O,HttpResponse:()=>p,HttpRoute:()=>Ue,HttpSystem:()=>Qe,InternalServerError:()=>B,InternalServerErrorResponse:()=>P,NoContent:()=>Pe,NoContentResponse:()=>V,NotFound:()=>qe,NotFoundResponse:()=>N,Ok:()=>Ae,OkResponse:()=>$,Params:()=>We,ParseBoolPipe:()=>xe,ParseIntPipe:()=>me,Query:()=>Fe,Req:()=>Le,Res:()=>Ke,Stream:()=>ve,StreamFile:()=>be,StreamFileResponse:()=>y,StreamResponse:()=>C,Unauthorized:()=>He,UnauthorizedResponse:()=>v,UnprocessableEntityResponse:()=>X,addAutoPipe:()=>De,getAutoPipe:()=>Ne,getHttpArgs:()=>de,parseRawCookie:()=>ae});module.exports=Oe(Ge);var m=require("@virid/core");var he=require("@virid/core");var L=class L{constructor(e,t,s,i,a){l(this,"id");l(this,"req");l(this,"res");l(this,"timestamp");l(this,"route");l(this,"rc",0);l(this,"isClosed",!1);this.id=e,this.req=t,this.res=s,this.timestamp=i,this.route=a}inc(){this.rc++}dec(){this.rc--,this.rc===0&&this.tryFinalize()}tryFinalize(){if(this.res.writableEnded||this.isClosed)return;this.isClosed=!0;let e=`[Virid Express] Request Orphaned: The connection was closed because all systems finished execution without sending a response.
6
6
  Route: ${this.route}
7
- Uptime: ${Date.now()-this.timestamp}ms`;he.MessageWriter.error(new Error(e)),this.res.headersSent?this.res.end():this.res.status(500).json({error:"Internal Logic Error",message:"Request processed but no response was returned by any system."})}};o(L,"HttpContext");var S=L,K=class K{constructor(e,t=null,s={}){l(this,"status");l(this,"data");l(this,"headers");this.status=e,this.data=t,this.headers=s}};o(K,"HttpResponse");var p=K,z=class z extends p{constructor(e,t={}){super(200,e,t)}};o(z,"OkResponse");var $=z,F=class F extends p{constructor(e,t={}){super(201,e,t)}};o(F,"CreatedResponse");var q=F,W=class W extends p{constructor(){super(204,null)}};o(W,"NoContentResponse");var V=W,_=class _ extends p{constructor(e="Bad Request"){super(400,{error:e})}};o(_,"BadRequestResponse");var v=_,G=class G extends p{constructor(e="Unauthorized"){super(401,{error:e})}};o(G,"UnauthorizedResponse");var b=G,J=class J extends p{constructor(e="Forbidden"){super(403,{error:e})}};o(J,"ForbiddenResponse");var D=J,Z=class Z extends p{constructor(e="Not Found"){super(404,{error:e})}};o(Z,"NotFoundResponse");var N=Z,k=class k extends p{constructor(e="Conflict"){super(409,{error:e})}};o(k,"ConflictResponse");var Y=k,ee=class ee extends p{constructor(e){super(422,{errors:e})}};o(ee,"UnprocessableEntityResponse");var X=ee,te=class te extends p{constructor(e="Internal Server Error"){super(500,{error:e})}};o(te,"InternalServerErrorResponse");var P=te,re=class re extends p{constructor(e,t,s={}){super(e,t,s)}};o(re,"CustomResponseResponse");var U=re,se=class se extends p{constructor(t,s={dotfiles:"allow"}){super(206,s);l(this,"filePath");l(this,"options");this.filePath=t,this.options=s}};o(se,"StreamFileResponse");var y=se,oe=class oe extends p{constructor(t,s={}){super(s.status||206,{},s.headers);l(this,"stream");l(this,"options");this.stream=t,this.options=s}};o(oe,"StreamResponse");var C=oe,Ae=o((r,e={})=>new $(r,e),"Ok"),Te=o((r,e={})=>new q(r,e),"Created"),Pe=o(()=>new V,"NoContent"),Ie=o((r="Bad Request")=>new v(r),"BadRequest"),He=o((r="Unauthorized")=>new b(r),"Unauthorized"),$e=o((r="Forbidden")=>new D(r),"Forbidden"),qe=o((r="Not Found")=>new N(r),"NotFound"),B=o((r="Internal Server Error")=>r instanceof Error?new P(r.message):new P(r),"InternalServerError"),Ve=o((r,e,t={})=>new U(r,e,t),"CustomResponse"),ve=o((r,e)=>new y(r,e),"StreamFile"),be=o((r,e)=>new C(r,e),"Stream"),ie=class ie extends Error{constructor(t,s){super(s);l(this,"status");l(this,"message");this.status=t,this.message=s}};o(ie,"HttpError");var w=ie;var fe=require("@virid/core");function me(r){let e=parseInt(r,10);if(isNaN(e))throw new w(400,`Validation failed: "${r}" is not a number.`);return e}o(me,"ParseIntPipe");function xe(r){return r==="true"||r==="1"?!0:r==="false"||r==="0"?!1:!!r}o(xe,"ParseBoolPipe");var I=new Map;I.set(Number,me);I.set(Boolean,xe);function De(r,e){if(I.has(r)){fe.MessageWriter.error(new Error(`[Virid Express Pipe] Repeated Pipe: Auto pipe for ${r} has already been registered.`));return}I.set(r,e)}o(De,"addAutoPipe");function Ne(r){return I.get(r)}o(Ne,"getAutoPipe");function ae(r){let e={};if(!r)return e;let t=r.split(";");for(let s of t){let i=s.indexOf("=");if(i===-1)continue;let a=s.substring(0,i).trim();if(!a)continue;let n=s.substring(i+1).trim();n[0]==='"'&&n[n.length-1]==='"'&&(n=n.slice(1,-1));try{e[a]=n.includes("%")?decodeURIComponent(n):n}catch{e[a]=n}}return e}o(ae,"parseRawCookie");var we=require("@virid/core");var ne=class ne extends we.EventMessage{constructor(t){super();l(this,"__virid_express_id");this.__virid_express_id=t}get requestId(){return this.__virid_express_id}};o(ne,"HttpRequestMessage");var O=ne;var Me=require("@virid/core"),d={...Me.VIRID_METADATA,HTTPROUTE:"virid:express:route",HTTPSYSTEM:"virid:express:system",BODY:"virid:express:body",QUERY:"virid:express:query",HEADERS:"virid:express:header",REQUEST:"virid:express:request",RESPONSE:"virid:express:response",CONTEXT:"virid:express:context",PARAMS:"virid:express:params",COOKIES:"virid:express:cookie"};function Ue(r){return e=>{let t=[];r.path.split("/").forEach(a=>{a.startsWith(":")&&t.push(a.substring(1))});let i={...r,httpMessage:e,params:t};Reflect.defineMetadata(d.HTTPROUTE,i,e)}}o(Ue,"HttpRoute");function Be(r){let e=[];if(r.forEach((t,s)=>{(t===O||t&&t.prototype instanceof O)&&e.push({type:t,idx:s})}),e.length===0)return null;if(e.length>1){let t=e.map(s=>`[Index: ${s.idx}, Name: ${s.type.name}]`).join(", ");throw new Error(`[Virid System] Multiple Messages: Multiple Message type parameters detected, this is not allowed! specific location: ${t}`)}return e[0]}o(Be,"checkMessageParam");function Qe(r={priority:0,messageClass:null}){return(e,t,s)=>{if(typeof e!="function")throw new Error(`[Virid System] Method Type Error: The Method ${t} is not a static method, please check if there is a static keyword tag.`);let i=s.value,a=Reflect.getMetadata("design:paramtypes",e,t);if(!a)throw new Error('[Virid System] System Parameter Loss: Unable to recognize system parameters, please confirm if import "reflect-metadata" was introduced at the beginning.');let n=a.map((M,A)=>M===void 0?A:-1).filter(M=>M!==-1);if(n.length>0)throw new Error(`[Virid System] Parameter Metadata Loss in "${t}": One or more parameters have 'undefined' types. This usually happens when you forget to add a type annotation or due to circular dependencies. Check parameter at indices: [${n.join(", ")}]`);let c,h=-1,u=Be(a);if(u&&r.messageClass)throw new Error(`[Virid System] Multiple Messages Are Not Allowed: Cannot specify messageClass in decorator options while already declaring it in method parameters at index ${u.idx} in ${t}.`);if(u)c=u.type,h=u.idx;else if(r.messageClass)c=r.messageClass,h=-1;else throw new Error("[Virid System] System Parameter Loss: Please declare the message type either in method parameters or via the Message decorator options.");let x=_e(e,t),f={params:a,targetClass:e,methodName:t,originalMethod:i},H={httpMetadata:x,messageClass:c,messageIdx:h,priority:r.priority||0,batchMode:!1};s.value.systemContext=f,s.value.httpSystemConfig=H}}o(Qe,"HttpSystem");function je(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.BODY,r,e))throw new Error(`[Virid Express Body] Multiple Body Are Not Allowed: ${e} has multiple @Body() decorators!`);let s={index:t};Reflect.defineMetadata(d.BODY,s,r,e)}}o(je,"Body");function Ye(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.HEADERS,r,e))throw new Error(`[Virid Express Headers] Multiple Header Are Not Allowed: ${e} has multiple @Headers() decorators!`);let s={index:t};Reflect.defineMetadata(d.HEADERS,s,r,e)}}o(Ye,"Headers");function Xe(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.COOKIES,r,e))throw new Error(`[Virid Express Cookies] Multiple Header Are Not Allowed: ${e} has multiple @Cookies() decorators!`);let s={index:t};Reflect.defineMetadata(d.COOKIES,s,r,e)}}o(Xe,"Cookies");function Le(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.REQUEST,r,e))throw new Error(`[Virid Express Req] Multiple Request Objects Are Not Allowed: ${e} has multiple @Req() decorators!`);let s={index:t};Reflect.defineMetadata(d.REQUEST,s,r,e)}}o(Le,"Req");function Ke(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.RESPONSE,r,e))throw new Error(`[Virid Express Res] Multiple Response Objects Are Not Allowed: ${e} has multiple @Res() decorators!`);let s={index:t};Reflect.defineMetadata(d.RESPONSE,s,r,e)}}o(Ke,"Res");function ze(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.CONTEXT,r,e))throw new Error(`[Virid Express Ctx] Multiple Context Objects Are Not Allowed: ${e} has multiple @Ctx() decorators!`);let s={index:t};Reflect.defineMetadata(d.CONTEXT,s,r,e)}}o(ze,"Ctx");function Fe(r,e){return(t,s,i)=>{let n=[...Reflect.getOwnMetadata(d.QUERY,t,s)||[],{index:i,query:r,pipe:e}];Reflect.defineMetadata(d.QUERY,n,t,s)}}o(Fe,"Query");function We(r,e){return(t,s,i)=>{let n=[...Reflect.getOwnMetadata(d.PARAMS,t,s)||[],{index:i,key:r,pipe:e}];Reflect.defineMetadata(d.PARAMS,n,t,s)}}o(We,"Params");function _e(r,e){let t=Reflect.getOwnMetadata(d.BODY,r,e),s=Reflect.getOwnMetadata(d.HEADERS,r,e),i=Reflect.getOwnMetadata(d.COOKIES,r,e),a=Reflect.getOwnMetadata(d.RESPONSE,r,e),n=Reflect.getOwnMetadata(d.REQUEST,r,e),c=Reflect.getOwnMetadata(d.CONTEXT,r,e),h=Reflect.getOwnMetadata(d.QUERY,r,e)||[],u=Reflect.getOwnMetadata(d.PARAMS,r,e)||[];return{bodyMeta:t,headerMeta:s,queryMeta:h,paramMeta:u,cookiesMeta:i,reqMeta:n,resMeta:a,ctxMeta:c}}o(_e,"getHttpMetadata");function de(r,e,t){let{req:s,res:i}=e;if(t.ctxMeta?.index===r)return e;let a=t.paramMeta?.find(c=>c.index===r);if(a){let c=a.key?s.params[a.key]:s.params;return a.pipe&&c!==void 0&&(c=a.pipe(c)),c}if(t.bodyMeta?.index===r)return s.body;if(t.headerMeta?.index===r)return s.headers;if(t.cookiesMeta?.index===r)return ae(s.headers.cookie);if(t.reqMeta?.index===r)return s;if(t.resMeta?.index===r)return i;let n=t.queryMeta?.find(c=>c.index===r);if(n){let c=s.query[n.query];if(c===void 0)throw new Error(`[Virid Express] Missing Query: "${n.query}"`);return n.pipe&&(c=n.pipe(c)),c}return null}o(de,"getHttpArgs");var le=class le{constructor(){l(this,"name","@virid/express");l(this,"stagingSystemRegister",new m.MessageRegistry);l(this,"httpRouteRegistry",new Map);l(this,"httpContextStore",new Map);l(this,"_internalHttpIdCounter",0)}register(e){let t=e.systemContext,s=e.httpSystemConfig;if(!t||!s)throw new Error(`[Virid HttpSystem] HttpSystem Parameter Loss: Please declare ${e.name} using the @HttpSystem decorator first.`);return this.stagingSystemRegister.register(t.targetClass,e,s.priority),()=>{}}bindRoute(e){let t=Reflect.getMetadata(d.HTTPROUTE,e);if(!t)throw new Error(`[Virid Http] Routing Error: ${e.name} is not a valid HttpRoute`);let s=`${t.method}:${t.path}`;if(this.httpRouteRegistry.has(s))throw new Error(`[Virid Http] Routing Conflict: The request method ${t.method} for path ${t.path} has already been registered by ${e.name}`);this.httpRouteRegistry.set(s,t)}install(e,t){e.spawn(t.server);for(let[s,i]of this.httpRouteRegistry.entries()){let{method:a,path:n,httpMessage:c}=i,h=a.toLowerCase();t.server[h](n,(u,x)=>{let f=this._internalHttpIdCounter++>>>0;new S(f,u,x,Date.now(),n).inc(),this.httpContextStore.set(f,new S(f,u,x,Date.now(),n));let M=new c(f);x.once("finish",()=>this.httpContextStore.delete(f)),x.once("close",()=>this.httpContextStore.delete(f)),m.MessageWriter.write(M)})}for(let[s,i]of this.stagingSystemRegister.systemTaskMap.entries())for(let a of i){let n=a.fn,c=n.systemContext,h=n.httpSystemConfig,{httpMetadata:u,messageClass:x,messageIdx:f}=h,{originalMethod:H,targetClass:M}=c,A=o(Q=>{let g=this.httpContextStore.get(Q.requestId);if(!g)throw new Error(`[Virid Express HttpSystem] Invalid Request Context: The request context for message ${Q.requestId} is missing.`);try{let E=c.params.map((R,pe)=>{if(pe===f)return Q;{let ue=de(pe,g,u);return ue||e.get(R)}}),j=H.apply(M,E);return j instanceof Promise?j.then(R=>{this.handleResult(R,g)}).catch(R=>{throw this.handleResult(B(R),g),R}):this.handleResult(j,g)}catch(E){throw E instanceof w?this.handleResult(E,g):this.handleResult(B(E),g),E}},"wrappedSystem");A.systemContext=c,A.httpSystemConfig=h,e.engine.register(x,A,a.priority)}this.stagingSystemRegister.systemTaskMap.clear()}handleResult(e,t){if(!e){t.dec();return}(Array.isArray(e)?e:[e]).forEach(i=>{i instanceof p?this.handleHttpResponse(i,t):i instanceof w?(t.res.status(i.status).json(i.message),this.httpContextStore.delete(t.id)):i instanceof m.BaseMessage?m.MessageWriter.write(i):m.MessageWriter.warn(`[Virid Express] Invalid Return Type: ${typeof i}. Expected HttpResponse or Message.`)}),t.dec()}handleHttpResponse(e,t){let{res:s}=t;if(e.headers&&Object.entries(e.headers).forEach(([i,a])=>s.setHeader(i,a)),e.status&&s.status(e.status),e instanceof y){t.inc(),s.sendFile(e.filePath,e.options,i=>{s.headersSent||m.MessageWriter.error(i,`[Virid Express] SteamFile Error: Path: ${e.filePath}`),t.res.end(),this.httpContextStore.delete(t.id),t.isClosed=!0,t.dec()});return}if(e instanceof C){let{stream:i}=e;t.inc(),i.pipe(s);let a=o(()=>{this.httpContextStore.has(t.id)&&(t.res.end(),this.httpContextStore.delete(t.id),t.isClosed=!0,t.dec())},"cleanup");i.on("end",a),i.on("error",n=>{s.headersSent||m.MessageWriter.error(n,"[Virid Express] Stream Error"),a()}),i.on("close",a);return}s.status(e.status).json(e.data),this.httpContextStore.delete(t.id)}};o(le,"ExpressPlugin");var ce=le;0&&(module.exports={BadRequest,BadRequestResponse,Body,ConflictResponse,Cookies,Created,CreatedResponse,Ctx,CustomResponse,CustomResponseResponse,ExpressPlugin,Forbidden,ForbiddenResponse,Headers,HttpContext,HttpError,HttpRequestMessage,HttpResponse,HttpRoute,HttpSystem,InternalServerError,InternalServerErrorResponse,NoContent,NoContentResponse,NotFound,NotFoundResponse,Ok,OkResponse,Params,ParseBoolPipe,ParseIntPipe,Query,Req,Res,Stream,StreamFile,StreamFileResponse,StreamResponse,Unauthorized,UnauthorizedResponse,UnprocessableEntityResponse,addAutoPipe,getAutoPipe,getHttpArgs,parseRawCookie});
7
+ Uptime: ${Date.now()-this.timestamp}ms`;he.MessageWriter.error(new Error(e)),this.res.headersSent?this.res.end():this.res.status(500).json({error:"Internal Logic Error",message:"Request processed but no response was returned by any system."})}};o(L,"HttpContext");var S=L,K=class K{constructor(e,t=null,s={}){l(this,"status");l(this,"data");l(this,"headers");this.status=e,this.data=t,this.headers=s}};o(K,"HttpResponse");var p=K,z=class z extends p{constructor(e,t={}){super(200,e,t)}};o(z,"OkResponse");var $=z,F=class F extends p{constructor(e,t={}){super(201,e,t)}};o(F,"CreatedResponse");var q=F,W=class W extends p{constructor(){super(204,null)}};o(W,"NoContentResponse");var V=W,_=class _ extends p{constructor(e="Bad Request"){super(400,{error:e})}};o(_,"BadRequestResponse");var b=_,G=class G extends p{constructor(e="Unauthorized"){super(401,{error:e})}};o(G,"UnauthorizedResponse");var v=G,J=class J extends p{constructor(e="Forbidden"){super(403,{error:e})}};o(J,"ForbiddenResponse");var D=J,Z=class Z extends p{constructor(e="Not Found"){super(404,{error:e})}};o(Z,"NotFoundResponse");var N=Z,k=class k extends p{constructor(e="Conflict"){super(409,{error:e})}};o(k,"ConflictResponse");var Y=k,ee=class ee extends p{constructor(e){super(422,{errors:e})}};o(ee,"UnprocessableEntityResponse");var X=ee,te=class te extends p{constructor(e="Internal Server Error"){super(500,{error:e})}};o(te,"InternalServerErrorResponse");var P=te,re=class re extends p{constructor(e,t,s={}){super(e,t,s)}};o(re,"CustomResponseResponse");var U=re,se=class se extends p{constructor(t,s={dotfiles:"allow"}){super(206,s);l(this,"filePath");l(this,"options");this.filePath=t,this.options=s}};o(se,"StreamFileResponse");var y=se,oe=class oe extends p{constructor(t,s={}){super(s.status||206,{},s.headers);l(this,"stream");l(this,"options");this.stream=t,this.options=s}};o(oe,"StreamResponse");var C=oe,Ae=o((r,e={})=>new $(r,e),"Ok"),Te=o((r,e={})=>new q(r,e),"Created"),Pe=o(()=>new V,"NoContent"),Ie=o((r="Bad Request")=>new b(r),"BadRequest"),He=o((r="Unauthorized")=>new v(r),"Unauthorized"),$e=o((r="Forbidden")=>new D(r),"Forbidden"),qe=o((r="Not Found")=>new N(r),"NotFound"),B=o((r="Internal Server Error")=>r instanceof Error?new P(r.message):new P(r),"InternalServerError"),Ve=o((r,e,t={})=>new U(r,e,t),"CustomResponse"),be=o((r,e)=>new y(r,e),"StreamFile"),ve=o((r,e)=>new C(r,e),"Stream"),ie=class ie extends Error{constructor(t,s){super(s);l(this,"status");l(this,"message");this.status=t,this.message=s}};o(ie,"HttpError");var w=ie;var fe=require("@virid/core");function me(r){let e=parseInt(r,10);if(isNaN(e))throw new w(400,`Validation failed: "${r}" is not a number.`);return e}o(me,"ParseIntPipe");function xe(r){return r==="true"||r==="1"?!0:r==="false"||r==="0"?!1:!!r}o(xe,"ParseBoolPipe");var I=new Map;I.set(Number,me);I.set(Boolean,xe);function De(r,e){if(I.has(r)){fe.MessageWriter.error(new Error(`[Virid Express Pipe] Repeated Pipe: Auto pipe for ${r} has already been registered.`));return}I.set(r,e)}o(De,"addAutoPipe");function Ne(r){return I.get(r)}o(Ne,"getAutoPipe");function ae(r){let e={};if(!r)return e;let t=r.split(";");for(let s of t){let i=s.indexOf("=");if(i===-1)continue;let a=s.substring(0,i).trim();if(!a)continue;let n=s.substring(i+1).trim();n[0]==='"'&&n[n.length-1]==='"'&&(n=n.slice(1,-1));try{e[a]=n.includes("%")?decodeURIComponent(n):n}catch{e[a]=n}}return e}o(ae,"parseRawCookie");var we=require("@virid/core");var ne=class ne extends we.EventMessage{constructor(t){super();l(this,"__virid_express_id");this.__virid_express_id=t}get requestId(){return this.__virid_express_id}};o(ne,"HttpRequestMessage");var O=ne;var Me=require("@virid/core"),d={...Me.VIRID_METADATA,HTTPROUTE:"virid:express:route",HTTPSYSTEM:"virid:express:system",BODY:"virid:express:body",QUERY:"virid:express:query",HEADERS:"virid:express:header",REQUEST:"virid:express:request",RESPONSE:"virid:express:response",CONTEXT:"virid:express:context",PARAMS:"virid:express:params",COOKIES:"virid:express:cookie"};function Ue(r){return e=>{let t=[];r.path.split("/").forEach(a=>{a.startsWith(":")&&t.push(a.substring(1))});let i={...r,httpMessage:e,params:t};Reflect.defineMetadata(d.HTTPROUTE,i,e)}}o(Ue,"HttpRoute");function Be(r){let e=[];if(r.forEach((t,s)=>{(t===O||t&&t.prototype instanceof O)&&e.push({type:t,idx:s})}),e.length===0)return null;if(e.length>1){let t=e.map(s=>`[Index: ${s.idx}, Name: ${s.type.name}]`).join(", ");throw new Error(`[Virid System] Multiple Messages: Multiple Message type parameters detected, this is not allowed! specific location: ${t}`)}return e[0]}o(Be,"checkMessageParam");function Qe(r={priority:0,messageClass:null}){return(e,t,s)=>{if(typeof e!="function")throw new Error(`[Virid System] Method Type Error: The Method ${t} is not a static method, please check if there is a static keyword tag.`);let i=s.value,a=Reflect.getMetadata("design:paramtypes",e,t);if(!a)throw new Error('[Virid System] System Parameter Loss: Unable to recognize system parameters, please confirm if import "reflect-metadata" was introduced at the beginning.');let n=a.map((M,A)=>M===void 0?A:-1).filter(M=>M!==-1);if(n.length>0)throw new Error(`[Virid System] Parameter Metadata Loss in "${t}": One or more parameters have 'undefined' types. This usually happens when you forget to add a type annotation or due to circular dependencies. Check parameter at indices: [${n.join(", ")}]`);let c,h=-1,u=Be(a);if(u&&r.messageClass)throw new Error(`[Virid System] Multiple Messages Are Not Allowed: Cannot specify messageClass in decorator options while already declaring it in method parameters at index ${u.idx} in ${t}.`);if(u)c=u.type,h=u.idx;else if(r.messageClass)c=r.messageClass,h=-1;else throw new Error("[Virid System] System Parameter Loss: Please declare the message type either in method parameters or via the Message decorator options.");let x=_e(e,t),f={params:a,targetClass:e,methodName:t,originalMethod:i},H={httpMetadata:x,messageClass:c,messageIdx:h,priority:r.priority||0,batchMode:!1};s.value.systemContext=f,s.value.httpSystemConfig=H}}o(Qe,"HttpSystem");function je(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.BODY,r,e))throw new Error(`[Virid Express Body] Multiple Body Are Not Allowed: ${e} has multiple @Body() decorators!`);let s={index:t};Reflect.defineMetadata(d.BODY,s,r,e)}}o(je,"Body");function Ye(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.HEADERS,r,e))throw new Error(`[Virid Express Headers] Multiple Header Are Not Allowed: ${e} has multiple @Headers() decorators!`);let s={index:t};Reflect.defineMetadata(d.HEADERS,s,r,e)}}o(Ye,"Headers");function Xe(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.COOKIES,r,e))throw new Error(`[Virid Express Cookies] Multiple Header Are Not Allowed: ${e} has multiple @Cookies() decorators!`);let s={index:t};Reflect.defineMetadata(d.COOKIES,s,r,e)}}o(Xe,"Cookies");function Le(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.REQUEST,r,e))throw new Error(`[Virid Express Req] Multiple Request Objects Are Not Allowed: ${e} has multiple @Req() decorators!`);let s={index:t};Reflect.defineMetadata(d.REQUEST,s,r,e)}}o(Le,"Req");function Ke(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.RESPONSE,r,e))throw new Error(`[Virid Express Res] Multiple Response Objects Are Not Allowed: ${e} has multiple @Res() decorators!`);let s={index:t};Reflect.defineMetadata(d.RESPONSE,s,r,e)}}o(Ke,"Res");function ze(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.CONTEXT,r,e))throw new Error(`[Virid Express Ctx] Multiple Context Objects Are Not Allowed: ${e} has multiple @Ctx() decorators!`);let s={index:t};Reflect.defineMetadata(d.CONTEXT,s,r,e)}}o(ze,"Ctx");function Fe(r,e){return(t,s,i)=>{let n=[...Reflect.getOwnMetadata(d.QUERY,t,s)||[],{index:i,query:r,pipe:e}];Reflect.defineMetadata(d.QUERY,n,t,s)}}o(Fe,"Query");function We(r,e){return(t,s,i)=>{let n=[...Reflect.getOwnMetadata(d.PARAMS,t,s)||[],{index:i,key:r,pipe:e}];Reflect.defineMetadata(d.PARAMS,n,t,s)}}o(We,"Params");function _e(r,e){let t=Reflect.getOwnMetadata(d.BODY,r,e),s=Reflect.getOwnMetadata(d.HEADERS,r,e),i=Reflect.getOwnMetadata(d.COOKIES,r,e),a=Reflect.getOwnMetadata(d.RESPONSE,r,e),n=Reflect.getOwnMetadata(d.REQUEST,r,e),c=Reflect.getOwnMetadata(d.CONTEXT,r,e),h=Reflect.getOwnMetadata(d.QUERY,r,e)||[],u=Reflect.getOwnMetadata(d.PARAMS,r,e)||[];return{bodyMeta:t,headerMeta:s,queryMeta:h,paramMeta:u,cookiesMeta:i,reqMeta:n,resMeta:a,ctxMeta:c}}o(_e,"getHttpMetadata");function de(r,e,t){let{req:s,res:i}=e;if(t.ctxMeta?.index===r)return e;let a=t.paramMeta?.find(c=>c.index===r);if(a){let c=a.key?s.params[a.key]:s.params;return a.pipe&&c!==void 0&&(c=a.pipe(c)),c}if(t.bodyMeta?.index===r)return s.body;if(t.headerMeta?.index===r)return s.headers;if(t.cookiesMeta?.index===r)return ae(s.headers.cookie);if(t.reqMeta?.index===r)return s;if(t.resMeta?.index===r)return i;let n=t.queryMeta?.find(c=>c.index===r);if(n){let c=s.query[n.query];if(c===void 0)throw new Error(`[Virid Express] Missing Query: "${n.query}"`);return n.pipe&&(c=n.pipe(c)),c}return null}o(de,"getHttpArgs");var le=class le{constructor(){l(this,"name","@virid/express");l(this,"stagingSystemRegister",new m.MessageRegistry);l(this,"httpRouteRegistry",new Map);l(this,"httpContextStore",new Map);l(this,"_internalHttpIdCounter",0)}register(e){let t=e.systemContext,s=e.httpSystemConfig;if(!t||!s)throw new Error(`[Virid HttpSystem] HttpSystem Parameter Loss: Please declare ${e.name} using the @HttpSystem decorator first.`);return this.stagingSystemRegister.register(t.targetClass,e,s.priority),()=>{}}bindRoute(e){let t=Reflect.getMetadata(d.HTTPROUTE,e);if(!t)throw new Error(`[Virid Http] Routing Error: ${e.name} is not a valid HttpRoute`);let s=`${t.method}:${t.path}`;if(this.httpRouteRegistry.has(s))throw new Error(`[Virid Http] Routing Conflict: The request method ${t.method} for path ${t.path} has already been registered by ${e.name}`);this.httpRouteRegistry.set(s,t)}install(e,t){for(let[s,i]of this.httpRouteRegistry.entries()){let{method:a,path:n,httpMessage:c}=i,h=a.toLowerCase();t.server[h](n,(u,x)=>{let f=this._internalHttpIdCounter++>>>0;new S(f,u,x,Date.now(),n).inc(),this.httpContextStore.set(f,new S(f,u,x,Date.now(),n));let M=new c(f);x.once("finish",()=>this.httpContextStore.delete(f)),x.once("close",()=>this.httpContextStore.delete(f)),m.MessageWriter.write(M)})}for(let[s,i]of this.stagingSystemRegister.systemTaskMap.entries())for(let a of i){let n=a.fn,c=n.systemContext,h=n.httpSystemConfig,{httpMetadata:u,messageClass:x,messageIdx:f}=h,{originalMethod:H,targetClass:M}=c,A=o(Q=>{let g=this.httpContextStore.get(Q.requestId);if(!g)throw new Error(`[Virid Express HttpSystem] Invalid Request Context: The request context for message ${Q.requestId} is missing.`);try{let E=c.params.map((R,pe)=>{if(pe===f)return Q;{let ue=de(pe,g,u);return ue||e.get(R)}}),j=H.apply(M,E);return j instanceof Promise?j.then(R=>{this.handleResult(R,g)}).catch(R=>{throw this.handleResult(B(R),g),R}):this.handleResult(j,g)}catch(E){throw E instanceof w?this.handleResult(E,g):this.handleResult(B(E),g),E}},"wrappedSystem");A.systemContext=c,A.httpSystemConfig=h,e.engine.register(x,A,a.priority)}this.stagingSystemRegister.systemTaskMap.clear()}handleResult(e,t){if(!e){t.dec();return}(Array.isArray(e)?e:[e]).forEach(i=>{i instanceof p?this.handleHttpResponse(i,t):i instanceof w?(t.res.status(i.status).json(i.message),this.httpContextStore.delete(t.id)):i instanceof m.BaseMessage?m.MessageWriter.write(i):m.MessageWriter.warn(`[Virid Express] Invalid Return Type: ${typeof i}. Expected HttpResponse or Message.`)}),t.dec()}handleHttpResponse(e,t){let{res:s}=t;if(e.headers&&Object.entries(e.headers).forEach(([i,a])=>s.setHeader(i,a)),e.status&&s.status(e.status),e instanceof y){t.inc(),s.sendFile(e.filePath,e.options,i=>{s.headersSent||m.MessageWriter.error(i,`[Virid Express] SteamFile Error: Path: ${e.filePath}`),t.res.end(),this.httpContextStore.delete(t.id),t.isClosed=!0,t.dec()});return}if(e instanceof C){let{stream:i}=e;t.inc(),i.pipe(s);let a=o(()=>{this.httpContextStore.has(t.id)&&(t.res.end(),this.httpContextStore.delete(t.id),t.isClosed=!0,t.dec())},"cleanup");i.on("end",a),i.on("error",n=>{s.headersSent||m.MessageWriter.error(n,"[Virid Express] Stream Error"),a()}),i.on("close",a);return}s.status(e.status).json(e.data),this.httpContextStore.delete(t.id)}};o(le,"ExpressPlugin");var ce=le;0&&(module.exports={BadRequest,BadRequestResponse,Body,ConflictResponse,Cookies,Created,CreatedResponse,Ctx,CustomResponse,CustomResponseResponse,ExpressPlugin,Forbidden,ForbiddenResponse,Headers,HttpContext,HttpError,HttpRequestMessage,HttpResponse,HttpRoute,HttpSystem,InternalServerError,InternalServerErrorResponse,NoContent,NoContentResponse,NotFound,NotFoundResponse,Ok,OkResponse,Params,ParseBoolPipe,ParseIntPipe,Query,Req,Res,Stream,StreamFile,StreamFileResponse,StreamResponse,Unauthorized,UnauthorizedResponse,UnprocessableEntityResponse,addAutoPipe,getAutoPipe,getHttpArgs,parseRawCookie});
8
8
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/http/response.ts","../src/http/utils.ts","../src/http/message.ts","../src/decorators/constant.ts","../src/decorators/decorator.ts"],"sourcesContent":["/*\n * Copyright (c) 2026-present Ailrid\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Description: Add express functionality to virid.\n */\nimport {\n ViridPlugin,\n type ViridApp,\n MessageRegistry,\n MessageWriter,\n Newable,\n SystemContext,\n BaseMessage,\n} from \"@virid/core\";\nimport { getHttpArgs } from \"./decorators\";\nimport {\n HttpSystemConfig,\n type HttpMethod,\n type HttpRouteInfo,\n} from \"./interfaces\";\n\nimport {\n HttpContext,\n HttpError,\n HttpRequestMessage,\n HttpResponse,\n InternalServerError,\n RequestId,\n StreamFileResponse,\n StreamResponse,\n} from \"./http\";\n\nimport { PluginOptions } from \"./interfaces\";\nimport { type Request, type Response } from \"express\";\nimport { VIRID_EXPRESS_METADATA } from \"./decorators/constant\";\nexport * from \"./http\";\nexport * from \"./decorators\";\n\nexport class ExpressPlugin implements ViridPlugin<PluginOptions> {\n name = \"@virid/express\";\n // temporary Registry\n private stagingSystemRegister = new MessageRegistry();\n // route Registry\n private httpRouteRegistry = new Map<string, HttpRouteInfo>();\n\n private httpContextStore = new Map<number, HttpContext>();\n\n private _internalHttpIdCounter = 0;\n\n register(systemFn: (...args: any[]) => any): () => void {\n // @ts-expect-error: get systemContext from systemFn\n const systemContext: SystemContext = systemFn.systemContext;\n // @ts-expect-error: get httpSystemConfig from systemFn\n const httpSystemConfig: HttpSystemConfig = systemFn.httpSystemConfig;\n if (!systemContext || !httpSystemConfig) {\n throw new Error(\n `[Virid HttpSystem] HttpSystem Parameter Loss: Please declare ${systemFn.name} using the @HttpSystem decorator first.`,\n );\n }\n this.stagingSystemRegister.register(\n systemContext.targetClass,\n systemFn,\n httpSystemConfig.priority,\n );\n return () => {};\n }\n\n bindRoute(constructor: Newable<HttpRequestMessage>) {\n const config: HttpRouteInfo = Reflect.getMetadata(\n VIRID_EXPRESS_METADATA.HTTPROUTE,\n constructor,\n );\n if (!config) {\n throw new Error(\n `[Virid Http] Routing Error: ${constructor.name} is not a valid HttpRoute`,\n );\n }\n // Uniqueness verification: Combining Method and Path\n const routeKey = `${config.method}:${config.path}`;\n if (this.httpRouteRegistry.has(routeKey)) {\n throw new Error(\n `[Virid Http] Routing Conflict: The request method ${config.method} for path ${config.path} has already been registered by ${constructor.name}`,\n );\n } else {\n this.httpRouteRegistry.set(routeKey, config);\n }\n }\n\n install(app: ViridApp, options: PluginOptions) {\n app.spawn(options.server);\n // register for express routing\n for (const [_, routeInfo] of this.httpRouteRegistry.entries()) {\n const { method, path, httpMessage } = routeInfo;\n const expressMethod = method.toLowerCase() as HttpMethod;\n\n options.server[expressMethod](path, (req: Request, res: Response) => {\n // instantiate Message\n const newId = this._internalHttpIdCounter++ >>> 0;\n\n // save contextual information\n const context = new HttpContext(newId, req, res, Date.now(), path);\n context.inc();\n this.httpContextStore.set(\n newId,\n new HttpContext(newId, req, res, Date.now(), path),\n );\n const message = new httpMessage(newId as RequestId);\n // finish means the response has been sent, close means the connection was unexpectedly interrupted, both should be cleaned up\n res.once(\"finish\", () => this.httpContextStore.delete(newId));\n res.once(\"close\", () => this.httpContextStore.delete(newId));\n // send message\n MessageWriter.write(message);\n });\n }\n\n // register HttpSystem into the app's scheduler\n for (const [\n messageClass,\n systemTasks,\n ] of this.stagingSystemRegister.systemTaskMap.entries()) {\n for (const task of systemTasks) {\n const systemFn = task.fn;\n // @ts-expect-error: get systemContext from systemFn\n const systemContext: SystemContext = systemFn.systemContext;\n // @ts-expect-error: get httpSystemConfig from systemFn\n const httpSystemConfig: HttpSystemConfig = systemFn.httpSystemConfig;\n const { httpMetadata, messageClass, messageIdx } = httpSystemConfig;\n const { originalMethod, targetClass } = systemContext;\n const wrappedSystem = (currentMessage: HttpRequestMessage) => {\n // retrieve the context of the current request\n const context = this.httpContextStore.get(currentMessage.requestId);\n if (!context) {\n throw new Error(\n `[Virid Express HttpSystem] Invalid Request Context: The request context for message ${currentMessage.requestId} is missing.`,\n );\n }\n try {\n const args = systemContext.params.map(\n (type: any, index: number) => {\n // If it is a message, inject\n if (index === messageIdx) {\n return currentMessage;\n } else {\n // Otherwise, try injecting HTTP parameters or components\n const arg = getHttpArgs(index, context, httpMetadata);\n return arg ? arg : app.get(type);\n }\n },\n );\n const result = originalMethod.apply(targetClass, args);\n return result instanceof Promise\n ? result\n .then((res) => {\n this.handleResult(res, context);\n })\n .catch((error) => {\n // asynchronous error needs to send 500 to the client\n this.handleResult(InternalServerError(error), context);\n // continue throwing, let Dispatcher capture and print detailed stack\n throw error;\n })\n : this.handleResult(result, context);\n } catch (error) {\n if (error instanceof HttpError) {\n // if manually throw new HttpError\n this.handleResult(error, context);\n } else {\n // real crash, return 500\n this.handleResult(InternalServerError(error as Error), context);\n }\n throw error; // continue throwing, let Dispatcher capture and print detailed stack\n }\n };\n wrappedSystem.systemContext = systemContext;\n wrappedSystem.httpSystemConfig = httpSystemConfig;\n app.engine.register(messageClass, wrappedSystem, task.priority);\n }\n }\n this.stagingSystemRegister.systemTaskMap.clear();\n }\n\n handleResult(res: any, context: HttpContext) {\n if (!res) {\n context.dec();\n return;\n }\n const results = Array.isArray(res) ? res : [res];\n results.forEach((item) => {\n if (item instanceof HttpResponse) {\n // if it is a termination response, handle it\n this.handleHttpResponse(item, context);\n } else if (item instanceof HttpError) {\n // handling errors\n context.res.status(item.status).json(item.message);\n this.httpContextStore.delete(context.id);\n } else if (item instanceof BaseMessage) {\n MessageWriter.write(item);\n } else {\n MessageWriter.warn(\n `[Virid Express] Invalid Return Type: ${typeof item}. Expected HttpResponse or Message.`,\n );\n }\n });\n //Whether the system encounters an error or completes execution, handleResult will execute with a reference count of -1 and check if it is 0\n //If it is 0 and it has not been closed yet, then force it to close\n //The first scenario: If handleHttpResponse is executed above, then HttpContext has already been deleted before that\n //The second scenario: If the HttpRequestMessage is forwarded above, it will erase the trace of the system execution, but the HttpContext will not be deleted due to reference counting\n //The third scenario: If other messages or return values are forwarded above, the reference count will be -1 and checked if it is 0. If it is 0, it will be forcibly closed\n context.dec();\n }\n\n handleHttpResponse(response: HttpResponse, ctx: HttpContext) {\n const { res } = ctx;\n\n if (response.headers) {\n Object.entries(response.headers).forEach(([k, v]) => res.setHeader(k, v));\n }\n\n if (response.status) res.status(response.status);\n\n if (response instanceof StreamFileResponse) {\n // return asynchronous stream and forcefully add an RC extension\n ctx.inc();\n res.sendFile(response.filePath, response.options, (err) => {\n if (!res.headersSent) {\n MessageWriter.error(\n err,\n `[Virid Express] SteamFile Error: Path: ${response.filePath}`,\n );\n }\n ctx.res.end();\n this.httpContextStore.delete(ctx.id);\n ctx.isClosed = true;\n ctx.dec();\n });\n return;\n }\n if (response instanceof StreamResponse) {\n const { stream } = response;\n ctx.inc();\n stream.pipe(res);\n // end of listening, harvest context\n const cleanup = () => {\n if (!this.httpContextStore.has(ctx.id)) return;\n ctx.res.end();\n this.httpContextStore.delete(ctx.id);\n ctx.isClosed = true;\n ctx.dec();\n };\n stream.on(\"end\", cleanup);\n stream.on(\"error\", (err) => {\n if (!res.headersSent) {\n MessageWriter.error(err, `[Virid Express] Stream Error`);\n }\n cleanup();\n });\n stream.on(\"close\", cleanup);\n return;\n }\n\n res.status(response.status).json(response.data);\n this.httpContextStore.delete(ctx.id);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { type Request, type Response } from \"express\";\nimport { Readable } from \"stream\";\nimport { MessageWriter } from \"@virid/core\";\ninterface HttpHeaders {\n [key: string]: string | string[];\n}\nexport class HttpContext {\n public rc: number = 0;\n public isClosed: boolean = false;\n\n constructor(\n public readonly id: number,\n public readonly req: Request,\n public readonly res: Response,\n public readonly timestamp: number,\n public readonly route: string,\n ) {}\n\n inc() {\n this.rc++;\n }\n\n dec() {\n this.rc--;\n if (this.rc === 0) {\n this.tryFinalize();\n }\n }\n\n private tryFinalize() {\n if (this.res.writableEnded || this.isClosed) return;\n\n this.isClosed = true;\n\n const errorMsg = `[Virid Express] Request Orphaned: The connection was closed because all systems finished execution without sending a response. \n Route: ${this.route}\n Uptime: ${Date.now() - this.timestamp}ms`;\n\n MessageWriter.error(new Error(errorMsg));\n\n if (!this.res.headersSent) {\n this.res.status(500).json({\n error: \"Internal Logic Error\",\n message:\n \"Request processed but no response was returned by any system.\",\n });\n } else {\n this.res.end();\n }\n }\n}\n\nexport abstract class HttpResponse {\n constructor(\n public status: number,\n public data: any = null,\n public headers: HttpHeaders = {},\n ) {}\n}\n\n// --- 2xx Success ---\nexport class OkResponse extends HttpResponse {\n constructor(data: any, headers: HttpHeaders = {}) {\n super(200, data, headers);\n }\n}\n\nexport class CreatedResponse extends HttpResponse {\n constructor(data: any, headers: HttpHeaders = {}) {\n super(201, data, headers);\n }\n}\n\nexport class NoContentResponse extends HttpResponse {\n constructor() {\n super(204, null);\n }\n}\n\n// --- 4xx Client Error ---\nexport class BadRequestResponse extends HttpResponse {\n constructor(message: string = \"Bad Request\") {\n super(400, { error: message });\n }\n}\n\nexport class UnauthorizedResponse extends HttpResponse {\n constructor(message: string = \"Unauthorized\") {\n super(401, { error: message });\n }\n}\n\nexport class ForbiddenResponse extends HttpResponse {\n constructor(message: string = \"Forbidden\") {\n super(403, { error: message });\n }\n}\n\nexport class NotFoundResponse extends HttpResponse {\n constructor(message: string = \"Not Found\") {\n super(404, { error: message });\n }\n}\n\nexport class ConflictResponse extends HttpResponse {\n constructor(message: string = \"Conflict\") {\n super(409, { error: message });\n }\n}\n\nexport class UnprocessableEntityResponse extends HttpResponse {\n constructor(errors: any) {\n super(422, { errors });\n }\n}\n\n// --- 5xx Server Error ---\nexport class InternalServerErrorResponse extends HttpResponse {\n constructor(message: string = \"Internal Server Error\") {\n super(500, { error: message });\n }\n}\n\n// --- 万能类 (Custom) ---\nexport class CustomResponseResponse extends HttpResponse {\n constructor(status: number, data: any, headers: HttpHeaders = {}) {\n super(status, data, headers);\n }\n}\n/**\n * @description: Express sendFile 配置项的强类型定义\n */\nexport interface StreamFileOptions {\n /** 根目录(如果 path 是相对路径则必填) */\n root?: string;\n /** * 对以 . 开头的文件处理策略:\n * - allow: 允许发送\n * - deny: 拒绝并返回 403\n * - ignore: 当作不存在返回 404\n */\n dotfiles?: \"allow\" | \"deny\" | \"ignore\";\n /** 是否发送 ETag */\n etag?: boolean;\n /** 扩展的 HTTP 响应头 */\n headers?: HttpHeaders;\n /** 缓存最大时长 (毫秒) */\n maxAge?: number | string;\n /** 是否在 Cache-Control 中添加 immutable */\n immutable?: boolean;\n /** 是否根据文件系统设置 Last-Modified */\n lastModified?: boolean;\n /** 是否支持断点续传 (Range 请求) */\n acceptRanges?: boolean;\n}\nexport class StreamFileResponse extends HttpResponse {\n constructor(\n public readonly filePath: string,\n public readonly options: StreamFileOptions = { dotfiles: \"allow\" },\n ) {\n super(206, options);\n }\n}\n\nexport class StreamResponse extends HttpResponse {\n constructor(\n public readonly stream: Readable,\n public readonly options: {\n status?: number;\n headers?: HttpHeaders;\n } = {},\n ) {\n super(options.status || 206, {}, options.headers);\n }\n}\n\n/** 200 OK */\nexport const Ok = (data: any, headers: HttpHeaders = {}) =>\n new OkResponse(data, headers);\n\n/** 201 Created */\nexport const Created = (data: any, headers: HttpHeaders = {}) =>\n new CreatedResponse(data, headers);\n\n/** 204 No Content */\nexport const NoContent = () => new NoContentResponse();\n\n/** 400 Bad Request */\nexport const BadRequest = (msg = \"Bad Request\") => new BadRequestResponse(msg);\n\n/** 401 Unauthorized */\nexport const Unauthorized = (msg = \"Unauthorized\") =>\n new UnauthorizedResponse(msg);\n\n/** 403 Forbidden */\nexport const Forbidden = (msg = \"Forbidden\") => new ForbiddenResponse(msg);\n\n/** 404 Not Found */\nexport const NotFound = (msg = \"Not Found\") => new NotFoundResponse(msg);\n\n/** 500 Internal Error */\nexport const InternalServerError = (\n msg: string | Error = \"Internal Server Error\",\n) => {\n return msg instanceof Error\n ? new InternalServerErrorResponse(msg.message)\n : new InternalServerErrorResponse(msg);\n};\n\nexport const CustomResponse = (\n status: number,\n data: any,\n headers: HttpHeaders = {},\n) => new CustomResponseResponse(status, data, headers);\n\n/** 发送本地文件 (自动处理 Range/206) */\nexport const StreamFile = (path: string, options?: StreamFileOptions) =>\n new StreamFileResponse(path, options);\n/**\n * 发送流响应\n */\nexport const Stream = (stream: Readable, options?: StreamResponse[\"options\"]) =>\n new StreamResponse(stream, options);\n\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n public readonly message: string,\n ) {\n super(message);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { MessageWriter } from \"@virid/core\";\nimport { HttpError } from \".\";\nimport { type TransformPipe } from \"../interfaces\";\n\nexport function ParseIntPipe(val: string) {\n const res = parseInt(val, 10);\n if (isNaN(res))\n throw new HttpError(400, `Validation failed: \"${val}\" is not a number.`);\n return res;\n}\n\nexport function ParseBoolPipe(val: string) {\n if (val === \"true\" || val === \"1\") return true;\n if (val === \"false\" || val === \"0\") return false;\n return !!val;\n}\n\nconst autoPipeMap = new Map<any, TransformPipe<any>>();\nautoPipeMap.set(Number, ParseIntPipe);\nautoPipeMap.set(Boolean, ParseBoolPipe);\n\nexport function addAutoPipe<T>(type: T, pipe: TransformPipe<T>) {\n if (autoPipeMap.has(type)) {\n MessageWriter.error(\n new Error(\n `[Virid Express Pipe] Repeated Pipe: Auto pipe for ${type} has already been registered.`,\n ),\n );\n return;\n }\n autoPipeMap.set(type, pipe);\n}\n\nexport function getAutoPipe<T>(type: T): TransformPipe<T> | undefined {\n return autoPipeMap.get(type);\n}\n\nexport function parseRawCookie(\n cookieHeader: string | undefined,\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n if (!cookieHeader) return result;\n const pairs = cookieHeader.split(\";\");\n\n for (const pair of pairs) {\n const indexOfEq = pair.indexOf(\"=\");\n if (indexOfEq === -1) continue;\n\n // 提取 key 和 value,并进行 trim 处理\n const key = pair.substring(0, indexOfEq).trim();\n if (!key) continue;\n\n let value = pair.substring(indexOfEq + 1).trim();\n\n if (value[0] === '\"' && value[value.length - 1] === '\"') {\n value = value.slice(1, -1);\n }\n\n try {\n result[key] = value.includes(\"%\") ? decodeURIComponent(value) : value;\n } catch (e) {\n result[key] = value;\n }\n }\n\n return result;\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { EventMessage } from \"@virid/core\";\nexport type RequestId = number & { readonly __brand: unique symbol };\n\nexport class HttpRequestMessage extends EventMessage {\n // ID must be of type RequestId\n constructor(private readonly __virid_express_id: RequestId) {\n super();\n }\n // expose a read-only attribute for use by the business layer\n public get requestId(): RequestId {\n return this.__virid_express_id;\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { VIRID_METADATA } from \"@virid/core\";\n\nexport const VIRID_EXPRESS_METADATA = {\n ...VIRID_METADATA,\n HTTPROUTE: \"virid:express:route\",\n HTTPSYSTEM: \"virid:express:system\",\n BODY: \"virid:express:body\",\n QUERY: \"virid:express:query\",\n HEADERS: \"virid:express:header\",\n REQUEST: \"virid:express:request\",\n RESPONSE: \"virid:express:response\",\n CONTEXT: \"virid:express:context\",\n PARAMS: \"virid:express:params\",\n COOKIES: \"virid:express:cookie\",\n} as const;\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { type Newable, type SystemContext } from \"@virid/core\";\nimport {\n type HttpRouteConfig,\n type HttpRouteInfo,\n type BodyMetadata,\n type HeaderMetadata,\n type QueryMetadata,\n type RequestMetadata,\n type ResponseMetadata,\n type ContextMetadata,\n type ParamMetadata,\n type TransformPipe,\n type CookieMetadata,\n type HttpSystemParams,\n type HttpMetadata,\n type HttpSystemConfig,\n} from \"../interfaces\";\nimport { HttpContext, HttpRequestMessage, parseRawCookie } from \"../http\";\n\nimport { VIRID_EXPRESS_METADATA } from \"./constant\";\n\nexport function HttpRoute(config: HttpRouteConfig) {\n return (constructor: Newable<HttpRequestMessage>) => {\n const params: string[] = [];\n const pathParts = config.path.split(\"/\");\n pathParts.forEach((part) => {\n if (part.startsWith(\":\")) {\n params.push(part.substring(1));\n }\n });\n\n const routeInfo: HttpRouteInfo = {\n ...config,\n httpMessage: constructor,\n params,\n };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.HTTPROUTE,\n routeInfo,\n constructor,\n );\n };\n}\n\n/**\n * Check if there are multiple message type parameters in the parameters\n * @param types Parameter list\n */\nfunction checkMessageParam(types: Array<any>) {\n const foundMatches: { type: Newable<HttpRequestMessage>; idx: number }[] = [];\n\n types.forEach((type, idx) => {\n const isHttpRequestMessage =\n type === HttpRequestMessage ||\n (type && type.prototype instanceof HttpRequestMessage);\n\n if (isHttpRequestMessage) {\n foundMatches.push({ type, idx });\n }\n });\n\n if (foundMatches.length === 0) {\n return null;\n }\n\n if (foundMatches.length > 1) {\n const errorDetails = foundMatches\n .map((item) => `[Index: ${item.idx}, Name: ${item.type.name}]`)\n .join(\", \");\n\n throw new Error(\n `[Virid System] Multiple Messages: Multiple Message type parameters detected, this is not allowed! specific location: ${errorDetails}`,\n );\n }\n\n return foundMatches[0];\n}\n\n/**\n * @description: 系统装饰器\n * @param priority 优先级,数值越大越早执行\n */\nexport function HttpSystem(\n params: HttpSystemParams = {\n priority: 0,\n messageClass: null,\n },\n) {\n return (target: any, key: string, descriptor: PropertyDescriptor) => {\n if (typeof target !== \"function\") {\n throw new Error(\n `[Virid System] Method Type Error: The Method ${key} is not a static method, please check if there is a static keyword tag.`,\n );\n }\n\n const originalMethod = descriptor.value;\n const types: Array<any> = Reflect.getMetadata(\n \"design:paramtypes\",\n target,\n key,\n );\n\n // Verify if metadata exists\n if (!types) {\n throw new Error(\n `[Virid System] System Parameter Loss: Unable to recognize system parameters, please confirm if import \"reflect-metadata\" was introduced at the beginning.`,\n );\n }\n\n // Verify if there are undefined parameters\n const undefinedIndices = types\n .map((t, i) => (t === undefined ? i : -1))\n .filter((i) => i !== -1);\n if (undefinedIndices.length > 0) {\n throw new Error(\n `[Virid System] Parameter Metadata Loss in \"${key}\": One or more parameters have 'undefined' types. This usually happens when you forget to add a type annotation or due to circular dependencies. Check parameter at indices: [${undefinedIndices.join(\", \")}]`,\n );\n }\n\n let messageClass: Newable<HttpRequestMessage>;\n // eslint-disable-next-line no-useless-assignment\n let messageIdx: number = -1;\n const matchedMessage = checkMessageParam(types); // { type: any, idx: number } | null\n if (matchedMessage && params.messageClass) {\n throw new Error(\n `[Virid System] Multiple Messages Are Not Allowed: Cannot specify messageClass in decorator options while already declaring it in method parameters at index ${matchedMessage.idx} in ${key}.`,\n );\n }\n\n if (matchedMessage) {\n messageClass = matchedMessage.type;\n messageIdx = matchedMessage.idx; // In single mode, idx points to the location of a specific BaseMessage subclass\n } else if (params.messageClass) {\n messageClass = params.messageClass;\n messageIdx = -1; // Only provided in the configuration, cannot be found in the parameters, set to -1\n } else {\n throw new Error(\n `[Virid System] System Parameter Loss: Please declare the message type either in method parameters or via the Message decorator options.`,\n );\n }\n const httpMetadata = getHttpMetadata(target, key);\n\n // Attach contextual information to the packaged function\n const systemContext: SystemContext = {\n params: types,\n targetClass: target,\n methodName: key,\n originalMethod: originalMethod,\n };\n const httpSystemConfig: HttpSystemConfig = {\n httpMetadata: httpMetadata,\n messageClass: messageClass,\n messageIdx: messageIdx,\n priority: params.priority || 0,\n batchMode: false,\n };\n\n // Purely mounting data without changing the execution logic of the original method\n (descriptor.value as any).systemContext = systemContext;\n (descriptor.value as any).httpSystemConfig = httpSystemConfig;\n };\n}\n\nexport function Body() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.BODY, target, key)) {\n throw new Error(\n `[Virid Express Body] Multiple Body Are Not Allowed: ${key} has multiple @Body() decorators!`,\n );\n }\n const bodyMetadata = { index } as BodyMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.BODY,\n bodyMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Headers() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.HEADERS, target, key)) {\n throw new Error(\n `[Virid Express Headers] Multiple Header Are Not Allowed: ${key} has multiple @Headers() decorators!`,\n );\n }\n const headerMetadata = { index } as HeaderMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.HEADERS,\n headerMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Cookies() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.COOKIES, target, key)) {\n throw new Error(\n `[Virid Express Cookies] Multiple Header Are Not Allowed: ${key} has multiple @Cookies() decorators!`,\n );\n }\n const cookiesMetadata = { index } as CookieMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.COOKIES,\n cookiesMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Req() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.REQUEST, target, key)) {\n throw new Error(\n `[Virid Express Req] Multiple Request Objects Are Not Allowed: ${key} has multiple @Req() decorators!`,\n );\n }\n const requestMetadata: RequestMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.REQUEST,\n requestMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Res() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.RESPONSE, target, key)) {\n throw new Error(\n `[Virid Express Res] Multiple Response Objects Are Not Allowed: ${key} has multiple @Res() decorators!`,\n );\n }\n const responseMetadata: ResponseMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.RESPONSE,\n responseMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Ctx() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.CONTEXT, target, key)) {\n throw new Error(\n `[Virid Express Ctx] Multiple Context Objects Are Not Allowed: ${key} has multiple @Ctx() decorators!`,\n );\n }\n const contextMetadata: ContextMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.CONTEXT,\n contextMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Query(query: string, pipe?: TransformPipe<any>) {\n return (target: any, key: string, index: number) => {\n const existingMetadata: QueryMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.QUERY, target, key) || [];\n const newMetadata = [...existingMetadata, { index, query, pipe }];\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.QUERY,\n newMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Params(key?: string, pipe?: TransformPipe<any>) {\n return (target: any, keyName: string, index: number) => {\n const existingMetadata: ParamMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.PARAMS, target, keyName) ||\n [];\n const newMetadata = [...existingMetadata, { index, key, pipe }];\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.PARAMS,\n newMetadata,\n target,\n keyName,\n );\n };\n}\n\nfunction getHttpMetadata(target: any, key: string): HttpMetadata {\n const bodyMeta: BodyMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.BODY,\n target,\n key,\n );\n const headerMeta: HeaderMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.HEADERS,\n target,\n key,\n );\n const cookiesMeta: CookieMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.COOKIES,\n target,\n key,\n );\n\n const resMeta: ResponseMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.RESPONSE,\n target,\n key,\n );\n const reqMeta: RequestMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.REQUEST,\n target,\n key,\n );\n const ctxMeta: ContextMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.CONTEXT,\n target,\n key,\n );\n\n const queryMeta: QueryMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.QUERY, target, key) || [];\n\n const paramMeta: ParamMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.PARAMS, target, key) || [];\n\n return {\n bodyMeta,\n headerMeta,\n queryMeta,\n paramMeta,\n cookiesMeta,\n reqMeta,\n resMeta,\n ctxMeta,\n };\n}\n\nexport function getHttpArgs(\n index: number,\n context: HttpContext,\n httpMetadata: HttpMetadata,\n): any {\n const { req, res } = context;\n\n // 匹配 @Ctx()\n if (httpMetadata.ctxMeta?.index === index) return context;\n\n // 匹配 @Param() -> 获取路由参数 (:id 等)\n const paramItem = httpMetadata.paramMeta?.find((p) => p.index === index);\n if (paramItem) {\n let val = paramItem.key ? req.params[paramItem.key] : req.params;\n\n // 如果有 Pipe 且值不是 undefined,进行转换\n if (paramItem.pipe && val !== undefined) {\n val = paramItem.pipe(val);\n }\n return val;\n }\n\n // @Body()\n if (httpMetadata.bodyMeta?.index === index) return req.body;\n\n // @Header()\n if (httpMetadata.headerMeta?.index === index) return req.headers;\n\n // @Cookie()\n if (httpMetadata.cookiesMeta?.index === index)\n return parseRawCookie(req.headers.cookie);\n\n // @Req() 和 @Res()\n if (httpMetadata.reqMeta?.index === index) return req;\n if (httpMetadata.resMeta?.index === index) return res;\n\n // @Query('name')\n const queryItem = httpMetadata.queryMeta?.find((q) => q.index === index);\n if (queryItem) {\n let val = req.query[queryItem.query];\n if (val === undefined) {\n throw new Error(`[Virid Express] Missing Query: \"${queryItem.query}\"`);\n }\n\n if (queryItem.pipe) {\n val = queryItem.pipe(val);\n }\n return val;\n }\n return null;\n}\n"],"mappings":"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","names":["index_exports","__export","BadRequest","BadRequestResponse","Body","ConflictResponse","Cookies","Created","CreatedResponse","Ctx","CustomResponse","CustomResponseResponse","ExpressPlugin","Forbidden","ForbiddenResponse","Headers","HttpContext","HttpError","HttpRequestMessage","HttpResponse","HttpRoute","HttpSystem","InternalServerError","InternalServerErrorResponse","NoContent","NoContentResponse","NotFound","NotFoundResponse","Ok","OkResponse","Params","ParseBoolPipe","ParseIntPipe","Query","Req","Res","Stream","StreamFile","StreamFileResponse","StreamResponse","Unauthorized","UnauthorizedResponse","UnprocessableEntityResponse","addAutoPipe","getAutoPipe","getHttpArgs","parseRawCookie","__toCommonJS","import_core","import_core","HttpContext","id","req","res","timestamp","route","rc","isClosed","inc","dec","tryFinalize","writableEnded","errorMsg","Date","now","MessageWriter","error","Error","headersSent","end","status","json","message","_HttpContext","HttpResponse","data","headers","_HttpResponse","OkResponse","_OkResponse","CreatedResponse","_CreatedResponse","NoContentResponse","_NoContentResponse","BadRequestResponse","_BadRequestResponse","UnauthorizedResponse","_UnauthorizedResponse","ForbiddenResponse","_ForbiddenResponse","NotFoundResponse","_NotFoundResponse","ConflictResponse","_ConflictResponse","UnprocessableEntityResponse","errors","_UnprocessableEntityResponse","InternalServerErrorResponse","_InternalServerErrorResponse","CustomResponseResponse","_CustomResponseResponse","StreamFileResponse","filePath","options","dotfiles","_StreamFileResponse","StreamResponse","stream","_StreamResponse","Ok","__name","Created","NoContent","BadRequest","msg","Unauthorized","Forbidden","NotFound","InternalServerError","CustomResponse","StreamFile","path","Stream","HttpError","_HttpError","import_core","ParseIntPipe","val","res","parseInt","isNaN","HttpError","ParseBoolPipe","autoPipeMap","Map","set","Number","Boolean","addAutoPipe","type","pipe","has","MessageWriter","error","Error","getAutoPipe","get","parseRawCookie","cookieHeader","result","pairs","split","pair","indexOfEq","indexOf","key","substring","trim","value","length","slice","includes","decodeURIComponent","import_core","HttpRequestMessage","EventMessage","__virid_express_id","requestId","_HttpRequestMessage","import_core","VIRID_EXPRESS_METADATA","VIRID_METADATA","HTTPROUTE","HTTPSYSTEM","BODY","QUERY","HEADERS","REQUEST","RESPONSE","CONTEXT","PARAMS","COOKIES","HttpRoute","config","constructor","params","path","split","forEach","part","startsWith","push","substring","routeInfo","httpMessage","Reflect","defineMetadata","VIRID_EXPRESS_METADATA","HTTPROUTE","checkMessageParam","types","foundMatches","type","idx","HttpRequestMessage","prototype","length","errorDetails","map","item","name","join","Error","HttpSystem","priority","messageClass","target","key","descriptor","originalMethod","value","getMetadata","undefinedIndices","t","i","undefined","filter","messageIdx","matchedMessage","httpMetadata","getHttpMetadata","systemContext","targetClass","methodName","httpSystemConfig","batchMode","Body","index","hasOwnMetadata","BODY","bodyMetadata","Headers","HEADERS","headerMetadata","Cookies","COOKIES","cookiesMetadata","Req","REQUEST","requestMetadata","Res","RESPONSE","responseMetadata","Ctx","CONTEXT","contextMetadata","Query","query","pipe","newMetadata","getOwnMetadata","QUERY","Params","keyName","PARAMS","bodyMeta","headerMeta","cookiesMeta","resMeta","reqMeta","ctxMeta","queryMeta","paramMeta","getHttpArgs","context","req","res","paramItem","find","p","val","body","headers","parseRawCookie","cookie","queryItem","q","ExpressPlugin","name","stagingSystemRegister","MessageRegistry","httpRouteRegistry","Map","httpContextStore","_internalHttpIdCounter","register","systemFn","systemContext","httpSystemConfig","Error","targetClass","priority","bindRoute","constructor","config","Reflect","getMetadata","VIRID_EXPRESS_METADATA","HTTPROUTE","routeKey","method","path","has","set","install","app","options","spawn","server","_","routeInfo","entries","httpMessage","expressMethod","toLowerCase","req","res","newId","HttpContext","Date","now","inc","message","once","delete","MessageWriter","write","messageClass","systemTasks","systemTaskMap","task","fn","httpMetadata","messageIdx","originalMethod","wrappedSystem","__name","currentMessage","context","get","requestId","args","params","map","type","index","arg","getHttpArgs","result","apply","Promise","then","handleResult","catch","error","InternalServerError","HttpError","engine","clear","dec","Array","isArray","forEach","item","HttpResponse","handleHttpResponse","status","json","id","BaseMessage","warn","response","ctx","headers","Object","k","v","setHeader","StreamFileResponse","sendFile","filePath","err","headersSent","end","isClosed","StreamResponse","stream","pipe","cleanup","on","data","_ExpressPlugin"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/http/response.ts","../src/http/utils.ts","../src/http/message.ts","../src/decorators/constant.ts","../src/decorators/decorator.ts"],"sourcesContent":["/*\n * Copyright (c) 2026-present Ailrid\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Description: Add express functionality to virid.\n */\nimport {\n ViridPlugin,\n type ViridApp,\n MessageRegistry,\n MessageWriter,\n Newable,\n SystemContext,\n BaseMessage,\n} from \"@virid/core\";\nimport { getHttpArgs } from \"./decorators\";\nimport {\n HttpSystemConfig,\n type HttpMethod,\n type HttpRouteInfo,\n} from \"./interfaces\";\n\nimport {\n HttpContext,\n HttpError,\n HttpRequestMessage,\n HttpResponse,\n InternalServerError,\n RequestId,\n StreamFileResponse,\n StreamResponse,\n} from \"./http\";\n\nimport { PluginOptions } from \"./interfaces\";\nimport { type Request, type Response } from \"express\";\nimport { VIRID_EXPRESS_METADATA } from \"./decorators/constant\";\nexport * from \"./http\";\nexport * from \"./decorators\";\n\nexport class ExpressPlugin implements ViridPlugin<PluginOptions> {\n name = \"@virid/express\";\n // temporary Registry\n private stagingSystemRegister = new MessageRegistry();\n // route Registry\n private httpRouteRegistry = new Map<string, HttpRouteInfo>();\n\n private httpContextStore = new Map<number, HttpContext>();\n\n private _internalHttpIdCounter = 0;\n\n register(systemFn: (...args: any[]) => any): () => void {\n // @ts-expect-error: get systemContext from systemFn\n const systemContext: SystemContext = systemFn.systemContext;\n // @ts-expect-error: get httpSystemConfig from systemFn\n const httpSystemConfig: HttpSystemConfig = systemFn.httpSystemConfig;\n if (!systemContext || !httpSystemConfig) {\n throw new Error(\n `[Virid HttpSystem] HttpSystem Parameter Loss: Please declare ${systemFn.name} using the @HttpSystem decorator first.`,\n );\n }\n this.stagingSystemRegister.register(\n systemContext.targetClass,\n systemFn,\n httpSystemConfig.priority,\n );\n return () => {};\n }\n\n bindRoute(constructor: Newable<HttpRequestMessage>) {\n const config: HttpRouteInfo = Reflect.getMetadata(\n VIRID_EXPRESS_METADATA.HTTPROUTE,\n constructor,\n );\n if (!config) {\n throw new Error(\n `[Virid Http] Routing Error: ${constructor.name} is not a valid HttpRoute`,\n );\n }\n // Uniqueness verification: Combining Method and Path\n const routeKey = `${config.method}:${config.path}`;\n if (this.httpRouteRegistry.has(routeKey)) {\n throw new Error(\n `[Virid Http] Routing Conflict: The request method ${config.method} for path ${config.path} has already been registered by ${constructor.name}`,\n );\n } else {\n this.httpRouteRegistry.set(routeKey, config);\n }\n }\n\n install(app: ViridApp, options: PluginOptions) {\n // register for express routing\n for (const [_, routeInfo] of this.httpRouteRegistry.entries()) {\n const { method, path, httpMessage } = routeInfo;\n const expressMethod = method.toLowerCase() as HttpMethod;\n\n options.server[expressMethod](path, (req: Request, res: Response) => {\n // instantiate Message\n const newId = this._internalHttpIdCounter++ >>> 0;\n\n // save contextual information\n const context = new HttpContext(newId, req, res, Date.now(), path);\n context.inc();\n this.httpContextStore.set(\n newId,\n new HttpContext(newId, req, res, Date.now(), path),\n );\n const message = new httpMessage(newId as RequestId);\n // finish means the response has been sent, close means the connection was unexpectedly interrupted, both should be cleaned up\n res.once(\"finish\", () => this.httpContextStore.delete(newId));\n res.once(\"close\", () => this.httpContextStore.delete(newId));\n // send message\n MessageWriter.write(message);\n });\n }\n\n // register HttpSystem into the app's scheduler\n for (const [\n messageClass,\n systemTasks,\n ] of this.stagingSystemRegister.systemTaskMap.entries()) {\n for (const task of systemTasks) {\n const systemFn = task.fn;\n // @ts-expect-error: get systemContext from systemFn\n const systemContext: SystemContext = systemFn.systemContext;\n // @ts-expect-error: get httpSystemConfig from systemFn\n const httpSystemConfig: HttpSystemConfig = systemFn.httpSystemConfig;\n const { httpMetadata, messageClass, messageIdx } = httpSystemConfig;\n const { originalMethod, targetClass } = systemContext;\n const wrappedSystem = (currentMessage: HttpRequestMessage) => {\n // retrieve the context of the current request\n const context = this.httpContextStore.get(currentMessage.requestId);\n if (!context) {\n throw new Error(\n `[Virid Express HttpSystem] Invalid Request Context: The request context for message ${currentMessage.requestId} is missing.`,\n );\n }\n try {\n const args = systemContext.params.map(\n (type: any, index: number) => {\n // If it is a message, inject\n if (index === messageIdx) {\n return currentMessage;\n } else {\n // Otherwise, try injecting HTTP parameters or components\n const arg = getHttpArgs(index, context, httpMetadata);\n return arg ? arg : app.get(type);\n }\n },\n );\n const result = originalMethod.apply(targetClass, args);\n return result instanceof Promise\n ? result\n .then((res) => {\n this.handleResult(res, context);\n })\n .catch((error) => {\n // asynchronous error needs to send 500 to the client\n this.handleResult(InternalServerError(error), context);\n // continue throwing, let Dispatcher capture and print detailed stack\n throw error;\n })\n : this.handleResult(result, context);\n } catch (error) {\n if (error instanceof HttpError) {\n // if manually throw new HttpError\n this.handleResult(error, context);\n } else {\n // real crash, return 500\n this.handleResult(InternalServerError(error as Error), context);\n }\n throw error; // continue throwing, let Dispatcher capture and print detailed stack\n }\n };\n wrappedSystem.systemContext = systemContext;\n wrappedSystem.httpSystemConfig = httpSystemConfig;\n app.engine.register(messageClass, wrappedSystem, task.priority);\n }\n }\n this.stagingSystemRegister.systemTaskMap.clear();\n }\n\n handleResult(res: any, context: HttpContext) {\n if (!res) {\n context.dec();\n return;\n }\n const results = Array.isArray(res) ? res : [res];\n results.forEach((item) => {\n if (item instanceof HttpResponse) {\n // if it is a termination response, handle it\n this.handleHttpResponse(item, context);\n } else if (item instanceof HttpError) {\n // handling errors\n context.res.status(item.status).json(item.message);\n this.httpContextStore.delete(context.id);\n } else if (item instanceof BaseMessage) {\n MessageWriter.write(item);\n } else {\n MessageWriter.warn(\n `[Virid Express] Invalid Return Type: ${typeof item}. Expected HttpResponse or Message.`,\n );\n }\n });\n //Whether the system encounters an error or completes execution, handleResult will execute with a reference count of -1 and check if it is 0\n //If it is 0 and it has not been closed yet, then force it to close\n //The first scenario: If handleHttpResponse is executed above, then HttpContext has already been deleted before that\n //The second scenario: If the HttpRequestMessage is forwarded above, it will erase the trace of the system execution, but the HttpContext will not be deleted due to reference counting\n //The third scenario: If other messages or return values are forwarded above, the reference count will be -1 and checked if it is 0. If it is 0, it will be forcibly closed\n context.dec();\n }\n\n handleHttpResponse(response: HttpResponse, ctx: HttpContext) {\n const { res } = ctx;\n\n if (response.headers) {\n Object.entries(response.headers).forEach(([k, v]) => res.setHeader(k, v));\n }\n\n if (response.status) res.status(response.status);\n\n if (response instanceof StreamFileResponse) {\n // return asynchronous stream and forcefully add an RC extension\n ctx.inc();\n res.sendFile(response.filePath, response.options, (err) => {\n if (!res.headersSent) {\n MessageWriter.error(\n err,\n `[Virid Express] SteamFile Error: Path: ${response.filePath}`,\n );\n }\n ctx.res.end();\n this.httpContextStore.delete(ctx.id);\n ctx.isClosed = true;\n ctx.dec();\n });\n return;\n }\n if (response instanceof StreamResponse) {\n const { stream } = response;\n ctx.inc();\n stream.pipe(res);\n // end of listening, harvest context\n const cleanup = () => {\n if (!this.httpContextStore.has(ctx.id)) return;\n ctx.res.end();\n this.httpContextStore.delete(ctx.id);\n ctx.isClosed = true;\n ctx.dec();\n };\n stream.on(\"end\", cleanup);\n stream.on(\"error\", (err) => {\n if (!res.headersSent) {\n MessageWriter.error(err, `[Virid Express] Stream Error`);\n }\n cleanup();\n });\n stream.on(\"close\", cleanup);\n return;\n }\n\n res.status(response.status).json(response.data);\n this.httpContextStore.delete(ctx.id);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { type Request, type Response } from \"express\";\nimport { Readable } from \"stream\";\nimport { MessageWriter } from \"@virid/core\";\ninterface HttpHeaders {\n [key: string]: string | string[];\n}\nexport class HttpContext {\n public rc: number = 0;\n public isClosed: boolean = false;\n\n constructor(\n public readonly id: number,\n public readonly req: Request,\n public readonly res: Response,\n public readonly timestamp: number,\n public readonly route: string,\n ) {}\n\n inc() {\n this.rc++;\n }\n\n dec() {\n this.rc--;\n if (this.rc === 0) {\n this.tryFinalize();\n }\n }\n\n private tryFinalize() {\n if (this.res.writableEnded || this.isClosed) return;\n\n this.isClosed = true;\n\n const errorMsg = `[Virid Express] Request Orphaned: The connection was closed because all systems finished execution without sending a response. \n Route: ${this.route}\n Uptime: ${Date.now() - this.timestamp}ms`;\n\n MessageWriter.error(new Error(errorMsg));\n\n if (!this.res.headersSent) {\n this.res.status(500).json({\n error: \"Internal Logic Error\",\n message:\n \"Request processed but no response was returned by any system.\",\n });\n } else {\n this.res.end();\n }\n }\n}\n\nexport abstract class HttpResponse {\n constructor(\n public status: number,\n public data: any = null,\n public headers: HttpHeaders = {},\n ) {}\n}\n\n// --- 2xx Success ---\nexport class OkResponse extends HttpResponse {\n constructor(data: any, headers: HttpHeaders = {}) {\n super(200, data, headers);\n }\n}\n\nexport class CreatedResponse extends HttpResponse {\n constructor(data: any, headers: HttpHeaders = {}) {\n super(201, data, headers);\n }\n}\n\nexport class NoContentResponse extends HttpResponse {\n constructor() {\n super(204, null);\n }\n}\n\n// --- 4xx Client Error ---\nexport class BadRequestResponse extends HttpResponse {\n constructor(message: string = \"Bad Request\") {\n super(400, { error: message });\n }\n}\n\nexport class UnauthorizedResponse extends HttpResponse {\n constructor(message: string = \"Unauthorized\") {\n super(401, { error: message });\n }\n}\n\nexport class ForbiddenResponse extends HttpResponse {\n constructor(message: string = \"Forbidden\") {\n super(403, { error: message });\n }\n}\n\nexport class NotFoundResponse extends HttpResponse {\n constructor(message: string = \"Not Found\") {\n super(404, { error: message });\n }\n}\n\nexport class ConflictResponse extends HttpResponse {\n constructor(message: string = \"Conflict\") {\n super(409, { error: message });\n }\n}\n\nexport class UnprocessableEntityResponse extends HttpResponse {\n constructor(errors: any) {\n super(422, { errors });\n }\n}\n\n// --- 5xx Server Error ---\nexport class InternalServerErrorResponse extends HttpResponse {\n constructor(message: string = \"Internal Server Error\") {\n super(500, { error: message });\n }\n}\n\n// --- 万能类 (Custom) ---\nexport class CustomResponseResponse extends HttpResponse {\n constructor(status: number, data: any, headers: HttpHeaders = {}) {\n super(status, data, headers);\n }\n}\n/**\n * @description: Express sendFile 配置项的强类型定义\n */\nexport interface StreamFileOptions {\n /** 根目录(如果 path 是相对路径则必填) */\n root?: string;\n /** * 对以 . 开头的文件处理策略:\n * - allow: 允许发送\n * - deny: 拒绝并返回 403\n * - ignore: 当作不存在返回 404\n */\n dotfiles?: \"allow\" | \"deny\" | \"ignore\";\n /** 是否发送 ETag */\n etag?: boolean;\n /** 扩展的 HTTP 响应头 */\n headers?: HttpHeaders;\n /** 缓存最大时长 (毫秒) */\n maxAge?: number | string;\n /** 是否在 Cache-Control 中添加 immutable */\n immutable?: boolean;\n /** 是否根据文件系统设置 Last-Modified */\n lastModified?: boolean;\n /** 是否支持断点续传 (Range 请求) */\n acceptRanges?: boolean;\n}\nexport class StreamFileResponse extends HttpResponse {\n constructor(\n public readonly filePath: string,\n public readonly options: StreamFileOptions = { dotfiles: \"allow\" },\n ) {\n super(206, options);\n }\n}\n\nexport class StreamResponse extends HttpResponse {\n constructor(\n public readonly stream: Readable,\n public readonly options: {\n status?: number;\n headers?: HttpHeaders;\n } = {},\n ) {\n super(options.status || 206, {}, options.headers);\n }\n}\n\n/** 200 OK */\nexport const Ok = (data: any, headers: HttpHeaders = {}) =>\n new OkResponse(data, headers);\n\n/** 201 Created */\nexport const Created = (data: any, headers: HttpHeaders = {}) =>\n new CreatedResponse(data, headers);\n\n/** 204 No Content */\nexport const NoContent = () => new NoContentResponse();\n\n/** 400 Bad Request */\nexport const BadRequest = (msg = \"Bad Request\") => new BadRequestResponse(msg);\n\n/** 401 Unauthorized */\nexport const Unauthorized = (msg = \"Unauthorized\") =>\n new UnauthorizedResponse(msg);\n\n/** 403 Forbidden */\nexport const Forbidden = (msg = \"Forbidden\") => new ForbiddenResponse(msg);\n\n/** 404 Not Found */\nexport const NotFound = (msg = \"Not Found\") => new NotFoundResponse(msg);\n\n/** 500 Internal Error */\nexport const InternalServerError = (\n msg: string | Error = \"Internal Server Error\",\n) => {\n return msg instanceof Error\n ? new InternalServerErrorResponse(msg.message)\n : new InternalServerErrorResponse(msg);\n};\n\nexport const CustomResponse = (\n status: number,\n data: any,\n headers: HttpHeaders = {},\n) => new CustomResponseResponse(status, data, headers);\n\n/** 发送本地文件 (自动处理 Range/206) */\nexport const StreamFile = (path: string, options?: StreamFileOptions) =>\n new StreamFileResponse(path, options);\n/**\n * 发送流响应\n */\nexport const Stream = (stream: Readable, options?: StreamResponse[\"options\"]) =>\n new StreamResponse(stream, options);\n\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n public readonly message: string,\n ) {\n super(message);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { MessageWriter } from \"@virid/core\";\nimport { HttpError } from \".\";\nimport { type TransformPipe } from \"../interfaces\";\n\nexport function ParseIntPipe(val: string) {\n const res = parseInt(val, 10);\n if (isNaN(res))\n throw new HttpError(400, `Validation failed: \"${val}\" is not a number.`);\n return res;\n}\n\nexport function ParseBoolPipe(val: string) {\n if (val === \"true\" || val === \"1\") return true;\n if (val === \"false\" || val === \"0\") return false;\n return !!val;\n}\n\nconst autoPipeMap = new Map<any, TransformPipe<any>>();\nautoPipeMap.set(Number, ParseIntPipe);\nautoPipeMap.set(Boolean, ParseBoolPipe);\n\nexport function addAutoPipe<T>(type: T, pipe: TransformPipe<T>) {\n if (autoPipeMap.has(type)) {\n MessageWriter.error(\n new Error(\n `[Virid Express Pipe] Repeated Pipe: Auto pipe for ${type} has already been registered.`,\n ),\n );\n return;\n }\n autoPipeMap.set(type, pipe);\n}\n\nexport function getAutoPipe<T>(type: T): TransformPipe<T> | undefined {\n return autoPipeMap.get(type);\n}\n\nexport function parseRawCookie(\n cookieHeader: string | undefined,\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n if (!cookieHeader) return result;\n const pairs = cookieHeader.split(\";\");\n\n for (const pair of pairs) {\n const indexOfEq = pair.indexOf(\"=\");\n if (indexOfEq === -1) continue;\n\n // 提取 key 和 value,并进行 trim 处理\n const key = pair.substring(0, indexOfEq).trim();\n if (!key) continue;\n\n let value = pair.substring(indexOfEq + 1).trim();\n\n if (value[0] === '\"' && value[value.length - 1] === '\"') {\n value = value.slice(1, -1);\n }\n\n try {\n result[key] = value.includes(\"%\") ? decodeURIComponent(value) : value;\n } catch (e) {\n result[key] = value;\n }\n }\n\n return result;\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { EventMessage } from \"@virid/core\";\nexport type RequestId = number & { readonly __brand: unique symbol };\n\nexport class HttpRequestMessage extends EventMessage {\n // ID must be of type RequestId\n constructor(private readonly __virid_express_id: RequestId) {\n super();\n }\n // expose a read-only attribute for use by the business layer\n public get requestId(): RequestId {\n return this.__virid_express_id;\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { VIRID_METADATA } from \"@virid/core\";\n\nexport const VIRID_EXPRESS_METADATA = {\n ...VIRID_METADATA,\n HTTPROUTE: \"virid:express:route\",\n HTTPSYSTEM: \"virid:express:system\",\n BODY: \"virid:express:body\",\n QUERY: \"virid:express:query\",\n HEADERS: \"virid:express:header\",\n REQUEST: \"virid:express:request\",\n RESPONSE: \"virid:express:response\",\n CONTEXT: \"virid:express:context\",\n PARAMS: \"virid:express:params\",\n COOKIES: \"virid:express:cookie\",\n} as const;\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { type Newable, type SystemContext } from \"@virid/core\";\nimport {\n type HttpRouteConfig,\n type HttpRouteInfo,\n type BodyMetadata,\n type HeaderMetadata,\n type QueryMetadata,\n type RequestMetadata,\n type ResponseMetadata,\n type ContextMetadata,\n type ParamMetadata,\n type TransformPipe,\n type CookieMetadata,\n type HttpSystemParams,\n type HttpMetadata,\n type HttpSystemConfig,\n} from \"../interfaces\";\nimport { HttpContext, HttpRequestMessage, parseRawCookie } from \"../http\";\n\nimport { VIRID_EXPRESS_METADATA } from \"./constant\";\n\nexport function HttpRoute(config: HttpRouteConfig) {\n return (constructor: Newable<HttpRequestMessage>) => {\n const params: string[] = [];\n const pathParts = config.path.split(\"/\");\n pathParts.forEach((part) => {\n if (part.startsWith(\":\")) {\n params.push(part.substring(1));\n }\n });\n\n const routeInfo: HttpRouteInfo = {\n ...config,\n httpMessage: constructor,\n params,\n };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.HTTPROUTE,\n routeInfo,\n constructor,\n );\n };\n}\n\n/**\n * Check if there are multiple message type parameters in the parameters\n * @param types Parameter list\n */\nfunction checkMessageParam(types: Array<any>) {\n const foundMatches: { type: Newable<HttpRequestMessage>; idx: number }[] = [];\n\n types.forEach((type, idx) => {\n const isHttpRequestMessage =\n type === HttpRequestMessage ||\n (type && type.prototype instanceof HttpRequestMessage);\n\n if (isHttpRequestMessage) {\n foundMatches.push({ type, idx });\n }\n });\n\n if (foundMatches.length === 0) {\n return null;\n }\n\n if (foundMatches.length > 1) {\n const errorDetails = foundMatches\n .map((item) => `[Index: ${item.idx}, Name: ${item.type.name}]`)\n .join(\", \");\n\n throw new Error(\n `[Virid System] Multiple Messages: Multiple Message type parameters detected, this is not allowed! specific location: ${errorDetails}`,\n );\n }\n\n return foundMatches[0];\n}\n\n/**\n * @description: 系统装饰器\n * @param priority 优先级,数值越大越早执行\n */\nexport function HttpSystem(\n params: HttpSystemParams = {\n priority: 0,\n messageClass: null,\n },\n) {\n return (target: any, key: string, descriptor: PropertyDescriptor) => {\n if (typeof target !== \"function\") {\n throw new Error(\n `[Virid System] Method Type Error: The Method ${key} is not a static method, please check if there is a static keyword tag.`,\n );\n }\n\n const originalMethod = descriptor.value;\n const types: Array<any> = Reflect.getMetadata(\n \"design:paramtypes\",\n target,\n key,\n );\n\n // Verify if metadata exists\n if (!types) {\n throw new Error(\n `[Virid System] System Parameter Loss: Unable to recognize system parameters, please confirm if import \"reflect-metadata\" was introduced at the beginning.`,\n );\n }\n\n // Verify if there are undefined parameters\n const undefinedIndices = types\n .map((t, i) => (t === undefined ? i : -1))\n .filter((i) => i !== -1);\n if (undefinedIndices.length > 0) {\n throw new Error(\n `[Virid System] Parameter Metadata Loss in \"${key}\": One or more parameters have 'undefined' types. This usually happens when you forget to add a type annotation or due to circular dependencies. Check parameter at indices: [${undefinedIndices.join(\", \")}]`,\n );\n }\n\n let messageClass: Newable<HttpRequestMessage>;\n // eslint-disable-next-line no-useless-assignment\n let messageIdx: number = -1;\n const matchedMessage = checkMessageParam(types); // { type: any, idx: number } | null\n if (matchedMessage && params.messageClass) {\n throw new Error(\n `[Virid System] Multiple Messages Are Not Allowed: Cannot specify messageClass in decorator options while already declaring it in method parameters at index ${matchedMessage.idx} in ${key}.`,\n );\n }\n\n if (matchedMessage) {\n messageClass = matchedMessage.type;\n messageIdx = matchedMessage.idx; // In single mode, idx points to the location of a specific BaseMessage subclass\n } else if (params.messageClass) {\n messageClass = params.messageClass;\n messageIdx = -1; // Only provided in the configuration, cannot be found in the parameters, set to -1\n } else {\n throw new Error(\n `[Virid System] System Parameter Loss: Please declare the message type either in method parameters or via the Message decorator options.`,\n );\n }\n const httpMetadata = getHttpMetadata(target, key);\n\n // Attach contextual information to the packaged function\n const systemContext: SystemContext = {\n params: types,\n targetClass: target,\n methodName: key,\n originalMethod: originalMethod,\n };\n const httpSystemConfig: HttpSystemConfig = {\n httpMetadata: httpMetadata,\n messageClass: messageClass,\n messageIdx: messageIdx,\n priority: params.priority || 0,\n batchMode: false,\n };\n\n // Purely mounting data without changing the execution logic of the original method\n (descriptor.value as any).systemContext = systemContext;\n (descriptor.value as any).httpSystemConfig = httpSystemConfig;\n };\n}\n\nexport function Body() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.BODY, target, key)) {\n throw new Error(\n `[Virid Express Body] Multiple Body Are Not Allowed: ${key} has multiple @Body() decorators!`,\n );\n }\n const bodyMetadata = { index } as BodyMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.BODY,\n bodyMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Headers() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.HEADERS, target, key)) {\n throw new Error(\n `[Virid Express Headers] Multiple Header Are Not Allowed: ${key} has multiple @Headers() decorators!`,\n );\n }\n const headerMetadata = { index } as HeaderMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.HEADERS,\n headerMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Cookies() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.COOKIES, target, key)) {\n throw new Error(\n `[Virid Express Cookies] Multiple Header Are Not Allowed: ${key} has multiple @Cookies() decorators!`,\n );\n }\n const cookiesMetadata = { index } as CookieMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.COOKIES,\n cookiesMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Req() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.REQUEST, target, key)) {\n throw new Error(\n `[Virid Express Req] Multiple Request Objects Are Not Allowed: ${key} has multiple @Req() decorators!`,\n );\n }\n const requestMetadata: RequestMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.REQUEST,\n requestMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Res() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.RESPONSE, target, key)) {\n throw new Error(\n `[Virid Express Res] Multiple Response Objects Are Not Allowed: ${key} has multiple @Res() decorators!`,\n );\n }\n const responseMetadata: ResponseMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.RESPONSE,\n responseMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Ctx() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.CONTEXT, target, key)) {\n throw new Error(\n `[Virid Express Ctx] Multiple Context Objects Are Not Allowed: ${key} has multiple @Ctx() decorators!`,\n );\n }\n const contextMetadata: ContextMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.CONTEXT,\n contextMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Query(query: string, pipe?: TransformPipe<any>) {\n return (target: any, key: string, index: number) => {\n const existingMetadata: QueryMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.QUERY, target, key) || [];\n const newMetadata = [...existingMetadata, { index, query, pipe }];\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.QUERY,\n newMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Params(key?: string, pipe?: TransformPipe<any>) {\n return (target: any, keyName: string, index: number) => {\n const existingMetadata: ParamMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.PARAMS, target, keyName) ||\n [];\n const newMetadata = [...existingMetadata, { index, key, pipe }];\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.PARAMS,\n newMetadata,\n target,\n keyName,\n );\n };\n}\n\nfunction getHttpMetadata(target: any, key: string): HttpMetadata {\n const bodyMeta: BodyMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.BODY,\n target,\n key,\n );\n const headerMeta: HeaderMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.HEADERS,\n target,\n key,\n );\n const cookiesMeta: CookieMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.COOKIES,\n target,\n key,\n );\n\n const resMeta: ResponseMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.RESPONSE,\n target,\n key,\n );\n const reqMeta: RequestMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.REQUEST,\n target,\n key,\n );\n const ctxMeta: ContextMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.CONTEXT,\n target,\n key,\n );\n\n const queryMeta: QueryMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.QUERY, target, key) || [];\n\n const paramMeta: ParamMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.PARAMS, target, key) || [];\n\n return {\n bodyMeta,\n headerMeta,\n queryMeta,\n paramMeta,\n cookiesMeta,\n reqMeta,\n resMeta,\n ctxMeta,\n };\n}\n\nexport function getHttpArgs(\n index: number,\n context: HttpContext,\n httpMetadata: HttpMetadata,\n): any {\n const { req, res } = context;\n\n // 匹配 @Ctx()\n if (httpMetadata.ctxMeta?.index === index) return context;\n\n // 匹配 @Param() -> 获取路由参数 (:id 等)\n const paramItem = httpMetadata.paramMeta?.find((p) => p.index === index);\n if (paramItem) {\n let val = paramItem.key ? req.params[paramItem.key] : req.params;\n\n // 如果有 Pipe 且值不是 undefined,进行转换\n if (paramItem.pipe && val !== undefined) {\n val = paramItem.pipe(val);\n }\n return val;\n }\n\n // @Body()\n if (httpMetadata.bodyMeta?.index === index) return req.body;\n\n // @Header()\n if (httpMetadata.headerMeta?.index === index) return req.headers;\n\n // @Cookie()\n if (httpMetadata.cookiesMeta?.index === index)\n return parseRawCookie(req.headers.cookie);\n\n // @Req() 和 @Res()\n if (httpMetadata.reqMeta?.index === index) return req;\n if (httpMetadata.resMeta?.index === index) return res;\n\n // @Query('name')\n const queryItem = httpMetadata.queryMeta?.find((q) => q.index === index);\n if (queryItem) {\n let val = req.query[queryItem.query];\n if (val === undefined) {\n throw new Error(`[Virid Express] Missing Query: \"${queryItem.query}\"`);\n }\n\n if (queryItem.pipe) {\n val = queryItem.pipe(val);\n }\n return val;\n }\n return null;\n}\n"],"mappings":"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","names":["index_exports","__export","BadRequest","BadRequestResponse","Body","ConflictResponse","Cookies","Created","CreatedResponse","Ctx","CustomResponse","CustomResponseResponse","ExpressPlugin","Forbidden","ForbiddenResponse","Headers","HttpContext","HttpError","HttpRequestMessage","HttpResponse","HttpRoute","HttpSystem","InternalServerError","InternalServerErrorResponse","NoContent","NoContentResponse","NotFound","NotFoundResponse","Ok","OkResponse","Params","ParseBoolPipe","ParseIntPipe","Query","Req","Res","Stream","StreamFile","StreamFileResponse","StreamResponse","Unauthorized","UnauthorizedResponse","UnprocessableEntityResponse","addAutoPipe","getAutoPipe","getHttpArgs","parseRawCookie","__toCommonJS","import_core","import_core","HttpContext","id","req","res","timestamp","route","rc","isClosed","inc","dec","tryFinalize","writableEnded","errorMsg","Date","now","MessageWriter","error","Error","headersSent","end","status","json","message","_HttpContext","HttpResponse","data","headers","_HttpResponse","OkResponse","_OkResponse","CreatedResponse","_CreatedResponse","NoContentResponse","_NoContentResponse","BadRequestResponse","_BadRequestResponse","UnauthorizedResponse","_UnauthorizedResponse","ForbiddenResponse","_ForbiddenResponse","NotFoundResponse","_NotFoundResponse","ConflictResponse","_ConflictResponse","UnprocessableEntityResponse","errors","_UnprocessableEntityResponse","InternalServerErrorResponse","_InternalServerErrorResponse","CustomResponseResponse","_CustomResponseResponse","StreamFileResponse","filePath","options","dotfiles","_StreamFileResponse","StreamResponse","stream","_StreamResponse","Ok","__name","Created","NoContent","BadRequest","msg","Unauthorized","Forbidden","NotFound","InternalServerError","CustomResponse","StreamFile","path","Stream","HttpError","_HttpError","import_core","ParseIntPipe","val","res","parseInt","isNaN","HttpError","ParseBoolPipe","autoPipeMap","Map","set","Number","Boolean","addAutoPipe","type","pipe","has","MessageWriter","error","Error","getAutoPipe","get","parseRawCookie","cookieHeader","result","pairs","split","pair","indexOfEq","indexOf","key","substring","trim","value","length","slice","includes","decodeURIComponent","import_core","HttpRequestMessage","EventMessage","__virid_express_id","requestId","_HttpRequestMessage","import_core","VIRID_EXPRESS_METADATA","VIRID_METADATA","HTTPROUTE","HTTPSYSTEM","BODY","QUERY","HEADERS","REQUEST","RESPONSE","CONTEXT","PARAMS","COOKIES","HttpRoute","config","constructor","params","path","split","forEach","part","startsWith","push","substring","routeInfo","httpMessage","Reflect","defineMetadata","VIRID_EXPRESS_METADATA","HTTPROUTE","checkMessageParam","types","foundMatches","type","idx","HttpRequestMessage","prototype","length","errorDetails","map","item","name","join","Error","HttpSystem","priority","messageClass","target","key","descriptor","originalMethod","value","getMetadata","undefinedIndices","t","i","undefined","filter","messageIdx","matchedMessage","httpMetadata","getHttpMetadata","systemContext","targetClass","methodName","httpSystemConfig","batchMode","Body","index","hasOwnMetadata","BODY","bodyMetadata","Headers","HEADERS","headerMetadata","Cookies","COOKIES","cookiesMetadata","Req","REQUEST","requestMetadata","Res","RESPONSE","responseMetadata","Ctx","CONTEXT","contextMetadata","Query","query","pipe","newMetadata","getOwnMetadata","QUERY","Params","keyName","PARAMS","bodyMeta","headerMeta","cookiesMeta","resMeta","reqMeta","ctxMeta","queryMeta","paramMeta","getHttpArgs","context","req","res","paramItem","find","p","val","body","headers","parseRawCookie","cookie","queryItem","q","ExpressPlugin","name","stagingSystemRegister","MessageRegistry","httpRouteRegistry","Map","httpContextStore","_internalHttpIdCounter","register","systemFn","systemContext","httpSystemConfig","Error","targetClass","priority","bindRoute","constructor","config","Reflect","getMetadata","VIRID_EXPRESS_METADATA","HTTPROUTE","routeKey","method","path","has","set","install","app","options","_","routeInfo","entries","httpMessage","expressMethod","toLowerCase","server","req","res","newId","HttpContext","Date","now","inc","message","once","delete","MessageWriter","write","messageClass","systemTasks","systemTaskMap","task","fn","httpMetadata","messageIdx","originalMethod","wrappedSystem","__name","currentMessage","context","get","requestId","args","params","map","type","index","arg","getHttpArgs","result","apply","Promise","then","handleResult","catch","error","InternalServerError","HttpError","engine","clear","dec","Array","isArray","forEach","item","HttpResponse","handleHttpResponse","status","json","id","BaseMessage","warn","response","ctx","headers","Object","k","v","setHeader","StreamFileResponse","sendFile","filePath","err","headersSent","end","isClosed","StreamResponse","stream","pipe","cleanup","on","data","_ExpressPlugin"]}
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
- * @virid/express v0.3.3
2
+ * @virid/express v0.3.4
3
3
  * Add express functionality to virid
4
4
  */
5
5
  var ne=Object.defineProperty;var he=(r,e,t)=>e in r?ne(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var o=(r,e)=>ne(r,"name",{value:e,configurable:!0});var l=(r,e,t)=>he(r,typeof e!="symbol"?e+"":e,t);import{MessageRegistry as Se,MessageWriter as T,BaseMessage as ye}from"@virid/core";import{MessageWriter as fe}from"@virid/core";var j=class j{constructor(e,t,s,i,a){l(this,"id");l(this,"req");l(this,"res");l(this,"timestamp");l(this,"route");l(this,"rc",0);l(this,"isClosed",!1);this.id=e,this.req=t,this.res=s,this.timestamp=i,this.route=a}inc(){this.rc++}dec(){this.rc--,this.rc===0&&this.tryFinalize()}tryFinalize(){if(this.res.writableEnded||this.isClosed)return;this.isClosed=!0;let e=`[Virid Express] Request Orphaned: The connection was closed because all systems finished execution without sending a response.
6
6
  Route: ${this.route}
7
- Uptime: ${Date.now()-this.timestamp}ms`;fe.error(new Error(e)),this.res.headersSent?this.res.end():this.res.status(500).json({error:"Internal Logic Error",message:"Request processed but no response was returned by any system."})}};o(j,"HttpContext");var S=j,Y=class Y{constructor(e,t=null,s={}){l(this,"status");l(this,"data");l(this,"headers");this.status=e,this.data=t,this.headers=s}};o(Y,"HttpResponse");var p=Y,X=class X extends p{constructor(e,t={}){super(200,e,t)}};o(X,"OkResponse");var q=X,L=class L extends p{constructor(e,t={}){super(201,e,t)}};o(L,"CreatedResponse");var V=L,K=class K extends p{constructor(){super(204,null)}};o(K,"NoContentResponse");var v=K,z=class z extends p{constructor(e="Bad Request"){super(400,{error:e})}};o(z,"BadRequestResponse");var b=z,F=class F extends p{constructor(e="Unauthorized"){super(401,{error:e})}};o(F,"UnauthorizedResponse");var D=F,W=class W extends p{constructor(e="Forbidden"){super(403,{error:e})}};o(W,"ForbiddenResponse");var N=W,_=class _ extends p{constructor(e="Not Found"){super(404,{error:e})}};o(_,"NotFoundResponse");var U=_,G=class G extends p{constructor(e="Conflict"){super(409,{error:e})}};o(G,"ConflictResponse");var de=G,J=class J extends p{constructor(e){super(422,{errors:e})}};o(J,"UnprocessableEntityResponse");var ce=J,Z=class Z extends p{constructor(e="Internal Server Error"){super(500,{error:e})}};o(Z,"InternalServerErrorResponse");var I=Z,k=class k extends p{constructor(e,t,s={}){super(e,t,s)}};o(k,"CustomResponseResponse");var B=k,ee=class ee extends p{constructor(t,s={dotfiles:"allow"}){super(206,s);l(this,"filePath");l(this,"options");this.filePath=t,this.options=s}};o(ee,"StreamFileResponse");var y=ee,te=class te extends p{constructor(t,s={}){super(s.status||206,{},s.headers);l(this,"stream");l(this,"options");this.stream=t,this.options=s}};o(te,"StreamResponse");var C=te,Ae=o((r,e={})=>new q(r,e),"Ok"),Te=o((r,e={})=>new V(r,e),"Created"),Pe=o(()=>new v,"NoContent"),Ie=o((r="Bad Request")=>new b(r),"BadRequest"),He=o((r="Unauthorized")=>new D(r),"Unauthorized"),$e=o((r="Forbidden")=>new N(r),"Forbidden"),qe=o((r="Not Found")=>new U(r),"NotFound"),Q=o((r="Internal Server Error")=>r instanceof Error?new I(r.message):new I(r),"InternalServerError"),Ve=o((r,e,t={})=>new B(r,e,t),"CustomResponse"),ve=o((r,e)=>new y(r,e),"StreamFile"),be=o((r,e)=>new C(r,e),"Stream"),re=class re extends Error{constructor(t,s){super(s);l(this,"status");l(this,"message");this.status=t,this.message=s}};o(re,"HttpError");var M=re;import{MessageWriter as me}from"@virid/core";function xe(r){let e=parseInt(r,10);if(isNaN(e))throw new M(400,`Validation failed: "${r}" is not a number.`);return e}o(xe,"ParseIntPipe");function we(r){return r==="true"||r==="1"?!0:r==="false"||r==="0"?!1:!!r}o(we,"ParseBoolPipe");var O=new Map;O.set(Number,xe);O.set(Boolean,we);function Qe(r,e){if(O.has(r)){me.error(new Error(`[Virid Express Pipe] Repeated Pipe: Auto pipe for ${r} has already been registered.`));return}O.set(r,e)}o(Qe,"addAutoPipe");function je(r){return O.get(r)}o(je,"getAutoPipe");function le(r){let e={};if(!r)return e;let t=r.split(";");for(let s of t){let i=s.indexOf("=");if(i===-1)continue;let a=s.substring(0,i).trim();if(!a)continue;let n=s.substring(i+1).trim();n[0]==='"'&&n[n.length-1]==='"'&&(n=n.slice(1,-1));try{e[a]=n.includes("%")?decodeURIComponent(n):n}catch{e[a]=n}}return e}o(le,"parseRawCookie");import{EventMessage as Me}from"@virid/core";var se=class se extends Me{constructor(t){super();l(this,"__virid_express_id");this.__virid_express_id=t}get requestId(){return this.__virid_express_id}};o(se,"HttpRequestMessage");var A=se;import{VIRID_METADATA as ge}from"@virid/core";var d={...ge,HTTPROUTE:"virid:express:route",HTTPSYSTEM:"virid:express:system",BODY:"virid:express:body",QUERY:"virid:express:query",HEADERS:"virid:express:header",REQUEST:"virid:express:request",RESPONSE:"virid:express:response",CONTEXT:"virid:express:context",PARAMS:"virid:express:params",COOKIES:"virid:express:cookie"};function tt(r){return e=>{let t=[];r.path.split("/").forEach(a=>{a.startsWith(":")&&t.push(a.substring(1))});let i={...r,httpMessage:e,params:t};Reflect.defineMetadata(d.HTTPROUTE,i,e)}}o(tt,"HttpRoute");function Ee(r){let e=[];if(r.forEach((t,s)=>{(t===A||t&&t.prototype instanceof A)&&e.push({type:t,idx:s})}),e.length===0)return null;if(e.length>1){let t=e.map(s=>`[Index: ${s.idx}, Name: ${s.type.name}]`).join(", ");throw new Error(`[Virid System] Multiple Messages: Multiple Message type parameters detected, this is not allowed! specific location: ${t}`)}return e[0]}o(Ee,"checkMessageParam");function rt(r={priority:0,messageClass:null}){return(e,t,s)=>{if(typeof e!="function")throw new Error(`[Virid System] Method Type Error: The Method ${t} is not a static method, please check if there is a static keyword tag.`);let i=s.value,a=Reflect.getMetadata("design:paramtypes",e,t);if(!a)throw new Error('[Virid System] System Parameter Loss: Unable to recognize system parameters, please confirm if import "reflect-metadata" was introduced at the beginning.');let n=a.map((x,R)=>x===void 0?R:-1).filter(x=>x!==-1);if(n.length>0)throw new Error(`[Virid System] Parameter Metadata Loss in "${t}": One or more parameters have 'undefined' types. This usually happens when you forget to add a type annotation or due to circular dependencies. Check parameter at indices: [${n.join(", ")}]`);let c,h=-1,u=Ee(a);if(u&&r.messageClass)throw new Error(`[Virid System] Multiple Messages Are Not Allowed: Cannot specify messageClass in decorator options while already declaring it in method parameters at index ${u.idx} in ${t}.`);if(u)c=u.type,h=u.idx;else if(r.messageClass)c=r.messageClass,h=-1;else throw new Error("[Virid System] System Parameter Loss: Please declare the message type either in method parameters or via the Message decorator options.");let m=Re(e,t),f={params:a,targetClass:e,methodName:t,originalMethod:i},P={httpMetadata:m,messageClass:c,messageIdx:h,priority:r.priority||0,batchMode:!1};s.value.systemContext=f,s.value.httpSystemConfig=P}}o(rt,"HttpSystem");function st(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.BODY,r,e))throw new Error(`[Virid Express Body] Multiple Body Are Not Allowed: ${e} has multiple @Body() decorators!`);let s={index:t};Reflect.defineMetadata(d.BODY,s,r,e)}}o(st,"Body");function ot(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.HEADERS,r,e))throw new Error(`[Virid Express Headers] Multiple Header Are Not Allowed: ${e} has multiple @Headers() decorators!`);let s={index:t};Reflect.defineMetadata(d.HEADERS,s,r,e)}}o(ot,"Headers");function it(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.COOKIES,r,e))throw new Error(`[Virid Express Cookies] Multiple Header Are Not Allowed: ${e} has multiple @Cookies() decorators!`);let s={index:t};Reflect.defineMetadata(d.COOKIES,s,r,e)}}o(it,"Cookies");function at(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.REQUEST,r,e))throw new Error(`[Virid Express Req] Multiple Request Objects Are Not Allowed: ${e} has multiple @Req() decorators!`);let s={index:t};Reflect.defineMetadata(d.REQUEST,s,r,e)}}o(at,"Req");function nt(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.RESPONSE,r,e))throw new Error(`[Virid Express Res] Multiple Response Objects Are Not Allowed: ${e} has multiple @Res() decorators!`);let s={index:t};Reflect.defineMetadata(d.RESPONSE,s,r,e)}}o(nt,"Res");function dt(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.CONTEXT,r,e))throw new Error(`[Virid Express Ctx] Multiple Context Objects Are Not Allowed: ${e} has multiple @Ctx() decorators!`);let s={index:t};Reflect.defineMetadata(d.CONTEXT,s,r,e)}}o(dt,"Ctx");function ct(r,e){return(t,s,i)=>{let n=[...Reflect.getOwnMetadata(d.QUERY,t,s)||[],{index:i,query:r,pipe:e}];Reflect.defineMetadata(d.QUERY,n,t,s)}}o(ct,"Query");function lt(r,e){return(t,s,i)=>{let n=[...Reflect.getOwnMetadata(d.PARAMS,t,s)||[],{index:i,key:r,pipe:e}];Reflect.defineMetadata(d.PARAMS,n,t,s)}}o(lt,"Params");function Re(r,e){let t=Reflect.getOwnMetadata(d.BODY,r,e),s=Reflect.getOwnMetadata(d.HEADERS,r,e),i=Reflect.getOwnMetadata(d.COOKIES,r,e),a=Reflect.getOwnMetadata(d.RESPONSE,r,e),n=Reflect.getOwnMetadata(d.REQUEST,r,e),c=Reflect.getOwnMetadata(d.CONTEXT,r,e),h=Reflect.getOwnMetadata(d.QUERY,r,e)||[],u=Reflect.getOwnMetadata(d.PARAMS,r,e)||[];return{bodyMeta:t,headerMeta:s,queryMeta:h,paramMeta:u,cookiesMeta:i,reqMeta:n,resMeta:a,ctxMeta:c}}o(Re,"getHttpMetadata");function pe(r,e,t){let{req:s,res:i}=e;if(t.ctxMeta?.index===r)return e;let a=t.paramMeta?.find(c=>c.index===r);if(a){let c=a.key?s.params[a.key]:s.params;return a.pipe&&c!==void 0&&(c=a.pipe(c)),c}if(t.bodyMeta?.index===r)return s.body;if(t.headerMeta?.index===r)return s.headers;if(t.cookiesMeta?.index===r)return le(s.headers.cookie);if(t.reqMeta?.index===r)return s;if(t.resMeta?.index===r)return i;let n=t.queryMeta?.find(c=>c.index===r);if(n){let c=s.query[n.query];if(c===void 0)throw new Error(`[Virid Express] Missing Query: "${n.query}"`);return n.pipe&&(c=n.pipe(c)),c}return null}o(pe,"getHttpArgs");var oe=class oe{constructor(){l(this,"name","@virid/express");l(this,"stagingSystemRegister",new Se);l(this,"httpRouteRegistry",new Map);l(this,"httpContextStore",new Map);l(this,"_internalHttpIdCounter",0)}register(e){let t=e.systemContext,s=e.httpSystemConfig;if(!t||!s)throw new Error(`[Virid HttpSystem] HttpSystem Parameter Loss: Please declare ${e.name} using the @HttpSystem decorator first.`);return this.stagingSystemRegister.register(t.targetClass,e,s.priority),()=>{}}bindRoute(e){let t=Reflect.getMetadata(d.HTTPROUTE,e);if(!t)throw new Error(`[Virid Http] Routing Error: ${e.name} is not a valid HttpRoute`);let s=`${t.method}:${t.path}`;if(this.httpRouteRegistry.has(s))throw new Error(`[Virid Http] Routing Conflict: The request method ${t.method} for path ${t.path} has already been registered by ${e.name}`);this.httpRouteRegistry.set(s,t)}install(e,t){e.spawn(t.server);for(let[s,i]of this.httpRouteRegistry.entries()){let{method:a,path:n,httpMessage:c}=i,h=a.toLowerCase();t.server[h](n,(u,m)=>{let f=this._internalHttpIdCounter++>>>0;new S(f,u,m,Date.now(),n).inc(),this.httpContextStore.set(f,new S(f,u,m,Date.now(),n));let x=new c(f);m.once("finish",()=>this.httpContextStore.delete(f)),m.once("close",()=>this.httpContextStore.delete(f)),T.write(x)})}for(let[s,i]of this.stagingSystemRegister.systemTaskMap.entries())for(let a of i){let n=a.fn,c=n.systemContext,h=n.httpSystemConfig,{httpMetadata:u,messageClass:m,messageIdx:f}=h,{originalMethod:P,targetClass:x}=c,R=o(H=>{let w=this.httpContextStore.get(H.requestId);if(!w)throw new Error(`[Virid Express HttpSystem] Invalid Request Context: The request context for message ${H.requestId} is missing.`);try{let g=c.params.map((E,ie)=>{if(ie===f)return H;{let ae=pe(ie,w,u);return ae||e.get(E)}}),$=P.apply(x,g);return $ instanceof Promise?$.then(E=>{this.handleResult(E,w)}).catch(E=>{throw this.handleResult(Q(E),w),E}):this.handleResult($,w)}catch(g){throw g instanceof M?this.handleResult(g,w):this.handleResult(Q(g),w),g}},"wrappedSystem");R.systemContext=c,R.httpSystemConfig=h,e.engine.register(m,R,a.priority)}this.stagingSystemRegister.systemTaskMap.clear()}handleResult(e,t){if(!e){t.dec();return}(Array.isArray(e)?e:[e]).forEach(i=>{i instanceof p?this.handleHttpResponse(i,t):i instanceof M?(t.res.status(i.status).json(i.message),this.httpContextStore.delete(t.id)):i instanceof ye?T.write(i):T.warn(`[Virid Express] Invalid Return Type: ${typeof i}. Expected HttpResponse or Message.`)}),t.dec()}handleHttpResponse(e,t){let{res:s}=t;if(e.headers&&Object.entries(e.headers).forEach(([i,a])=>s.setHeader(i,a)),e.status&&s.status(e.status),e instanceof y){t.inc(),s.sendFile(e.filePath,e.options,i=>{s.headersSent||T.error(i,`[Virid Express] SteamFile Error: Path: ${e.filePath}`),t.res.end(),this.httpContextStore.delete(t.id),t.isClosed=!0,t.dec()});return}if(e instanceof C){let{stream:i}=e;t.inc(),i.pipe(s);let a=o(()=>{this.httpContextStore.has(t.id)&&(t.res.end(),this.httpContextStore.delete(t.id),t.isClosed=!0,t.dec())},"cleanup");i.on("end",a),i.on("error",n=>{s.headersSent||T.error(n,"[Virid Express] Stream Error"),a()}),i.on("close",a);return}s.status(e.status).json(e.data),this.httpContextStore.delete(t.id)}};o(oe,"ExpressPlugin");var ue=oe;export{Ie as BadRequest,b as BadRequestResponse,st as Body,de as ConflictResponse,it as Cookies,Te as Created,V as CreatedResponse,dt as Ctx,Ve as CustomResponse,B as CustomResponseResponse,ue as ExpressPlugin,$e as Forbidden,N as ForbiddenResponse,ot as Headers,S as HttpContext,M as HttpError,A as HttpRequestMessage,p as HttpResponse,tt as HttpRoute,rt as HttpSystem,Q as InternalServerError,I as InternalServerErrorResponse,Pe as NoContent,v as NoContentResponse,qe as NotFound,U as NotFoundResponse,Ae as Ok,q as OkResponse,lt as Params,we as ParseBoolPipe,xe as ParseIntPipe,ct as Query,at as Req,nt as Res,be as Stream,ve as StreamFile,y as StreamFileResponse,C as StreamResponse,He as Unauthorized,D as UnauthorizedResponse,ce as UnprocessableEntityResponse,Qe as addAutoPipe,je as getAutoPipe,pe as getHttpArgs,le as parseRawCookie};
7
+ Uptime: ${Date.now()-this.timestamp}ms`;fe.error(new Error(e)),this.res.headersSent?this.res.end():this.res.status(500).json({error:"Internal Logic Error",message:"Request processed but no response was returned by any system."})}};o(j,"HttpContext");var S=j,Y=class Y{constructor(e,t=null,s={}){l(this,"status");l(this,"data");l(this,"headers");this.status=e,this.data=t,this.headers=s}};o(Y,"HttpResponse");var p=Y,X=class X extends p{constructor(e,t={}){super(200,e,t)}};o(X,"OkResponse");var q=X,L=class L extends p{constructor(e,t={}){super(201,e,t)}};o(L,"CreatedResponse");var V=L,K=class K extends p{constructor(){super(204,null)}};o(K,"NoContentResponse");var b=K,z=class z extends p{constructor(e="Bad Request"){super(400,{error:e})}};o(z,"BadRequestResponse");var v=z,F=class F extends p{constructor(e="Unauthorized"){super(401,{error:e})}};o(F,"UnauthorizedResponse");var D=F,W=class W extends p{constructor(e="Forbidden"){super(403,{error:e})}};o(W,"ForbiddenResponse");var N=W,_=class _ extends p{constructor(e="Not Found"){super(404,{error:e})}};o(_,"NotFoundResponse");var U=_,G=class G extends p{constructor(e="Conflict"){super(409,{error:e})}};o(G,"ConflictResponse");var de=G,J=class J extends p{constructor(e){super(422,{errors:e})}};o(J,"UnprocessableEntityResponse");var ce=J,Z=class Z extends p{constructor(e="Internal Server Error"){super(500,{error:e})}};o(Z,"InternalServerErrorResponse");var I=Z,k=class k extends p{constructor(e,t,s={}){super(e,t,s)}};o(k,"CustomResponseResponse");var B=k,ee=class ee extends p{constructor(t,s={dotfiles:"allow"}){super(206,s);l(this,"filePath");l(this,"options");this.filePath=t,this.options=s}};o(ee,"StreamFileResponse");var y=ee,te=class te extends p{constructor(t,s={}){super(s.status||206,{},s.headers);l(this,"stream");l(this,"options");this.stream=t,this.options=s}};o(te,"StreamResponse");var C=te,Ae=o((r,e={})=>new q(r,e),"Ok"),Te=o((r,e={})=>new V(r,e),"Created"),Pe=o(()=>new b,"NoContent"),Ie=o((r="Bad Request")=>new v(r),"BadRequest"),He=o((r="Unauthorized")=>new D(r),"Unauthorized"),$e=o((r="Forbidden")=>new N(r),"Forbidden"),qe=o((r="Not Found")=>new U(r),"NotFound"),Q=o((r="Internal Server Error")=>r instanceof Error?new I(r.message):new I(r),"InternalServerError"),Ve=o((r,e,t={})=>new B(r,e,t),"CustomResponse"),be=o((r,e)=>new y(r,e),"StreamFile"),ve=o((r,e)=>new C(r,e),"Stream"),re=class re extends Error{constructor(t,s){super(s);l(this,"status");l(this,"message");this.status=t,this.message=s}};o(re,"HttpError");var M=re;import{MessageWriter as me}from"@virid/core";function xe(r){let e=parseInt(r,10);if(isNaN(e))throw new M(400,`Validation failed: "${r}" is not a number.`);return e}o(xe,"ParseIntPipe");function we(r){return r==="true"||r==="1"?!0:r==="false"||r==="0"?!1:!!r}o(we,"ParseBoolPipe");var O=new Map;O.set(Number,xe);O.set(Boolean,we);function Qe(r,e){if(O.has(r)){me.error(new Error(`[Virid Express Pipe] Repeated Pipe: Auto pipe for ${r} has already been registered.`));return}O.set(r,e)}o(Qe,"addAutoPipe");function je(r){return O.get(r)}o(je,"getAutoPipe");function le(r){let e={};if(!r)return e;let t=r.split(";");for(let s of t){let i=s.indexOf("=");if(i===-1)continue;let a=s.substring(0,i).trim();if(!a)continue;let n=s.substring(i+1).trim();n[0]==='"'&&n[n.length-1]==='"'&&(n=n.slice(1,-1));try{e[a]=n.includes("%")?decodeURIComponent(n):n}catch{e[a]=n}}return e}o(le,"parseRawCookie");import{EventMessage as Me}from"@virid/core";var se=class se extends Me{constructor(t){super();l(this,"__virid_express_id");this.__virid_express_id=t}get requestId(){return this.__virid_express_id}};o(se,"HttpRequestMessage");var A=se;import{VIRID_METADATA as ge}from"@virid/core";var d={...ge,HTTPROUTE:"virid:express:route",HTTPSYSTEM:"virid:express:system",BODY:"virid:express:body",QUERY:"virid:express:query",HEADERS:"virid:express:header",REQUEST:"virid:express:request",RESPONSE:"virid:express:response",CONTEXT:"virid:express:context",PARAMS:"virid:express:params",COOKIES:"virid:express:cookie"};function tt(r){return e=>{let t=[];r.path.split("/").forEach(a=>{a.startsWith(":")&&t.push(a.substring(1))});let i={...r,httpMessage:e,params:t};Reflect.defineMetadata(d.HTTPROUTE,i,e)}}o(tt,"HttpRoute");function Ee(r){let e=[];if(r.forEach((t,s)=>{(t===A||t&&t.prototype instanceof A)&&e.push({type:t,idx:s})}),e.length===0)return null;if(e.length>1){let t=e.map(s=>`[Index: ${s.idx}, Name: ${s.type.name}]`).join(", ");throw new Error(`[Virid System] Multiple Messages: Multiple Message type parameters detected, this is not allowed! specific location: ${t}`)}return e[0]}o(Ee,"checkMessageParam");function rt(r={priority:0,messageClass:null}){return(e,t,s)=>{if(typeof e!="function")throw new Error(`[Virid System] Method Type Error: The Method ${t} is not a static method, please check if there is a static keyword tag.`);let i=s.value,a=Reflect.getMetadata("design:paramtypes",e,t);if(!a)throw new Error('[Virid System] System Parameter Loss: Unable to recognize system parameters, please confirm if import "reflect-metadata" was introduced at the beginning.');let n=a.map((x,R)=>x===void 0?R:-1).filter(x=>x!==-1);if(n.length>0)throw new Error(`[Virid System] Parameter Metadata Loss in "${t}": One or more parameters have 'undefined' types. This usually happens when you forget to add a type annotation or due to circular dependencies. Check parameter at indices: [${n.join(", ")}]`);let c,h=-1,u=Ee(a);if(u&&r.messageClass)throw new Error(`[Virid System] Multiple Messages Are Not Allowed: Cannot specify messageClass in decorator options while already declaring it in method parameters at index ${u.idx} in ${t}.`);if(u)c=u.type,h=u.idx;else if(r.messageClass)c=r.messageClass,h=-1;else throw new Error("[Virid System] System Parameter Loss: Please declare the message type either in method parameters or via the Message decorator options.");let m=Re(e,t),f={params:a,targetClass:e,methodName:t,originalMethod:i},P={httpMetadata:m,messageClass:c,messageIdx:h,priority:r.priority||0,batchMode:!1};s.value.systemContext=f,s.value.httpSystemConfig=P}}o(rt,"HttpSystem");function st(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.BODY,r,e))throw new Error(`[Virid Express Body] Multiple Body Are Not Allowed: ${e} has multiple @Body() decorators!`);let s={index:t};Reflect.defineMetadata(d.BODY,s,r,e)}}o(st,"Body");function ot(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.HEADERS,r,e))throw new Error(`[Virid Express Headers] Multiple Header Are Not Allowed: ${e} has multiple @Headers() decorators!`);let s={index:t};Reflect.defineMetadata(d.HEADERS,s,r,e)}}o(ot,"Headers");function it(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.COOKIES,r,e))throw new Error(`[Virid Express Cookies] Multiple Header Are Not Allowed: ${e} has multiple @Cookies() decorators!`);let s={index:t};Reflect.defineMetadata(d.COOKIES,s,r,e)}}o(it,"Cookies");function at(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.REQUEST,r,e))throw new Error(`[Virid Express Req] Multiple Request Objects Are Not Allowed: ${e} has multiple @Req() decorators!`);let s={index:t};Reflect.defineMetadata(d.REQUEST,s,r,e)}}o(at,"Req");function nt(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.RESPONSE,r,e))throw new Error(`[Virid Express Res] Multiple Response Objects Are Not Allowed: ${e} has multiple @Res() decorators!`);let s={index:t};Reflect.defineMetadata(d.RESPONSE,s,r,e)}}o(nt,"Res");function dt(){return(r,e,t)=>{if(Reflect.hasOwnMetadata(d.CONTEXT,r,e))throw new Error(`[Virid Express Ctx] Multiple Context Objects Are Not Allowed: ${e} has multiple @Ctx() decorators!`);let s={index:t};Reflect.defineMetadata(d.CONTEXT,s,r,e)}}o(dt,"Ctx");function ct(r,e){return(t,s,i)=>{let n=[...Reflect.getOwnMetadata(d.QUERY,t,s)||[],{index:i,query:r,pipe:e}];Reflect.defineMetadata(d.QUERY,n,t,s)}}o(ct,"Query");function lt(r,e){return(t,s,i)=>{let n=[...Reflect.getOwnMetadata(d.PARAMS,t,s)||[],{index:i,key:r,pipe:e}];Reflect.defineMetadata(d.PARAMS,n,t,s)}}o(lt,"Params");function Re(r,e){let t=Reflect.getOwnMetadata(d.BODY,r,e),s=Reflect.getOwnMetadata(d.HEADERS,r,e),i=Reflect.getOwnMetadata(d.COOKIES,r,e),a=Reflect.getOwnMetadata(d.RESPONSE,r,e),n=Reflect.getOwnMetadata(d.REQUEST,r,e),c=Reflect.getOwnMetadata(d.CONTEXT,r,e),h=Reflect.getOwnMetadata(d.QUERY,r,e)||[],u=Reflect.getOwnMetadata(d.PARAMS,r,e)||[];return{bodyMeta:t,headerMeta:s,queryMeta:h,paramMeta:u,cookiesMeta:i,reqMeta:n,resMeta:a,ctxMeta:c}}o(Re,"getHttpMetadata");function pe(r,e,t){let{req:s,res:i}=e;if(t.ctxMeta?.index===r)return e;let a=t.paramMeta?.find(c=>c.index===r);if(a){let c=a.key?s.params[a.key]:s.params;return a.pipe&&c!==void 0&&(c=a.pipe(c)),c}if(t.bodyMeta?.index===r)return s.body;if(t.headerMeta?.index===r)return s.headers;if(t.cookiesMeta?.index===r)return le(s.headers.cookie);if(t.reqMeta?.index===r)return s;if(t.resMeta?.index===r)return i;let n=t.queryMeta?.find(c=>c.index===r);if(n){let c=s.query[n.query];if(c===void 0)throw new Error(`[Virid Express] Missing Query: "${n.query}"`);return n.pipe&&(c=n.pipe(c)),c}return null}o(pe,"getHttpArgs");var oe=class oe{constructor(){l(this,"name","@virid/express");l(this,"stagingSystemRegister",new Se);l(this,"httpRouteRegistry",new Map);l(this,"httpContextStore",new Map);l(this,"_internalHttpIdCounter",0)}register(e){let t=e.systemContext,s=e.httpSystemConfig;if(!t||!s)throw new Error(`[Virid HttpSystem] HttpSystem Parameter Loss: Please declare ${e.name} using the @HttpSystem decorator first.`);return this.stagingSystemRegister.register(t.targetClass,e,s.priority),()=>{}}bindRoute(e){let t=Reflect.getMetadata(d.HTTPROUTE,e);if(!t)throw new Error(`[Virid Http] Routing Error: ${e.name} is not a valid HttpRoute`);let s=`${t.method}:${t.path}`;if(this.httpRouteRegistry.has(s))throw new Error(`[Virid Http] Routing Conflict: The request method ${t.method} for path ${t.path} has already been registered by ${e.name}`);this.httpRouteRegistry.set(s,t)}install(e,t){for(let[s,i]of this.httpRouteRegistry.entries()){let{method:a,path:n,httpMessage:c}=i,h=a.toLowerCase();t.server[h](n,(u,m)=>{let f=this._internalHttpIdCounter++>>>0;new S(f,u,m,Date.now(),n).inc(),this.httpContextStore.set(f,new S(f,u,m,Date.now(),n));let x=new c(f);m.once("finish",()=>this.httpContextStore.delete(f)),m.once("close",()=>this.httpContextStore.delete(f)),T.write(x)})}for(let[s,i]of this.stagingSystemRegister.systemTaskMap.entries())for(let a of i){let n=a.fn,c=n.systemContext,h=n.httpSystemConfig,{httpMetadata:u,messageClass:m,messageIdx:f}=h,{originalMethod:P,targetClass:x}=c,R=o(H=>{let w=this.httpContextStore.get(H.requestId);if(!w)throw new Error(`[Virid Express HttpSystem] Invalid Request Context: The request context for message ${H.requestId} is missing.`);try{let g=c.params.map((E,ie)=>{if(ie===f)return H;{let ae=pe(ie,w,u);return ae||e.get(E)}}),$=P.apply(x,g);return $ instanceof Promise?$.then(E=>{this.handleResult(E,w)}).catch(E=>{throw this.handleResult(Q(E),w),E}):this.handleResult($,w)}catch(g){throw g instanceof M?this.handleResult(g,w):this.handleResult(Q(g),w),g}},"wrappedSystem");R.systemContext=c,R.httpSystemConfig=h,e.engine.register(m,R,a.priority)}this.stagingSystemRegister.systemTaskMap.clear()}handleResult(e,t){if(!e){t.dec();return}(Array.isArray(e)?e:[e]).forEach(i=>{i instanceof p?this.handleHttpResponse(i,t):i instanceof M?(t.res.status(i.status).json(i.message),this.httpContextStore.delete(t.id)):i instanceof ye?T.write(i):T.warn(`[Virid Express] Invalid Return Type: ${typeof i}. Expected HttpResponse or Message.`)}),t.dec()}handleHttpResponse(e,t){let{res:s}=t;if(e.headers&&Object.entries(e.headers).forEach(([i,a])=>s.setHeader(i,a)),e.status&&s.status(e.status),e instanceof y){t.inc(),s.sendFile(e.filePath,e.options,i=>{s.headersSent||T.error(i,`[Virid Express] SteamFile Error: Path: ${e.filePath}`),t.res.end(),this.httpContextStore.delete(t.id),t.isClosed=!0,t.dec()});return}if(e instanceof C){let{stream:i}=e;t.inc(),i.pipe(s);let a=o(()=>{this.httpContextStore.has(t.id)&&(t.res.end(),this.httpContextStore.delete(t.id),t.isClosed=!0,t.dec())},"cleanup");i.on("end",a),i.on("error",n=>{s.headersSent||T.error(n,"[Virid Express] Stream Error"),a()}),i.on("close",a);return}s.status(e.status).json(e.data),this.httpContextStore.delete(t.id)}};o(oe,"ExpressPlugin");var ue=oe;export{Ie as BadRequest,v as BadRequestResponse,st as Body,de as ConflictResponse,it as Cookies,Te as Created,V as CreatedResponse,dt as Ctx,Ve as CustomResponse,B as CustomResponseResponse,ue as ExpressPlugin,$e as Forbidden,N as ForbiddenResponse,ot as Headers,S as HttpContext,M as HttpError,A as HttpRequestMessage,p as HttpResponse,tt as HttpRoute,rt as HttpSystem,Q as InternalServerError,I as InternalServerErrorResponse,Pe as NoContent,b as NoContentResponse,qe as NotFound,U as NotFoundResponse,Ae as Ok,q as OkResponse,lt as Params,we as ParseBoolPipe,xe as ParseIntPipe,ct as Query,at as Req,nt as Res,ve as Stream,be as StreamFile,y as StreamFileResponse,C as StreamResponse,He as Unauthorized,D as UnauthorizedResponse,ce as UnprocessableEntityResponse,Qe as addAutoPipe,je as getAutoPipe,pe as getHttpArgs,le as parseRawCookie};
8
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/http/response.ts","../src/http/utils.ts","../src/http/message.ts","../src/decorators/constant.ts","../src/decorators/decorator.ts"],"sourcesContent":["/*\n * Copyright (c) 2026-present Ailrid\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Description: Add express functionality to virid.\n */\nimport {\n ViridPlugin,\n type ViridApp,\n MessageRegistry,\n MessageWriter,\n Newable,\n SystemContext,\n BaseMessage,\n} from \"@virid/core\";\nimport { getHttpArgs } from \"./decorators\";\nimport {\n HttpSystemConfig,\n type HttpMethod,\n type HttpRouteInfo,\n} from \"./interfaces\";\n\nimport {\n HttpContext,\n HttpError,\n HttpRequestMessage,\n HttpResponse,\n InternalServerError,\n RequestId,\n StreamFileResponse,\n StreamResponse,\n} from \"./http\";\n\nimport { PluginOptions } from \"./interfaces\";\nimport { type Request, type Response } from \"express\";\nimport { VIRID_EXPRESS_METADATA } from \"./decorators/constant\";\nexport * from \"./http\";\nexport * from \"./decorators\";\n\nexport class ExpressPlugin implements ViridPlugin<PluginOptions> {\n name = \"@virid/express\";\n // temporary Registry\n private stagingSystemRegister = new MessageRegistry();\n // route Registry\n private httpRouteRegistry = new Map<string, HttpRouteInfo>();\n\n private httpContextStore = new Map<number, HttpContext>();\n\n private _internalHttpIdCounter = 0;\n\n register(systemFn: (...args: any[]) => any): () => void {\n // @ts-expect-error: get systemContext from systemFn\n const systemContext: SystemContext = systemFn.systemContext;\n // @ts-expect-error: get httpSystemConfig from systemFn\n const httpSystemConfig: HttpSystemConfig = systemFn.httpSystemConfig;\n if (!systemContext || !httpSystemConfig) {\n throw new Error(\n `[Virid HttpSystem] HttpSystem Parameter Loss: Please declare ${systemFn.name} using the @HttpSystem decorator first.`,\n );\n }\n this.stagingSystemRegister.register(\n systemContext.targetClass,\n systemFn,\n httpSystemConfig.priority,\n );\n return () => {};\n }\n\n bindRoute(constructor: Newable<HttpRequestMessage>) {\n const config: HttpRouteInfo = Reflect.getMetadata(\n VIRID_EXPRESS_METADATA.HTTPROUTE,\n constructor,\n );\n if (!config) {\n throw new Error(\n `[Virid Http] Routing Error: ${constructor.name} is not a valid HttpRoute`,\n );\n }\n // Uniqueness verification: Combining Method and Path\n const routeKey = `${config.method}:${config.path}`;\n if (this.httpRouteRegistry.has(routeKey)) {\n throw new Error(\n `[Virid Http] Routing Conflict: The request method ${config.method} for path ${config.path} has already been registered by ${constructor.name}`,\n );\n } else {\n this.httpRouteRegistry.set(routeKey, config);\n }\n }\n\n install(app: ViridApp, options: PluginOptions) {\n app.spawn(options.server);\n // register for express routing\n for (const [_, routeInfo] of this.httpRouteRegistry.entries()) {\n const { method, path, httpMessage } = routeInfo;\n const expressMethod = method.toLowerCase() as HttpMethod;\n\n options.server[expressMethod](path, (req: Request, res: Response) => {\n // instantiate Message\n const newId = this._internalHttpIdCounter++ >>> 0;\n\n // save contextual information\n const context = new HttpContext(newId, req, res, Date.now(), path);\n context.inc();\n this.httpContextStore.set(\n newId,\n new HttpContext(newId, req, res, Date.now(), path),\n );\n const message = new httpMessage(newId as RequestId);\n // finish means the response has been sent, close means the connection was unexpectedly interrupted, both should be cleaned up\n res.once(\"finish\", () => this.httpContextStore.delete(newId));\n res.once(\"close\", () => this.httpContextStore.delete(newId));\n // send message\n MessageWriter.write(message);\n });\n }\n\n // register HttpSystem into the app's scheduler\n for (const [\n messageClass,\n systemTasks,\n ] of this.stagingSystemRegister.systemTaskMap.entries()) {\n for (const task of systemTasks) {\n const systemFn = task.fn;\n // @ts-expect-error: get systemContext from systemFn\n const systemContext: SystemContext = systemFn.systemContext;\n // @ts-expect-error: get httpSystemConfig from systemFn\n const httpSystemConfig: HttpSystemConfig = systemFn.httpSystemConfig;\n const { httpMetadata, messageClass, messageIdx } = httpSystemConfig;\n const { originalMethod, targetClass } = systemContext;\n const wrappedSystem = (currentMessage: HttpRequestMessage) => {\n // retrieve the context of the current request\n const context = this.httpContextStore.get(currentMessage.requestId);\n if (!context) {\n throw new Error(\n `[Virid Express HttpSystem] Invalid Request Context: The request context for message ${currentMessage.requestId} is missing.`,\n );\n }\n try {\n const args = systemContext.params.map(\n (type: any, index: number) => {\n // If it is a message, inject\n if (index === messageIdx) {\n return currentMessage;\n } else {\n // Otherwise, try injecting HTTP parameters or components\n const arg = getHttpArgs(index, context, httpMetadata);\n return arg ? arg : app.get(type);\n }\n },\n );\n const result = originalMethod.apply(targetClass, args);\n return result instanceof Promise\n ? result\n .then((res) => {\n this.handleResult(res, context);\n })\n .catch((error) => {\n // asynchronous error needs to send 500 to the client\n this.handleResult(InternalServerError(error), context);\n // continue throwing, let Dispatcher capture and print detailed stack\n throw error;\n })\n : this.handleResult(result, context);\n } catch (error) {\n if (error instanceof HttpError) {\n // if manually throw new HttpError\n this.handleResult(error, context);\n } else {\n // real crash, return 500\n this.handleResult(InternalServerError(error as Error), context);\n }\n throw error; // continue throwing, let Dispatcher capture and print detailed stack\n }\n };\n wrappedSystem.systemContext = systemContext;\n wrappedSystem.httpSystemConfig = httpSystemConfig;\n app.engine.register(messageClass, wrappedSystem, task.priority);\n }\n }\n this.stagingSystemRegister.systemTaskMap.clear();\n }\n\n handleResult(res: any, context: HttpContext) {\n if (!res) {\n context.dec();\n return;\n }\n const results = Array.isArray(res) ? res : [res];\n results.forEach((item) => {\n if (item instanceof HttpResponse) {\n // if it is a termination response, handle it\n this.handleHttpResponse(item, context);\n } else if (item instanceof HttpError) {\n // handling errors\n context.res.status(item.status).json(item.message);\n this.httpContextStore.delete(context.id);\n } else if (item instanceof BaseMessage) {\n MessageWriter.write(item);\n } else {\n MessageWriter.warn(\n `[Virid Express] Invalid Return Type: ${typeof item}. Expected HttpResponse or Message.`,\n );\n }\n });\n //Whether the system encounters an error or completes execution, handleResult will execute with a reference count of -1 and check if it is 0\n //If it is 0 and it has not been closed yet, then force it to close\n //The first scenario: If handleHttpResponse is executed above, then HttpContext has already been deleted before that\n //The second scenario: If the HttpRequestMessage is forwarded above, it will erase the trace of the system execution, but the HttpContext will not be deleted due to reference counting\n //The third scenario: If other messages or return values are forwarded above, the reference count will be -1 and checked if it is 0. If it is 0, it will be forcibly closed\n context.dec();\n }\n\n handleHttpResponse(response: HttpResponse, ctx: HttpContext) {\n const { res } = ctx;\n\n if (response.headers) {\n Object.entries(response.headers).forEach(([k, v]) => res.setHeader(k, v));\n }\n\n if (response.status) res.status(response.status);\n\n if (response instanceof StreamFileResponse) {\n // return asynchronous stream and forcefully add an RC extension\n ctx.inc();\n res.sendFile(response.filePath, response.options, (err) => {\n if (!res.headersSent) {\n MessageWriter.error(\n err,\n `[Virid Express] SteamFile Error: Path: ${response.filePath}`,\n );\n }\n ctx.res.end();\n this.httpContextStore.delete(ctx.id);\n ctx.isClosed = true;\n ctx.dec();\n });\n return;\n }\n if (response instanceof StreamResponse) {\n const { stream } = response;\n ctx.inc();\n stream.pipe(res);\n // end of listening, harvest context\n const cleanup = () => {\n if (!this.httpContextStore.has(ctx.id)) return;\n ctx.res.end();\n this.httpContextStore.delete(ctx.id);\n ctx.isClosed = true;\n ctx.dec();\n };\n stream.on(\"end\", cleanup);\n stream.on(\"error\", (err) => {\n if (!res.headersSent) {\n MessageWriter.error(err, `[Virid Express] Stream Error`);\n }\n cleanup();\n });\n stream.on(\"close\", cleanup);\n return;\n }\n\n res.status(response.status).json(response.data);\n this.httpContextStore.delete(ctx.id);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { type Request, type Response } from \"express\";\nimport { Readable } from \"stream\";\nimport { MessageWriter } from \"@virid/core\";\ninterface HttpHeaders {\n [key: string]: string | string[];\n}\nexport class HttpContext {\n public rc: number = 0;\n public isClosed: boolean = false;\n\n constructor(\n public readonly id: number,\n public readonly req: Request,\n public readonly res: Response,\n public readonly timestamp: number,\n public readonly route: string,\n ) {}\n\n inc() {\n this.rc++;\n }\n\n dec() {\n this.rc--;\n if (this.rc === 0) {\n this.tryFinalize();\n }\n }\n\n private tryFinalize() {\n if (this.res.writableEnded || this.isClosed) return;\n\n this.isClosed = true;\n\n const errorMsg = `[Virid Express] Request Orphaned: The connection was closed because all systems finished execution without sending a response. \n Route: ${this.route}\n Uptime: ${Date.now() - this.timestamp}ms`;\n\n MessageWriter.error(new Error(errorMsg));\n\n if (!this.res.headersSent) {\n this.res.status(500).json({\n error: \"Internal Logic Error\",\n message:\n \"Request processed but no response was returned by any system.\",\n });\n } else {\n this.res.end();\n }\n }\n}\n\nexport abstract class HttpResponse {\n constructor(\n public status: number,\n public data: any = null,\n public headers: HttpHeaders = {},\n ) {}\n}\n\n// --- 2xx Success ---\nexport class OkResponse extends HttpResponse {\n constructor(data: any, headers: HttpHeaders = {}) {\n super(200, data, headers);\n }\n}\n\nexport class CreatedResponse extends HttpResponse {\n constructor(data: any, headers: HttpHeaders = {}) {\n super(201, data, headers);\n }\n}\n\nexport class NoContentResponse extends HttpResponse {\n constructor() {\n super(204, null);\n }\n}\n\n// --- 4xx Client Error ---\nexport class BadRequestResponse extends HttpResponse {\n constructor(message: string = \"Bad Request\") {\n super(400, { error: message });\n }\n}\n\nexport class UnauthorizedResponse extends HttpResponse {\n constructor(message: string = \"Unauthorized\") {\n super(401, { error: message });\n }\n}\n\nexport class ForbiddenResponse extends HttpResponse {\n constructor(message: string = \"Forbidden\") {\n super(403, { error: message });\n }\n}\n\nexport class NotFoundResponse extends HttpResponse {\n constructor(message: string = \"Not Found\") {\n super(404, { error: message });\n }\n}\n\nexport class ConflictResponse extends HttpResponse {\n constructor(message: string = \"Conflict\") {\n super(409, { error: message });\n }\n}\n\nexport class UnprocessableEntityResponse extends HttpResponse {\n constructor(errors: any) {\n super(422, { errors });\n }\n}\n\n// --- 5xx Server Error ---\nexport class InternalServerErrorResponse extends HttpResponse {\n constructor(message: string = \"Internal Server Error\") {\n super(500, { error: message });\n }\n}\n\n// --- 万能类 (Custom) ---\nexport class CustomResponseResponse extends HttpResponse {\n constructor(status: number, data: any, headers: HttpHeaders = {}) {\n super(status, data, headers);\n }\n}\n/**\n * @description: Express sendFile 配置项的强类型定义\n */\nexport interface StreamFileOptions {\n /** 根目录(如果 path 是相对路径则必填) */\n root?: string;\n /** * 对以 . 开头的文件处理策略:\n * - allow: 允许发送\n * - deny: 拒绝并返回 403\n * - ignore: 当作不存在返回 404\n */\n dotfiles?: \"allow\" | \"deny\" | \"ignore\";\n /** 是否发送 ETag */\n etag?: boolean;\n /** 扩展的 HTTP 响应头 */\n headers?: HttpHeaders;\n /** 缓存最大时长 (毫秒) */\n maxAge?: number | string;\n /** 是否在 Cache-Control 中添加 immutable */\n immutable?: boolean;\n /** 是否根据文件系统设置 Last-Modified */\n lastModified?: boolean;\n /** 是否支持断点续传 (Range 请求) */\n acceptRanges?: boolean;\n}\nexport class StreamFileResponse extends HttpResponse {\n constructor(\n public readonly filePath: string,\n public readonly options: StreamFileOptions = { dotfiles: \"allow\" },\n ) {\n super(206, options);\n }\n}\n\nexport class StreamResponse extends HttpResponse {\n constructor(\n public readonly stream: Readable,\n public readonly options: {\n status?: number;\n headers?: HttpHeaders;\n } = {},\n ) {\n super(options.status || 206, {}, options.headers);\n }\n}\n\n/** 200 OK */\nexport const Ok = (data: any, headers: HttpHeaders = {}) =>\n new OkResponse(data, headers);\n\n/** 201 Created */\nexport const Created = (data: any, headers: HttpHeaders = {}) =>\n new CreatedResponse(data, headers);\n\n/** 204 No Content */\nexport const NoContent = () => new NoContentResponse();\n\n/** 400 Bad Request */\nexport const BadRequest = (msg = \"Bad Request\") => new BadRequestResponse(msg);\n\n/** 401 Unauthorized */\nexport const Unauthorized = (msg = \"Unauthorized\") =>\n new UnauthorizedResponse(msg);\n\n/** 403 Forbidden */\nexport const Forbidden = (msg = \"Forbidden\") => new ForbiddenResponse(msg);\n\n/** 404 Not Found */\nexport const NotFound = (msg = \"Not Found\") => new NotFoundResponse(msg);\n\n/** 500 Internal Error */\nexport const InternalServerError = (\n msg: string | Error = \"Internal Server Error\",\n) => {\n return msg instanceof Error\n ? new InternalServerErrorResponse(msg.message)\n : new InternalServerErrorResponse(msg);\n};\n\nexport const CustomResponse = (\n status: number,\n data: any,\n headers: HttpHeaders = {},\n) => new CustomResponseResponse(status, data, headers);\n\n/** 发送本地文件 (自动处理 Range/206) */\nexport const StreamFile = (path: string, options?: StreamFileOptions) =>\n new StreamFileResponse(path, options);\n/**\n * 发送流响应\n */\nexport const Stream = (stream: Readable, options?: StreamResponse[\"options\"]) =>\n new StreamResponse(stream, options);\n\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n public readonly message: string,\n ) {\n super(message);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { MessageWriter } from \"@virid/core\";\nimport { HttpError } from \".\";\nimport { type TransformPipe } from \"../interfaces\";\n\nexport function ParseIntPipe(val: string) {\n const res = parseInt(val, 10);\n if (isNaN(res))\n throw new HttpError(400, `Validation failed: \"${val}\" is not a number.`);\n return res;\n}\n\nexport function ParseBoolPipe(val: string) {\n if (val === \"true\" || val === \"1\") return true;\n if (val === \"false\" || val === \"0\") return false;\n return !!val;\n}\n\nconst autoPipeMap = new Map<any, TransformPipe<any>>();\nautoPipeMap.set(Number, ParseIntPipe);\nautoPipeMap.set(Boolean, ParseBoolPipe);\n\nexport function addAutoPipe<T>(type: T, pipe: TransformPipe<T>) {\n if (autoPipeMap.has(type)) {\n MessageWriter.error(\n new Error(\n `[Virid Express Pipe] Repeated Pipe: Auto pipe for ${type} has already been registered.`,\n ),\n );\n return;\n }\n autoPipeMap.set(type, pipe);\n}\n\nexport function getAutoPipe<T>(type: T): TransformPipe<T> | undefined {\n return autoPipeMap.get(type);\n}\n\nexport function parseRawCookie(\n cookieHeader: string | undefined,\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n if (!cookieHeader) return result;\n const pairs = cookieHeader.split(\";\");\n\n for (const pair of pairs) {\n const indexOfEq = pair.indexOf(\"=\");\n if (indexOfEq === -1) continue;\n\n // 提取 key 和 value,并进行 trim 处理\n const key = pair.substring(0, indexOfEq).trim();\n if (!key) continue;\n\n let value = pair.substring(indexOfEq + 1).trim();\n\n if (value[0] === '\"' && value[value.length - 1] === '\"') {\n value = value.slice(1, -1);\n }\n\n try {\n result[key] = value.includes(\"%\") ? decodeURIComponent(value) : value;\n } catch (e) {\n result[key] = value;\n }\n }\n\n return result;\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { EventMessage } from \"@virid/core\";\nexport type RequestId = number & { readonly __brand: unique symbol };\n\nexport class HttpRequestMessage extends EventMessage {\n // ID must be of type RequestId\n constructor(private readonly __virid_express_id: RequestId) {\n super();\n }\n // expose a read-only attribute for use by the business layer\n public get requestId(): RequestId {\n return this.__virid_express_id;\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { VIRID_METADATA } from \"@virid/core\";\n\nexport const VIRID_EXPRESS_METADATA = {\n ...VIRID_METADATA,\n HTTPROUTE: \"virid:express:route\",\n HTTPSYSTEM: \"virid:express:system\",\n BODY: \"virid:express:body\",\n QUERY: \"virid:express:query\",\n HEADERS: \"virid:express:header\",\n REQUEST: \"virid:express:request\",\n RESPONSE: \"virid:express:response\",\n CONTEXT: \"virid:express:context\",\n PARAMS: \"virid:express:params\",\n COOKIES: \"virid:express:cookie\",\n} as const;\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { type Newable, type SystemContext } from \"@virid/core\";\nimport {\n type HttpRouteConfig,\n type HttpRouteInfo,\n type BodyMetadata,\n type HeaderMetadata,\n type QueryMetadata,\n type RequestMetadata,\n type ResponseMetadata,\n type ContextMetadata,\n type ParamMetadata,\n type TransformPipe,\n type CookieMetadata,\n type HttpSystemParams,\n type HttpMetadata,\n type HttpSystemConfig,\n} from \"../interfaces\";\nimport { HttpContext, HttpRequestMessage, parseRawCookie } from \"../http\";\n\nimport { VIRID_EXPRESS_METADATA } from \"./constant\";\n\nexport function HttpRoute(config: HttpRouteConfig) {\n return (constructor: Newable<HttpRequestMessage>) => {\n const params: string[] = [];\n const pathParts = config.path.split(\"/\");\n pathParts.forEach((part) => {\n if (part.startsWith(\":\")) {\n params.push(part.substring(1));\n }\n });\n\n const routeInfo: HttpRouteInfo = {\n ...config,\n httpMessage: constructor,\n params,\n };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.HTTPROUTE,\n routeInfo,\n constructor,\n );\n };\n}\n\n/**\n * Check if there are multiple message type parameters in the parameters\n * @param types Parameter list\n */\nfunction checkMessageParam(types: Array<any>) {\n const foundMatches: { type: Newable<HttpRequestMessage>; idx: number }[] = [];\n\n types.forEach((type, idx) => {\n const isHttpRequestMessage =\n type === HttpRequestMessage ||\n (type && type.prototype instanceof HttpRequestMessage);\n\n if (isHttpRequestMessage) {\n foundMatches.push({ type, idx });\n }\n });\n\n if (foundMatches.length === 0) {\n return null;\n }\n\n if (foundMatches.length > 1) {\n const errorDetails = foundMatches\n .map((item) => `[Index: ${item.idx}, Name: ${item.type.name}]`)\n .join(\", \");\n\n throw new Error(\n `[Virid System] Multiple Messages: Multiple Message type parameters detected, this is not allowed! specific location: ${errorDetails}`,\n );\n }\n\n return foundMatches[0];\n}\n\n/**\n * @description: 系统装饰器\n * @param priority 优先级,数值越大越早执行\n */\nexport function HttpSystem(\n params: HttpSystemParams = {\n priority: 0,\n messageClass: null,\n },\n) {\n return (target: any, key: string, descriptor: PropertyDescriptor) => {\n if (typeof target !== \"function\") {\n throw new Error(\n `[Virid System] Method Type Error: The Method ${key} is not a static method, please check if there is a static keyword tag.`,\n );\n }\n\n const originalMethod = descriptor.value;\n const types: Array<any> = Reflect.getMetadata(\n \"design:paramtypes\",\n target,\n key,\n );\n\n // Verify if metadata exists\n if (!types) {\n throw new Error(\n `[Virid System] System Parameter Loss: Unable to recognize system parameters, please confirm if import \"reflect-metadata\" was introduced at the beginning.`,\n );\n }\n\n // Verify if there are undefined parameters\n const undefinedIndices = types\n .map((t, i) => (t === undefined ? i : -1))\n .filter((i) => i !== -1);\n if (undefinedIndices.length > 0) {\n throw new Error(\n `[Virid System] Parameter Metadata Loss in \"${key}\": One or more parameters have 'undefined' types. This usually happens when you forget to add a type annotation or due to circular dependencies. Check parameter at indices: [${undefinedIndices.join(\", \")}]`,\n );\n }\n\n let messageClass: Newable<HttpRequestMessage>;\n // eslint-disable-next-line no-useless-assignment\n let messageIdx: number = -1;\n const matchedMessage = checkMessageParam(types); // { type: any, idx: number } | null\n if (matchedMessage && params.messageClass) {\n throw new Error(\n `[Virid System] Multiple Messages Are Not Allowed: Cannot specify messageClass in decorator options while already declaring it in method parameters at index ${matchedMessage.idx} in ${key}.`,\n );\n }\n\n if (matchedMessage) {\n messageClass = matchedMessage.type;\n messageIdx = matchedMessage.idx; // In single mode, idx points to the location of a specific BaseMessage subclass\n } else if (params.messageClass) {\n messageClass = params.messageClass;\n messageIdx = -1; // Only provided in the configuration, cannot be found in the parameters, set to -1\n } else {\n throw new Error(\n `[Virid System] System Parameter Loss: Please declare the message type either in method parameters or via the Message decorator options.`,\n );\n }\n const httpMetadata = getHttpMetadata(target, key);\n\n // Attach contextual information to the packaged function\n const systemContext: SystemContext = {\n params: types,\n targetClass: target,\n methodName: key,\n originalMethod: originalMethod,\n };\n const httpSystemConfig: HttpSystemConfig = {\n httpMetadata: httpMetadata,\n messageClass: messageClass,\n messageIdx: messageIdx,\n priority: params.priority || 0,\n batchMode: false,\n };\n\n // Purely mounting data without changing the execution logic of the original method\n (descriptor.value as any).systemContext = systemContext;\n (descriptor.value as any).httpSystemConfig = httpSystemConfig;\n };\n}\n\nexport function Body() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.BODY, target, key)) {\n throw new Error(\n `[Virid Express Body] Multiple Body Are Not Allowed: ${key} has multiple @Body() decorators!`,\n );\n }\n const bodyMetadata = { index } as BodyMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.BODY,\n bodyMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Headers() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.HEADERS, target, key)) {\n throw new Error(\n `[Virid Express Headers] Multiple Header Are Not Allowed: ${key} has multiple @Headers() decorators!`,\n );\n }\n const headerMetadata = { index } as HeaderMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.HEADERS,\n headerMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Cookies() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.COOKIES, target, key)) {\n throw new Error(\n `[Virid Express Cookies] Multiple Header Are Not Allowed: ${key} has multiple @Cookies() decorators!`,\n );\n }\n const cookiesMetadata = { index } as CookieMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.COOKIES,\n cookiesMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Req() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.REQUEST, target, key)) {\n throw new Error(\n `[Virid Express Req] Multiple Request Objects Are Not Allowed: ${key} has multiple @Req() decorators!`,\n );\n }\n const requestMetadata: RequestMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.REQUEST,\n requestMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Res() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.RESPONSE, target, key)) {\n throw new Error(\n `[Virid Express Res] Multiple Response Objects Are Not Allowed: ${key} has multiple @Res() decorators!`,\n );\n }\n const responseMetadata: ResponseMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.RESPONSE,\n responseMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Ctx() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.CONTEXT, target, key)) {\n throw new Error(\n `[Virid Express Ctx] Multiple Context Objects Are Not Allowed: ${key} has multiple @Ctx() decorators!`,\n );\n }\n const contextMetadata: ContextMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.CONTEXT,\n contextMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Query(query: string, pipe?: TransformPipe<any>) {\n return (target: any, key: string, index: number) => {\n const existingMetadata: QueryMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.QUERY, target, key) || [];\n const newMetadata = [...existingMetadata, { index, query, pipe }];\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.QUERY,\n newMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Params(key?: string, pipe?: TransformPipe<any>) {\n return (target: any, keyName: string, index: number) => {\n const existingMetadata: ParamMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.PARAMS, target, keyName) ||\n [];\n const newMetadata = [...existingMetadata, { index, key, pipe }];\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.PARAMS,\n newMetadata,\n target,\n keyName,\n );\n };\n}\n\nfunction getHttpMetadata(target: any, key: string): HttpMetadata {\n const bodyMeta: BodyMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.BODY,\n target,\n key,\n );\n const headerMeta: HeaderMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.HEADERS,\n target,\n key,\n );\n const cookiesMeta: CookieMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.COOKIES,\n target,\n key,\n );\n\n const resMeta: ResponseMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.RESPONSE,\n target,\n key,\n );\n const reqMeta: RequestMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.REQUEST,\n target,\n key,\n );\n const ctxMeta: ContextMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.CONTEXT,\n target,\n key,\n );\n\n const queryMeta: QueryMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.QUERY, target, key) || [];\n\n const paramMeta: ParamMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.PARAMS, target, key) || [];\n\n return {\n bodyMeta,\n headerMeta,\n queryMeta,\n paramMeta,\n cookiesMeta,\n reqMeta,\n resMeta,\n ctxMeta,\n };\n}\n\nexport function getHttpArgs(\n index: number,\n context: HttpContext,\n httpMetadata: HttpMetadata,\n): any {\n const { req, res } = context;\n\n // 匹配 @Ctx()\n if (httpMetadata.ctxMeta?.index === index) return context;\n\n // 匹配 @Param() -> 获取路由参数 (:id 等)\n const paramItem = httpMetadata.paramMeta?.find((p) => p.index === index);\n if (paramItem) {\n let val = paramItem.key ? req.params[paramItem.key] : req.params;\n\n // 如果有 Pipe 且值不是 undefined,进行转换\n if (paramItem.pipe && val !== undefined) {\n val = paramItem.pipe(val);\n }\n return val;\n }\n\n // @Body()\n if (httpMetadata.bodyMeta?.index === index) return req.body;\n\n // @Header()\n if (httpMetadata.headerMeta?.index === index) return req.headers;\n\n // @Cookie()\n if (httpMetadata.cookiesMeta?.index === index)\n return parseRawCookie(req.headers.cookie);\n\n // @Req() 和 @Res()\n if (httpMetadata.reqMeta?.index === index) return req;\n if (httpMetadata.resMeta?.index === index) return res;\n\n // @Query('name')\n const queryItem = httpMetadata.queryMeta?.find((q) => q.index === index);\n if (queryItem) {\n let val = req.query[queryItem.query];\n if (val === undefined) {\n throw new Error(`[Virid Express] Missing Query: \"${queryItem.query}\"`);\n }\n\n if (queryItem.pipe) {\n val = queryItem.pipe(val);\n }\n return val;\n }\n return null;\n}\n"],"mappings":"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","names":["MessageRegistry","MessageWriter","BaseMessage","MessageWriter","HttpContext","id","req","res","timestamp","route","rc","isClosed","inc","dec","tryFinalize","writableEnded","errorMsg","Date","now","MessageWriter","error","Error","headersSent","end","status","json","message","_HttpContext","HttpResponse","data","headers","_HttpResponse","OkResponse","_OkResponse","CreatedResponse","_CreatedResponse","NoContentResponse","_NoContentResponse","BadRequestResponse","_BadRequestResponse","UnauthorizedResponse","_UnauthorizedResponse","ForbiddenResponse","_ForbiddenResponse","NotFoundResponse","_NotFoundResponse","ConflictResponse","_ConflictResponse","UnprocessableEntityResponse","errors","_UnprocessableEntityResponse","InternalServerErrorResponse","_InternalServerErrorResponse","CustomResponseResponse","_CustomResponseResponse","StreamFileResponse","filePath","options","dotfiles","_StreamFileResponse","StreamResponse","stream","_StreamResponse","Ok","__name","Created","NoContent","BadRequest","msg","Unauthorized","Forbidden","NotFound","InternalServerError","CustomResponse","StreamFile","path","Stream","HttpError","_HttpError","MessageWriter","ParseIntPipe","val","res","parseInt","isNaN","HttpError","ParseBoolPipe","autoPipeMap","Map","set","Number","Boolean","addAutoPipe","type","pipe","has","MessageWriter","error","Error","getAutoPipe","get","parseRawCookie","cookieHeader","result","pairs","split","pair","indexOfEq","indexOf","key","substring","trim","value","length","slice","includes","decodeURIComponent","EventMessage","HttpRequestMessage","EventMessage","__virid_express_id","requestId","_HttpRequestMessage","VIRID_METADATA","VIRID_EXPRESS_METADATA","HTTPROUTE","HTTPSYSTEM","BODY","QUERY","HEADERS","REQUEST","RESPONSE","CONTEXT","PARAMS","COOKIES","HttpRoute","config","constructor","params","path","split","forEach","part","startsWith","push","substring","routeInfo","httpMessage","Reflect","defineMetadata","VIRID_EXPRESS_METADATA","HTTPROUTE","checkMessageParam","types","foundMatches","type","idx","HttpRequestMessage","prototype","length","errorDetails","map","item","name","join","Error","HttpSystem","priority","messageClass","target","key","descriptor","originalMethod","value","getMetadata","undefinedIndices","t","i","undefined","filter","messageIdx","matchedMessage","httpMetadata","getHttpMetadata","systemContext","targetClass","methodName","httpSystemConfig","batchMode","Body","index","hasOwnMetadata","BODY","bodyMetadata","Headers","HEADERS","headerMetadata","Cookies","COOKIES","cookiesMetadata","Req","REQUEST","requestMetadata","Res","RESPONSE","responseMetadata","Ctx","CONTEXT","contextMetadata","Query","query","pipe","newMetadata","getOwnMetadata","QUERY","Params","keyName","PARAMS","bodyMeta","headerMeta","cookiesMeta","resMeta","reqMeta","ctxMeta","queryMeta","paramMeta","getHttpArgs","context","req","res","paramItem","find","p","val","body","headers","parseRawCookie","cookie","queryItem","q","ExpressPlugin","name","stagingSystemRegister","MessageRegistry","httpRouteRegistry","Map","httpContextStore","_internalHttpIdCounter","register","systemFn","systemContext","httpSystemConfig","Error","targetClass","priority","bindRoute","constructor","config","Reflect","getMetadata","VIRID_EXPRESS_METADATA","HTTPROUTE","routeKey","method","path","has","set","install","app","options","spawn","server","_","routeInfo","entries","httpMessage","expressMethod","toLowerCase","req","res","newId","HttpContext","Date","now","inc","message","once","delete","MessageWriter","write","messageClass","systemTasks","systemTaskMap","task","fn","httpMetadata","messageIdx","originalMethod","wrappedSystem","__name","currentMessage","context","get","requestId","args","params","map","type","index","arg","getHttpArgs","result","apply","Promise","then","handleResult","catch","error","InternalServerError","HttpError","engine","clear","dec","Array","isArray","forEach","item","HttpResponse","handleHttpResponse","status","json","id","BaseMessage","warn","response","ctx","headers","Object","k","v","setHeader","StreamFileResponse","sendFile","filePath","err","headersSent","end","isClosed","StreamResponse","stream","pipe","cleanup","on","data","_ExpressPlugin"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/http/response.ts","../src/http/utils.ts","../src/http/message.ts","../src/decorators/constant.ts","../src/decorators/decorator.ts"],"sourcesContent":["/*\n * Copyright (c) 2026-present Ailrid\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Description: Add express functionality to virid.\n */\nimport {\n ViridPlugin,\n type ViridApp,\n MessageRegistry,\n MessageWriter,\n Newable,\n SystemContext,\n BaseMessage,\n} from \"@virid/core\";\nimport { getHttpArgs } from \"./decorators\";\nimport {\n HttpSystemConfig,\n type HttpMethod,\n type HttpRouteInfo,\n} from \"./interfaces\";\n\nimport {\n HttpContext,\n HttpError,\n HttpRequestMessage,\n HttpResponse,\n InternalServerError,\n RequestId,\n StreamFileResponse,\n StreamResponse,\n} from \"./http\";\n\nimport { PluginOptions } from \"./interfaces\";\nimport { type Request, type Response } from \"express\";\nimport { VIRID_EXPRESS_METADATA } from \"./decorators/constant\";\nexport * from \"./http\";\nexport * from \"./decorators\";\n\nexport class ExpressPlugin implements ViridPlugin<PluginOptions> {\n name = \"@virid/express\";\n // temporary Registry\n private stagingSystemRegister = new MessageRegistry();\n // route Registry\n private httpRouteRegistry = new Map<string, HttpRouteInfo>();\n\n private httpContextStore = new Map<number, HttpContext>();\n\n private _internalHttpIdCounter = 0;\n\n register(systemFn: (...args: any[]) => any): () => void {\n // @ts-expect-error: get systemContext from systemFn\n const systemContext: SystemContext = systemFn.systemContext;\n // @ts-expect-error: get httpSystemConfig from systemFn\n const httpSystemConfig: HttpSystemConfig = systemFn.httpSystemConfig;\n if (!systemContext || !httpSystemConfig) {\n throw new Error(\n `[Virid HttpSystem] HttpSystem Parameter Loss: Please declare ${systemFn.name} using the @HttpSystem decorator first.`,\n );\n }\n this.stagingSystemRegister.register(\n systemContext.targetClass,\n systemFn,\n httpSystemConfig.priority,\n );\n return () => {};\n }\n\n bindRoute(constructor: Newable<HttpRequestMessage>) {\n const config: HttpRouteInfo = Reflect.getMetadata(\n VIRID_EXPRESS_METADATA.HTTPROUTE,\n constructor,\n );\n if (!config) {\n throw new Error(\n `[Virid Http] Routing Error: ${constructor.name} is not a valid HttpRoute`,\n );\n }\n // Uniqueness verification: Combining Method and Path\n const routeKey = `${config.method}:${config.path}`;\n if (this.httpRouteRegistry.has(routeKey)) {\n throw new Error(\n `[Virid Http] Routing Conflict: The request method ${config.method} for path ${config.path} has already been registered by ${constructor.name}`,\n );\n } else {\n this.httpRouteRegistry.set(routeKey, config);\n }\n }\n\n install(app: ViridApp, options: PluginOptions) {\n // register for express routing\n for (const [_, routeInfo] of this.httpRouteRegistry.entries()) {\n const { method, path, httpMessage } = routeInfo;\n const expressMethod = method.toLowerCase() as HttpMethod;\n\n options.server[expressMethod](path, (req: Request, res: Response) => {\n // instantiate Message\n const newId = this._internalHttpIdCounter++ >>> 0;\n\n // save contextual information\n const context = new HttpContext(newId, req, res, Date.now(), path);\n context.inc();\n this.httpContextStore.set(\n newId,\n new HttpContext(newId, req, res, Date.now(), path),\n );\n const message = new httpMessage(newId as RequestId);\n // finish means the response has been sent, close means the connection was unexpectedly interrupted, both should be cleaned up\n res.once(\"finish\", () => this.httpContextStore.delete(newId));\n res.once(\"close\", () => this.httpContextStore.delete(newId));\n // send message\n MessageWriter.write(message);\n });\n }\n\n // register HttpSystem into the app's scheduler\n for (const [\n messageClass,\n systemTasks,\n ] of this.stagingSystemRegister.systemTaskMap.entries()) {\n for (const task of systemTasks) {\n const systemFn = task.fn;\n // @ts-expect-error: get systemContext from systemFn\n const systemContext: SystemContext = systemFn.systemContext;\n // @ts-expect-error: get httpSystemConfig from systemFn\n const httpSystemConfig: HttpSystemConfig = systemFn.httpSystemConfig;\n const { httpMetadata, messageClass, messageIdx } = httpSystemConfig;\n const { originalMethod, targetClass } = systemContext;\n const wrappedSystem = (currentMessage: HttpRequestMessage) => {\n // retrieve the context of the current request\n const context = this.httpContextStore.get(currentMessage.requestId);\n if (!context) {\n throw new Error(\n `[Virid Express HttpSystem] Invalid Request Context: The request context for message ${currentMessage.requestId} is missing.`,\n );\n }\n try {\n const args = systemContext.params.map(\n (type: any, index: number) => {\n // If it is a message, inject\n if (index === messageIdx) {\n return currentMessage;\n } else {\n // Otherwise, try injecting HTTP parameters or components\n const arg = getHttpArgs(index, context, httpMetadata);\n return arg ? arg : app.get(type);\n }\n },\n );\n const result = originalMethod.apply(targetClass, args);\n return result instanceof Promise\n ? result\n .then((res) => {\n this.handleResult(res, context);\n })\n .catch((error) => {\n // asynchronous error needs to send 500 to the client\n this.handleResult(InternalServerError(error), context);\n // continue throwing, let Dispatcher capture and print detailed stack\n throw error;\n })\n : this.handleResult(result, context);\n } catch (error) {\n if (error instanceof HttpError) {\n // if manually throw new HttpError\n this.handleResult(error, context);\n } else {\n // real crash, return 500\n this.handleResult(InternalServerError(error as Error), context);\n }\n throw error; // continue throwing, let Dispatcher capture and print detailed stack\n }\n };\n wrappedSystem.systemContext = systemContext;\n wrappedSystem.httpSystemConfig = httpSystemConfig;\n app.engine.register(messageClass, wrappedSystem, task.priority);\n }\n }\n this.stagingSystemRegister.systemTaskMap.clear();\n }\n\n handleResult(res: any, context: HttpContext) {\n if (!res) {\n context.dec();\n return;\n }\n const results = Array.isArray(res) ? res : [res];\n results.forEach((item) => {\n if (item instanceof HttpResponse) {\n // if it is a termination response, handle it\n this.handleHttpResponse(item, context);\n } else if (item instanceof HttpError) {\n // handling errors\n context.res.status(item.status).json(item.message);\n this.httpContextStore.delete(context.id);\n } else if (item instanceof BaseMessage) {\n MessageWriter.write(item);\n } else {\n MessageWriter.warn(\n `[Virid Express] Invalid Return Type: ${typeof item}. Expected HttpResponse or Message.`,\n );\n }\n });\n //Whether the system encounters an error or completes execution, handleResult will execute with a reference count of -1 and check if it is 0\n //If it is 0 and it has not been closed yet, then force it to close\n //The first scenario: If handleHttpResponse is executed above, then HttpContext has already been deleted before that\n //The second scenario: If the HttpRequestMessage is forwarded above, it will erase the trace of the system execution, but the HttpContext will not be deleted due to reference counting\n //The third scenario: If other messages or return values are forwarded above, the reference count will be -1 and checked if it is 0. If it is 0, it will be forcibly closed\n context.dec();\n }\n\n handleHttpResponse(response: HttpResponse, ctx: HttpContext) {\n const { res } = ctx;\n\n if (response.headers) {\n Object.entries(response.headers).forEach(([k, v]) => res.setHeader(k, v));\n }\n\n if (response.status) res.status(response.status);\n\n if (response instanceof StreamFileResponse) {\n // return asynchronous stream and forcefully add an RC extension\n ctx.inc();\n res.sendFile(response.filePath, response.options, (err) => {\n if (!res.headersSent) {\n MessageWriter.error(\n err,\n `[Virid Express] SteamFile Error: Path: ${response.filePath}`,\n );\n }\n ctx.res.end();\n this.httpContextStore.delete(ctx.id);\n ctx.isClosed = true;\n ctx.dec();\n });\n return;\n }\n if (response instanceof StreamResponse) {\n const { stream } = response;\n ctx.inc();\n stream.pipe(res);\n // end of listening, harvest context\n const cleanup = () => {\n if (!this.httpContextStore.has(ctx.id)) return;\n ctx.res.end();\n this.httpContextStore.delete(ctx.id);\n ctx.isClosed = true;\n ctx.dec();\n };\n stream.on(\"end\", cleanup);\n stream.on(\"error\", (err) => {\n if (!res.headersSent) {\n MessageWriter.error(err, `[Virid Express] Stream Error`);\n }\n cleanup();\n });\n stream.on(\"close\", cleanup);\n return;\n }\n\n res.status(response.status).json(response.data);\n this.httpContextStore.delete(ctx.id);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { type Request, type Response } from \"express\";\nimport { Readable } from \"stream\";\nimport { MessageWriter } from \"@virid/core\";\ninterface HttpHeaders {\n [key: string]: string | string[];\n}\nexport class HttpContext {\n public rc: number = 0;\n public isClosed: boolean = false;\n\n constructor(\n public readonly id: number,\n public readonly req: Request,\n public readonly res: Response,\n public readonly timestamp: number,\n public readonly route: string,\n ) {}\n\n inc() {\n this.rc++;\n }\n\n dec() {\n this.rc--;\n if (this.rc === 0) {\n this.tryFinalize();\n }\n }\n\n private tryFinalize() {\n if (this.res.writableEnded || this.isClosed) return;\n\n this.isClosed = true;\n\n const errorMsg = `[Virid Express] Request Orphaned: The connection was closed because all systems finished execution without sending a response. \n Route: ${this.route}\n Uptime: ${Date.now() - this.timestamp}ms`;\n\n MessageWriter.error(new Error(errorMsg));\n\n if (!this.res.headersSent) {\n this.res.status(500).json({\n error: \"Internal Logic Error\",\n message:\n \"Request processed but no response was returned by any system.\",\n });\n } else {\n this.res.end();\n }\n }\n}\n\nexport abstract class HttpResponse {\n constructor(\n public status: number,\n public data: any = null,\n public headers: HttpHeaders = {},\n ) {}\n}\n\n// --- 2xx Success ---\nexport class OkResponse extends HttpResponse {\n constructor(data: any, headers: HttpHeaders = {}) {\n super(200, data, headers);\n }\n}\n\nexport class CreatedResponse extends HttpResponse {\n constructor(data: any, headers: HttpHeaders = {}) {\n super(201, data, headers);\n }\n}\n\nexport class NoContentResponse extends HttpResponse {\n constructor() {\n super(204, null);\n }\n}\n\n// --- 4xx Client Error ---\nexport class BadRequestResponse extends HttpResponse {\n constructor(message: string = \"Bad Request\") {\n super(400, { error: message });\n }\n}\n\nexport class UnauthorizedResponse extends HttpResponse {\n constructor(message: string = \"Unauthorized\") {\n super(401, { error: message });\n }\n}\n\nexport class ForbiddenResponse extends HttpResponse {\n constructor(message: string = \"Forbidden\") {\n super(403, { error: message });\n }\n}\n\nexport class NotFoundResponse extends HttpResponse {\n constructor(message: string = \"Not Found\") {\n super(404, { error: message });\n }\n}\n\nexport class ConflictResponse extends HttpResponse {\n constructor(message: string = \"Conflict\") {\n super(409, { error: message });\n }\n}\n\nexport class UnprocessableEntityResponse extends HttpResponse {\n constructor(errors: any) {\n super(422, { errors });\n }\n}\n\n// --- 5xx Server Error ---\nexport class InternalServerErrorResponse extends HttpResponse {\n constructor(message: string = \"Internal Server Error\") {\n super(500, { error: message });\n }\n}\n\n// --- 万能类 (Custom) ---\nexport class CustomResponseResponse extends HttpResponse {\n constructor(status: number, data: any, headers: HttpHeaders = {}) {\n super(status, data, headers);\n }\n}\n/**\n * @description: Express sendFile 配置项的强类型定义\n */\nexport interface StreamFileOptions {\n /** 根目录(如果 path 是相对路径则必填) */\n root?: string;\n /** * 对以 . 开头的文件处理策略:\n * - allow: 允许发送\n * - deny: 拒绝并返回 403\n * - ignore: 当作不存在返回 404\n */\n dotfiles?: \"allow\" | \"deny\" | \"ignore\";\n /** 是否发送 ETag */\n etag?: boolean;\n /** 扩展的 HTTP 响应头 */\n headers?: HttpHeaders;\n /** 缓存最大时长 (毫秒) */\n maxAge?: number | string;\n /** 是否在 Cache-Control 中添加 immutable */\n immutable?: boolean;\n /** 是否根据文件系统设置 Last-Modified */\n lastModified?: boolean;\n /** 是否支持断点续传 (Range 请求) */\n acceptRanges?: boolean;\n}\nexport class StreamFileResponse extends HttpResponse {\n constructor(\n public readonly filePath: string,\n public readonly options: StreamFileOptions = { dotfiles: \"allow\" },\n ) {\n super(206, options);\n }\n}\n\nexport class StreamResponse extends HttpResponse {\n constructor(\n public readonly stream: Readable,\n public readonly options: {\n status?: number;\n headers?: HttpHeaders;\n } = {},\n ) {\n super(options.status || 206, {}, options.headers);\n }\n}\n\n/** 200 OK */\nexport const Ok = (data: any, headers: HttpHeaders = {}) =>\n new OkResponse(data, headers);\n\n/** 201 Created */\nexport const Created = (data: any, headers: HttpHeaders = {}) =>\n new CreatedResponse(data, headers);\n\n/** 204 No Content */\nexport const NoContent = () => new NoContentResponse();\n\n/** 400 Bad Request */\nexport const BadRequest = (msg = \"Bad Request\") => new BadRequestResponse(msg);\n\n/** 401 Unauthorized */\nexport const Unauthorized = (msg = \"Unauthorized\") =>\n new UnauthorizedResponse(msg);\n\n/** 403 Forbidden */\nexport const Forbidden = (msg = \"Forbidden\") => new ForbiddenResponse(msg);\n\n/** 404 Not Found */\nexport const NotFound = (msg = \"Not Found\") => new NotFoundResponse(msg);\n\n/** 500 Internal Error */\nexport const InternalServerError = (\n msg: string | Error = \"Internal Server Error\",\n) => {\n return msg instanceof Error\n ? new InternalServerErrorResponse(msg.message)\n : new InternalServerErrorResponse(msg);\n};\n\nexport const CustomResponse = (\n status: number,\n data: any,\n headers: HttpHeaders = {},\n) => new CustomResponseResponse(status, data, headers);\n\n/** 发送本地文件 (自动处理 Range/206) */\nexport const StreamFile = (path: string, options?: StreamFileOptions) =>\n new StreamFileResponse(path, options);\n/**\n * 发送流响应\n */\nexport const Stream = (stream: Readable, options?: StreamResponse[\"options\"]) =>\n new StreamResponse(stream, options);\n\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n public readonly message: string,\n ) {\n super(message);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { MessageWriter } from \"@virid/core\";\nimport { HttpError } from \".\";\nimport { type TransformPipe } from \"../interfaces\";\n\nexport function ParseIntPipe(val: string) {\n const res = parseInt(val, 10);\n if (isNaN(res))\n throw new HttpError(400, `Validation failed: \"${val}\" is not a number.`);\n return res;\n}\n\nexport function ParseBoolPipe(val: string) {\n if (val === \"true\" || val === \"1\") return true;\n if (val === \"false\" || val === \"0\") return false;\n return !!val;\n}\n\nconst autoPipeMap = new Map<any, TransformPipe<any>>();\nautoPipeMap.set(Number, ParseIntPipe);\nautoPipeMap.set(Boolean, ParseBoolPipe);\n\nexport function addAutoPipe<T>(type: T, pipe: TransformPipe<T>) {\n if (autoPipeMap.has(type)) {\n MessageWriter.error(\n new Error(\n `[Virid Express Pipe] Repeated Pipe: Auto pipe for ${type} has already been registered.`,\n ),\n );\n return;\n }\n autoPipeMap.set(type, pipe);\n}\n\nexport function getAutoPipe<T>(type: T): TransformPipe<T> | undefined {\n return autoPipeMap.get(type);\n}\n\nexport function parseRawCookie(\n cookieHeader: string | undefined,\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n if (!cookieHeader) return result;\n const pairs = cookieHeader.split(\";\");\n\n for (const pair of pairs) {\n const indexOfEq = pair.indexOf(\"=\");\n if (indexOfEq === -1) continue;\n\n // 提取 key 和 value,并进行 trim 处理\n const key = pair.substring(0, indexOfEq).trim();\n if (!key) continue;\n\n let value = pair.substring(indexOfEq + 1).trim();\n\n if (value[0] === '\"' && value[value.length - 1] === '\"') {\n value = value.slice(1, -1);\n }\n\n try {\n result[key] = value.includes(\"%\") ? decodeURIComponent(value) : value;\n } catch (e) {\n result[key] = value;\n }\n }\n\n return result;\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { EventMessage } from \"@virid/core\";\nexport type RequestId = number & { readonly __brand: unique symbol };\n\nexport class HttpRequestMessage extends EventMessage {\n // ID must be of type RequestId\n constructor(private readonly __virid_express_id: RequestId) {\n super();\n }\n // expose a read-only attribute for use by the business layer\n public get requestId(): RequestId {\n return this.__virid_express_id;\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { VIRID_METADATA } from \"@virid/core\";\n\nexport const VIRID_EXPRESS_METADATA = {\n ...VIRID_METADATA,\n HTTPROUTE: \"virid:express:route\",\n HTTPSYSTEM: \"virid:express:system\",\n BODY: \"virid:express:body\",\n QUERY: \"virid:express:query\",\n HEADERS: \"virid:express:header\",\n REQUEST: \"virid:express:request\",\n RESPONSE: \"virid:express:response\",\n CONTEXT: \"virid:express:context\",\n PARAMS: \"virid:express:params\",\n COOKIES: \"virid:express:cookie\",\n} as const;\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Express\n */\nimport { type Newable, type SystemContext } from \"@virid/core\";\nimport {\n type HttpRouteConfig,\n type HttpRouteInfo,\n type BodyMetadata,\n type HeaderMetadata,\n type QueryMetadata,\n type RequestMetadata,\n type ResponseMetadata,\n type ContextMetadata,\n type ParamMetadata,\n type TransformPipe,\n type CookieMetadata,\n type HttpSystemParams,\n type HttpMetadata,\n type HttpSystemConfig,\n} from \"../interfaces\";\nimport { HttpContext, HttpRequestMessage, parseRawCookie } from \"../http\";\n\nimport { VIRID_EXPRESS_METADATA } from \"./constant\";\n\nexport function HttpRoute(config: HttpRouteConfig) {\n return (constructor: Newable<HttpRequestMessage>) => {\n const params: string[] = [];\n const pathParts = config.path.split(\"/\");\n pathParts.forEach((part) => {\n if (part.startsWith(\":\")) {\n params.push(part.substring(1));\n }\n });\n\n const routeInfo: HttpRouteInfo = {\n ...config,\n httpMessage: constructor,\n params,\n };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.HTTPROUTE,\n routeInfo,\n constructor,\n );\n };\n}\n\n/**\n * Check if there are multiple message type parameters in the parameters\n * @param types Parameter list\n */\nfunction checkMessageParam(types: Array<any>) {\n const foundMatches: { type: Newable<HttpRequestMessage>; idx: number }[] = [];\n\n types.forEach((type, idx) => {\n const isHttpRequestMessage =\n type === HttpRequestMessage ||\n (type && type.prototype instanceof HttpRequestMessage);\n\n if (isHttpRequestMessage) {\n foundMatches.push({ type, idx });\n }\n });\n\n if (foundMatches.length === 0) {\n return null;\n }\n\n if (foundMatches.length > 1) {\n const errorDetails = foundMatches\n .map((item) => `[Index: ${item.idx}, Name: ${item.type.name}]`)\n .join(\", \");\n\n throw new Error(\n `[Virid System] Multiple Messages: Multiple Message type parameters detected, this is not allowed! specific location: ${errorDetails}`,\n );\n }\n\n return foundMatches[0];\n}\n\n/**\n * @description: 系统装饰器\n * @param priority 优先级,数值越大越早执行\n */\nexport function HttpSystem(\n params: HttpSystemParams = {\n priority: 0,\n messageClass: null,\n },\n) {\n return (target: any, key: string, descriptor: PropertyDescriptor) => {\n if (typeof target !== \"function\") {\n throw new Error(\n `[Virid System] Method Type Error: The Method ${key} is not a static method, please check if there is a static keyword tag.`,\n );\n }\n\n const originalMethod = descriptor.value;\n const types: Array<any> = Reflect.getMetadata(\n \"design:paramtypes\",\n target,\n key,\n );\n\n // Verify if metadata exists\n if (!types) {\n throw new Error(\n `[Virid System] System Parameter Loss: Unable to recognize system parameters, please confirm if import \"reflect-metadata\" was introduced at the beginning.`,\n );\n }\n\n // Verify if there are undefined parameters\n const undefinedIndices = types\n .map((t, i) => (t === undefined ? i : -1))\n .filter((i) => i !== -1);\n if (undefinedIndices.length > 0) {\n throw new Error(\n `[Virid System] Parameter Metadata Loss in \"${key}\": One or more parameters have 'undefined' types. This usually happens when you forget to add a type annotation or due to circular dependencies. Check parameter at indices: [${undefinedIndices.join(\", \")}]`,\n );\n }\n\n let messageClass: Newable<HttpRequestMessage>;\n // eslint-disable-next-line no-useless-assignment\n let messageIdx: number = -1;\n const matchedMessage = checkMessageParam(types); // { type: any, idx: number } | null\n if (matchedMessage && params.messageClass) {\n throw new Error(\n `[Virid System] Multiple Messages Are Not Allowed: Cannot specify messageClass in decorator options while already declaring it in method parameters at index ${matchedMessage.idx} in ${key}.`,\n );\n }\n\n if (matchedMessage) {\n messageClass = matchedMessage.type;\n messageIdx = matchedMessage.idx; // In single mode, idx points to the location of a specific BaseMessage subclass\n } else if (params.messageClass) {\n messageClass = params.messageClass;\n messageIdx = -1; // Only provided in the configuration, cannot be found in the parameters, set to -1\n } else {\n throw new Error(\n `[Virid System] System Parameter Loss: Please declare the message type either in method parameters or via the Message decorator options.`,\n );\n }\n const httpMetadata = getHttpMetadata(target, key);\n\n // Attach contextual information to the packaged function\n const systemContext: SystemContext = {\n params: types,\n targetClass: target,\n methodName: key,\n originalMethod: originalMethod,\n };\n const httpSystemConfig: HttpSystemConfig = {\n httpMetadata: httpMetadata,\n messageClass: messageClass,\n messageIdx: messageIdx,\n priority: params.priority || 0,\n batchMode: false,\n };\n\n // Purely mounting data without changing the execution logic of the original method\n (descriptor.value as any).systemContext = systemContext;\n (descriptor.value as any).httpSystemConfig = httpSystemConfig;\n };\n}\n\nexport function Body() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.BODY, target, key)) {\n throw new Error(\n `[Virid Express Body] Multiple Body Are Not Allowed: ${key} has multiple @Body() decorators!`,\n );\n }\n const bodyMetadata = { index } as BodyMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.BODY,\n bodyMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Headers() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.HEADERS, target, key)) {\n throw new Error(\n `[Virid Express Headers] Multiple Header Are Not Allowed: ${key} has multiple @Headers() decorators!`,\n );\n }\n const headerMetadata = { index } as HeaderMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.HEADERS,\n headerMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Cookies() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.COOKIES, target, key)) {\n throw new Error(\n `[Virid Express Cookies] Multiple Header Are Not Allowed: ${key} has multiple @Cookies() decorators!`,\n );\n }\n const cookiesMetadata = { index } as CookieMetadata;\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.COOKIES,\n cookiesMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Req() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.REQUEST, target, key)) {\n throw new Error(\n `[Virid Express Req] Multiple Request Objects Are Not Allowed: ${key} has multiple @Req() decorators!`,\n );\n }\n const requestMetadata: RequestMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.REQUEST,\n requestMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Res() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.RESPONSE, target, key)) {\n throw new Error(\n `[Virid Express Res] Multiple Response Objects Are Not Allowed: ${key} has multiple @Res() decorators!`,\n );\n }\n const responseMetadata: ResponseMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.RESPONSE,\n responseMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Ctx() {\n return (target: any, key: string, index: number) => {\n if (Reflect.hasOwnMetadata(VIRID_EXPRESS_METADATA.CONTEXT, target, key)) {\n throw new Error(\n `[Virid Express Ctx] Multiple Context Objects Are Not Allowed: ${key} has multiple @Ctx() decorators!`,\n );\n }\n const contextMetadata: ContextMetadata = { index };\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.CONTEXT,\n contextMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Query(query: string, pipe?: TransformPipe<any>) {\n return (target: any, key: string, index: number) => {\n const existingMetadata: QueryMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.QUERY, target, key) || [];\n const newMetadata = [...existingMetadata, { index, query, pipe }];\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.QUERY,\n newMetadata,\n target,\n key,\n );\n };\n}\n\nexport function Params(key?: string, pipe?: TransformPipe<any>) {\n return (target: any, keyName: string, index: number) => {\n const existingMetadata: ParamMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.PARAMS, target, keyName) ||\n [];\n const newMetadata = [...existingMetadata, { index, key, pipe }];\n Reflect.defineMetadata(\n VIRID_EXPRESS_METADATA.PARAMS,\n newMetadata,\n target,\n keyName,\n );\n };\n}\n\nfunction getHttpMetadata(target: any, key: string): HttpMetadata {\n const bodyMeta: BodyMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.BODY,\n target,\n key,\n );\n const headerMeta: HeaderMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.HEADERS,\n target,\n key,\n );\n const cookiesMeta: CookieMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.COOKIES,\n target,\n key,\n );\n\n const resMeta: ResponseMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.RESPONSE,\n target,\n key,\n );\n const reqMeta: RequestMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.REQUEST,\n target,\n key,\n );\n const ctxMeta: ContextMetadata = Reflect.getOwnMetadata(\n VIRID_EXPRESS_METADATA.CONTEXT,\n target,\n key,\n );\n\n const queryMeta: QueryMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.QUERY, target, key) || [];\n\n const paramMeta: ParamMetadata =\n Reflect.getOwnMetadata(VIRID_EXPRESS_METADATA.PARAMS, target, key) || [];\n\n return {\n bodyMeta,\n headerMeta,\n queryMeta,\n paramMeta,\n cookiesMeta,\n reqMeta,\n resMeta,\n ctxMeta,\n };\n}\n\nexport function getHttpArgs(\n index: number,\n context: HttpContext,\n httpMetadata: HttpMetadata,\n): any {\n const { req, res } = context;\n\n // 匹配 @Ctx()\n if (httpMetadata.ctxMeta?.index === index) return context;\n\n // 匹配 @Param() -> 获取路由参数 (:id 等)\n const paramItem = httpMetadata.paramMeta?.find((p) => p.index === index);\n if (paramItem) {\n let val = paramItem.key ? req.params[paramItem.key] : req.params;\n\n // 如果有 Pipe 且值不是 undefined,进行转换\n if (paramItem.pipe && val !== undefined) {\n val = paramItem.pipe(val);\n }\n return val;\n }\n\n // @Body()\n if (httpMetadata.bodyMeta?.index === index) return req.body;\n\n // @Header()\n if (httpMetadata.headerMeta?.index === index) return req.headers;\n\n // @Cookie()\n if (httpMetadata.cookiesMeta?.index === index)\n return parseRawCookie(req.headers.cookie);\n\n // @Req() 和 @Res()\n if (httpMetadata.reqMeta?.index === index) return req;\n if (httpMetadata.resMeta?.index === index) return res;\n\n // @Query('name')\n const queryItem = httpMetadata.queryMeta?.find((q) => q.index === index);\n if (queryItem) {\n let val = req.query[queryItem.query];\n if (val === undefined) {\n throw new Error(`[Virid Express] Missing Query: \"${queryItem.query}\"`);\n }\n\n if (queryItem.pipe) {\n val = queryItem.pipe(val);\n }\n return val;\n }\n return null;\n}\n"],"mappings":"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","names":["MessageRegistry","MessageWriter","BaseMessage","MessageWriter","HttpContext","id","req","res","timestamp","route","rc","isClosed","inc","dec","tryFinalize","writableEnded","errorMsg","Date","now","MessageWriter","error","Error","headersSent","end","status","json","message","_HttpContext","HttpResponse","data","headers","_HttpResponse","OkResponse","_OkResponse","CreatedResponse","_CreatedResponse","NoContentResponse","_NoContentResponse","BadRequestResponse","_BadRequestResponse","UnauthorizedResponse","_UnauthorizedResponse","ForbiddenResponse","_ForbiddenResponse","NotFoundResponse","_NotFoundResponse","ConflictResponse","_ConflictResponse","UnprocessableEntityResponse","errors","_UnprocessableEntityResponse","InternalServerErrorResponse","_InternalServerErrorResponse","CustomResponseResponse","_CustomResponseResponse","StreamFileResponse","filePath","options","dotfiles","_StreamFileResponse","StreamResponse","stream","_StreamResponse","Ok","__name","Created","NoContent","BadRequest","msg","Unauthorized","Forbidden","NotFound","InternalServerError","CustomResponse","StreamFile","path","Stream","HttpError","_HttpError","MessageWriter","ParseIntPipe","val","res","parseInt","isNaN","HttpError","ParseBoolPipe","autoPipeMap","Map","set","Number","Boolean","addAutoPipe","type","pipe","has","MessageWriter","error","Error","getAutoPipe","get","parseRawCookie","cookieHeader","result","pairs","split","pair","indexOfEq","indexOf","key","substring","trim","value","length","slice","includes","decodeURIComponent","EventMessage","HttpRequestMessage","EventMessage","__virid_express_id","requestId","_HttpRequestMessage","VIRID_METADATA","VIRID_EXPRESS_METADATA","HTTPROUTE","HTTPSYSTEM","BODY","QUERY","HEADERS","REQUEST","RESPONSE","CONTEXT","PARAMS","COOKIES","HttpRoute","config","constructor","params","path","split","forEach","part","startsWith","push","substring","routeInfo","httpMessage","Reflect","defineMetadata","VIRID_EXPRESS_METADATA","HTTPROUTE","checkMessageParam","types","foundMatches","type","idx","HttpRequestMessage","prototype","length","errorDetails","map","item","name","join","Error","HttpSystem","priority","messageClass","target","key","descriptor","originalMethod","value","getMetadata","undefinedIndices","t","i","undefined","filter","messageIdx","matchedMessage","httpMetadata","getHttpMetadata","systemContext","targetClass","methodName","httpSystemConfig","batchMode","Body","index","hasOwnMetadata","BODY","bodyMetadata","Headers","HEADERS","headerMetadata","Cookies","COOKIES","cookiesMetadata","Req","REQUEST","requestMetadata","Res","RESPONSE","responseMetadata","Ctx","CONTEXT","contextMetadata","Query","query","pipe","newMetadata","getOwnMetadata","QUERY","Params","keyName","PARAMS","bodyMeta","headerMeta","cookiesMeta","resMeta","reqMeta","ctxMeta","queryMeta","paramMeta","getHttpArgs","context","req","res","paramItem","find","p","val","body","headers","parseRawCookie","cookie","queryItem","q","ExpressPlugin","name","stagingSystemRegister","MessageRegistry","httpRouteRegistry","Map","httpContextStore","_internalHttpIdCounter","register","systemFn","systemContext","httpSystemConfig","Error","targetClass","priority","bindRoute","constructor","config","Reflect","getMetadata","VIRID_EXPRESS_METADATA","HTTPROUTE","routeKey","method","path","has","set","install","app","options","_","routeInfo","entries","httpMessage","expressMethod","toLowerCase","server","req","res","newId","HttpContext","Date","now","inc","message","once","delete","MessageWriter","write","messageClass","systemTasks","systemTaskMap","task","fn","httpMetadata","messageIdx","originalMethod","wrappedSystem","__name","currentMessage","context","get","requestId","args","params","map","type","index","arg","getHttpArgs","result","apply","Promise","then","handleResult","catch","error","InternalServerError","HttpError","engine","clear","dec","Array","isArray","forEach","item","HttpResponse","handleHttpResponse","status","json","id","BaseMessage","warn","response","ctx","headers","Object","k","v","setHeader","StreamFileResponse","sendFile","filePath","err","headersSent","end","isClosed","StreamResponse","stream","pipe","cleanup","on","data","_ExpressPlugin"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@virid/express",
3
3
  "type": "module",
4
- "version": "0.3.3",
4
+ "version": "0.3.4",
5
5
  "description": "Add express functionality to virid",
6
6
  "author": "Ailrid",
7
7
  "license": "Apache 2.0",
@@ -35,7 +35,7 @@
35
35
  "peerDependencies": {
36
36
  "express": ">=4.17.1",
37
37
  "@types/express": ">=4.17.1",
38
- "@virid/core": "0.3.3"
38
+ "@virid/core": "0.3.4"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsup --config tsup.config.ts"