@andrewcaires/express 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +2 -2
- package/package.json +9 -9
package/dist/index.cjs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/express v2.
|
|
2
|
+
* @andrewcaires/express v2.4.0
|
|
3
3
|
* Decorators for express
|
|
4
4
|
* (c) 2026 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
6
6
|
*/
|
|
7
|
-
"use strict";var t=require("@andrewcaires/decorator"),e=require("@andrewcaires/node"),s=require("@andrewcaires/utils.js"),r=require("compression"),o=require("cookie-parser"),i=require("cors"),a=require("express"),n=require("express-session"),u=require("fs"),d=require("http"),l=require("https"),c=require("net"),p=require("path"),h=require("request-ip"),E=require("multer");function S(t){var e=Object.create(null);return t&&Object.keys(t).forEach(function(s){if("default"!==s){var r=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,r.get?r:{enumerable:!0,get:function(){return t[s]}})}}),e.default=t,Object.freeze(e)}var T=S(d),_=S(l),v=S(c);function R(t,e,s,r){return new(s||(s=Promise))(function(o,i){function a(t){try{u(r.next(t))}catch(t){i(t)}}function n(t){try{u(r.throw(t))}catch(t){i(t)}}function u(t){var e;t.done?o(t.value):(e=t.value,e instanceof s?e:new s(function(t){t(e)})).then(a,n)}u((r=r.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class StatusCodes{}StatusCodes.CONTINUE=100,StatusCodes.SWITCHING_PROTOCOLS=101,StatusCodes.PROCESSING=102,StatusCodes.OK=200,StatusCodes.CREATED=201,StatusCodes.ACCEPTED=202,StatusCodes.NON_AUTHORITATIVE_INFORMATION=203,StatusCodes.NO_CONTENT=204,StatusCodes.RESET_CONTENT=205,StatusCodes.PARTIAL_CONTENT=206,StatusCodes.MULTI_STATUS=207,StatusCodes.ALREADY_REPORTED=208,StatusCodes.IM_USED=226,StatusCodes.MULTIPLE_CHOICES=300,StatusCodes.MOVED_PERMANENTLY=301,StatusCodes.FOUND=302,StatusCodes.SEE_OTHER=303,StatusCodes.NOT_MODIFIED=304,StatusCodes.USE_PROXY=305,StatusCodes.TEMPORARY_REDIRECT=307,StatusCodes.PERMANENT_REDIRECT=308,StatusCodes.BAD_REQUEST=400,StatusCodes.UNAUTHORIZED=401,StatusCodes.PAYMENT_REQUIRED=402,StatusCodes.FORBIDDEN=403,StatusCodes.NOT_FOUND=404,StatusCodes.METHOD_NOT_ALLOWED=405,StatusCodes.NOT_ACCEPTABLE=406,StatusCodes.PROXY_AUTHENTICATION_REQUIRED=407,StatusCodes.REQUEST_TIMEOUT=408,StatusCodes.CONFLICT=409,StatusCodes.GONE=410,StatusCodes.LENGTH_REQUIRED=411,StatusCodes.PRECONDITION_FAILED=412,StatusCodes.PAYLOAD_TOO_LARGE=413,StatusCodes.REQUEST_URI_TOO_LONG=414,StatusCodes.UNSUPPORTED_MEDIA_TYPE=415,StatusCodes.REQUESTED_RANGE_NOT_SATISFIABLE=416,StatusCodes.EXPECTATION_FAILED=417,StatusCodes.IM_A_TEAPOT=418,StatusCodes.MISDIRECTED_REQUEST=421,StatusCodes.UNPROCESSABLE_ENTITY=422,StatusCodes.LOCKED=423,StatusCodes.FAILED_DEPENDENCY=424,StatusCodes.UPGRADE_REQUIRED=426,StatusCodes.PRECONDITION_REQUIRED=428,StatusCodes.TOO_MANY_REQUESTS=429,StatusCodes.REQUEST_HEADER_FIELDS_TOO_LARGE=431,StatusCodes.CONNECTION_CLOSED_WITHOUT_RESPONSE=444,StatusCodes.UNAVAILABLE_FOR_LEGAL_REASONS=451,StatusCodes.CLIENT_CLOSED_REQUEST=499,StatusCodes.INTERNAL_SERVER_ERROR=500,StatusCodes.NOT_IMPLEMENTED=501,StatusCodes.BAD_GATEWAY=502,StatusCodes.SERVICE_UNAVAILABLE=503,StatusCodes.GATEWAY_TIMEOUT=504,StatusCodes.HTTP_VERSION_NOT_SUPPORTED=505,StatusCodes.VARIANT_ALSO_NEGOCIATES=506,StatusCodes.INSUFFICIENT_STORAGE=507,StatusCodes.LOOP_DETECTED=508,StatusCodes.NOT_EXTENDED=510,StatusCodes.NETWORK_AUTHENTICATION_REQUIRED=511,StatusCodes.NETWORK_CONNECTION_TIMEOUT_ERROR=599;class StatusText{}StatusText[100]="Continue",StatusText[101]="Switching Protocols",StatusText[102]="Processing",StatusText[200]="OK",StatusText[201]="Created",StatusText[202]="Accepted",StatusText[203]="Non-Authoritative Information",StatusText[204]="No Content",StatusText[205]="Reset Content",StatusText[206]="Partial Content",StatusText[207]="Multi-Status",StatusText[226]="IM Used",StatusText[300]="Multiple Choices",StatusText[301]="Moved Permanently",StatusText[302]="Found",StatusText[303]="See Other",StatusText[304]="Not Modified",StatusText[305]="Use Proxy",StatusText[307]="Temporary Redirect",StatusText[308]="Permanent Redirect",StatusText[400]="Bad Request",StatusText[401]="Unauthorized",StatusText[402]="Payment Required",StatusText[403]="Forbidden",StatusText[404]="Not Found",StatusText[405]="Method Not Allowed",StatusText[406]="Not Acceptable",StatusText[407]="Proxy Authentication Required",StatusText[408]="Request Timeout",StatusText[409]="Conflict",StatusText[410]="Gone",StatusText[411]="Length Required",StatusText[412]="Precondition Failed",StatusText[413]="Payload Too Large",StatusText[414]="URI Too Long",StatusText[415]="Unsupported Media Type",StatusText[416]="Range Not Satisfiable",StatusText[417]="Expectation Failed",StatusText[418]="I'm a teapot",StatusText[422]="Unprocessable Entity",StatusText[423]="Locked",StatusText[424]="Failed Dependency",StatusText[426]="Upgrade Required",StatusText[428]="Precondition Required",StatusText[429]="Too Many Requests",StatusText[431]="Request Header Fields Too Large",StatusText[451]="Unavailable For Legal Reasons",StatusText[500]="Internal Server Error",StatusText[501]="Not Implemented",StatusText[502]="Bad Gateway",StatusText[503]="Service Unavailable",StatusText[504]="Gateway Time-out",StatusText[505]="HTTP Version Not Supported",StatusText[506]="Variant Also Negotiates",StatusText[507]="Insufficient Storage",StatusText[511]="Network Authentication Required";class ResponseError extends Error{constructor(t,e=StatusCodes.INTERNAL_SERVER_ERROR){super(t),this.status=e}}class NotFoundError extends ResponseError{constructor(t="Not Found"){super(t,StatusCodes.NOT_FOUND)}}class ValidationError extends ResponseError{constructor(t){super(t,StatusCodes.UNPROCESSABLE_ENTITY)}}class HttpResponse{static created(t,e,s){var r,o;const i=StatusCodes.CREATED,a={success:!0,status:i,data:e?{id:e}:{},meta:null!==(r=null==s?void 0:s.meta)&&void 0!==r?r:{},message:null!==(o=null==s?void 0:s.message)&&void 0!==o?o:null};return t.status(i).json(a),a}static noContent(t){t.status(StatusCodes.NO_CONTENT).end()}static ok(t,e,s){var r,o;const i=StatusCodes.OK,a={success:!0,status:i,data:e,meta:null!==(r=null==s?void 0:s.meta)&&void 0!==r?r:{},message:null!==(o=null==s?void 0:s.message)&&void 0!==o?o:null};return t.status(i).json(a),a}static error(t,e,s){var r,o;const{status:i,message:a}=this.normalizeError(s),n=null!==(r=null==StatusText?void 0:StatusText[i])&&void 0!==r?r:"Internal Server Error",u=this.getErrorCode(s),d=this.getErrorName(s),l=Object.assign(Object.assign(Object.assign(Object.assign({success:!1,status:i,statusText:n,message:a,path:null!==(o=t.originalUrl)&&void 0!==o?o:t.url},u?{code:u}:{}),d?{name:d}:{}),{timestamp:(new Date).toISOString()}),this.isDev()&&s instanceof Error&&s.stack?{stack:s.stack}:{});return e.status(i).json(l),l}static getErrorCode(t){return t&&s.isObject(t)&&s.isString(t.code)?this.safeMessage(t.code):""}static getErrorName(t){return t instanceof ResponseError?t.constructor.name:this.isDev()?t instanceof Error?t.name||t.constructor.name:s.isObject(t)&&s.isString(t.name)?t.name:typeof t:""}static isDev(){return"production"!==process.env.NODE_ENV}static normalizeError(t){let e=StatusCodes.INTERNAL_SERVER_ERROR,r=StatusText[500];if(t instanceof ResponseError)return e=this.safeStatus(t.status),r=this.safeMessage(t.message)||r,{status:e,message:r};if(t instanceof Error){const o=t;return s.isNumber(o.statusCode)?e=this.safeStatus(o.statusCode):s.isNumber(o.status)&&(e=this.safeStatus(o.status)),r=this.safeMessage(t.message)||r,{status:e,message:r}}if(s.isString(t))return r=this.safeMessage(t)||r,{status:e,message:r};if(t&&s.isObject(t)){const o=t;return s.isNumber(o.statusCode)?e=this.safeStatus(o.statusCode):s.isNumber(o.status)&&(e=this.safeStatus(o.status)),s.isString(o.message)&&(r=this.safeMessage(o.message)||r),{status:e,message:r}}return{status:e,message:r}}static safeStatus(t){if(!Number.isFinite(t))return StatusCodes.INTERNAL_SERVER_ERROR;const e=Math.trunc(t);return e<400||e>599?StatusCodes.INTERNAL_SERVER_ERROR:e}static safeMessage(t){if(!s.isString(t))return"";const e=t.trim();return e.length>2e3?e.slice(0,2e3)+"...":e}}class Context{constructor(t,e,r,o,i){this.storage={},this.req=t,this.res=e,this.next=r,this.id=s.uuidv7(),this.app=o,this.controller=i}cache(t){const e=Object.assign({},t),r=[];e.private?r.push("private"):e.public&&r.push("public"),e.noStore&&(e.noCache=!0,r.push("no-store")),e.noCache&&(e.maxAge=0,delete e.sMaxAge,r.push("no-cache")),e.noTransform&&r.push("no-transform"),e.proxyRevalidate&&r.push("proxy-revalidate"),e.mustRevalidate?r.push("must-revalidate"):e.noCache||(s.isNumber(e.staleIfError)&&r.push(`stale-if-error=${e.staleIfError}`),s.isNumber(e.staleWhileRevalidate)&&r.push(`stale-while-revalidate=${e.staleWhileRevalidate}`)),s.isNumber(e.maxAge)&&r.push(`max-age=${e.maxAge}`),s.isNumber(e.sMaxAge)&&r.push(`s-maxage=${e.sMaxAge}`),r.length&&(this.res.setHeader("Cache-Control",r.join(",")),e.noCache&&s.forEachKey({"Surrogate-Control":"no-store",Pragma:"no-cache",ETag:"false",Expires:"0"},(t,e)=>this.res.setHeader(e,t)))}clearCookie(t,e){this.res.clearCookie(t,e)}close(t){this.isResponded()||this.res.json(null!=t?t:this.storage)}destroy(t){var e;t&&this.error(t),null===(e=this.res.socket)||void 0===e||e.destroy(t)}error(t){this.isResponded()||HttpResponse.error(this.req,this.res,t)}file(t){this.isResponded()||(this.status(StatusCodes.OK),this.res.sendFile(p.resolve(t)))}getBody(){var t,e;return null!==(e=null===(t=this.req)||void 0===t?void 0:t.body)&&void 0!==e?e:{}}getBodyValue(t){var e;return null===(e=this.req.body)||void 0===e?void 0:e[t]}getCookie(t){var e;return this.normalize(null===(e=this.req.cookies)||void 0===e?void 0:e[t])}getCookies(){var t,e;return s.map(null!==(e=null===(t=this.req)||void 0===t?void 0:t.cookies)&&void 0!==e?e:{},t=>this.normalize(t))}getFiles(){var t,e;return null!==(e=null===(t=this.req)||void 0===t?void 0:t.files)&&void 0!==e?e:{}}getFullUrl(){return`${this.getUrl()}${this.req.originalUrl}`}getHeader(t){var e;return this.normalize(null===(e=this.req.headers)||void 0===e?void 0:e[t])}getHeaders(){var t,e;return s.map(null!==(e=null===(t=this.req)||void 0===t?void 0:t.headers)&&void 0!==e?e:{},t=>this.normalize(t))}getIp(){return h.getClientIp(this.req)||"0.0.0.0"}getQuery(t){var e;return this.normalize(null===(e=this.req.query)||void 0===e?void 0:e[t])}getQueries(){var t,e;return s.map(null!==(e=null===(t=this.req)||void 0===t?void 0:t.query)&&void 0!==e?e:{},t=>this.normalize(t))}getParam(t){var e;const r=null===(e=this.req.params)||void 0===e?void 0:e[t];return s.isUndefined(r)?void 0:String(r)}getParams(){var t,e;return s.map(null!==(e=null===(t=this.req)||void 0===t?void 0:t.params)&&void 0!==e?e:{},t=>{if(!s.isUndefined(t)&&!s.isNull(t))return String(t)})}getUrl(){let t=this.getHeader("x-forwarded-proto")||this.req.protocol||"http";s.isString(t)&&t.includes(",")&&(t=t.split(",")[0].trim());const e=this.getHeader("cf-visitor");if(e){const r=s.parseJson(e);(null==r?void 0:r.scheme)&&(t=r.scheme)}return`${t}://${this.getHeader("host")}`}isResponded(){return this.res.headersSent||this.res.writableEnded}json(t){this.send(StatusCodes.OK,t)}normalize(t){if(!s.isUndefined(t)&&!s.isNull(t))return s.isObject(t)?JSON.stringify(t):String(t)}ok(t,e){this.isResponded()||HttpResponse.ok(this.res,t,e)}prepare(t,e){this.isResponded()||(this.status(t),this.storage=e)}redirect(t){this.isResponded()||this.res.redirect(t)}send(t,e){this.isResponded()||(this.status(t),204===t||304===t||s.isUndefined(e)?this.res.end():this.res.json(e))}setCookie(t,e,s){this.res.cookie(t,e,null!=s?s:{})}status(t){return s.isUndefined(t)||this.res.status(t),this.res.statusCode}success(t){this.send(StatusCodes.OK,{message:t})}}class Metadata{static extends(e){return t.metadata(Metadata.EXTENDS,e,[])}static middleware(e){return t.metadata(Metadata.MIDDLEWARE,e,[])}static parameters(e){return t.metadata(Metadata.PARAMETERS,e,[])}static path(e,s){return t.metadata(Metadata.PATH,e,s)}static routers(e){return t.metadata(Metadata.ROUTERS,e,[])}}Metadata.EXTENDS=Symbol("EXTENDS"),Metadata.MIDDLEWARE=Symbol("MIDDLEWARE"),Metadata.PARAMETERS=Symbol("PARAMETERS"),Metadata.PATH=Symbol("PATH"),Metadata.ROUTERS=Symbol("ROUTERS");class Application extends s.EventEmitter{get controllers(){return[...this._controllers]}get instance(){return this._app}get router(){return this._globalRouter}get server(){return this._server}constructor(e,d){var l,c;super(),this._app=a(),this._boundServers=[],this._options={},this._baseRouter=a.Router(),this._globalRouter=a.Router(),this._controllers=[],this._controllers.push(...e.map(e=>s.isConstructor(e)?new e(...t.getInjectionArgs(e)):e)),this._options=s.merge({},{cross:!1,path:"/",port:3e3,session:{secret:"yoursecret",resave:!0,saveUninitialized:!1,cookie:{maxAge:864e5},proxy:Boolean(null==d?void 0:d.proxy)}},null!=d?d:{}),this._app.use(a.json(this._options.json)),this._app.disable("x-powered-by"),this._options.proxy&&this._app.set("trust proxy",this._options.proxy),this._app.use(a.urlencoded({extended:!0})),this._options.cross&&this._app.use(i(s.isObject(this._options.cross)?this._options.cross:{})),this._app.use(r(this._options.compression)),this._app.use(o(null===(l=this._options.cookie)||void 0===l?void 0:l.secret,this._options.cookie)),this._app.use(n(this._options.session)),this.init(),this._app.use(this._globalRouter);const h=(null===(c=this._options.path)||void 0===c?void 0:c.length)?this._options.path:"/";if(this._app.use(h,this._baseRouter),this._app.all(h+"/*path",(t,e)=>{this._options.redirect?e.redirect(this._options.redirect):HttpResponse.error(t,e,new NotFoundError("Endpoint Not Found"))}),this._options.public){const t=p.resolve(this._options.public);u.existsSync(t)&&this._app.use(a.static(t)),this._app.get("*path",(e,s)=>{u.existsSync(t)?s.sendFile(t+"/index.html"):this._options.notFound?s.redirect(this._options.notFound):HttpResponse.error(e,s,new NotFoundError("File not found"))})}else this._app.all("*path",(t,e)=>{this._options.redirect?e.redirect(this._options.redirect):HttpResponse.error(t,e,new NotFoundError("Endpoint not found"))});this._controllers.forEach(t=>{const e=a.Router(),r=this._collectMiddlewares(t),o=Metadata.parameters(t);this._collectExtends(t).forEach(t=>{r.push(...this._collectMiddlewares(t)),o.push(...Metadata.parameters(t))}),Metadata.routers(t).forEach(i=>{const a=i.propertyKey.toString();if(s.isFunction(t[a])){if(!s.isFunction(e[i.method]))return this._logRouteNotFound(i.method);const n=this._buildMiddlewareChain(t,a,r,o);return e[i.method](i.path,...n,(e,r,i)=>R(this,void 0,void 0,function*(){const n=new Context(e,r,i,this,t),u=this._resolveArgs(n,this._filterParamsByKey(a,o)),d=yield t[a](...u);n.close(s.isArray(d)||s.isObject(d)?d:void 0)}))}this._logRouteNotFound(`${t.name}.${a}`)}),this._collectExtends(t).forEach(i=>{Metadata.routers(i).forEach(i=>{const a=i.propertyKey.toString();if(s.isFunction(t[a])){if(!s.isFunction(e[i.method]))return this._logRouteNotFound(i.method);const n=this._buildMiddlewareChain(t,a,r,o);return e[i.method](i.path,...n,(e,r,i)=>R(this,void 0,void 0,function*(){const n=new Context(e,r,i,this,t),u=this._resolveArgs(n,this._filterParamsByKey(a,o)),d=yield t[a](...u);n.close(s.isArray(d)||s.isObject(d)?d:void 0)}))}this._logRouteNotFound(`${t.constructor.name}.${a}`)})}),this._baseRouter.use(Metadata.path(t,"/"),e)}),this._app.use((t,e,s,r)=>{s.headersSent?r(t):HttpResponse.error(e,s,t)})}init(){}error(t,s){e.Log.error(t)}log(t,s){e.Log.info(t)}_resolveArgs(t,e,s){const r=[],o={ctx:t,key:"",app:this,argument:s};return e.forEach(t=>{r[t.parameterIndex]=t.callback(Object.assign(Object.assign({},o),{key:t.key}))}),r}_buildMiddlewareChain(t,e,r,o){return r.filter(t=>t.propertyKey==e).map(e=>{if(e.callback!=s.noop){const r=this._filterParamsByKey(e.method,o);return(o,i,a)=>R(this,void 0,void 0,function*(){const n=new Context(o,i,a,this,t),u=s.isFunction(e.argument)?e.argument(n):e.argument,d=yield e.callback.call(t,...this._resolveArgs(n,r,u));(s.isArray(d)||s.isObject(d))&&n.close(d)})}this._logRouteNotFound(e.method)}).filter(s.isFunction)}_collectExtends(t){return Metadata.extends(t).reduce((t,e)=>(t.push(e,...this._collectExtends(e)),t),[]).filter((t,e,s)=>s.indexOf(t)===e)}_filterParamsByKey(t,e){return e.filter(e=>e.propertyKey==t)}_collectMiddlewares(t){return[...Metadata.middleware(t)].reverse()}_logRouteNotFound(t){this.error(new Error(`Router "${t}" not found`),"express")}_formatListeningMessage(t){return`Server listening on port ${t}`}listen(){return R(this,void 0,void 0,function*(){var t;const e=this._resolveMode(),s={http:this._startHttp,https:this._startHttps,hybrid:this._startHybrid,redirect:this._startHttpsWithRedirect};yield(null!==(t=s[e])&&void 0!==t?t:this._startHttp).call(this)})}close(){return R(this,void 0,void 0,function*(){yield Promise.all(this._boundServers.map(t=>new Promise((e,s)=>{t.close(t=>t?s(t):e())}))),this._boundServers.length=0,this._server=void 0})}_resolveMode(){return this._resolveTls()&&this._options.mode?this._options.mode:"http"}_resolveTls(){if(this._options.tls&&this._options.tls.key&&this._options.tls.cert)return this._options.tls}_bindServer(t,e,s){return new Promise((r,o)=>{const i=e=>{t.off("listening",a),o(e)},a=()=>{t.off("error",i),this.log(this._formatListeningMessage(e),"express"),r()};t.once("error",i),t.once("listening",a),t.listen(e,s)})}_startHttp(){return R(this,void 0,void 0,function*(){var t;const e=T.createServer(this._app);this._server=e,this._boundServers.push(e),yield this._bindServer(e,null!==(t=this._options.port)&&void 0!==t?t:3e3,this._options.host)})}_startHttps(){return R(this,void 0,void 0,function*(){var t;const e=_.createServer(this._resolveTls(),this._app);this._server=e,this._boundServers.push(e),yield this._bindServer(e,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host)})}_startHttpsWithRedirect(){return R(this,void 0,void 0,function*(){var t,e;const s=_.createServer(this._resolveTls(),this._app),r=T.createServer((t,e)=>{var s,r;const o=(null!==(s=t.headers.host)&&void 0!==s?s:"").split(":")[0];e.writeHead(StatusCodes.MOVED_PERMANENTLY,{Location:`https://${o}${null!==(r=t.url)&&void 0!==r?r:""}`}),e.end()});this._server=s,this._boundServers.push(s,r),yield Promise.all([this._bindServer(s,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host),this._bindServer(r,null!==(e=this._options.redirectPort)&&void 0!==e?e:80,this._options.host)])})}_startHybrid(){return R(this,void 0,void 0,function*(){var t;const e=T.createServer(this._app),s=_.createServer(this._resolveTls(),this._app),r=v.createServer(t=>{const r=setTimeout(()=>t.destroy(),5e3);t.once("data",o=>{clearTimeout(r),t.pause(),t.unshift(o),(22===o[0]?s:e).emit("connection",t),process.nextTick(()=>t.resume())}),t.once("error",()=>clearTimeout(r))});return this._server=s,this._boundServers.push(r,s,e),yield this._bindServer(r,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host),s})}}const C=t=>e=>(s,r,o)=>{Metadata.parameters(s).push({callback:t,key:e,propertyKey:r,parameterIndex:o})},x=C(({app:t})=>t),m=C(({argument:t})=>t),g=C(({ctx:t,key:e})=>e?t.getBodyValue(e):t.getBody()),O=C(({ctx:t,key:e})=>e?t.getCookie(e):t.getCookies()),N=C(({ctx:t})=>t),A=C(({ctx:t})=>t.getFiles()),f=C(({ctx:t,key:e})=>e?t.getHeader(e):t.getHeaders()),I=C(({ctx:t,key:e})=>e?t.getParam(e):t.getParams()),y=C(({ctx:t,key:e})=>e?t.getQuery(e):t.getQueries()),D=C(({ctx:t})=>{var e;return null===(e=t.req)||void 0===e?void 0:e.session}),b=(t,e)=>(r,o)=>{const i=s.uuidv7();N()(r,i,0),Metadata.middleware(r).push({method:i,argument:e,propertyKey:o,callback:t})},M={ALL:"all",GET:"get",POST:"post",PUT:"put",HEAD:"head",DELETE:"delete",OPTIONS:"options",PATCH:"patch"},P=t=>e=>(s,r)=>{Metadata.routers(s).push({method:t,path:(null==e?void 0:e.length)?e:"/",propertyKey:r})},U=P(M.ALL),L=P(M.DELETE),F=P(M.GET),H=P(M.HEAD),q=P(M.OPTIONS),k=P(M.PATCH),w=P(M.POST),j=P(M.PUT),B=(t,e=StatusCodes.BAD_REQUEST)=>{const s=new Error(t);return s.status=e,s},V=t=>{var e;return(null===(e=t.split(".").pop())||void 0===e?void 0:e.toLowerCase())||"bin"},G=(t,e)=>{var s;return null!==(s=t[e])&&void 0!==s?s:null},K=(t,e)=>{const r=s.uuidv7()+"."+e;return u.existsSync(p.join(t,r))?K(t,e):r};exports.All=U,exports.App=x,exports.Application=Application,exports.Argument=m,exports.BadRequestError=class BadRequestError extends ResponseError{constructor(t="Bad Request"){super(t,StatusCodes.BAD_REQUEST)}},exports.Body=g,exports.Cache=t=>(e,s,r)=>{b(e=>{e.cache(Object.assign({},t)),e.next()})(e,s,r)},exports.Context=Context,exports.Controller=t=>e=>{Metadata.path(e,(null==t?void 0:t.length)?t:"/")},exports.Cookies=O,exports.Ctx=N,exports.Delete=L,exports.Extends=t=>e=>{Metadata.extends(e).push(t)},exports.Files=A,exports.ForbiddenError=class ForbiddenError extends ResponseError{constructor(t="Forbidden"){super(t,StatusCodes.FORBIDDEN)}},exports.Get=F,exports.Head=H,exports.Headers=f,exports.HttpResponse=HttpResponse,exports.InternalServerError=class InternalServerError extends ResponseError{constructor(t="Internal server error"){super(t,StatusCodes.INTERNAL_SERVER_ERROR)}},exports.Metadata=Metadata,exports.Methods=M,exports.Middleware=(t,e)=>(r,o)=>{let i=s.noop;if(s.isString(o)){const e=r;s.isFunction(e[t])&&(i=e[t])}Metadata.middleware(r).push({method:t,argument:e,propertyKey:o,callback:i})},exports.NotFoundError=NotFoundError,exports.Options=q,exports.Params=I,exports.Patch=k,exports.Post=w,exports.Put=j,exports.Query=y,exports.ResponseError=ResponseError,exports.Session=D,exports.StatusCodes=StatusCodes,exports.StatusText=StatusText,exports.UnauthorizedError=class UnauthorizedError extends ResponseError{constructor(t="Unauthorized"){super(t,StatusCodes.UNAUTHORIZED)}},exports.Upload=t=>{const e=s.merge({},t),r=E.diskStorage({destination(t,s,r){var o;const i=G(e,s.fieldname);r(null,null!==(o=null==i?void 0:i.path)&&void 0!==o?o:"./")},filename(t,s,r){var o;const i=G(e,s.fieldname);r(null,K(null!==(o=null==i?void 0:i.path)&&void 0!==o?o:"./",V(s.originalname)))}}),o=Math.max(...Object.values(e).map(t=>{var e;return null!==(e=t.size)&&void 0!==e?e:0})),i=E({storage:r,fileFilter(t,s,r){var o;const i=G(e,s.fieldname);return i?((t,e)=>!e.length||e.includes(V(t.originalname))||e.includes(t.mimetype.toLowerCase()))(s,null!==(o=null==i?void 0:i.types)&&void 0!==o?o:[])?void r(null,!0):r(B(`FILE TYPE NOT ALLOWED FOR "${s.fieldname}"`)):r(B(`UPLOAD FIELD "${s.fieldname}" IS NOT CONFIGURED`))},limits:{fileSize:1024*o*1024}}).fields(Object.keys(e).map(t=>{var s,r;return{name:t,maxCount:null!==(r=null===(s=e[t])||void 0===s?void 0:s.count)&&void 0!==r?r:1}}));return(t,e,s)=>{b(t=>{i(t.req,t.res,e=>{if(!e)return t.next();t.error((t=>"LIMIT_FILE_SIZE"==t.code?(t.message=t.field?`FILE "${t.field}" EXCEEDS MAX SIZE`:"FILE EXCEEDS MAX SIZE",t.status=StatusCodes.PAYLOAD_TOO_LARGE,t):"LIMIT_UNEXPECTED_FILE"==t.code?(t.message=t.field?`FIELD "${t.field}" IS UNEXPECTED OR EXCEEDS MAX COUNT`:"UPLOAD FIELD IS UNEXPECTED OR EXCEEDS MAX COUNT",t.status=StatusCodes.BAD_REQUEST,t):t)(e))})})(t,e,s)}},exports.Use=b,exports.Validate=t=>{const e=s.Validation.object(s.isFunction(t)?t(s.Validation):t).parse();return(t,s,r)=>{b(t=>R(void 0,void 0,void 0,function*(){var s,r;const{error:o,message:i,value:a}=yield e.validateAsync(null!==(r=null===(s=t.req)||void 0===s?void 0:s.body)&&void 0!==r?r:{});if(o)return t.error(new ValidationError(null!=i?i:o));t.req.body=a,t.next()}))(t,s,r)}},exports.ValidationError=ValidationError,exports.methodFactory=P,exports.parameterFactory=C;
|
|
7
|
+
"use strict";var t=require("@andrewcaires/decorator"),e=require("@andrewcaires/node"),s=require("@andrewcaires/utils.js"),r=require("compression"),o=require("cookie-parser"),i=require("cors"),a=require("express"),n=require("express-session"),u=require("fs"),d=require("http"),l=require("https"),c=require("net"),p=require("path"),h=require("request-ip"),E=require("multer");function S(t){var e=Object.create(null);return t&&Object.keys(t).forEach(function(s){if("default"!==s){var r=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,r.get?r:{enumerable:!0,get:function(){return t[s]}})}}),e.default=t,Object.freeze(e)}var T=S(d),_=S(l),v=S(c);function R(t,e,s,r){return new(s||(s=Promise))(function(o,i){function a(t){try{u(r.next(t))}catch(t){i(t)}}function n(t){try{u(r.throw(t))}catch(t){i(t)}}function u(t){var e;t.done?o(t.value):(e=t.value,e instanceof s?e:new s(function(t){t(e)})).then(a,n)}u((r=r.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class StatusCodes{}StatusCodes.CONTINUE=100,StatusCodes.SWITCHING_PROTOCOLS=101,StatusCodes.PROCESSING=102,StatusCodes.OK=200,StatusCodes.CREATED=201,StatusCodes.ACCEPTED=202,StatusCodes.NON_AUTHORITATIVE_INFORMATION=203,StatusCodes.NO_CONTENT=204,StatusCodes.RESET_CONTENT=205,StatusCodes.PARTIAL_CONTENT=206,StatusCodes.MULTI_STATUS=207,StatusCodes.ALREADY_REPORTED=208,StatusCodes.IM_USED=226,StatusCodes.MULTIPLE_CHOICES=300,StatusCodes.MOVED_PERMANENTLY=301,StatusCodes.FOUND=302,StatusCodes.SEE_OTHER=303,StatusCodes.NOT_MODIFIED=304,StatusCodes.USE_PROXY=305,StatusCodes.TEMPORARY_REDIRECT=307,StatusCodes.PERMANENT_REDIRECT=308,StatusCodes.BAD_REQUEST=400,StatusCodes.UNAUTHORIZED=401,StatusCodes.PAYMENT_REQUIRED=402,StatusCodes.FORBIDDEN=403,StatusCodes.NOT_FOUND=404,StatusCodes.METHOD_NOT_ALLOWED=405,StatusCodes.NOT_ACCEPTABLE=406,StatusCodes.PROXY_AUTHENTICATION_REQUIRED=407,StatusCodes.REQUEST_TIMEOUT=408,StatusCodes.CONFLICT=409,StatusCodes.GONE=410,StatusCodes.LENGTH_REQUIRED=411,StatusCodes.PRECONDITION_FAILED=412,StatusCodes.PAYLOAD_TOO_LARGE=413,StatusCodes.REQUEST_URI_TOO_LONG=414,StatusCodes.UNSUPPORTED_MEDIA_TYPE=415,StatusCodes.REQUESTED_RANGE_NOT_SATISFIABLE=416,StatusCodes.EXPECTATION_FAILED=417,StatusCodes.IM_A_TEAPOT=418,StatusCodes.MISDIRECTED_REQUEST=421,StatusCodes.UNPROCESSABLE_ENTITY=422,StatusCodes.LOCKED=423,StatusCodes.FAILED_DEPENDENCY=424,StatusCodes.UPGRADE_REQUIRED=426,StatusCodes.PRECONDITION_REQUIRED=428,StatusCodes.TOO_MANY_REQUESTS=429,StatusCodes.REQUEST_HEADER_FIELDS_TOO_LARGE=431,StatusCodes.CONNECTION_CLOSED_WITHOUT_RESPONSE=444,StatusCodes.UNAVAILABLE_FOR_LEGAL_REASONS=451,StatusCodes.CLIENT_CLOSED_REQUEST=499,StatusCodes.INTERNAL_SERVER_ERROR=500,StatusCodes.NOT_IMPLEMENTED=501,StatusCodes.BAD_GATEWAY=502,StatusCodes.SERVICE_UNAVAILABLE=503,StatusCodes.GATEWAY_TIMEOUT=504,StatusCodes.HTTP_VERSION_NOT_SUPPORTED=505,StatusCodes.VARIANT_ALSO_NEGOCIATES=506,StatusCodes.INSUFFICIENT_STORAGE=507,StatusCodes.LOOP_DETECTED=508,StatusCodes.NOT_EXTENDED=510,StatusCodes.NETWORK_AUTHENTICATION_REQUIRED=511,StatusCodes.NETWORK_CONNECTION_TIMEOUT_ERROR=599;class StatusText{}StatusText[100]="Continue",StatusText[101]="Switching Protocols",StatusText[102]="Processing",StatusText[200]="OK",StatusText[201]="Created",StatusText[202]="Accepted",StatusText[203]="Non-Authoritative Information",StatusText[204]="No Content",StatusText[205]="Reset Content",StatusText[206]="Partial Content",StatusText[207]="Multi-Status",StatusText[226]="IM Used",StatusText[300]="Multiple Choices",StatusText[301]="Moved Permanently",StatusText[302]="Found",StatusText[303]="See Other",StatusText[304]="Not Modified",StatusText[305]="Use Proxy",StatusText[307]="Temporary Redirect",StatusText[308]="Permanent Redirect",StatusText[400]="Bad Request",StatusText[401]="Unauthorized",StatusText[402]="Payment Required",StatusText[403]="Forbidden",StatusText[404]="Not Found",StatusText[405]="Method Not Allowed",StatusText[406]="Not Acceptable",StatusText[407]="Proxy Authentication Required",StatusText[408]="Request Timeout",StatusText[409]="Conflict",StatusText[410]="Gone",StatusText[411]="Length Required",StatusText[412]="Precondition Failed",StatusText[413]="Payload Too Large",StatusText[414]="URI Too Long",StatusText[415]="Unsupported Media Type",StatusText[416]="Range Not Satisfiable",StatusText[417]="Expectation Failed",StatusText[418]="I'm a teapot",StatusText[422]="Unprocessable Entity",StatusText[423]="Locked",StatusText[424]="Failed Dependency",StatusText[426]="Upgrade Required",StatusText[428]="Precondition Required",StatusText[429]="Too Many Requests",StatusText[431]="Request Header Fields Too Large",StatusText[451]="Unavailable For Legal Reasons",StatusText[500]="Internal Server Error",StatusText[501]="Not Implemented",StatusText[502]="Bad Gateway",StatusText[503]="Service Unavailable",StatusText[504]="Gateway Time-out",StatusText[505]="HTTP Version Not Supported",StatusText[506]="Variant Also Negotiates",StatusText[507]="Insufficient Storage",StatusText[511]="Network Authentication Required";class ResponseError extends Error{constructor(t,e=StatusCodes.INTERNAL_SERVER_ERROR){super(t),this.status=e,this.name=this.constructor.name}}class NotFoundError extends ResponseError{constructor(t="Not Found"){super(t,StatusCodes.NOT_FOUND)}}class ValidationError extends ResponseError{constructor(t){super(t,StatusCodes.UNPROCESSABLE_ENTITY)}}class HttpResponse{static created(t,e,s){var r,o;const i=StatusCodes.CREATED,a={success:!0,status:i,data:e?{id:e}:{},meta:null!==(r=null==s?void 0:s.meta)&&void 0!==r?r:{},message:null!==(o=null==s?void 0:s.message)&&void 0!==o?o:null};return t.status(i).json(a),a}static noContent(t){t.status(StatusCodes.NO_CONTENT).end()}static ok(t,e,s){var r,o;const i=StatusCodes.OK,a={success:!0,status:i,data:e,meta:null!==(r=null==s?void 0:s.meta)&&void 0!==r?r:{},message:null!==(o=null==s?void 0:s.message)&&void 0!==o?o:null};return t.status(i).json(a),a}static error(t,e,s){var r,o;const{status:i,message:a}=this.normalizeError(s),n=null!==(r=null==StatusText?void 0:StatusText[i])&&void 0!==r?r:"Internal Server Error",u=this.getErrorCode(s),d=this.getErrorName(s),l=Object.assign(Object.assign(Object.assign(Object.assign({success:!1,status:i,statusText:n,message:a,path:null!==(o=t.originalUrl)&&void 0!==o?o:t.url},u?{code:u}:{}),d?{name:d}:{}),{timestamp:(new Date).toISOString()}),this.isDev()&&s instanceof Error&&s.stack?{stack:s.stack}:{});return e.status(i).json(l),l}static getErrorCode(t){return t&&s.isObject(t)&&s.isString(t.code)?this.safeMessage(t.code):""}static getErrorName(t){return t instanceof ResponseError?t.constructor.name:this.isDev()?t instanceof Error?t.name||t.constructor.name:s.isObject(t)&&s.isString(t.name)?t.name:typeof t:""}static isDev(){return"production"!==process.env.NODE_ENV}static normalizeError(t){let e=StatusCodes.INTERNAL_SERVER_ERROR,r=StatusText[500];if(t instanceof ResponseError)return e=this.safeStatus(t.status),r=this.safeMessage(t.message)||r,{status:e,message:r};if(t instanceof Error){const o=t;return s.isNumber(o.statusCode)?e=this.safeStatus(o.statusCode):s.isNumber(o.status)&&(e=this.safeStatus(o.status)),r=this.safeMessage(t.message)||r,{status:e,message:r}}if(s.isString(t))return r=this.safeMessage(t)||r,{status:e,message:r};if(t&&s.isObject(t)){const o=t;return s.isNumber(o.statusCode)?e=this.safeStatus(o.statusCode):s.isNumber(o.status)&&(e=this.safeStatus(o.status)),s.isString(o.message)&&(r=this.safeMessage(o.message)||r),{status:e,message:r}}return{status:e,message:r}}static safeStatus(t){if(!Number.isFinite(t))return StatusCodes.INTERNAL_SERVER_ERROR;const e=Math.trunc(t);return e<400||e>599?StatusCodes.INTERNAL_SERVER_ERROR:e}static safeMessage(t){if(!s.isString(t))return"";const e=t.trim();return e.length>2e3?e.slice(0,2e3)+"...":e}}class Context{constructor(t,e,r,o,i){this.storage={},this.req=t,this.res=e,this.next=r,this.id=s.uuidv7(),this.app=o,this.controller=i}cache(t){const e=Object.assign({},t),r=[];e.private?r.push("private"):e.public&&r.push("public"),e.noStore&&(e.noCache=!0,r.push("no-store")),e.noCache&&(e.maxAge=0,delete e.sMaxAge,r.push("no-cache")),e.noTransform&&r.push("no-transform"),e.proxyRevalidate&&r.push("proxy-revalidate"),e.mustRevalidate?r.push("must-revalidate"):e.noCache||(s.isNumber(e.staleIfError)&&r.push(`stale-if-error=${e.staleIfError}`),s.isNumber(e.staleWhileRevalidate)&&r.push(`stale-while-revalidate=${e.staleWhileRevalidate}`)),s.isNumber(e.maxAge)&&r.push(`max-age=${e.maxAge}`),s.isNumber(e.sMaxAge)&&r.push(`s-maxage=${e.sMaxAge}`),r.length&&(this.res.setHeader("Cache-Control",r.join(",")),e.noCache&&s.forEachKey({"Surrogate-Control":"no-store",Pragma:"no-cache",ETag:"false",Expires:"0"},(t,e)=>this.res.setHeader(e,t)))}clearCookie(t,e){this.res.clearCookie(t,e)}close(t){this.isResponded()||this.res.json(null!=t?t:this.storage)}destroy(t){var e;t&&this.error(t),null===(e=this.res.socket)||void 0===e||e.destroy(t)}error(t){this.isResponded()||HttpResponse.error(this.req,this.res,t)}file(t){this.isResponded()||(this.status(StatusCodes.OK),this.res.sendFile(p.resolve(t)))}getBody(){var t,e;return null!==(e=null===(t=this.req)||void 0===t?void 0:t.body)&&void 0!==e?e:{}}getBodyValue(t){var e;return null===(e=this.req.body)||void 0===e?void 0:e[t]}getCookie(t){var e;return this.normalize(null===(e=this.req.cookies)||void 0===e?void 0:e[t])}getCookies(){var t,e;return s.map(null!==(e=null===(t=this.req)||void 0===t?void 0:t.cookies)&&void 0!==e?e:{},t=>this.normalize(t))}getFiles(){var t,e;return null!==(e=null===(t=this.req)||void 0===t?void 0:t.files)&&void 0!==e?e:{}}getFullUrl(){return`${this.getUrl()}${this.req.originalUrl}`}getHeader(t){var e;return this.normalize(null===(e=this.req.headers)||void 0===e?void 0:e[t])}getHeaders(){var t,e;return s.map(null!==(e=null===(t=this.req)||void 0===t?void 0:t.headers)&&void 0!==e?e:{},t=>this.normalize(t))}getIp(){return h.getClientIp(this.req)||"0.0.0.0"}getQuery(t){var e;return this.normalize(null===(e=this.req.query)||void 0===e?void 0:e[t])}getQueries(){var t,e;return s.map(null!==(e=null===(t=this.req)||void 0===t?void 0:t.query)&&void 0!==e?e:{},t=>this.normalize(t))}getParam(t){var e;const r=null===(e=this.req.params)||void 0===e?void 0:e[t];return s.isUndefined(r)?void 0:String(r)}getParams(){var t,e;return s.map(null!==(e=null===(t=this.req)||void 0===t?void 0:t.params)&&void 0!==e?e:{},t=>{if(!s.isUndefined(t)&&!s.isNull(t))return String(t)})}getUrl(){let t=this.getHeader("x-forwarded-proto")||this.req.protocol||"http";s.isString(t)&&t.includes(",")&&(t=t.split(",")[0].trim());const e=this.getHeader("cf-visitor");if(e){const r=s.parseJson(e);(null==r?void 0:r.scheme)&&(t=r.scheme)}return`${t}://${this.getHeader("host")}`}isResponded(){return this.res.headersSent||this.res.writableEnded}json(t){this.send(StatusCodes.OK,t)}normalize(t){if(!s.isUndefined(t)&&!s.isNull(t))return s.isObject(t)?JSON.stringify(t):String(t)}ok(t,e){this.isResponded()||HttpResponse.ok(this.res,t,e)}prepare(t,e){this.isResponded()||(this.status(t),this.storage=e)}redirect(t){this.isResponded()||this.res.redirect(t)}send(t,e){this.isResponded()||(this.status(t),204===t||304===t||s.isUndefined(e)?this.res.end():this.res.json(e))}setCookie(t,e,s){this.res.cookie(t,e,null!=s?s:{})}status(t){return s.isUndefined(t)||this.res.status(t),this.res.statusCode}success(t){this.send(StatusCodes.OK,{message:t})}}class Metadata{static extends(e){return t.metadata(Metadata.EXTENDS,e,[])}static middleware(e){return t.metadata(Metadata.MIDDLEWARE,e,[])}static parameters(e){return t.metadata(Metadata.PARAMETERS,e,[])}static path(e,s){return t.metadata(Metadata.PATH,e,s)}static routers(e){return t.metadata(Metadata.ROUTERS,e,[])}}Metadata.EXTENDS=Symbol("EXTENDS"),Metadata.MIDDLEWARE=Symbol("MIDDLEWARE"),Metadata.PARAMETERS=Symbol("PARAMETERS"),Metadata.PATH=Symbol("PATH"),Metadata.ROUTERS=Symbol("ROUTERS");class Application extends s.EventEmitter{get controllers(){return[...this._controllers]}get instance(){return this._app}get router(){return this._globalRouter}get server(){return this._server}constructor(e,d){var l,c;super(),this._app=a(),this._boundServers=[],this._options={},this._baseRouter=a.Router(),this._globalRouter=a.Router(),this._controllers=[],this._controllers.push(...e.map(e=>s.isConstructor(e)?new e(...t.getInjectionArgs(e)):e)),this._options=s.merge({},{cross:!1,path:"/",port:3e3,session:{secret:"yoursecret",resave:!0,saveUninitialized:!1,cookie:{maxAge:864e5},proxy:Boolean(null==d?void 0:d.proxy)}},null!=d?d:{}),this._app.use(a.json(this._options.json)),this._app.disable("x-powered-by"),this._options.proxy&&this._app.set("trust proxy",this._options.proxy),this._app.use(a.urlencoded({extended:!0})),this._options.cross&&this._app.use(i(s.isObject(this._options.cross)?this._options.cross:{})),this._app.use(r(this._options.compression)),this._app.use(o(null===(l=this._options.cookie)||void 0===l?void 0:l.secret,this._options.cookie)),this._app.use(n(this._options.session)),this.init(),this._app.use(this._globalRouter);const h=(null===(c=this._options.path)||void 0===c?void 0:c.length)?this._options.path:"/";if(this._app.use(h,this._baseRouter),this._app.all(h+"/*path",(t,e)=>{this._options.redirect?e.redirect(this._options.redirect):HttpResponse.error(t,e,new NotFoundError("Endpoint Not Found"))}),this._options.public){const t=p.resolve(this._options.public);u.existsSync(t)&&this._app.use(a.static(t)),this._app.get("*path",(e,s)=>{u.existsSync(t)?s.sendFile(t+"/index.html"):this._options.notFound?s.redirect(this._options.notFound):HttpResponse.error(e,s,new NotFoundError("File not found"))})}else this._app.all("*path",(t,e)=>{this._options.redirect?e.redirect(this._options.redirect):HttpResponse.error(t,e,new NotFoundError("Endpoint not found"))});this._controllers.forEach(t=>{const e=a.Router(),r=this._collectMiddlewares(t),o=Metadata.parameters(t);this._collectExtends(t).forEach(t=>{r.push(...this._collectMiddlewares(t)),o.push(...Metadata.parameters(t))}),Metadata.routers(t).forEach(i=>{const a=i.propertyKey.toString();if(s.isFunction(t[a])){if(!s.isFunction(e[i.method]))return this._logRouteNotFound(i.method);const n=this._buildMiddlewareChain(t,a,r,o);return e[i.method](i.path,...n,(e,r,i)=>R(this,void 0,void 0,function*(){const n=new Context(e,r,i,this,t),u=this._resolveArgs(n,this._filterParamsByKey(a,o)),d=yield t[a](...u);n.close(s.isArray(d)||s.isObject(d)?d:void 0)}))}this._logRouteNotFound(`${t.name}.${a}`)}),this._collectExtends(t).forEach(i=>{Metadata.routers(i).forEach(i=>{const a=i.propertyKey.toString();if(s.isFunction(t[a])){if(!s.isFunction(e[i.method]))return this._logRouteNotFound(i.method);const n=this._buildMiddlewareChain(t,a,r,o);return e[i.method](i.path,...n,(e,r,i)=>R(this,void 0,void 0,function*(){const n=new Context(e,r,i,this,t),u=this._resolveArgs(n,this._filterParamsByKey(a,o)),d=yield t[a](...u);n.close(s.isArray(d)||s.isObject(d)?d:void 0)}))}this._logRouteNotFound(`${t.constructor.name}.${a}`)})}),this._baseRouter.use(Metadata.path(t,"/"),e)}),this._app.use((t,e,s,r)=>{s.headersSent?r(t):HttpResponse.error(e,s,t)})}init(){}error(t,s){e.Log.error(t)}log(t,s){e.Log.info(t)}_resolveArgs(t,e,s){const r=[],o={ctx:t,key:"",app:this,argument:s};return e.forEach(t=>{r[t.parameterIndex]=t.callback(Object.assign(Object.assign({},o),{key:t.key}))}),r}_buildMiddlewareChain(t,e,r,o){return r.filter(t=>t.propertyKey==e).map(e=>{if(e.callback!=s.noop){const r=this._filterParamsByKey(e.method,o);return(o,i,a)=>R(this,void 0,void 0,function*(){const n=new Context(o,i,a,this,t),u=s.isFunction(e.argument)?e.argument(n):e.argument,d=yield e.callback.call(t,...this._resolveArgs(n,r,u));(s.isArray(d)||s.isObject(d))&&n.close(d)})}this._logRouteNotFound(e.method)}).filter(s.isFunction)}_collectExtends(t){return Metadata.extends(t).reduce((t,e)=>(t.push(e,...this._collectExtends(e)),t),[]).filter((t,e,s)=>s.indexOf(t)===e)}_filterParamsByKey(t,e){return e.filter(e=>e.propertyKey==t)}_collectMiddlewares(t){return[...Metadata.middleware(t)].reverse()}_logRouteNotFound(t){this.error(new Error(`Router "${t}" not found`),"express")}_formatListeningMessage(t){return`Server listening on port ${t}`}listen(){return R(this,void 0,void 0,function*(){var t;const e=this._resolveMode(),s={http:this._startHttp,https:this._startHttps,hybrid:this._startHybrid,redirect:this._startHttpsWithRedirect};yield(null!==(t=s[e])&&void 0!==t?t:this._startHttp).call(this)})}close(){return R(this,void 0,void 0,function*(){yield Promise.all(this._boundServers.map(t=>new Promise((e,s)=>{t.close(t=>t?s(t):e())}))),this._boundServers.length=0,this._server=void 0})}_resolveMode(){return this._resolveTls()&&this._options.mode?this._options.mode:"http"}_resolveTls(){if(this._options.tls&&this._options.tls.key&&this._options.tls.cert)return this._options.tls}_bindServer(t,e,s){return new Promise((r,o)=>{const i=e=>{t.off("listening",a),o(e)},a=()=>{t.off("error",i),this.log(this._formatListeningMessage(e),"express"),r()};t.once("error",i),t.once("listening",a),t.listen(e,s)})}_startHttp(){return R(this,void 0,void 0,function*(){var t;const e=T.createServer(this._app);this._server=e,this._boundServers.push(e),yield this._bindServer(e,null!==(t=this._options.port)&&void 0!==t?t:3e3,this._options.host)})}_startHttps(){return R(this,void 0,void 0,function*(){var t;const e=_.createServer(this._resolveTls(),this._app);this._server=e,this._boundServers.push(e),yield this._bindServer(e,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host)})}_startHttpsWithRedirect(){return R(this,void 0,void 0,function*(){var t,e;const s=_.createServer(this._resolveTls(),this._app),r=T.createServer((t,e)=>{var s,r;const o=(null!==(s=t.headers.host)&&void 0!==s?s:"").split(":")[0];e.writeHead(StatusCodes.MOVED_PERMANENTLY,{Location:`https://${o}${null!==(r=t.url)&&void 0!==r?r:""}`}),e.end()});this._server=s,this._boundServers.push(s,r),yield Promise.all([this._bindServer(s,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host),this._bindServer(r,null!==(e=this._options.redirectPort)&&void 0!==e?e:80,this._options.host)])})}_startHybrid(){return R(this,void 0,void 0,function*(){var t;const e=T.createServer(this._app),s=_.createServer(this._resolveTls(),this._app),r=v.createServer(t=>{const r=setTimeout(()=>t.destroy(),5e3);t.once("data",o=>{clearTimeout(r),t.pause(),t.unshift(o),(22===o[0]?s:e).emit("connection",t),process.nextTick(()=>t.resume())}),t.once("error",()=>clearTimeout(r))});return this._server=s,this._boundServers.push(r,s,e),yield this._bindServer(r,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host),s})}}const C=t=>e=>(s,r,o)=>{Metadata.parameters(s).push({callback:t,key:e,propertyKey:r,parameterIndex:o})},x=C(({app:t})=>t),m=C(({argument:t})=>t),g=C(({ctx:t,key:e})=>e?t.getBodyValue(e):t.getBody()),O=C(({ctx:t,key:e})=>e?t.getCookie(e):t.getCookies()),N=C(({ctx:t})=>t),A=C(({ctx:t})=>t.getFiles()),f=C(({ctx:t,key:e})=>e?t.getHeader(e):t.getHeaders()),I=C(({ctx:t,key:e})=>e?t.getParam(e):t.getParams()),y=C(({ctx:t,key:e})=>e?t.getQuery(e):t.getQueries()),D=C(({ctx:t})=>{var e;return null===(e=t.req)||void 0===e?void 0:e.session}),b=(t,e)=>(r,o)=>{const i=s.uuidv7();N()(r,i,0),Metadata.middleware(r).push({method:i,argument:e,propertyKey:o,callback:t})},M={ALL:"all",GET:"get",POST:"post",PUT:"put",HEAD:"head",DELETE:"delete",OPTIONS:"options",PATCH:"patch"},P=t=>e=>(s,r)=>{Metadata.routers(s).push({method:t,path:(null==e?void 0:e.length)?e:"/",propertyKey:r})},U=P(M.ALL),L=P(M.DELETE),F=P(M.GET),H=P(M.HEAD),q=P(M.OPTIONS),k=P(M.PATCH),w=P(M.POST),j=P(M.PUT),B=(t,e=StatusCodes.BAD_REQUEST)=>{const s=new Error(t);return s.status=e,s},V=t=>{var e;return(null===(e=t.split(".").pop())||void 0===e?void 0:e.toLowerCase())||"bin"},G=(t,e)=>{var s;return null!==(s=t[e])&&void 0!==s?s:null},K=(t,e)=>{const r=s.uuidv7()+"."+e;return u.existsSync(p.join(t,r))?K(t,e):r};exports.All=U,exports.App=x,exports.Application=Application,exports.Argument=m,exports.BadRequestError=class BadRequestError extends ResponseError{constructor(t="Bad Request"){super(t,StatusCodes.BAD_REQUEST)}},exports.Body=g,exports.Cache=t=>(e,s,r)=>{b(e=>{e.cache(Object.assign({},t)),e.next()})(e,s,r)},exports.Context=Context,exports.Controller=t=>e=>{Metadata.path(e,(null==t?void 0:t.length)?t:"/")},exports.Cookies=O,exports.Ctx=N,exports.Delete=L,exports.Extends=t=>e=>{Metadata.extends(e).push(t)},exports.Files=A,exports.ForbiddenError=class ForbiddenError extends ResponseError{constructor(t="Forbidden"){super(t,StatusCodes.FORBIDDEN)}},exports.Get=F,exports.Head=H,exports.Headers=f,exports.HttpResponse=HttpResponse,exports.InternalServerError=class InternalServerError extends ResponseError{constructor(t="Internal server error"){super(t,StatusCodes.INTERNAL_SERVER_ERROR)}},exports.Metadata=Metadata,exports.Methods=M,exports.Middleware=(t,e)=>(r,o)=>{let i=s.noop;if(s.isString(o)){const e=r;s.isFunction(e[t])&&(i=e[t])}Metadata.middleware(r).push({method:t,argument:e,propertyKey:o,callback:i})},exports.NotFoundError=NotFoundError,exports.Options=q,exports.Params=I,exports.Patch=k,exports.Post=w,exports.Put=j,exports.Query=y,exports.ResponseError=ResponseError,exports.Session=D,exports.StatusCodes=StatusCodes,exports.StatusText=StatusText,exports.UnauthorizedError=class UnauthorizedError extends ResponseError{constructor(t="Unauthorized"){super(t,StatusCodes.UNAUTHORIZED)}},exports.Upload=t=>{const e=s.merge({},t),r=E.diskStorage({destination(t,s,r){var o;const i=G(e,s.fieldname);r(null,null!==(o=null==i?void 0:i.path)&&void 0!==o?o:"./")},filename(t,s,r){var o;const i=G(e,s.fieldname);r(null,K(null!==(o=null==i?void 0:i.path)&&void 0!==o?o:"./",V(s.originalname)))}}),o=Math.max(...Object.values(e).map(t=>{var e;return null!==(e=t.size)&&void 0!==e?e:0})),i=E({storage:r,fileFilter(t,s,r){var o;const i=G(e,s.fieldname);return i?((t,e)=>!e.length||e.includes(V(t.originalname))||e.includes(t.mimetype.toLowerCase()))(s,null!==(o=null==i?void 0:i.types)&&void 0!==o?o:[])?void r(null,!0):r(B(`FILE TYPE NOT ALLOWED FOR "${s.fieldname}"`)):r(B(`UPLOAD FIELD "${s.fieldname}" IS NOT CONFIGURED`))},limits:{fileSize:1024*o*1024}}).fields(Object.keys(e).map(t=>{var s,r;return{name:t,maxCount:null!==(r=null===(s=e[t])||void 0===s?void 0:s.count)&&void 0!==r?r:1}}));return(t,e,s)=>{b(t=>{i(t.req,t.res,e=>{if(!e)return t.next();t.error((t=>"LIMIT_FILE_SIZE"==t.code?(t.message=t.field?`FILE "${t.field}" EXCEEDS MAX SIZE`:"FILE EXCEEDS MAX SIZE",t.status=StatusCodes.PAYLOAD_TOO_LARGE,t):"LIMIT_UNEXPECTED_FILE"==t.code?(t.message=t.field?`FIELD "${t.field}" IS UNEXPECTED OR EXCEEDS MAX COUNT`:"UPLOAD FIELD IS UNEXPECTED OR EXCEEDS MAX COUNT",t.status=StatusCodes.BAD_REQUEST,t):t)(e))})})(t,e,s)}},exports.Use=b,exports.Validate=t=>{const e=s.Validation.object(s.isFunction(t)?t(s.Validation):t).parse();return(t,s,r)=>{b(t=>{var s,r,o;const i=e.validate(null!==(r=null===(s=t.req)||void 0===s?void 0:s.body)&&void 0!==r?r:{});if(i.error)return t.error(new ValidationError(null!==(o=i.message)&&void 0!==o?o:i.error));t.req.body=i.value,t.next()})(t,s,r)}},exports.ValidationError=ValidationError,exports.methodFactory=P,exports.parameterFactory=C;
|
package/dist/index.d.ts
CHANGED
package/dist/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/express v2.
|
|
2
|
+
* @andrewcaires/express v2.4.0
|
|
3
3
|
* Decorators for express
|
|
4
4
|
* (c) 2026 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
6
6
|
*/
|
|
7
|
-
import{metadata as t,getInjectionArgs as e}from"@andrewcaires/decorator";import{Log as s}from"@andrewcaires/node";import{isObject as r,isString as o,isNumber as a,uuidv7 as i,forEachKey as n,map as u,isUndefined as d,isNull as l,parseJson as h,EventEmitter as c,isConstructor as p,merge as E,isFunction as S,noop as T,isArray as _,Validation as v}from"@andrewcaires/utils.js";import R from"compression";import m from"cookie-parser";import C from"cors";import g,{Router as O,json as N,urlencoded as x}from"express";import f from"express-session";import{existsSync as A}from"fs";import*as I from"http";import*as y from"https";import*as D from"net";import{resolve as M,join as P}from"path";import{getClientIp as L}from"request-ip";import U,{diskStorage as b}from"multer";function F(t,e,s,r){return new(s||(s=Promise))(function(o,a){function i(t){try{u(r.next(t))}catch(t){a(t)}}function n(t){try{u(r.throw(t))}catch(t){a(t)}}function u(t){var e;t.done?o(t.value):(e=t.value,e instanceof s?e:new s(function(t){t(e)})).then(i,n)}u((r=r.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class StatusCodes{}StatusCodes.CONTINUE=100,StatusCodes.SWITCHING_PROTOCOLS=101,StatusCodes.PROCESSING=102,StatusCodes.OK=200,StatusCodes.CREATED=201,StatusCodes.ACCEPTED=202,StatusCodes.NON_AUTHORITATIVE_INFORMATION=203,StatusCodes.NO_CONTENT=204,StatusCodes.RESET_CONTENT=205,StatusCodes.PARTIAL_CONTENT=206,StatusCodes.MULTI_STATUS=207,StatusCodes.ALREADY_REPORTED=208,StatusCodes.IM_USED=226,StatusCodes.MULTIPLE_CHOICES=300,StatusCodes.MOVED_PERMANENTLY=301,StatusCodes.FOUND=302,StatusCodes.SEE_OTHER=303,StatusCodes.NOT_MODIFIED=304,StatusCodes.USE_PROXY=305,StatusCodes.TEMPORARY_REDIRECT=307,StatusCodes.PERMANENT_REDIRECT=308,StatusCodes.BAD_REQUEST=400,StatusCodes.UNAUTHORIZED=401,StatusCodes.PAYMENT_REQUIRED=402,StatusCodes.FORBIDDEN=403,StatusCodes.NOT_FOUND=404,StatusCodes.METHOD_NOT_ALLOWED=405,StatusCodes.NOT_ACCEPTABLE=406,StatusCodes.PROXY_AUTHENTICATION_REQUIRED=407,StatusCodes.REQUEST_TIMEOUT=408,StatusCodes.CONFLICT=409,StatusCodes.GONE=410,StatusCodes.LENGTH_REQUIRED=411,StatusCodes.PRECONDITION_FAILED=412,StatusCodes.PAYLOAD_TOO_LARGE=413,StatusCodes.REQUEST_URI_TOO_LONG=414,StatusCodes.UNSUPPORTED_MEDIA_TYPE=415,StatusCodes.REQUESTED_RANGE_NOT_SATISFIABLE=416,StatusCodes.EXPECTATION_FAILED=417,StatusCodes.IM_A_TEAPOT=418,StatusCodes.MISDIRECTED_REQUEST=421,StatusCodes.UNPROCESSABLE_ENTITY=422,StatusCodes.LOCKED=423,StatusCodes.FAILED_DEPENDENCY=424,StatusCodes.UPGRADE_REQUIRED=426,StatusCodes.PRECONDITION_REQUIRED=428,StatusCodes.TOO_MANY_REQUESTS=429,StatusCodes.REQUEST_HEADER_FIELDS_TOO_LARGE=431,StatusCodes.CONNECTION_CLOSED_WITHOUT_RESPONSE=444,StatusCodes.UNAVAILABLE_FOR_LEGAL_REASONS=451,StatusCodes.CLIENT_CLOSED_REQUEST=499,StatusCodes.INTERNAL_SERVER_ERROR=500,StatusCodes.NOT_IMPLEMENTED=501,StatusCodes.BAD_GATEWAY=502,StatusCodes.SERVICE_UNAVAILABLE=503,StatusCodes.GATEWAY_TIMEOUT=504,StatusCodes.HTTP_VERSION_NOT_SUPPORTED=505,StatusCodes.VARIANT_ALSO_NEGOCIATES=506,StatusCodes.INSUFFICIENT_STORAGE=507,StatusCodes.LOOP_DETECTED=508,StatusCodes.NOT_EXTENDED=510,StatusCodes.NETWORK_AUTHENTICATION_REQUIRED=511,StatusCodes.NETWORK_CONNECTION_TIMEOUT_ERROR=599;class StatusText{}StatusText[100]="Continue",StatusText[101]="Switching Protocols",StatusText[102]="Processing",StatusText[200]="OK",StatusText[201]="Created",StatusText[202]="Accepted",StatusText[203]="Non-Authoritative Information",StatusText[204]="No Content",StatusText[205]="Reset Content",StatusText[206]="Partial Content",StatusText[207]="Multi-Status",StatusText[226]="IM Used",StatusText[300]="Multiple Choices",StatusText[301]="Moved Permanently",StatusText[302]="Found",StatusText[303]="See Other",StatusText[304]="Not Modified",StatusText[305]="Use Proxy",StatusText[307]="Temporary Redirect",StatusText[308]="Permanent Redirect",StatusText[400]="Bad Request",StatusText[401]="Unauthorized",StatusText[402]="Payment Required",StatusText[403]="Forbidden",StatusText[404]="Not Found",StatusText[405]="Method Not Allowed",StatusText[406]="Not Acceptable",StatusText[407]="Proxy Authentication Required",StatusText[408]="Request Timeout",StatusText[409]="Conflict",StatusText[410]="Gone",StatusText[411]="Length Required",StatusText[412]="Precondition Failed",StatusText[413]="Payload Too Large",StatusText[414]="URI Too Long",StatusText[415]="Unsupported Media Type",StatusText[416]="Range Not Satisfiable",StatusText[417]="Expectation Failed",StatusText[418]="I'm a teapot",StatusText[422]="Unprocessable Entity",StatusText[423]="Locked",StatusText[424]="Failed Dependency",StatusText[426]="Upgrade Required",StatusText[428]="Precondition Required",StatusText[429]="Too Many Requests",StatusText[431]="Request Header Fields Too Large",StatusText[451]="Unavailable For Legal Reasons",StatusText[500]="Internal Server Error",StatusText[501]="Not Implemented",StatusText[502]="Bad Gateway",StatusText[503]="Service Unavailable",StatusText[504]="Gateway Time-out",StatusText[505]="HTTP Version Not Supported",StatusText[506]="Variant Also Negotiates",StatusText[507]="Insufficient Storage",StatusText[511]="Network Authentication Required";class ResponseError extends Error{constructor(t,e=StatusCodes.INTERNAL_SERVER_ERROR){super(t),this.status=e}}class BadRequestError extends ResponseError{constructor(t="Bad Request"){super(t,StatusCodes.BAD_REQUEST)}}class ForbiddenError extends ResponseError{constructor(t="Forbidden"){super(t,StatusCodes.FORBIDDEN)}}class InternalServerError extends ResponseError{constructor(t="Internal server error"){super(t,StatusCodes.INTERNAL_SERVER_ERROR)}}class NotFoundError extends ResponseError{constructor(t="Not Found"){super(t,StatusCodes.NOT_FOUND)}}class UnauthorizedError extends ResponseError{constructor(t="Unauthorized"){super(t,StatusCodes.UNAUTHORIZED)}}class ValidationError extends ResponseError{constructor(t){super(t,StatusCodes.UNPROCESSABLE_ENTITY)}}class HttpResponse{static created(t,e,s){var r,o;const a=StatusCodes.CREATED,i={success:!0,status:a,data:e?{id:e}:{},meta:null!==(r=null==s?void 0:s.meta)&&void 0!==r?r:{},message:null!==(o=null==s?void 0:s.message)&&void 0!==o?o:null};return t.status(a).json(i),i}static noContent(t){t.status(StatusCodes.NO_CONTENT).end()}static ok(t,e,s){var r,o;const a=StatusCodes.OK,i={success:!0,status:a,data:e,meta:null!==(r=null==s?void 0:s.meta)&&void 0!==r?r:{},message:null!==(o=null==s?void 0:s.message)&&void 0!==o?o:null};return t.status(a).json(i),i}static error(t,e,s){var r,o;const{status:a,message:i}=this.normalizeError(s),n=null!==(r=null==StatusText?void 0:StatusText[a])&&void 0!==r?r:"Internal Server Error",u=this.getErrorCode(s),d=this.getErrorName(s),l=Object.assign(Object.assign(Object.assign(Object.assign({success:!1,status:a,statusText:n,message:i,path:null!==(o=t.originalUrl)&&void 0!==o?o:t.url},u?{code:u}:{}),d?{name:d}:{}),{timestamp:(new Date).toISOString()}),this.isDev()&&s instanceof Error&&s.stack?{stack:s.stack}:{});return e.status(a).json(l),l}static getErrorCode(t){return t&&r(t)&&o(t.code)?this.safeMessage(t.code):""}static getErrorName(t){return t instanceof ResponseError?t.constructor.name:this.isDev()?t instanceof Error?t.name||t.constructor.name:r(t)&&o(t.name)?t.name:typeof t:""}static isDev(){return"production"!==process.env.NODE_ENV}static normalizeError(t){let e=StatusCodes.INTERNAL_SERVER_ERROR,s=StatusText[500];if(t instanceof ResponseError)return e=this.safeStatus(t.status),s=this.safeMessage(t.message)||s,{status:e,message:s};if(t instanceof Error){const r=t;return a(r.statusCode)?e=this.safeStatus(r.statusCode):a(r.status)&&(e=this.safeStatus(r.status)),s=this.safeMessage(t.message)||s,{status:e,message:s}}if(o(t))return s=this.safeMessage(t)||s,{status:e,message:s};if(t&&r(t)){const r=t;return a(r.statusCode)?e=this.safeStatus(r.statusCode):a(r.status)&&(e=this.safeStatus(r.status)),o(r.message)&&(s=this.safeMessage(r.message)||s),{status:e,message:s}}return{status:e,message:s}}static safeStatus(t){if(!Number.isFinite(t))return StatusCodes.INTERNAL_SERVER_ERROR;const e=Math.trunc(t);return e<400||e>599?StatusCodes.INTERNAL_SERVER_ERROR:e}static safeMessage(t){if(!o(t))return"";const e=t.trim();return e.length>2e3?e.slice(0,2e3)+"...":e}}class Context{constructor(t,e,s,r,o){this.storage={},this.req=t,this.res=e,this.next=s,this.id=i(),this.app=r,this.controller=o}cache(t){const e=Object.assign({},t),s=[];e.private?s.push("private"):e.public&&s.push("public"),e.noStore&&(e.noCache=!0,s.push("no-store")),e.noCache&&(e.maxAge=0,delete e.sMaxAge,s.push("no-cache")),e.noTransform&&s.push("no-transform"),e.proxyRevalidate&&s.push("proxy-revalidate"),e.mustRevalidate?s.push("must-revalidate"):e.noCache||(a(e.staleIfError)&&s.push(`stale-if-error=${e.staleIfError}`),a(e.staleWhileRevalidate)&&s.push(`stale-while-revalidate=${e.staleWhileRevalidate}`)),a(e.maxAge)&&s.push(`max-age=${e.maxAge}`),a(e.sMaxAge)&&s.push(`s-maxage=${e.sMaxAge}`),s.length&&(this.res.setHeader("Cache-Control",s.join(",")),e.noCache&&n({"Surrogate-Control":"no-store",Pragma:"no-cache",ETag:"false",Expires:"0"},(t,e)=>this.res.setHeader(e,t)))}clearCookie(t,e){this.res.clearCookie(t,e)}close(t){this.isResponded()||this.res.json(null!=t?t:this.storage)}destroy(t){var e;t&&this.error(t),null===(e=this.res.socket)||void 0===e||e.destroy(t)}error(t){this.isResponded()||HttpResponse.error(this.req,this.res,t)}file(t){this.isResponded()||(this.status(StatusCodes.OK),this.res.sendFile(M(t)))}getBody(){var t,e;return null!==(e=null===(t=this.req)||void 0===t?void 0:t.body)&&void 0!==e?e:{}}getBodyValue(t){var e;return null===(e=this.req.body)||void 0===e?void 0:e[t]}getCookie(t){var e;return this.normalize(null===(e=this.req.cookies)||void 0===e?void 0:e[t])}getCookies(){var t,e;return u(null!==(e=null===(t=this.req)||void 0===t?void 0:t.cookies)&&void 0!==e?e:{},t=>this.normalize(t))}getFiles(){var t,e;return null!==(e=null===(t=this.req)||void 0===t?void 0:t.files)&&void 0!==e?e:{}}getFullUrl(){return`${this.getUrl()}${this.req.originalUrl}`}getHeader(t){var e;return this.normalize(null===(e=this.req.headers)||void 0===e?void 0:e[t])}getHeaders(){var t,e;return u(null!==(e=null===(t=this.req)||void 0===t?void 0:t.headers)&&void 0!==e?e:{},t=>this.normalize(t))}getIp(){return L(this.req)||"0.0.0.0"}getQuery(t){var e;return this.normalize(null===(e=this.req.query)||void 0===e?void 0:e[t])}getQueries(){var t,e;return u(null!==(e=null===(t=this.req)||void 0===t?void 0:t.query)&&void 0!==e?e:{},t=>this.normalize(t))}getParam(t){var e;const s=null===(e=this.req.params)||void 0===e?void 0:e[t];return d(s)?void 0:String(s)}getParams(){var t,e;return u(null!==(e=null===(t=this.req)||void 0===t?void 0:t.params)&&void 0!==e?e:{},t=>{if(!d(t)&&!l(t))return String(t)})}getUrl(){let t=this.getHeader("x-forwarded-proto")||this.req.protocol||"http";o(t)&&t.includes(",")&&(t=t.split(",")[0].trim());const e=this.getHeader("cf-visitor");if(e){const s=h(e);(null==s?void 0:s.scheme)&&(t=s.scheme)}return`${t}://${this.getHeader("host")}`}isResponded(){return this.res.headersSent||this.res.writableEnded}json(t){this.send(StatusCodes.OK,t)}normalize(t){if(!d(t)&&!l(t))return r(t)?JSON.stringify(t):String(t)}ok(t,e){this.isResponded()||HttpResponse.ok(this.res,t,e)}prepare(t,e){this.isResponded()||(this.status(t),this.storage=e)}redirect(t){this.isResponded()||this.res.redirect(t)}send(t,e){this.isResponded()||(this.status(t),204===t||304===t||d(e)?this.res.end():this.res.json(e))}setCookie(t,e,s){this.res.cookie(t,e,null!=s?s:{})}status(t){return d(t)||this.res.status(t),this.res.statusCode}success(t){this.send(StatusCodes.OK,{message:t})}}class Metadata{static extends(e){return t(Metadata.EXTENDS,e,[])}static middleware(e){return t(Metadata.MIDDLEWARE,e,[])}static parameters(e){return t(Metadata.PARAMETERS,e,[])}static path(e,s){return t(Metadata.PATH,e,s)}static routers(e){return t(Metadata.ROUTERS,e,[])}}Metadata.EXTENDS=Symbol("EXTENDS"),Metadata.MIDDLEWARE=Symbol("MIDDLEWARE"),Metadata.PARAMETERS=Symbol("PARAMETERS"),Metadata.PATH=Symbol("PATH"),Metadata.ROUTERS=Symbol("ROUTERS");class Application extends c{get controllers(){return[...this._controllers]}get instance(){return this._app}get router(){return this._globalRouter}get server(){return this._server}constructor(t,s){var o,a;super(),this._app=g(),this._boundServers=[],this._options={},this._baseRouter=O(),this._globalRouter=O(),this._controllers=[],this._controllers.push(...t.map(t=>p(t)?new t(...e(t)):t)),this._options=E({},{cross:!1,path:"/",port:3e3,session:{secret:"yoursecret",resave:!0,saveUninitialized:!1,cookie:{maxAge:864e5},proxy:Boolean(null==s?void 0:s.proxy)}},null!=s?s:{}),this._app.use(N(this._options.json)),this._app.disable("x-powered-by"),this._options.proxy&&this._app.set("trust proxy",this._options.proxy),this._app.use(x({extended:!0})),this._options.cross&&this._app.use(C(r(this._options.cross)?this._options.cross:{})),this._app.use(R(this._options.compression)),this._app.use(m(null===(o=this._options.cookie)||void 0===o?void 0:o.secret,this._options.cookie)),this._app.use(f(this._options.session)),this.init(),this._app.use(this._globalRouter);const i=(null===(a=this._options.path)||void 0===a?void 0:a.length)?this._options.path:"/";if(this._app.use(i,this._baseRouter),this._app.all(i+"/*path",(t,e)=>{this._options.redirect?e.redirect(this._options.redirect):HttpResponse.error(t,e,new NotFoundError("Endpoint Not Found"))}),this._options.public){const t=M(this._options.public);A(t)&&this._app.use(g.static(t)),this._app.get("*path",(e,s)=>{A(t)?s.sendFile(t+"/index.html"):this._options.notFound?s.redirect(this._options.notFound):HttpResponse.error(e,s,new NotFoundError("File not found"))})}else this._app.all("*path",(t,e)=>{this._options.redirect?e.redirect(this._options.redirect):HttpResponse.error(t,e,new NotFoundError("Endpoint not found"))});this._controllers.forEach(t=>{const e=O(),s=this._collectMiddlewares(t),o=Metadata.parameters(t);this._collectExtends(t).forEach(t=>{s.push(...this._collectMiddlewares(t)),o.push(...Metadata.parameters(t))}),Metadata.routers(t).forEach(a=>{const i=a.propertyKey.toString();if(S(t[i])){if(!S(e[a.method]))return this._logRouteNotFound(a.method);const n=this._buildMiddlewareChain(t,i,s,o);return e[a.method](a.path,...n,(e,s,a)=>F(this,void 0,void 0,function*(){const n=new Context(e,s,a,this,t),u=this._resolveArgs(n,this._filterParamsByKey(i,o)),d=yield t[i](...u);n.close(_(d)||r(d)?d:void 0)}))}this._logRouteNotFound(`${t.name}.${i}`)}),this._collectExtends(t).forEach(a=>{Metadata.routers(a).forEach(a=>{const i=a.propertyKey.toString();if(S(t[i])){if(!S(e[a.method]))return this._logRouteNotFound(a.method);const n=this._buildMiddlewareChain(t,i,s,o);return e[a.method](a.path,...n,(e,s,a)=>F(this,void 0,void 0,function*(){const n=new Context(e,s,a,this,t),u=this._resolveArgs(n,this._filterParamsByKey(i,o)),d=yield t[i](...u);n.close(_(d)||r(d)?d:void 0)}))}this._logRouteNotFound(`${t.constructor.name}.${i}`)})}),this._baseRouter.use(Metadata.path(t,"/"),e)}),this._app.use((t,e,s,r)=>{s.headersSent?r(t):HttpResponse.error(e,s,t)})}init(){}error(t,e){s.error(t)}log(t,e){s.info(t)}_resolveArgs(t,e,s){const r=[],o={ctx:t,key:"",app:this,argument:s};return e.forEach(t=>{r[t.parameterIndex]=t.callback(Object.assign(Object.assign({},o),{key:t.key}))}),r}_buildMiddlewareChain(t,e,s,o){return s.filter(t=>t.propertyKey==e).map(e=>{if(e.callback!=T){const s=this._filterParamsByKey(e.method,o);return(o,a,i)=>F(this,void 0,void 0,function*(){const n=new Context(o,a,i,this,t),u=S(e.argument)?e.argument(n):e.argument,d=yield e.callback.call(t,...this._resolveArgs(n,s,u));(_(d)||r(d))&&n.close(d)})}this._logRouteNotFound(e.method)}).filter(S)}_collectExtends(t){return Metadata.extends(t).reduce((t,e)=>(t.push(e,...this._collectExtends(e)),t),[]).filter((t,e,s)=>s.indexOf(t)===e)}_filterParamsByKey(t,e){return e.filter(e=>e.propertyKey==t)}_collectMiddlewares(t){return[...Metadata.middleware(t)].reverse()}_logRouteNotFound(t){this.error(new Error(`Router "${t}" not found`),"express")}_formatListeningMessage(t){return`Server listening on port ${t}`}listen(){return F(this,void 0,void 0,function*(){var t;const e=this._resolveMode(),s={http:this._startHttp,https:this._startHttps,hybrid:this._startHybrid,redirect:this._startHttpsWithRedirect};yield(null!==(t=s[e])&&void 0!==t?t:this._startHttp).call(this)})}close(){return F(this,void 0,void 0,function*(){yield Promise.all(this._boundServers.map(t=>new Promise((e,s)=>{t.close(t=>t?s(t):e())}))),this._boundServers.length=0,this._server=void 0})}_resolveMode(){return this._resolveTls()&&this._options.mode?this._options.mode:"http"}_resolveTls(){if(this._options.tls&&this._options.tls.key&&this._options.tls.cert)return this._options.tls}_bindServer(t,e,s){return new Promise((r,o)=>{const a=e=>{t.off("listening",i),o(e)},i=()=>{t.off("error",a),this.log(this._formatListeningMessage(e),"express"),r()};t.once("error",a),t.once("listening",i),t.listen(e,s)})}_startHttp(){return F(this,void 0,void 0,function*(){var t;const e=I.createServer(this._app);this._server=e,this._boundServers.push(e),yield this._bindServer(e,null!==(t=this._options.port)&&void 0!==t?t:3e3,this._options.host)})}_startHttps(){return F(this,void 0,void 0,function*(){var t;const e=y.createServer(this._resolveTls(),this._app);this._server=e,this._boundServers.push(e),yield this._bindServer(e,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host)})}_startHttpsWithRedirect(){return F(this,void 0,void 0,function*(){var t,e;const s=y.createServer(this._resolveTls(),this._app),r=I.createServer((t,e)=>{var s,r;const o=(null!==(s=t.headers.host)&&void 0!==s?s:"").split(":")[0];e.writeHead(StatusCodes.MOVED_PERMANENTLY,{Location:`https://${o}${null!==(r=t.url)&&void 0!==r?r:""}`}),e.end()});this._server=s,this._boundServers.push(s,r),yield Promise.all([this._bindServer(s,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host),this._bindServer(r,null!==(e=this._options.redirectPort)&&void 0!==e?e:80,this._options.host)])})}_startHybrid(){return F(this,void 0,void 0,function*(){var t;const e=I.createServer(this._app),s=y.createServer(this._resolveTls(),this._app),r=D.createServer(t=>{const r=setTimeout(()=>t.destroy(),5e3);t.once("data",o=>{clearTimeout(r),t.pause(),t.unshift(o),(22===o[0]?s:e).emit("connection",t),process.nextTick(()=>t.resume())}),t.once("error",()=>clearTimeout(r))});return this._server=s,this._boundServers.push(r,s,e),yield this._bindServer(r,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host),s})}}const H=t=>e=>{Metadata.path(e,(null==t?void 0:t.length)?t:"/")},k=t=>e=>{Metadata.extends(e).push(t)},w=t=>e=>(s,r,o)=>{Metadata.parameters(s).push({callback:t,key:e,propertyKey:r,parameterIndex:o})},q=w(({app:t})=>t),B=w(({argument:t})=>t),V=w(({ctx:t,key:e})=>e?t.getBodyValue(e):t.getBody()),G=w(({ctx:t,key:e})=>e?t.getCookie(e):t.getCookies()),K=w(({ctx:t})=>t),Q=w(({ctx:t})=>t.getFiles()),j=w(({ctx:t,key:e})=>e?t.getHeader(e):t.getHeaders()),$=w(({ctx:t,key:e})=>e?t.getParam(e):t.getParams()),X=w(({ctx:t,key:e})=>e?t.getQuery(e):t.getQueries()),Y=w(({ctx:t})=>{var e;return null===(e=t.req)||void 0===e?void 0:e.session}),z=(t,e)=>(s,r)=>{const o=i();K()(s,o,0),Metadata.middleware(s).push({method:o,argument:e,propertyKey:r,callback:t})},W=t=>(e,s,r)=>{z(e=>{e.cache(Object.assign({},t)),e.next()})(e,s,r)},Z={ALL:"all",GET:"get",POST:"post",PUT:"put",HEAD:"head",DELETE:"delete",OPTIONS:"options",PATCH:"patch"},J=t=>e=>(s,r)=>{Metadata.routers(s).push({method:t,path:(null==e?void 0:e.length)?e:"/",propertyKey:r})},tt=J(Z.ALL),et=J(Z.DELETE),st=J(Z.GET),rt=J(Z.HEAD),ot=J(Z.OPTIONS),at=J(Z.PATCH),it=J(Z.POST),nt=J(Z.PUT),ut=(t,e)=>(s,r)=>{let a=T;if(o(r)){const e=s;S(e[t])&&(a=e[t])}Metadata.middleware(s).push({method:t,argument:e,propertyKey:r,callback:a})},dt=(t,e=StatusCodes.BAD_REQUEST)=>{const s=new Error(t);return s.status=e,s},lt=t=>{var e;return(null===(e=t.split(".").pop())||void 0===e?void 0:e.toLowerCase())||"bin"},ht=(t,e)=>{var s;return null!==(s=t[e])&&void 0!==s?s:null},ct=(t,e)=>{const s=i()+"."+e;return A(P(t,s))?ct(t,e):s},pt=t=>{const e=E({},t),s=b({destination(t,s,r){var o;const a=ht(e,s.fieldname);r(null,null!==(o=null==a?void 0:a.path)&&void 0!==o?o:"./")},filename(t,s,r){var o;const a=ht(e,s.fieldname);r(null,ct(null!==(o=null==a?void 0:a.path)&&void 0!==o?o:"./",lt(s.originalname)))}}),r=Math.max(...Object.values(e).map(t=>{var e;return null!==(e=t.size)&&void 0!==e?e:0})),o=U({storage:s,fileFilter(t,s,r){var o;const a=ht(e,s.fieldname);return a?((t,e)=>!e.length||e.includes(lt(t.originalname))||e.includes(t.mimetype.toLowerCase()))(s,null!==(o=null==a?void 0:a.types)&&void 0!==o?o:[])?void r(null,!0):r(dt(`FILE TYPE NOT ALLOWED FOR "${s.fieldname}"`)):r(dt(`UPLOAD FIELD "${s.fieldname}" IS NOT CONFIGURED`))},limits:{fileSize:1024*r*1024}}).fields(Object.keys(e).map(t=>{var s,r;return{name:t,maxCount:null!==(r=null===(s=e[t])||void 0===s?void 0:s.count)&&void 0!==r?r:1}}));return(t,e,s)=>{z(t=>{o(t.req,t.res,e=>{if(!e)return t.next();t.error((t=>"LIMIT_FILE_SIZE"==t.code?(t.message=t.field?`FILE "${t.field}" EXCEEDS MAX SIZE`:"FILE EXCEEDS MAX SIZE",t.status=StatusCodes.PAYLOAD_TOO_LARGE,t):"LIMIT_UNEXPECTED_FILE"==t.code?(t.message=t.field?`FIELD "${t.field}" IS UNEXPECTED OR EXCEEDS MAX COUNT`:"UPLOAD FIELD IS UNEXPECTED OR EXCEEDS MAX COUNT",t.status=StatusCodes.BAD_REQUEST,t):t)(e))})})(t,e,s)}},Et=t=>{const e=v.object(S(t)?t(v):t).parse();return(t,s,r)=>{z(t=>F(void 0,void 0,void 0,function*(){var s,r;const{error:o,message:a,value:i}=yield e.validateAsync(null!==(r=null===(s=t.req)||void 0===s?void 0:s.body)&&void 0!==r?r:{});if(o)return t.error(new ValidationError(null!=a?a:o));t.req.body=i,t.next()}))(t,s,r)}};export{tt as All,q as App,Application,B as Argument,BadRequestError,V as Body,W as Cache,Context,H as Controller,G as Cookies,K as Ctx,et as Delete,k as Extends,Q as Files,ForbiddenError,st as Get,rt as Head,j as Headers,HttpResponse,InternalServerError,Metadata,Z as Methods,ut as Middleware,NotFoundError,ot as Options,$ as Params,at as Patch,it as Post,nt as Put,X as Query,ResponseError,Y as Session,StatusCodes,StatusText,UnauthorizedError,pt as Upload,z as Use,Et as Validate,ValidationError,J as methodFactory,w as parameterFactory};
|
|
7
|
+
import{metadata as t,getInjectionArgs as e}from"@andrewcaires/decorator";import{Log as s}from"@andrewcaires/node";import{isObject as r,isString as o,isNumber as a,uuidv7 as i,forEachKey as n,map as u,isUndefined as d,isNull as l,parseJson as h,EventEmitter as c,isConstructor as p,merge as E,isFunction as S,noop as T,isArray as _,Validation as v}from"@andrewcaires/utils.js";import R from"compression";import m from"cookie-parser";import C from"cors";import g,{Router as O,json as N,urlencoded as x}from"express";import f from"express-session";import{existsSync as A}from"fs";import*as I from"http";import*as y from"https";import*as D from"net";import{resolve as M,join as P}from"path";import{getClientIp as L}from"request-ip";import U,{diskStorage as b}from"multer";function F(t,e,s,r){return new(s||(s=Promise))(function(o,a){function i(t){try{u(r.next(t))}catch(t){a(t)}}function n(t){try{u(r.throw(t))}catch(t){a(t)}}function u(t){var e;t.done?o(t.value):(e=t.value,e instanceof s?e:new s(function(t){t(e)})).then(i,n)}u((r=r.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class StatusCodes{}StatusCodes.CONTINUE=100,StatusCodes.SWITCHING_PROTOCOLS=101,StatusCodes.PROCESSING=102,StatusCodes.OK=200,StatusCodes.CREATED=201,StatusCodes.ACCEPTED=202,StatusCodes.NON_AUTHORITATIVE_INFORMATION=203,StatusCodes.NO_CONTENT=204,StatusCodes.RESET_CONTENT=205,StatusCodes.PARTIAL_CONTENT=206,StatusCodes.MULTI_STATUS=207,StatusCodes.ALREADY_REPORTED=208,StatusCodes.IM_USED=226,StatusCodes.MULTIPLE_CHOICES=300,StatusCodes.MOVED_PERMANENTLY=301,StatusCodes.FOUND=302,StatusCodes.SEE_OTHER=303,StatusCodes.NOT_MODIFIED=304,StatusCodes.USE_PROXY=305,StatusCodes.TEMPORARY_REDIRECT=307,StatusCodes.PERMANENT_REDIRECT=308,StatusCodes.BAD_REQUEST=400,StatusCodes.UNAUTHORIZED=401,StatusCodes.PAYMENT_REQUIRED=402,StatusCodes.FORBIDDEN=403,StatusCodes.NOT_FOUND=404,StatusCodes.METHOD_NOT_ALLOWED=405,StatusCodes.NOT_ACCEPTABLE=406,StatusCodes.PROXY_AUTHENTICATION_REQUIRED=407,StatusCodes.REQUEST_TIMEOUT=408,StatusCodes.CONFLICT=409,StatusCodes.GONE=410,StatusCodes.LENGTH_REQUIRED=411,StatusCodes.PRECONDITION_FAILED=412,StatusCodes.PAYLOAD_TOO_LARGE=413,StatusCodes.REQUEST_URI_TOO_LONG=414,StatusCodes.UNSUPPORTED_MEDIA_TYPE=415,StatusCodes.REQUESTED_RANGE_NOT_SATISFIABLE=416,StatusCodes.EXPECTATION_FAILED=417,StatusCodes.IM_A_TEAPOT=418,StatusCodes.MISDIRECTED_REQUEST=421,StatusCodes.UNPROCESSABLE_ENTITY=422,StatusCodes.LOCKED=423,StatusCodes.FAILED_DEPENDENCY=424,StatusCodes.UPGRADE_REQUIRED=426,StatusCodes.PRECONDITION_REQUIRED=428,StatusCodes.TOO_MANY_REQUESTS=429,StatusCodes.REQUEST_HEADER_FIELDS_TOO_LARGE=431,StatusCodes.CONNECTION_CLOSED_WITHOUT_RESPONSE=444,StatusCodes.UNAVAILABLE_FOR_LEGAL_REASONS=451,StatusCodes.CLIENT_CLOSED_REQUEST=499,StatusCodes.INTERNAL_SERVER_ERROR=500,StatusCodes.NOT_IMPLEMENTED=501,StatusCodes.BAD_GATEWAY=502,StatusCodes.SERVICE_UNAVAILABLE=503,StatusCodes.GATEWAY_TIMEOUT=504,StatusCodes.HTTP_VERSION_NOT_SUPPORTED=505,StatusCodes.VARIANT_ALSO_NEGOCIATES=506,StatusCodes.INSUFFICIENT_STORAGE=507,StatusCodes.LOOP_DETECTED=508,StatusCodes.NOT_EXTENDED=510,StatusCodes.NETWORK_AUTHENTICATION_REQUIRED=511,StatusCodes.NETWORK_CONNECTION_TIMEOUT_ERROR=599;class StatusText{}StatusText[100]="Continue",StatusText[101]="Switching Protocols",StatusText[102]="Processing",StatusText[200]="OK",StatusText[201]="Created",StatusText[202]="Accepted",StatusText[203]="Non-Authoritative Information",StatusText[204]="No Content",StatusText[205]="Reset Content",StatusText[206]="Partial Content",StatusText[207]="Multi-Status",StatusText[226]="IM Used",StatusText[300]="Multiple Choices",StatusText[301]="Moved Permanently",StatusText[302]="Found",StatusText[303]="See Other",StatusText[304]="Not Modified",StatusText[305]="Use Proxy",StatusText[307]="Temporary Redirect",StatusText[308]="Permanent Redirect",StatusText[400]="Bad Request",StatusText[401]="Unauthorized",StatusText[402]="Payment Required",StatusText[403]="Forbidden",StatusText[404]="Not Found",StatusText[405]="Method Not Allowed",StatusText[406]="Not Acceptable",StatusText[407]="Proxy Authentication Required",StatusText[408]="Request Timeout",StatusText[409]="Conflict",StatusText[410]="Gone",StatusText[411]="Length Required",StatusText[412]="Precondition Failed",StatusText[413]="Payload Too Large",StatusText[414]="URI Too Long",StatusText[415]="Unsupported Media Type",StatusText[416]="Range Not Satisfiable",StatusText[417]="Expectation Failed",StatusText[418]="I'm a teapot",StatusText[422]="Unprocessable Entity",StatusText[423]="Locked",StatusText[424]="Failed Dependency",StatusText[426]="Upgrade Required",StatusText[428]="Precondition Required",StatusText[429]="Too Many Requests",StatusText[431]="Request Header Fields Too Large",StatusText[451]="Unavailable For Legal Reasons",StatusText[500]="Internal Server Error",StatusText[501]="Not Implemented",StatusText[502]="Bad Gateway",StatusText[503]="Service Unavailable",StatusText[504]="Gateway Time-out",StatusText[505]="HTTP Version Not Supported",StatusText[506]="Variant Also Negotiates",StatusText[507]="Insufficient Storage",StatusText[511]="Network Authentication Required";class ResponseError extends Error{constructor(t,e=StatusCodes.INTERNAL_SERVER_ERROR){super(t),this.status=e,this.name=this.constructor.name}}class BadRequestError extends ResponseError{constructor(t="Bad Request"){super(t,StatusCodes.BAD_REQUEST)}}class ForbiddenError extends ResponseError{constructor(t="Forbidden"){super(t,StatusCodes.FORBIDDEN)}}class InternalServerError extends ResponseError{constructor(t="Internal server error"){super(t,StatusCodes.INTERNAL_SERVER_ERROR)}}class NotFoundError extends ResponseError{constructor(t="Not Found"){super(t,StatusCodes.NOT_FOUND)}}class UnauthorizedError extends ResponseError{constructor(t="Unauthorized"){super(t,StatusCodes.UNAUTHORIZED)}}class ValidationError extends ResponseError{constructor(t){super(t,StatusCodes.UNPROCESSABLE_ENTITY)}}class HttpResponse{static created(t,e,s){var r,o;const a=StatusCodes.CREATED,i={success:!0,status:a,data:e?{id:e}:{},meta:null!==(r=null==s?void 0:s.meta)&&void 0!==r?r:{},message:null!==(o=null==s?void 0:s.message)&&void 0!==o?o:null};return t.status(a).json(i),i}static noContent(t){t.status(StatusCodes.NO_CONTENT).end()}static ok(t,e,s){var r,o;const a=StatusCodes.OK,i={success:!0,status:a,data:e,meta:null!==(r=null==s?void 0:s.meta)&&void 0!==r?r:{},message:null!==(o=null==s?void 0:s.message)&&void 0!==o?o:null};return t.status(a).json(i),i}static error(t,e,s){var r,o;const{status:a,message:i}=this.normalizeError(s),n=null!==(r=null==StatusText?void 0:StatusText[a])&&void 0!==r?r:"Internal Server Error",u=this.getErrorCode(s),d=this.getErrorName(s),l=Object.assign(Object.assign(Object.assign(Object.assign({success:!1,status:a,statusText:n,message:i,path:null!==(o=t.originalUrl)&&void 0!==o?o:t.url},u?{code:u}:{}),d?{name:d}:{}),{timestamp:(new Date).toISOString()}),this.isDev()&&s instanceof Error&&s.stack?{stack:s.stack}:{});return e.status(a).json(l),l}static getErrorCode(t){return t&&r(t)&&o(t.code)?this.safeMessage(t.code):""}static getErrorName(t){return t instanceof ResponseError?t.constructor.name:this.isDev()?t instanceof Error?t.name||t.constructor.name:r(t)&&o(t.name)?t.name:typeof t:""}static isDev(){return"production"!==process.env.NODE_ENV}static normalizeError(t){let e=StatusCodes.INTERNAL_SERVER_ERROR,s=StatusText[500];if(t instanceof ResponseError)return e=this.safeStatus(t.status),s=this.safeMessage(t.message)||s,{status:e,message:s};if(t instanceof Error){const r=t;return a(r.statusCode)?e=this.safeStatus(r.statusCode):a(r.status)&&(e=this.safeStatus(r.status)),s=this.safeMessage(t.message)||s,{status:e,message:s}}if(o(t))return s=this.safeMessage(t)||s,{status:e,message:s};if(t&&r(t)){const r=t;return a(r.statusCode)?e=this.safeStatus(r.statusCode):a(r.status)&&(e=this.safeStatus(r.status)),o(r.message)&&(s=this.safeMessage(r.message)||s),{status:e,message:s}}return{status:e,message:s}}static safeStatus(t){if(!Number.isFinite(t))return StatusCodes.INTERNAL_SERVER_ERROR;const e=Math.trunc(t);return e<400||e>599?StatusCodes.INTERNAL_SERVER_ERROR:e}static safeMessage(t){if(!o(t))return"";const e=t.trim();return e.length>2e3?e.slice(0,2e3)+"...":e}}class Context{constructor(t,e,s,r,o){this.storage={},this.req=t,this.res=e,this.next=s,this.id=i(),this.app=r,this.controller=o}cache(t){const e=Object.assign({},t),s=[];e.private?s.push("private"):e.public&&s.push("public"),e.noStore&&(e.noCache=!0,s.push("no-store")),e.noCache&&(e.maxAge=0,delete e.sMaxAge,s.push("no-cache")),e.noTransform&&s.push("no-transform"),e.proxyRevalidate&&s.push("proxy-revalidate"),e.mustRevalidate?s.push("must-revalidate"):e.noCache||(a(e.staleIfError)&&s.push(`stale-if-error=${e.staleIfError}`),a(e.staleWhileRevalidate)&&s.push(`stale-while-revalidate=${e.staleWhileRevalidate}`)),a(e.maxAge)&&s.push(`max-age=${e.maxAge}`),a(e.sMaxAge)&&s.push(`s-maxage=${e.sMaxAge}`),s.length&&(this.res.setHeader("Cache-Control",s.join(",")),e.noCache&&n({"Surrogate-Control":"no-store",Pragma:"no-cache",ETag:"false",Expires:"0"},(t,e)=>this.res.setHeader(e,t)))}clearCookie(t,e){this.res.clearCookie(t,e)}close(t){this.isResponded()||this.res.json(null!=t?t:this.storage)}destroy(t){var e;t&&this.error(t),null===(e=this.res.socket)||void 0===e||e.destroy(t)}error(t){this.isResponded()||HttpResponse.error(this.req,this.res,t)}file(t){this.isResponded()||(this.status(StatusCodes.OK),this.res.sendFile(M(t)))}getBody(){var t,e;return null!==(e=null===(t=this.req)||void 0===t?void 0:t.body)&&void 0!==e?e:{}}getBodyValue(t){var e;return null===(e=this.req.body)||void 0===e?void 0:e[t]}getCookie(t){var e;return this.normalize(null===(e=this.req.cookies)||void 0===e?void 0:e[t])}getCookies(){var t,e;return u(null!==(e=null===(t=this.req)||void 0===t?void 0:t.cookies)&&void 0!==e?e:{},t=>this.normalize(t))}getFiles(){var t,e;return null!==(e=null===(t=this.req)||void 0===t?void 0:t.files)&&void 0!==e?e:{}}getFullUrl(){return`${this.getUrl()}${this.req.originalUrl}`}getHeader(t){var e;return this.normalize(null===(e=this.req.headers)||void 0===e?void 0:e[t])}getHeaders(){var t,e;return u(null!==(e=null===(t=this.req)||void 0===t?void 0:t.headers)&&void 0!==e?e:{},t=>this.normalize(t))}getIp(){return L(this.req)||"0.0.0.0"}getQuery(t){var e;return this.normalize(null===(e=this.req.query)||void 0===e?void 0:e[t])}getQueries(){var t,e;return u(null!==(e=null===(t=this.req)||void 0===t?void 0:t.query)&&void 0!==e?e:{},t=>this.normalize(t))}getParam(t){var e;const s=null===(e=this.req.params)||void 0===e?void 0:e[t];return d(s)?void 0:String(s)}getParams(){var t,e;return u(null!==(e=null===(t=this.req)||void 0===t?void 0:t.params)&&void 0!==e?e:{},t=>{if(!d(t)&&!l(t))return String(t)})}getUrl(){let t=this.getHeader("x-forwarded-proto")||this.req.protocol||"http";o(t)&&t.includes(",")&&(t=t.split(",")[0].trim());const e=this.getHeader("cf-visitor");if(e){const s=h(e);(null==s?void 0:s.scheme)&&(t=s.scheme)}return`${t}://${this.getHeader("host")}`}isResponded(){return this.res.headersSent||this.res.writableEnded}json(t){this.send(StatusCodes.OK,t)}normalize(t){if(!d(t)&&!l(t))return r(t)?JSON.stringify(t):String(t)}ok(t,e){this.isResponded()||HttpResponse.ok(this.res,t,e)}prepare(t,e){this.isResponded()||(this.status(t),this.storage=e)}redirect(t){this.isResponded()||this.res.redirect(t)}send(t,e){this.isResponded()||(this.status(t),204===t||304===t||d(e)?this.res.end():this.res.json(e))}setCookie(t,e,s){this.res.cookie(t,e,null!=s?s:{})}status(t){return d(t)||this.res.status(t),this.res.statusCode}success(t){this.send(StatusCodes.OK,{message:t})}}class Metadata{static extends(e){return t(Metadata.EXTENDS,e,[])}static middleware(e){return t(Metadata.MIDDLEWARE,e,[])}static parameters(e){return t(Metadata.PARAMETERS,e,[])}static path(e,s){return t(Metadata.PATH,e,s)}static routers(e){return t(Metadata.ROUTERS,e,[])}}Metadata.EXTENDS=Symbol("EXTENDS"),Metadata.MIDDLEWARE=Symbol("MIDDLEWARE"),Metadata.PARAMETERS=Symbol("PARAMETERS"),Metadata.PATH=Symbol("PATH"),Metadata.ROUTERS=Symbol("ROUTERS");class Application extends c{get controllers(){return[...this._controllers]}get instance(){return this._app}get router(){return this._globalRouter}get server(){return this._server}constructor(t,s){var o,a;super(),this._app=g(),this._boundServers=[],this._options={},this._baseRouter=O(),this._globalRouter=O(),this._controllers=[],this._controllers.push(...t.map(t=>p(t)?new t(...e(t)):t)),this._options=E({},{cross:!1,path:"/",port:3e3,session:{secret:"yoursecret",resave:!0,saveUninitialized:!1,cookie:{maxAge:864e5},proxy:Boolean(null==s?void 0:s.proxy)}},null!=s?s:{}),this._app.use(N(this._options.json)),this._app.disable("x-powered-by"),this._options.proxy&&this._app.set("trust proxy",this._options.proxy),this._app.use(x({extended:!0})),this._options.cross&&this._app.use(C(r(this._options.cross)?this._options.cross:{})),this._app.use(R(this._options.compression)),this._app.use(m(null===(o=this._options.cookie)||void 0===o?void 0:o.secret,this._options.cookie)),this._app.use(f(this._options.session)),this.init(),this._app.use(this._globalRouter);const i=(null===(a=this._options.path)||void 0===a?void 0:a.length)?this._options.path:"/";if(this._app.use(i,this._baseRouter),this._app.all(i+"/*path",(t,e)=>{this._options.redirect?e.redirect(this._options.redirect):HttpResponse.error(t,e,new NotFoundError("Endpoint Not Found"))}),this._options.public){const t=M(this._options.public);A(t)&&this._app.use(g.static(t)),this._app.get("*path",(e,s)=>{A(t)?s.sendFile(t+"/index.html"):this._options.notFound?s.redirect(this._options.notFound):HttpResponse.error(e,s,new NotFoundError("File not found"))})}else this._app.all("*path",(t,e)=>{this._options.redirect?e.redirect(this._options.redirect):HttpResponse.error(t,e,new NotFoundError("Endpoint not found"))});this._controllers.forEach(t=>{const e=O(),s=this._collectMiddlewares(t),o=Metadata.parameters(t);this._collectExtends(t).forEach(t=>{s.push(...this._collectMiddlewares(t)),o.push(...Metadata.parameters(t))}),Metadata.routers(t).forEach(a=>{const i=a.propertyKey.toString();if(S(t[i])){if(!S(e[a.method]))return this._logRouteNotFound(a.method);const n=this._buildMiddlewareChain(t,i,s,o);return e[a.method](a.path,...n,(e,s,a)=>F(this,void 0,void 0,function*(){const n=new Context(e,s,a,this,t),u=this._resolveArgs(n,this._filterParamsByKey(i,o)),d=yield t[i](...u);n.close(_(d)||r(d)?d:void 0)}))}this._logRouteNotFound(`${t.name}.${i}`)}),this._collectExtends(t).forEach(a=>{Metadata.routers(a).forEach(a=>{const i=a.propertyKey.toString();if(S(t[i])){if(!S(e[a.method]))return this._logRouteNotFound(a.method);const n=this._buildMiddlewareChain(t,i,s,o);return e[a.method](a.path,...n,(e,s,a)=>F(this,void 0,void 0,function*(){const n=new Context(e,s,a,this,t),u=this._resolveArgs(n,this._filterParamsByKey(i,o)),d=yield t[i](...u);n.close(_(d)||r(d)?d:void 0)}))}this._logRouteNotFound(`${t.constructor.name}.${i}`)})}),this._baseRouter.use(Metadata.path(t,"/"),e)}),this._app.use((t,e,s,r)=>{s.headersSent?r(t):HttpResponse.error(e,s,t)})}init(){}error(t,e){s.error(t)}log(t,e){s.info(t)}_resolveArgs(t,e,s){const r=[],o={ctx:t,key:"",app:this,argument:s};return e.forEach(t=>{r[t.parameterIndex]=t.callback(Object.assign(Object.assign({},o),{key:t.key}))}),r}_buildMiddlewareChain(t,e,s,o){return s.filter(t=>t.propertyKey==e).map(e=>{if(e.callback!=T){const s=this._filterParamsByKey(e.method,o);return(o,a,i)=>F(this,void 0,void 0,function*(){const n=new Context(o,a,i,this,t),u=S(e.argument)?e.argument(n):e.argument,d=yield e.callback.call(t,...this._resolveArgs(n,s,u));(_(d)||r(d))&&n.close(d)})}this._logRouteNotFound(e.method)}).filter(S)}_collectExtends(t){return Metadata.extends(t).reduce((t,e)=>(t.push(e,...this._collectExtends(e)),t),[]).filter((t,e,s)=>s.indexOf(t)===e)}_filterParamsByKey(t,e){return e.filter(e=>e.propertyKey==t)}_collectMiddlewares(t){return[...Metadata.middleware(t)].reverse()}_logRouteNotFound(t){this.error(new Error(`Router "${t}" not found`),"express")}_formatListeningMessage(t){return`Server listening on port ${t}`}listen(){return F(this,void 0,void 0,function*(){var t;const e=this._resolveMode(),s={http:this._startHttp,https:this._startHttps,hybrid:this._startHybrid,redirect:this._startHttpsWithRedirect};yield(null!==(t=s[e])&&void 0!==t?t:this._startHttp).call(this)})}close(){return F(this,void 0,void 0,function*(){yield Promise.all(this._boundServers.map(t=>new Promise((e,s)=>{t.close(t=>t?s(t):e())}))),this._boundServers.length=0,this._server=void 0})}_resolveMode(){return this._resolveTls()&&this._options.mode?this._options.mode:"http"}_resolveTls(){if(this._options.tls&&this._options.tls.key&&this._options.tls.cert)return this._options.tls}_bindServer(t,e,s){return new Promise((r,o)=>{const a=e=>{t.off("listening",i),o(e)},i=()=>{t.off("error",a),this.log(this._formatListeningMessage(e),"express"),r()};t.once("error",a),t.once("listening",i),t.listen(e,s)})}_startHttp(){return F(this,void 0,void 0,function*(){var t;const e=I.createServer(this._app);this._server=e,this._boundServers.push(e),yield this._bindServer(e,null!==(t=this._options.port)&&void 0!==t?t:3e3,this._options.host)})}_startHttps(){return F(this,void 0,void 0,function*(){var t;const e=y.createServer(this._resolveTls(),this._app);this._server=e,this._boundServers.push(e),yield this._bindServer(e,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host)})}_startHttpsWithRedirect(){return F(this,void 0,void 0,function*(){var t,e;const s=y.createServer(this._resolveTls(),this._app),r=I.createServer((t,e)=>{var s,r;const o=(null!==(s=t.headers.host)&&void 0!==s?s:"").split(":")[0];e.writeHead(StatusCodes.MOVED_PERMANENTLY,{Location:`https://${o}${null!==(r=t.url)&&void 0!==r?r:""}`}),e.end()});this._server=s,this._boundServers.push(s,r),yield Promise.all([this._bindServer(s,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host),this._bindServer(r,null!==(e=this._options.redirectPort)&&void 0!==e?e:80,this._options.host)])})}_startHybrid(){return F(this,void 0,void 0,function*(){var t;const e=I.createServer(this._app),s=y.createServer(this._resolveTls(),this._app),r=D.createServer(t=>{const r=setTimeout(()=>t.destroy(),5e3);t.once("data",o=>{clearTimeout(r),t.pause(),t.unshift(o),(22===o[0]?s:e).emit("connection",t),process.nextTick(()=>t.resume())}),t.once("error",()=>clearTimeout(r))});return this._server=s,this._boundServers.push(r,s,e),yield this._bindServer(r,null!==(t=this._options.port)&&void 0!==t?t:443,this._options.host),s})}}const H=t=>e=>{Metadata.path(e,(null==t?void 0:t.length)?t:"/")},k=t=>e=>{Metadata.extends(e).push(t)},w=t=>e=>(s,r,o)=>{Metadata.parameters(s).push({callback:t,key:e,propertyKey:r,parameterIndex:o})},q=w(({app:t})=>t),B=w(({argument:t})=>t),V=w(({ctx:t,key:e})=>e?t.getBodyValue(e):t.getBody()),G=w(({ctx:t,key:e})=>e?t.getCookie(e):t.getCookies()),K=w(({ctx:t})=>t),Q=w(({ctx:t})=>t.getFiles()),j=w(({ctx:t,key:e})=>e?t.getHeader(e):t.getHeaders()),$=w(({ctx:t,key:e})=>e?t.getParam(e):t.getParams()),X=w(({ctx:t,key:e})=>e?t.getQuery(e):t.getQueries()),Y=w(({ctx:t})=>{var e;return null===(e=t.req)||void 0===e?void 0:e.session}),z=(t,e)=>(s,r)=>{const o=i();K()(s,o,0),Metadata.middleware(s).push({method:o,argument:e,propertyKey:r,callback:t})},W=t=>(e,s,r)=>{z(e=>{e.cache(Object.assign({},t)),e.next()})(e,s,r)},Z={ALL:"all",GET:"get",POST:"post",PUT:"put",HEAD:"head",DELETE:"delete",OPTIONS:"options",PATCH:"patch"},J=t=>e=>(s,r)=>{Metadata.routers(s).push({method:t,path:(null==e?void 0:e.length)?e:"/",propertyKey:r})},tt=J(Z.ALL),et=J(Z.DELETE),st=J(Z.GET),rt=J(Z.HEAD),ot=J(Z.OPTIONS),at=J(Z.PATCH),it=J(Z.POST),nt=J(Z.PUT),ut=(t,e)=>(s,r)=>{let a=T;if(o(r)){const e=s;S(e[t])&&(a=e[t])}Metadata.middleware(s).push({method:t,argument:e,propertyKey:r,callback:a})},dt=(t,e=StatusCodes.BAD_REQUEST)=>{const s=new Error(t);return s.status=e,s},lt=t=>{var e;return(null===(e=t.split(".").pop())||void 0===e?void 0:e.toLowerCase())||"bin"},ht=(t,e)=>{var s;return null!==(s=t[e])&&void 0!==s?s:null},ct=(t,e)=>{const s=i()+"."+e;return A(P(t,s))?ct(t,e):s},pt=t=>{const e=E({},t),s=b({destination(t,s,r){var o;const a=ht(e,s.fieldname);r(null,null!==(o=null==a?void 0:a.path)&&void 0!==o?o:"./")},filename(t,s,r){var o;const a=ht(e,s.fieldname);r(null,ct(null!==(o=null==a?void 0:a.path)&&void 0!==o?o:"./",lt(s.originalname)))}}),r=Math.max(...Object.values(e).map(t=>{var e;return null!==(e=t.size)&&void 0!==e?e:0})),o=U({storage:s,fileFilter(t,s,r){var o;const a=ht(e,s.fieldname);return a?((t,e)=>!e.length||e.includes(lt(t.originalname))||e.includes(t.mimetype.toLowerCase()))(s,null!==(o=null==a?void 0:a.types)&&void 0!==o?o:[])?void r(null,!0):r(dt(`FILE TYPE NOT ALLOWED FOR "${s.fieldname}"`)):r(dt(`UPLOAD FIELD "${s.fieldname}" IS NOT CONFIGURED`))},limits:{fileSize:1024*r*1024}}).fields(Object.keys(e).map(t=>{var s,r;return{name:t,maxCount:null!==(r=null===(s=e[t])||void 0===s?void 0:s.count)&&void 0!==r?r:1}}));return(t,e,s)=>{z(t=>{o(t.req,t.res,e=>{if(!e)return t.next();t.error((t=>"LIMIT_FILE_SIZE"==t.code?(t.message=t.field?`FILE "${t.field}" EXCEEDS MAX SIZE`:"FILE EXCEEDS MAX SIZE",t.status=StatusCodes.PAYLOAD_TOO_LARGE,t):"LIMIT_UNEXPECTED_FILE"==t.code?(t.message=t.field?`FIELD "${t.field}" IS UNEXPECTED OR EXCEEDS MAX COUNT`:"UPLOAD FIELD IS UNEXPECTED OR EXCEEDS MAX COUNT",t.status=StatusCodes.BAD_REQUEST,t):t)(e))})})(t,e,s)}},Et=t=>{const e=v.object(S(t)?t(v):t).parse();return(t,s,r)=>{z(t=>{var s,r,o;const a=e.validate(null!==(r=null===(s=t.req)||void 0===s?void 0:s.body)&&void 0!==r?r:{});if(a.error)return t.error(new ValidationError(null!==(o=a.message)&&void 0!==o?o:a.error));t.req.body=a.value,t.next()})(t,s,r)}};export{tt as All,q as App,Application,B as Argument,BadRequestError,V as Body,W as Cache,Context,H as Controller,G as Cookies,K as Ctx,et as Delete,k as Extends,Q as Files,ForbiddenError,st as Get,rt as Head,j as Headers,HttpResponse,InternalServerError,Metadata,Z as Methods,ut as Middleware,NotFoundError,ot as Options,$ as Params,at as Patch,it as Post,nt as Put,X as Query,ResponseError,Y as Session,StatusCodes,StatusText,UnauthorizedError,pt as Upload,z as Use,Et as Validate,ValidationError,J as methodFactory,w as parameterFactory};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrewcaires/express",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Decorators for express",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs.js",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
},
|
|
39
39
|
"homepage": "https://github.com/andrewcaires/npm/tree/main/api#readme",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@andrewcaires/decorator": "^1.
|
|
42
|
-
"@andrewcaires/node": "^1.
|
|
43
|
-
"@andrewcaires/utils.js": "^0.
|
|
41
|
+
"@andrewcaires/decorator": "^1.2.0",
|
|
42
|
+
"@andrewcaires/node": "^1.4.0",
|
|
43
|
+
"@andrewcaires/utils.js": "^0.5.0",
|
|
44
44
|
"compression": "^1.8.1",
|
|
45
45
|
"cookie-parser": "^1.4.7",
|
|
46
46
|
"cors": "^2.8.6",
|
|
@@ -51,24 +51,24 @@
|
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@eslint/js": "^10.0.1",
|
|
54
|
-
"@rollup/plugin-commonjs": "^29.0.
|
|
54
|
+
"@rollup/plugin-commonjs": "^29.0.3",
|
|
55
55
|
"@rollup/plugin-terser": "^1.0.0",
|
|
56
56
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
57
|
-
"@rollup/rollup-darwin-arm64": "^4.60.
|
|
57
|
+
"@rollup/rollup-darwin-arm64": "^4.60.4",
|
|
58
58
|
"@types/compression": "^1.8.1",
|
|
59
59
|
"@types/cookie-parser": "^1.4.10",
|
|
60
60
|
"@types/cors": "^2.8.19",
|
|
61
61
|
"@types/express": "^5.0.6",
|
|
62
62
|
"@types/express-session": "^1.19.0",
|
|
63
63
|
"@types/multer": "^2.1.0",
|
|
64
|
-
"@types/node": "^25.
|
|
64
|
+
"@types/node": "^25.9.1",
|
|
65
65
|
"@types/request-ip": "^0.0.41",
|
|
66
66
|
"@types/swagger-ui-express": "^4.1.8",
|
|
67
|
-
"eslint": "^10.
|
|
67
|
+
"eslint": "^10.4.1",
|
|
68
68
|
"globals": "^17.6.0",
|
|
69
69
|
"rollup-plugin-dts": "^6.4.1",
|
|
70
70
|
"swagger-ui-express": "^5.0.1",
|
|
71
71
|
"tslib": "^2.8.1",
|
|
72
|
-
"typescript-eslint": "^8.
|
|
72
|
+
"typescript-eslint": "^8.60.0"
|
|
73
73
|
}
|
|
74
74
|
}
|