@andrewcaires/express 2.2.1 → 2.3.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 +19 -6
- package/dist/index.esm.js +2 -2
- package/package.json +6 -4
package/dist/index.cjs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/express v2.
|
|
2
|
+
* @andrewcaires/express v2.3.0
|
|
3
3
|
* Decorators for express
|
|
4
4
|
* (c) 2026 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
6
6
|
*/
|
|
7
|
-
"use strict";var e=require("@andrewcaires/decorator"),t=require("@andrewcaires/node"),s=require("@andrewcaires/utils.js"),r=require("compression"),o=require("cookie-parser"),i=require("cors"),n=require("express"),a=require("express-session"),l=require("fs"),u=require("http"),d=require("https"),h=require("net"),c=require("path"),p=require("request-ip"),E=require("multer");function _(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(s){if("default"!==s){var r=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,r.get?r:{enumerable:!0,get:function(){return e[s]}})}}),t.default=e,Object.freeze(t)}var v=_(u),R=_(d),m=_(h);function T(e,t,s,r){return new(s||(s=Promise))(function(o,i){function n(e){try{l(r.next(e))}catch(e){i(e)}}function a(e){try{l(r.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?o(e.value):(t=e.value,t instanceof s?t:new s(function(e){e(t)})).then(n,a)}l((r=r.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class g{}g.CONTINUE=100,g.SWITCHING_PROTOCOLS=101,g.PROCESSING=102,g.OK=200,g.CREATED=201,g.ACCEPTED=202,g.NON_AUTHORITATIVE_INFORMATION=203,g.NO_CONTENT=204,g.RESET_CONTENT=205,g.PARTIAL_CONTENT=206,g.MULTI_STATUS=207,g.ALREADY_REPORTED=208,g.IM_USED=226,g.MULTIPLE_CHOICES=300,g.MOVED_PERMANENTLY=301,g.FOUND=302,g.SEE_OTHER=303,g.NOT_MODIFIED=304,g.USE_PROXY=305,g.TEMPORARY_REDIRECT=307,g.PERMANENT_REDIRECT=308,g.BAD_REQUEST=400,g.UNAUTHORIZED=401,g.PAYMENT_REQUIRED=402,g.FORBIDDEN=403,g.NOT_FOUND=404,g.METHOD_NOT_ALLOWED=405,g.NOT_ACCEPTABLE=406,g.PROXY_AUTHENTICATION_REQUIRED=407,g.REQUEST_TIMEOUT=408,g.CONFLICT=409,g.GONE=410,g.LENGTH_REQUIRED=411,g.PRECONDITION_FAILED=412,g.PAYLOAD_TOO_LARGE=413,g.REQUEST_URI_TOO_LONG=414,g.UNSUPPORTED_MEDIA_TYPE=415,g.REQUESTED_RANGE_NOT_SATISFIABLE=416,g.EXPECTATION_FAILED=417,g.IM_A_TEAPOT=418,g.MISDIRECTED_REQUEST=421,g.UNPROCESSABLE_ENTITY=422,g.LOCKED=423,g.FAILED_DEPENDENCY=424,g.UPGRADE_REQUIRED=426,g.PRECONDITION_REQUIRED=428,g.TOO_MANY_REQUESTS=429,g.REQUEST_HEADER_FIELDS_TOO_LARGE=431,g.CONNECTION_CLOSED_WITHOUT_RESPONSE=444,g.UNAVAILABLE_FOR_LEGAL_REASONS=451,g.CLIENT_CLOSED_REQUEST=499,g.INTERNAL_SERVER_ERROR=500,g.NOT_IMPLEMENTED=501,g.BAD_GATEWAY=502,g.SERVICE_UNAVAILABLE=503,g.GATEWAY_TIMEOUT=504,g.HTTP_VERSION_NOT_SUPPORTED=505,g.VARIANT_ALSO_NEGOCIATES=506,g.INSUFFICIENT_STORAGE=507,g.LOOP_DETECTED=508,g.NOT_EXTENDED=510,g.NETWORK_AUTHENTICATION_REQUIRED=511,g.NETWORK_CONNECTION_TIMEOUT_ERROR=599;class O{}O[100]="Continue",O[101]="Switching Protocols",O[102]="Processing",O[200]="OK",O[201]="Created",O[202]="Accepted",O[203]="Non-Authoritative Information",O[204]="No Content",O[205]="Reset Content",O[206]="Partial Content",O[207]="Multi-Status",O[226]="IM Used",O[300]="Multiple Choices",O[301]="Moved Permanently",O[302]="Found",O[303]="See Other",O[304]="Not Modified",O[305]="Use Proxy",O[307]="Temporary Redirect",O[308]="Permanent Redirect",O[400]="Bad Request",O[401]="Unauthorized",O[402]="Payment Required",O[403]="Forbidden",O[404]="Not Found",O[405]="Method Not Allowed",O[406]="Not Acceptable",O[407]="Proxy Authentication Required",O[408]="Request Timeout",O[409]="Conflict",O[410]="Gone",O[411]="Length Required",O[412]="Precondition Failed",O[413]="Payload Too Large",O[414]="URI Too Long",O[415]="Unsupported Media Type",O[416]="Range Not Satisfiable",O[417]="Expectation Failed",O[418]="I'm a teapot",O[422]="Unprocessable Entity",O[423]="Locked",O[424]="Failed Dependency",O[426]="Upgrade Required",O[428]="Precondition Required",O[429]="Too Many Requests",O[431]="Request Header Fields Too Large",O[451]="Unavailable For Legal Reasons",O[500]="Internal Server Error",O[501]="Not Implemented",O[502]="Bad Gateway",O[503]="Service Unavailable",O[504]="Gateway Time-out",O[505]="HTTP Version Not Supported",O[506]="Variant Also Negotiates",O[507]="Insufficient Storage",O[511]="Network Authentication Required";class N extends Error{constructor(e,t=g.INTERNAL_SERVER_ERROR){super(e),this.status=t}}class S extends N{constructor(e="Not Found"){super(e,g.NOT_FOUND)}}class f extends N{constructor(e){super(e,g.UNPROCESSABLE_ENTITY)}}class A{static created(e,t,s){var r,o;const i=g.CREATED,n={success:!0,status:i,data:t?{id:t}:{},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 e.status(i).json(n),n}static noContent(e){e.status(g.NO_CONTENT).end()}static ok(e,t,s){var r,o;const i=g.OK,n={success:!0,status:i,data:t,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 e.status(i).json(n),n}static error(e,t,s){var r,o;const{status:i,message:n}=this.normalizeError(s),a=Object.assign({success:!1,status:i,error:null!==(r=null==O?void 0:O[i])&&void 0!==r?r:"Internal Server Error",message:n,path:null!==(o=e.originalUrl)&&void 0!==o?o:e.url,timestamp:(new Date).toISOString()},this.isDev()&&s instanceof Error&&s.stack?{stack:s.stack}:{});return t.status(i).json(a),a}static isDev(){return"production"!==process.env.NODE_ENV}static normalizeError(e){let t=g.INTERNAL_SERVER_ERROR,r=O[500];if(e instanceof N)return t=this.safeStatus(e.status),r=this.safeMessage(e.message)||r,{status:t,message:r};if(e instanceof Error){const o=e;return s.isNumber(o.statusCode)?t=this.safeStatus(o.statusCode):s.isNumber(o.status)&&(t=this.safeStatus(o.status)),r=this.safeMessage(e.message)||r,{status:t,message:r}}if(s.isString(e))return r=this.safeMessage(e)||r,{status:t,message:r};if(e&&s.isObject(e)){const o=e;return s.isNumber(o.statusCode)?t=this.safeStatus(o.statusCode):s.isNumber(o.status)&&(t=this.safeStatus(o.status)),s.isString(o.message)&&(r=this.safeMessage(o.message)||r),{status:t,message:r}}return{status:t,message:r}}static safeStatus(e){if(!Number.isFinite(e))return g.INTERNAL_SERVER_ERROR;const t=Math.trunc(e);return t<400||t>599?g.INTERNAL_SERVER_ERROR:t}static safeMessage(e){if(!s.isString(e))return"";const t=e.trim();return t.length>2e3?t.slice(0,2e3)+"...":t}}class x{constructor(e,t,r,o,i){this.storage={},this.req=e,this.res=t,this.next=r,this.id=s.uuidv7(),this.app=o,this.controller=i}cache(e){const t=Object.assign({},e),r=[];t.private?r.push("private"):t.public&&r.push("public"),t.noStore&&(t.noCache=!0,r.push("no-store")),t.noCache&&(t.maxAge=0,delete t.sMaxAge,r.push("no-cache")),t.noTransform&&r.push("no-transform"),t.proxyRevalidate&&r.push("proxy-revalidate"),t.mustRevalidate?r.push("must-revalidate"):t.noCache||(s.isNumber(t.staleIfError)&&r.push(`stale-if-error=${t.staleIfError}`),s.isNumber(t.staleWhileRevalidate)&&r.push(`stale-while-revalidate=${t.staleWhileRevalidate}`)),s.isNumber(t.maxAge)&&r.push(`max-age=${t.maxAge}`),s.isNumber(t.sMaxAge)&&r.push(`s-maxage=${t.sMaxAge}`),r.length&&(this.res.setHeader("Cache-Control",r.join(",")),t.noCache&&s.forEachKey({"Surrogate-Control":"no-store",Pragma:"no-cache",ETag:"false",Expires:"0"},(e,t)=>this.res.setHeader(t,e)))}clearCookie(e,t){this.res.clearCookie(e,t)}close(e){this.isResponded()||this.res.json(null!=e?e:this.storage)}destroy(e){var t;e&&this.error(e),null===(t=this.res.socket)||void 0===t||t.destroy(e)}error(e){this.isResponded()||A.error(this.req,this.res,e)}file(e){this.isResponded()||(this.status(g.OK),this.res.sendFile(c.resolve(e)))}getBody(){var e,t;return null!==(t=null===(e=this.req)||void 0===e?void 0:e.body)&&void 0!==t?t:{}}getBodyValue(e){var t;return null===(t=this.req.body)||void 0===t?void 0:t[e]}getCookie(e){var t;return this.normalize(null===(t=this.req.cookies)||void 0===t?void 0:t[e])}getCookies(){var e,t;return s.map(null!==(t=null===(e=this.req)||void 0===e?void 0:e.cookies)&&void 0!==t?t:{},e=>this.normalize(e))}getFiles(){var e,t;return null!==(t=null===(e=this.req)||void 0===e?void 0:e.files)&&void 0!==t?t:{}}getFullUrl(){return`${this.getUrl()}${this.req.originalUrl}`}getHeader(e){var t;return this.normalize(null===(t=this.req.headers)||void 0===t?void 0:t[e])}getHeaders(){var e,t;return s.map(null!==(t=null===(e=this.req)||void 0===e?void 0:e.headers)&&void 0!==t?t:{},e=>this.normalize(e))}getIp(){return p.getClientIp(this.req)||"0.0.0.0"}getQuery(e){var t;return this.normalize(null===(t=this.req.query)||void 0===t?void 0:t[e])}getQueries(){var e,t;return s.map(null!==(t=null===(e=this.req)||void 0===e?void 0:e.query)&&void 0!==t?t:{},e=>this.normalize(e))}getParam(e){var t;const r=null===(t=this.req.params)||void 0===t?void 0:t[e];return s.isUndefined(r)?void 0:String(r)}getParams(){var e,t;return s.map(null!==(t=null===(e=this.req)||void 0===e?void 0:e.params)&&void 0!==t?t:{},e=>{if(!s.isUndefined(e)&&!s.isNull(e))return String(e)})}getUrl(){let e=this.getHeader("x-forwarded-proto")||this.req.protocol||"http";s.isString(e)&&e.includes(",")&&(e=e.split(",")[0].trim());const t=this.getHeader("cf-visitor");if(t){const r=s.parseJson(t);(null==r?void 0:r.scheme)&&(e=r.scheme)}return`${e}://${this.getHeader("host")}`}isResponded(){return this.res.headersSent||this.res.writableEnded}json(e){this.send(g.OK,e)}normalize(e){if(!s.isUndefined(e)&&!s.isNull(e))return s.isObject(e)?JSON.stringify(e):String(e)}ok(e,t){this.isResponded()||A.ok(this.res,e,t)}prepare(e,t){this.isResponded()||(this.status(e),this.storage=t)}redirect(e){this.isResponded()||this.res.redirect(e)}send(e,t){this.isResponded()||(this.status(e),204===e||304===e||s.isUndefined(t)?this.res.end():this.res.json(t))}setCookie(e,t,s){this.res.cookie(e,t,null!=s?s:{})}status(e){return s.isUndefined(e)||this.res.status(e),this.res.statusCode}success(e){this.send(g.OK,{message:e})}}class y{static extends(t){return e.metadata(y.EXTENDS,t,[])}static middleware(t){return e.metadata(y.MIDDLEWARE,t,[])}static parameters(t){return e.metadata(y.PARAMETERS,t,[])}static path(t,s){return e.metadata(y.PATH,t,s)}static routers(t){return e.metadata(y.ROUTERS,t,[])}}y.EXTENDS=Symbol("EXTENDS"),y.MIDDLEWARE=Symbol("MIDDLEWARE"),y.PARAMETERS=Symbol("PARAMETERS"),y.PATH=Symbol("PATH"),y.ROUTERS=Symbol("ROUTERS");class I extends s.EventEmitter{get controllers(){return[...this._controllers]}get instance(){return this._app}get router(){return this._globalRouter}get server(){return this._server}constructor(t,u){var d,h;super(),this._app=n(),this._boundServers=[],this._options={},this._baseRouter=n.Router(),this._globalRouter=n.Router(),this._controllers=[],this._controllers.push(...t.map(t=>s.isConstructor(t)?new t(...e.getInjectionArgs(t)):t)),this._options=s.merge({},{cross:!1,path:"/",port:3e3,session:{secret:"yoursecret",resave:!0,saveUninitialized:!1,cookie:{maxAge:864e5}}},null!=u?u:{}),this._app.use(n.json(this._options.json)),this._app.disable("x-powered-by"),this._options.proxy&&this._app.set("trust proxy",this._options.proxy),this._app.use(n.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===(d=this._options.cookie)||void 0===d?void 0:d.secret,this._options.cookie)),this._app.use(a(this._options.session)),this.init(),this._app.use(this._globalRouter);const p=(null===(h=this._options.path)||void 0===h?void 0:h.length)?this._options.path:"/";if(this._app.use(p,this._baseRouter),this._app.all(p+"/*path",(e,t)=>{this._options.redirect?t.redirect(this._options.redirect):A.error(e,t,new S("Endpoint Not Found"))}),this._options.public){const e=c.resolve(this._options.public);l.existsSync(e)&&this._app.use(n.static(e)),this._app.get("*path",(t,s)=>{l.existsSync(e)?s.sendFile(e+"/index.html"):this._options.notfound?s.redirect(this._options.notfound):A.error(t,s,new S('FILE "index.html" Not Found'))})}else this._app.all("*path",(e,t)=>{this._options.redirect?t.redirect(this._options.redirect):A.error(e,t,new S("Endpoint not found"))});this._controllers.forEach(e=>{const t=n.Router(),r=this._collectMiddlewares(e),o=y.parameters(e);this._collectExtends(e).forEach(e=>{r.push(...this._collectMiddlewares(e)),o.push(...y.parameters(e))}),y.routers(e).forEach(i=>{const n=i.propertyKey.toString();if(s.isFunction(e[n])){if(!s.isFunction(t[i.method]))return this._logRouteNotFound(i.method);const a=this._buildMiddlewareChain(e,n,r,o);return t[i.method](i.path,...a,(t,r,i)=>T(this,void 0,void 0,function*(){const a=new x(t,r,i,this,e),l=this._resolveArgs(a,this._filterParamsByKey(n,o)),u=yield e[n](...l);a.close(s.isArray(u)||s.isObject(u)?u:void 0)}))}this._logRouteNotFound(`${e.name}.${n}`)}),this._collectExtends(e).forEach(i=>{y.routers(i).forEach(i=>{const n=i.propertyKey.toString();if(s.isFunction(e[n])){if(!s.isFunction(t[i.method]))return this._logRouteNotFound(i.method);const a=this._buildMiddlewareChain(e,n,r,o);return t[i.method](i.path,...a,(t,r,i)=>T(this,void 0,void 0,function*(){const a=new x(t,r,i,this,e),l=this._resolveArgs(a,this._filterParamsByKey(n,o)),u=yield e[n](...l);a.close(s.isArray(u)||s.isObject(u)?u:void 0)}))}this._logRouteNotFound(`${e.constructor.name}.${n}`)})}),this._baseRouter.use(y.path(e,"/"),t)})}init(){}error(e,s){t.Log.error(e)}log(e,s){t.Log.info(e)}_resolveArgs(e,t,s){const r=[],o={ctx:e,key:"",app:this,argument:s};return t.forEach(e=>{r[e.parameterIndex]=e.callback(Object.assign(Object.assign({},o),{key:e.key}))}),r}_buildMiddlewareChain(e,t,r,o){return r.filter(e=>e.propertyKey==t).map(t=>{if(t.callback!=s.noop){const r=this._filterParamsByKey(t.method,o);return(o,i,n)=>T(this,void 0,void 0,function*(){const a=new x(o,i,n,this,e),l=s.isFunction(t.argument)?t.argument(a):t.argument,u=yield t.callback.call(e,...this._resolveArgs(a,r,l));(s.isArray(u)||s.isObject(u))&&a.close(u)})}this._logRouteNotFound(t.method)}).filter(s.isFunction)}_collectExtends(e){return y.extends(e).reduce((e,t)=>(e.push(t,...this._collectExtends(t)),e),[]).filter((e,t,s)=>s.indexOf(e)===t)}_filterParamsByKey(e,t){return t.filter(t=>t.propertyKey==e)}_collectMiddlewares(e){return[...y.middleware(e)].reverse()}_logRouteNotFound(e){this.error(new Error(`Router "${e}" not found`),"express")}_formatListeningMessage(e){return`Server listening on port ${e}`}listen(){return T(this,void 0,void 0,function*(){var e;const t=this._resolveMode(),s={http:this._startHttp,https:this._startHttps,hybrid:this._startHybrid,redirect:this._startHttpsWithRedirect};yield(null!==(e=s[t])&&void 0!==e?e:this._startHttp).call(this)})}close(){return T(this,void 0,void 0,function*(){yield Promise.all(this._boundServers.map(e=>new Promise((t,s)=>{e.close(e=>e?s(e):t())}))),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(e,t,s){return new Promise((r,o)=>{const i=t=>{e.off("listening",n),o(t)},n=()=>{e.off("error",i),this.log(this._formatListeningMessage(t),"express"),r()};e.once("error",i),e.once("listening",n),e.listen(t,s)})}_startHttp(){return T(this,void 0,void 0,function*(){var e;const t=v.createServer(this._app);this._server=t,this._boundServers.push(t),yield this._bindServer(t,null!==(e=this._options.port)&&void 0!==e?e:3e3,this._options.host)})}_startHttps(){return T(this,void 0,void 0,function*(){var e;const t=R.createServer(this._resolveTls(),this._app);this._server=t,this._boundServers.push(t),yield this._bindServer(t,null!==(e=this._options.port)&&void 0!==e?e:443,this._options.host)})}_startHttpsWithRedirect(){return T(this,void 0,void 0,function*(){var e,t;const s=R.createServer(this._resolveTls(),this._app),r=v.createServer((e,t)=>{var s,r;const o=(null!==(s=e.headers.host)&&void 0!==s?s:"").split(":")[0];t.writeHead(g.MOVED_PERMANENTLY,{Location:`https://${o}${null!==(r=e.url)&&void 0!==r?r:""}`}),t.end()});this._server=s,this._boundServers.push(s,r),yield Promise.all([this._bindServer(s,null!==(e=this._options.port)&&void 0!==e?e:443,this._options.host),this._bindServer(r,null!==(t=this._options.redirectPort)&&void 0!==t?t:80,this._options.host)])})}_startHybrid(){return T(this,void 0,void 0,function*(){var e;const t=v.createServer(this._app),s=R.createServer(this._resolveTls(),this._app),r=m.createServer(e=>{const r=setTimeout(()=>e.destroy(),5e3);e.once("data",o=>{clearTimeout(r),e.pause(),e.unshift(o),(22===o[0]?s:t).emit("connection",e),process.nextTick(()=>e.resume())}),e.once("error",()=>clearTimeout(r))});return this._server=s,this._boundServers.push(r,s,t),yield this._bindServer(r,null!==(e=this._options.port)&&void 0!==e?e:443,this._options.host),s})}}const C=e=>t=>(s,r,o)=>{y.parameters(s).push({callback:e,key:t,propertyKey:r,parameterIndex:o})},b=C(({app:e})=>e),D=C(({argument:e})=>e),P=C(({ctx:e,key:t})=>t?e.getBodyValue(t):e.getBody()),U=C(({ctx:e,key:t})=>t?e.getCookie(t):e.getCookies()),L=C(({ctx:e})=>e),F=C(({ctx:e})=>e.getFiles()),M=C(({ctx:e,key:t})=>t?e.getHeader(t):e.getHeaders()),q=C(({ctx:e,key:t})=>t?e.getParam(t):e.getParams()),k=C(({ctx:e,key:t})=>t?e.getQuery(t):e.getQueries()),w=C(({ctx:e})=>{var t;return null===(t=e.req)||void 0===t?void 0:t.session}),H=(e,t)=>(r,o)=>{const i=s.uuidv7();L()(r,i,0),y.middleware(r).push({method:i,argument:t,propertyKey:o,callback:e})},j={ALL:"all",GET:"get",POST:"post",PUT:"put",HEAD:"head",DELETE:"delete",OPTIONS:"options",PATCH:"patch"},B=e=>t=>(s,r)=>{y.routers(s).push({method:e,path:(null==t?void 0:t.length)?t:"/",propertyKey:r})},V=B(j.ALL),K=B(j.DELETE),G=B(j.GET),Q=B(j.HEAD),$=B(j.OPTIONS),z=B(j.PATCH),Y=B(j.POST),W=B(j.PUT),X=e=>{var t;return(null===(t=e.split(".").pop())||void 0===t?void 0:t.toLowerCase())||"bin"},Z=(e,t)=>{var s;return null!==(s=e[t])&&void 0!==s?s:null},J=(e,t)=>{const r=s.uuidv7()+"."+t;return l.existsSync(c.join(e,r))?J(e,t):r};exports.All=V,exports.App=b,exports.Application=I,exports.Argument=D,exports.BadRequestError=class extends N{constructor(e="Bad Request"){super(e,g.BAD_REQUEST)}},exports.Body=P,exports.Cache=e=>(t,s,r)=>{H(t=>{t.cache(Object.assign({},e)),t.next()})(t,s,r)},exports.Context=x,exports.Controller=e=>t=>{y.path(t,(null==e?void 0:e.length)?e:"/")},exports.Cookies=U,exports.Ctx=L,exports.Delete=K,exports.Extends=e=>t=>{y.extends(t).push(e)},exports.Files=F,exports.ForbiddenError=class extends N{constructor(e="Forbidden"){super(e,g.FORBIDDEN)}},exports.Get=G,exports.Head=Q,exports.Headers=M,exports.HttpResponse=A,exports.InternalServerError=class extends N{constructor(e="Internal server error"){super(e,g.INTERNAL_SERVER_ERROR)}},exports.Metadata=y,exports.Methods=j,exports.Middleware=(e,t)=>(r,o)=>{let i=s.noop;if(s.isString(o)){const t=r;s.isFunction(t[e])&&(i=t[e])}y.middleware(r).push({method:e,argument:t,propertyKey:o,callback:i})},exports.NotFoundError=S,exports.Options=$,exports.Params=q,exports.Patch=z,exports.Post=Y,exports.Put=W,exports.Query=k,exports.ResponseError=N,exports.Session=w,exports.StatusCodes=g,exports.StatusText=O,exports.UnauthorizedError=class extends N{constructor(e="Unauthorized"){super(e,g.UNAUTHORIZED)}},exports.Upload=e=>{const t=s.merge({},e),r=E.diskStorage({destination(e,s,r){var o;const i=Z(t,s.fieldname);r(null,null!==(o=null==i?void 0:i.path)&&void 0!==o?o:"./")},filename(e,s,r){var o;const i=Z(t,s.fieldname);r(null,J(null!==(o=null==i?void 0:i.path)&&void 0!==o?o:"./",X(s.originalname)))}}),o=Math.max(...Object.values(t).map(e=>{var t;return null!==(t=e.size)&&void 0!==t?t:0})),i=E({storage:r,fileFilter(e,s,r){var o;const i=Z(t,s.fieldname);return i?((e,t)=>!t.length||t.includes(X(e.originalname))||t.includes(e.mimetype.toLowerCase()))(s,null!==(o=null==i?void 0:i.types)&&void 0!==o?o:[])?void r(null,!0):r(new Error(`FILE TYPE NOT ALLOWED FOR "${s.fieldname}"`)):r(new Error(`UPLOAD FIELD "${s.fieldname}" IS NOT CONFIGURED`))},limits:{fileSize:1024*o*1024}}).fields(Object.keys(t).map(e=>{var s,r;return{name:e,maxCount:null!==(r=null===(s=t[e])||void 0===s?void 0:s.count)&&void 0!==r?r:1}}));return(e,t,s)=>{H(e=>{i(e.req,e.res,t=>{if(!t)return e.next();"LIMIT_UNEXPECTED_FILE"==t.code&&(t.message=`FIELD "${t.field}" EXCEEDS MAX SIZE`),e.destroy(t)})})(e,t,s)}},exports.Use=H,exports.Validate=e=>{const t=s.Validation.object(s.isFunction(e)?e(s.Validation):e).parse();return(e,s,r)=>{H(e=>T(void 0,void 0,void 0,function*(){var s,r;const{error:o,message:i,value:n}=yield t.validateAsync(null!==(r=null===(s=e.req)||void 0===s?void 0:s.body)&&void 0!==r?r:{});if(o)return e.error(new f(null!=i?i:o));e.req.body=n,e.next()}))(e,s,r)}},exports.ValidationError=f,exports.methodFactory=B,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}}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;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/express v2.
|
|
2
|
+
* @andrewcaires/express v2.3.0
|
|
3
3
|
* Decorators for express
|
|
4
4
|
* (c) 2026 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
@@ -14,6 +14,11 @@ import { CorsOptions } from 'cors';
|
|
|
14
14
|
import { SessionOptions } from 'express-session';
|
|
15
15
|
import { CookieParseOptions } from 'cookie-parser';
|
|
16
16
|
|
|
17
|
+
interface ExpressError extends Error {
|
|
18
|
+
code?: string;
|
|
19
|
+
status?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
interface ICookie extends CookieParseOptions {
|
|
18
23
|
secret?: string | Array<string>;
|
|
19
24
|
}
|
|
@@ -34,7 +39,7 @@ interface ExpressOptions {
|
|
|
34
39
|
proxy?: boolean | number;
|
|
35
40
|
json?: OptionsJson;
|
|
36
41
|
mode?: ServerMode;
|
|
37
|
-
|
|
42
|
+
notFound?: string;
|
|
38
43
|
path?: string;
|
|
39
44
|
port?: number;
|
|
40
45
|
public?: string;
|
|
@@ -428,10 +433,12 @@ interface HttpResponseCreated extends HttpResponseBase<{
|
|
|
428
433
|
interface HttpResponseError {
|
|
429
434
|
success: false;
|
|
430
435
|
status: number;
|
|
431
|
-
|
|
436
|
+
statusText: string;
|
|
432
437
|
message: string;
|
|
433
|
-
path
|
|
434
|
-
timestamp
|
|
438
|
+
path: string;
|
|
439
|
+
timestamp: string;
|
|
440
|
+
code?: string;
|
|
441
|
+
name?: string;
|
|
435
442
|
stack?: string;
|
|
436
443
|
}
|
|
437
444
|
|
|
@@ -440,6 +447,10 @@ interface HttpResponseOptions {
|
|
|
440
447
|
meta?: TypeAnyObject;
|
|
441
448
|
}
|
|
442
449
|
|
|
450
|
+
interface UploadError extends ExpressError {
|
|
451
|
+
field?: string;
|
|
452
|
+
}
|
|
453
|
+
|
|
443
454
|
interface UploadOptions {
|
|
444
455
|
count?: number;
|
|
445
456
|
path?: string;
|
|
@@ -571,6 +582,8 @@ declare class HttpResponse {
|
|
|
571
582
|
static noContent(res: Response): void;
|
|
572
583
|
static ok<T = TypeAnyObject | Array<TypeAnyObject>>(res: Response, data: T, options?: HttpResponseOptions): HttpResponseBase<T>;
|
|
573
584
|
static error(req: Request, res: Response, error: unknown): HttpResponseError;
|
|
585
|
+
private static getErrorCode;
|
|
586
|
+
private static getErrorName;
|
|
574
587
|
private static isDev;
|
|
575
588
|
private static normalizeError;
|
|
576
589
|
private static safeStatus;
|
|
@@ -716,4 +729,4 @@ declare class StatusText {
|
|
|
716
729
|
}
|
|
717
730
|
|
|
718
731
|
export { All, App, Application, Argument, BadRequestError, Body, Cache, Context, Controller, Cookies, Ctx, Delete, Extends, Files, ForbiddenError, Get, Head, Headers, HttpResponse, InternalServerError, Metadata, Methods, Middleware, NotFoundError, Options, Params, Patch, Post, Put, Query, ResponseError, Session, StatusCodes, StatusText, UnauthorizedError, Upload, Use, Validate, ValidationError, methodFactory, parameterFactory };
|
|
719
|
-
export type { CallbackObject, ComponentsObject, ContactObject, EncodingObject, ExampleObject, ExpressOptions, ExternalDocumentationObject, FileUpload, HeaderObject, HttpResponseBase, HttpResponseCreated, HttpResponseError, HttpResponseOptions, IArgs, ICache, ICookie, IHandler, IMiddlewares, IParameter, IRouter, IStore, IUse, InfoObject, LicenseObject, LinkObject, MediaTypeObject, Method, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterObject, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, ResponseObject, ResponsesObject, SchemaObject, SecurityRequirementObject, SecuritySchemeObject, ServerMode, ServerObject, ServerVariableObject, TagObject, TlsOptions, UploadOptions, ValidationFunction };
|
|
732
|
+
export type { CallbackObject, ComponentsObject, ContactObject, EncodingObject, ExampleObject, ExpressError, ExpressOptions, ExternalDocumentationObject, FileUpload, HeaderObject, HttpResponseBase, HttpResponseCreated, HttpResponseError, HttpResponseOptions, IArgs, ICache, ICookie, IHandler, IMiddlewares, IParameter, IRouter, IStore, IUse, InfoObject, LicenseObject, LinkObject, MediaTypeObject, Method, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterObject, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, ResponseObject, ResponsesObject, SchemaObject, SecurityRequirementObject, SecuritySchemeObject, ServerMode, ServerObject, ServerVariableObject, TagObject, TlsOptions, UploadError, UploadOptions, ValidationFunction };
|
package/dist/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/express v2.
|
|
2
|
+
* @andrewcaires/express v2.3.0
|
|
3
3
|
* Decorators for express
|
|
4
4
|
* (c) 2026 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
6
6
|
*/
|
|
7
|
-
import{metadata as e,getInjectionArgs as t}from"@andrewcaires/decorator";import{Log as s}from"@andrewcaires/node";import{isNumber as r,isString as o,isObject as i,uuidv7 as n,forEachKey as a,map as l,isUndefined as u,isNull as d,parseJson as h,EventEmitter as c,isConstructor as p,merge as E,isFunction as _,noop as v,isArray as m,Validation as R}from"@andrewcaires/utils.js";import T from"compression";import g from"cookie-parser";import N from"cors";import O,{Router as f,json as S,urlencoded as A}from"express";import I from"express-session";import{existsSync as y}from"fs";import*as D from"http";import*as C from"https";import*as P from"net";import{resolve as L,join as U}from"path";import{getClientIp as b}from"request-ip";import x,{diskStorage as M}from"multer";function F(e,t,s,r){return new(s||(s=Promise))(function(o,i){function n(e){try{l(r.next(e))}catch(e){i(e)}}function a(e){try{l(r.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?o(e.value):(t=e.value,t instanceof s?t:new s(function(e){e(t)})).then(n,a)}l((r=r.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class w{}w.CONTINUE=100,w.SWITCHING_PROTOCOLS=101,w.PROCESSING=102,w.OK=200,w.CREATED=201,w.ACCEPTED=202,w.NON_AUTHORITATIVE_INFORMATION=203,w.NO_CONTENT=204,w.RESET_CONTENT=205,w.PARTIAL_CONTENT=206,w.MULTI_STATUS=207,w.ALREADY_REPORTED=208,w.IM_USED=226,w.MULTIPLE_CHOICES=300,w.MOVED_PERMANENTLY=301,w.FOUND=302,w.SEE_OTHER=303,w.NOT_MODIFIED=304,w.USE_PROXY=305,w.TEMPORARY_REDIRECT=307,w.PERMANENT_REDIRECT=308,w.BAD_REQUEST=400,w.UNAUTHORIZED=401,w.PAYMENT_REQUIRED=402,w.FORBIDDEN=403,w.NOT_FOUND=404,w.METHOD_NOT_ALLOWED=405,w.NOT_ACCEPTABLE=406,w.PROXY_AUTHENTICATION_REQUIRED=407,w.REQUEST_TIMEOUT=408,w.CONFLICT=409,w.GONE=410,w.LENGTH_REQUIRED=411,w.PRECONDITION_FAILED=412,w.PAYLOAD_TOO_LARGE=413,w.REQUEST_URI_TOO_LONG=414,w.UNSUPPORTED_MEDIA_TYPE=415,w.REQUESTED_RANGE_NOT_SATISFIABLE=416,w.EXPECTATION_FAILED=417,w.IM_A_TEAPOT=418,w.MISDIRECTED_REQUEST=421,w.UNPROCESSABLE_ENTITY=422,w.LOCKED=423,w.FAILED_DEPENDENCY=424,w.UPGRADE_REQUIRED=426,w.PRECONDITION_REQUIRED=428,w.TOO_MANY_REQUESTS=429,w.REQUEST_HEADER_FIELDS_TOO_LARGE=431,w.CONNECTION_CLOSED_WITHOUT_RESPONSE=444,w.UNAVAILABLE_FOR_LEGAL_REASONS=451,w.CLIENT_CLOSED_REQUEST=499,w.INTERNAL_SERVER_ERROR=500,w.NOT_IMPLEMENTED=501,w.BAD_GATEWAY=502,w.SERVICE_UNAVAILABLE=503,w.GATEWAY_TIMEOUT=504,w.HTTP_VERSION_NOT_SUPPORTED=505,w.VARIANT_ALSO_NEGOCIATES=506,w.INSUFFICIENT_STORAGE=507,w.LOOP_DETECTED=508,w.NOT_EXTENDED=510,w.NETWORK_AUTHENTICATION_REQUIRED=511,w.NETWORK_CONNECTION_TIMEOUT_ERROR=599;class k{}k[100]="Continue",k[101]="Switching Protocols",k[102]="Processing",k[200]="OK",k[201]="Created",k[202]="Accepted",k[203]="Non-Authoritative Information",k[204]="No Content",k[205]="Reset Content",k[206]="Partial Content",k[207]="Multi-Status",k[226]="IM Used",k[300]="Multiple Choices",k[301]="Moved Permanently",k[302]="Found",k[303]="See Other",k[304]="Not Modified",k[305]="Use Proxy",k[307]="Temporary Redirect",k[308]="Permanent Redirect",k[400]="Bad Request",k[401]="Unauthorized",k[402]="Payment Required",k[403]="Forbidden",k[404]="Not Found",k[405]="Method Not Allowed",k[406]="Not Acceptable",k[407]="Proxy Authentication Required",k[408]="Request Timeout",k[409]="Conflict",k[410]="Gone",k[411]="Length Required",k[412]="Precondition Failed",k[413]="Payload Too Large",k[414]="URI Too Long",k[415]="Unsupported Media Type",k[416]="Range Not Satisfiable",k[417]="Expectation Failed",k[418]="I'm a teapot",k[422]="Unprocessable Entity",k[423]="Locked",k[424]="Failed Dependency",k[426]="Upgrade Required",k[428]="Precondition Required",k[429]="Too Many Requests",k[431]="Request Header Fields Too Large",k[451]="Unavailable For Legal Reasons",k[500]="Internal Server Error",k[501]="Not Implemented",k[502]="Bad Gateway",k[503]="Service Unavailable",k[504]="Gateway Time-out",k[505]="HTTP Version Not Supported",k[506]="Variant Also Negotiates",k[507]="Insufficient Storage",k[511]="Network Authentication Required";class H extends Error{constructor(e,t=w.INTERNAL_SERVER_ERROR){super(e),this.status=t}}class q extends H{constructor(e="Bad Request"){super(e,w.BAD_REQUEST)}}class B extends H{constructor(e="Forbidden"){super(e,w.FORBIDDEN)}}class K extends H{constructor(e="Internal server error"){super(e,w.INTERNAL_SERVER_ERROR)}}class G extends H{constructor(e="Not Found"){super(e,w.NOT_FOUND)}}class Q extends H{constructor(e="Unauthorized"){super(e,w.UNAUTHORIZED)}}class V extends H{constructor(e){super(e,w.UNPROCESSABLE_ENTITY)}}class ${static created(e,t,s){var r,o;const i=w.CREATED,n={success:!0,status:i,data:t?{id:t}:{},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 e.status(i).json(n),n}static noContent(e){e.status(w.NO_CONTENT).end()}static ok(e,t,s){var r,o;const i=w.OK,n={success:!0,status:i,data:t,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 e.status(i).json(n),n}static error(e,t,s){var r,o;const{status:i,message:n}=this.normalizeError(s),a=Object.assign({success:!1,status:i,error:null!==(r=null==k?void 0:k[i])&&void 0!==r?r:"Internal Server Error",message:n,path:null!==(o=e.originalUrl)&&void 0!==o?o:e.url,timestamp:(new Date).toISOString()},this.isDev()&&s instanceof Error&&s.stack?{stack:s.stack}:{});return t.status(i).json(a),a}static isDev(){return"production"!==process.env.NODE_ENV}static normalizeError(e){let t=w.INTERNAL_SERVER_ERROR,s=k[500];if(e instanceof H)return t=this.safeStatus(e.status),s=this.safeMessage(e.message)||s,{status:t,message:s};if(e instanceof Error){const o=e;return r(o.statusCode)?t=this.safeStatus(o.statusCode):r(o.status)&&(t=this.safeStatus(o.status)),s=this.safeMessage(e.message)||s,{status:t,message:s}}if(o(e))return s=this.safeMessage(e)||s,{status:t,message:s};if(e&&i(e)){const i=e;return r(i.statusCode)?t=this.safeStatus(i.statusCode):r(i.status)&&(t=this.safeStatus(i.status)),o(i.message)&&(s=this.safeMessage(i.message)||s),{status:t,message:s}}return{status:t,message:s}}static safeStatus(e){if(!Number.isFinite(e))return w.INTERNAL_SERVER_ERROR;const t=Math.trunc(e);return t<400||t>599?w.INTERNAL_SERVER_ERROR:t}static safeMessage(e){if(!o(e))return"";const t=e.trim();return t.length>2e3?t.slice(0,2e3)+"...":t}}class j{constructor(e,t,s,r,o){this.storage={},this.req=e,this.res=t,this.next=s,this.id=n(),this.app=r,this.controller=o}cache(e){const t=Object.assign({},e),s=[];t.private?s.push("private"):t.public&&s.push("public"),t.noStore&&(t.noCache=!0,s.push("no-store")),t.noCache&&(t.maxAge=0,delete t.sMaxAge,s.push("no-cache")),t.noTransform&&s.push("no-transform"),t.proxyRevalidate&&s.push("proxy-revalidate"),t.mustRevalidate?s.push("must-revalidate"):t.noCache||(r(t.staleIfError)&&s.push(`stale-if-error=${t.staleIfError}`),r(t.staleWhileRevalidate)&&s.push(`stale-while-revalidate=${t.staleWhileRevalidate}`)),r(t.maxAge)&&s.push(`max-age=${t.maxAge}`),r(t.sMaxAge)&&s.push(`s-maxage=${t.sMaxAge}`),s.length&&(this.res.setHeader("Cache-Control",s.join(",")),t.noCache&&a({"Surrogate-Control":"no-store",Pragma:"no-cache",ETag:"false",Expires:"0"},(e,t)=>this.res.setHeader(t,e)))}clearCookie(e,t){this.res.clearCookie(e,t)}close(e){this.isResponded()||this.res.json(null!=e?e:this.storage)}destroy(e){var t;e&&this.error(e),null===(t=this.res.socket)||void 0===t||t.destroy(e)}error(e){this.isResponded()||$.error(this.req,this.res,e)}file(e){this.isResponded()||(this.status(w.OK),this.res.sendFile(L(e)))}getBody(){var e,t;return null!==(t=null===(e=this.req)||void 0===e?void 0:e.body)&&void 0!==t?t:{}}getBodyValue(e){var t;return null===(t=this.req.body)||void 0===t?void 0:t[e]}getCookie(e){var t;return this.normalize(null===(t=this.req.cookies)||void 0===t?void 0:t[e])}getCookies(){var e,t;return l(null!==(t=null===(e=this.req)||void 0===e?void 0:e.cookies)&&void 0!==t?t:{},e=>this.normalize(e))}getFiles(){var e,t;return null!==(t=null===(e=this.req)||void 0===e?void 0:e.files)&&void 0!==t?t:{}}getFullUrl(){return`${this.getUrl()}${this.req.originalUrl}`}getHeader(e){var t;return this.normalize(null===(t=this.req.headers)||void 0===t?void 0:t[e])}getHeaders(){var e,t;return l(null!==(t=null===(e=this.req)||void 0===e?void 0:e.headers)&&void 0!==t?t:{},e=>this.normalize(e))}getIp(){return b(this.req)||"0.0.0.0"}getQuery(e){var t;return this.normalize(null===(t=this.req.query)||void 0===t?void 0:t[e])}getQueries(){var e,t;return l(null!==(t=null===(e=this.req)||void 0===e?void 0:e.query)&&void 0!==t?t:{},e=>this.normalize(e))}getParam(e){var t;const s=null===(t=this.req.params)||void 0===t?void 0:t[e];return u(s)?void 0:String(s)}getParams(){var e,t;return l(null!==(t=null===(e=this.req)||void 0===e?void 0:e.params)&&void 0!==t?t:{},e=>{if(!u(e)&&!d(e))return String(e)})}getUrl(){let e=this.getHeader("x-forwarded-proto")||this.req.protocol||"http";o(e)&&e.includes(",")&&(e=e.split(",")[0].trim());const t=this.getHeader("cf-visitor");if(t){const s=h(t);(null==s?void 0:s.scheme)&&(e=s.scheme)}return`${e}://${this.getHeader("host")}`}isResponded(){return this.res.headersSent||this.res.writableEnded}json(e){this.send(w.OK,e)}normalize(e){if(!u(e)&&!d(e))return i(e)?JSON.stringify(e):String(e)}ok(e,t){this.isResponded()||$.ok(this.res,e,t)}prepare(e,t){this.isResponded()||(this.status(e),this.storage=t)}redirect(e){this.isResponded()||this.res.redirect(e)}send(e,t){this.isResponded()||(this.status(e),204===e||304===e||u(t)?this.res.end():this.res.json(t))}setCookie(e,t,s){this.res.cookie(e,t,null!=s?s:{})}status(e){return u(e)||this.res.status(e),this.res.statusCode}success(e){this.send(w.OK,{message:e})}}class Y{static extends(t){return e(Y.EXTENDS,t,[])}static middleware(t){return e(Y.MIDDLEWARE,t,[])}static parameters(t){return e(Y.PARAMETERS,t,[])}static path(t,s){return e(Y.PATH,t,s)}static routers(t){return e(Y.ROUTERS,t,[])}}Y.EXTENDS=Symbol("EXTENDS"),Y.MIDDLEWARE=Symbol("MIDDLEWARE"),Y.PARAMETERS=Symbol("PARAMETERS"),Y.PATH=Symbol("PATH"),Y.ROUTERS=Symbol("ROUTERS");class W extends c{get controllers(){return[...this._controllers]}get instance(){return this._app}get router(){return this._globalRouter}get server(){return this._server}constructor(e,s){var r,o;super(),this._app=O(),this._boundServers=[],this._options={},this._baseRouter=f(),this._globalRouter=f(),this._controllers=[],this._controllers.push(...e.map(e=>p(e)?new e(...t(e)):e)),this._options=E({},{cross:!1,path:"/",port:3e3,session:{secret:"yoursecret",resave:!0,saveUninitialized:!1,cookie:{maxAge:864e5}}},null!=s?s:{}),this._app.use(S(this._options.json)),this._app.disable("x-powered-by"),this._options.proxy&&this._app.set("trust proxy",this._options.proxy),this._app.use(A({extended:!0})),this._options.cross&&this._app.use(N(i(this._options.cross)?this._options.cross:{})),this._app.use(T(this._options.compression)),this._app.use(g(null===(r=this._options.cookie)||void 0===r?void 0:r.secret,this._options.cookie)),this._app.use(I(this._options.session)),this.init(),this._app.use(this._globalRouter);const n=(null===(o=this._options.path)||void 0===o?void 0:o.length)?this._options.path:"/";if(this._app.use(n,this._baseRouter),this._app.all(n+"/*path",(e,t)=>{this._options.redirect?t.redirect(this._options.redirect):$.error(e,t,new G("Endpoint Not Found"))}),this._options.public){const e=L(this._options.public);y(e)&&this._app.use(O.static(e)),this._app.get("*path",(t,s)=>{y(e)?s.sendFile(e+"/index.html"):this._options.notfound?s.redirect(this._options.notfound):$.error(t,s,new G('FILE "index.html" Not Found'))})}else this._app.all("*path",(e,t)=>{this._options.redirect?t.redirect(this._options.redirect):$.error(e,t,new G("Endpoint not found"))});this._controllers.forEach(e=>{const t=f(),s=this._collectMiddlewares(e),r=Y.parameters(e);this._collectExtends(e).forEach(e=>{s.push(...this._collectMiddlewares(e)),r.push(...Y.parameters(e))}),Y.routers(e).forEach(o=>{const n=o.propertyKey.toString();if(_(e[n])){if(!_(t[o.method]))return this._logRouteNotFound(o.method);const a=this._buildMiddlewareChain(e,n,s,r);return t[o.method](o.path,...a,(t,s,o)=>F(this,void 0,void 0,function*(){const a=new j(t,s,o,this,e),l=this._resolveArgs(a,this._filterParamsByKey(n,r)),u=yield e[n](...l);a.close(m(u)||i(u)?u:void 0)}))}this._logRouteNotFound(`${e.name}.${n}`)}),this._collectExtends(e).forEach(o=>{Y.routers(o).forEach(o=>{const n=o.propertyKey.toString();if(_(e[n])){if(!_(t[o.method]))return this._logRouteNotFound(o.method);const a=this._buildMiddlewareChain(e,n,s,r);return t[o.method](o.path,...a,(t,s,o)=>F(this,void 0,void 0,function*(){const a=new j(t,s,o,this,e),l=this._resolveArgs(a,this._filterParamsByKey(n,r)),u=yield e[n](...l);a.close(m(u)||i(u)?u:void 0)}))}this._logRouteNotFound(`${e.constructor.name}.${n}`)})}),this._baseRouter.use(Y.path(e,"/"),t)})}init(){}error(e,t){s.error(e)}log(e,t){s.info(e)}_resolveArgs(e,t,s){const r=[],o={ctx:e,key:"",app:this,argument:s};return t.forEach(e=>{r[e.parameterIndex]=e.callback(Object.assign(Object.assign({},o),{key:e.key}))}),r}_buildMiddlewareChain(e,t,s,r){return s.filter(e=>e.propertyKey==t).map(t=>{if(t.callback!=v){const s=this._filterParamsByKey(t.method,r);return(r,o,n)=>F(this,void 0,void 0,function*(){const a=new j(r,o,n,this,e),l=_(t.argument)?t.argument(a):t.argument,u=yield t.callback.call(e,...this._resolveArgs(a,s,l));(m(u)||i(u))&&a.close(u)})}this._logRouteNotFound(t.method)}).filter(_)}_collectExtends(e){return Y.extends(e).reduce((e,t)=>(e.push(t,...this._collectExtends(t)),e),[]).filter((e,t,s)=>s.indexOf(e)===t)}_filterParamsByKey(e,t){return t.filter(t=>t.propertyKey==e)}_collectMiddlewares(e){return[...Y.middleware(e)].reverse()}_logRouteNotFound(e){this.error(new Error(`Router "${e}" not found`),"express")}_formatListeningMessage(e){return`Server listening on port ${e}`}listen(){return F(this,void 0,void 0,function*(){var e;const t=this._resolveMode(),s={http:this._startHttp,https:this._startHttps,hybrid:this._startHybrid,redirect:this._startHttpsWithRedirect};yield(null!==(e=s[t])&&void 0!==e?e:this._startHttp).call(this)})}close(){return F(this,void 0,void 0,function*(){yield Promise.all(this._boundServers.map(e=>new Promise((t,s)=>{e.close(e=>e?s(e):t())}))),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(e,t,s){return new Promise((r,o)=>{const i=t=>{e.off("listening",n),o(t)},n=()=>{e.off("error",i),this.log(this._formatListeningMessage(t),"express"),r()};e.once("error",i),e.once("listening",n),e.listen(t,s)})}_startHttp(){return F(this,void 0,void 0,function*(){var e;const t=D.createServer(this._app);this._server=t,this._boundServers.push(t),yield this._bindServer(t,null!==(e=this._options.port)&&void 0!==e?e:3e3,this._options.host)})}_startHttps(){return F(this,void 0,void 0,function*(){var e;const t=C.createServer(this._resolveTls(),this._app);this._server=t,this._boundServers.push(t),yield this._bindServer(t,null!==(e=this._options.port)&&void 0!==e?e:443,this._options.host)})}_startHttpsWithRedirect(){return F(this,void 0,void 0,function*(){var e,t;const s=C.createServer(this._resolveTls(),this._app),r=D.createServer((e,t)=>{var s,r;const o=(null!==(s=e.headers.host)&&void 0!==s?s:"").split(":")[0];t.writeHead(w.MOVED_PERMANENTLY,{Location:`https://${o}${null!==(r=e.url)&&void 0!==r?r:""}`}),t.end()});this._server=s,this._boundServers.push(s,r),yield Promise.all([this._bindServer(s,null!==(e=this._options.port)&&void 0!==e?e:443,this._options.host),this._bindServer(r,null!==(t=this._options.redirectPort)&&void 0!==t?t:80,this._options.host)])})}_startHybrid(){return F(this,void 0,void 0,function*(){var e;const t=D.createServer(this._app),s=C.createServer(this._resolveTls(),this._app),r=P.createServer(e=>{const r=setTimeout(()=>e.destroy(),5e3);e.once("data",o=>{clearTimeout(r),e.pause(),e.unshift(o),(22===o[0]?s:t).emit("connection",e),process.nextTick(()=>e.resume())}),e.once("error",()=>clearTimeout(r))});return this._server=s,this._boundServers.push(r,s,t),yield this._bindServer(r,null!==(e=this._options.port)&&void 0!==e?e:443,this._options.host),s})}}const z=e=>t=>{Y.path(t,(null==e?void 0:e.length)?e:"/")},X=e=>t=>{Y.extends(t).push(e)},Z=e=>t=>(s,r,o)=>{Y.parameters(s).push({callback:e,key:t,propertyKey:r,parameterIndex:o})},J=Z(({app:e})=>e),ee=Z(({argument:e})=>e),te=Z(({ctx:e,key:t})=>t?e.getBodyValue(t):e.getBody()),se=Z(({ctx:e,key:t})=>t?e.getCookie(t):e.getCookies()),re=Z(({ctx:e})=>e),oe=Z(({ctx:e})=>e.getFiles()),ie=Z(({ctx:e,key:t})=>t?e.getHeader(t):e.getHeaders()),ne=Z(({ctx:e,key:t})=>t?e.getParam(t):e.getParams()),ae=Z(({ctx:e,key:t})=>t?e.getQuery(t):e.getQueries()),le=Z(({ctx:e})=>{var t;return null===(t=e.req)||void 0===t?void 0:t.session}),ue=(e,t)=>(s,r)=>{const o=n();re()(s,o,0),Y.middleware(s).push({method:o,argument:t,propertyKey:r,callback:e})},de=e=>(t,s,r)=>{ue(t=>{t.cache(Object.assign({},e)),t.next()})(t,s,r)},he={ALL:"all",GET:"get",POST:"post",PUT:"put",HEAD:"head",DELETE:"delete",OPTIONS:"options",PATCH:"patch"},ce=e=>t=>(s,r)=>{Y.routers(s).push({method:e,path:(null==t?void 0:t.length)?t:"/",propertyKey:r})},pe=ce(he.ALL),Ee=ce(he.DELETE),_e=ce(he.GET),ve=ce(he.HEAD),me=ce(he.OPTIONS),Re=ce(he.PATCH),Te=ce(he.POST),ge=ce(he.PUT),Ne=(e,t)=>(s,r)=>{let i=v;if(o(r)){const t=s;_(t[e])&&(i=t[e])}Y.middleware(s).push({method:e,argument:t,propertyKey:r,callback:i})},Oe=e=>{var t;return(null===(t=e.split(".").pop())||void 0===t?void 0:t.toLowerCase())||"bin"},fe=(e,t)=>{var s;return null!==(s=e[t])&&void 0!==s?s:null},Se=(e,t)=>{const s=n()+"."+t;return y(U(e,s))?Se(e,t):s},Ae=e=>{const t=E({},e),s=M({destination(e,s,r){var o;const i=fe(t,s.fieldname);r(null,null!==(o=null==i?void 0:i.path)&&void 0!==o?o:"./")},filename(e,s,r){var o;const i=fe(t,s.fieldname);r(null,Se(null!==(o=null==i?void 0:i.path)&&void 0!==o?o:"./",Oe(s.originalname)))}}),r=Math.max(...Object.values(t).map(e=>{var t;return null!==(t=e.size)&&void 0!==t?t:0})),o=x({storage:s,fileFilter(e,s,r){var o;const i=fe(t,s.fieldname);return i?((e,t)=>!t.length||t.includes(Oe(e.originalname))||t.includes(e.mimetype.toLowerCase()))(s,null!==(o=null==i?void 0:i.types)&&void 0!==o?o:[])?void r(null,!0):r(new Error(`FILE TYPE NOT ALLOWED FOR "${s.fieldname}"`)):r(new Error(`UPLOAD FIELD "${s.fieldname}" IS NOT CONFIGURED`))},limits:{fileSize:1024*r*1024}}).fields(Object.keys(t).map(e=>{var s,r;return{name:e,maxCount:null!==(r=null===(s=t[e])||void 0===s?void 0:s.count)&&void 0!==r?r:1}}));return(e,t,s)=>{ue(e=>{o(e.req,e.res,t=>{if(!t)return e.next();"LIMIT_UNEXPECTED_FILE"==t.code&&(t.message=`FIELD "${t.field}" EXCEEDS MAX SIZE`),e.destroy(t)})})(e,t,s)}},Ie=e=>{const t=R.object(_(e)?e(R):e).parse();return(e,s,r)=>{ue(e=>F(void 0,void 0,void 0,function*(){var s,r;const{error:o,message:i,value:n}=yield t.validateAsync(null!==(r=null===(s=e.req)||void 0===s?void 0:s.body)&&void 0!==r?r:{});if(o)return e.error(new V(null!=i?i:o));e.req.body=n,e.next()}))(e,s,r)}};export{pe as All,J as App,W as Application,ee as Argument,q as BadRequestError,te as Body,de as Cache,j as Context,z as Controller,se as Cookies,re as Ctx,Ee as Delete,X as Extends,oe as Files,B as ForbiddenError,_e as Get,ve as Head,ie as Headers,$ as HttpResponse,K as InternalServerError,Y as Metadata,he as Methods,Ne as Middleware,G as NotFoundError,me as Options,ne as Params,Re as Patch,Te as Post,ge as Put,ae as Query,H as ResponseError,le as Session,w as StatusCodes,k as StatusText,Q as UnauthorizedError,Ae as Upload,ue as Use,Ie as Validate,V as ValidationError,ce as methodFactory,Z 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}}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};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrewcaires/express",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Decorators for express",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs.js",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"dev": "tsx-dev --watch --clear ./src/dev.ts",
|
|
23
23
|
"build": "npm run lint && rollup --bundleConfigAsCjs -c rollup.config.js",
|
|
24
|
-
"lint": "eslint \"src/**/*.{ts,tsx,js,jsx}\" --max-warnings=0"
|
|
24
|
+
"lint": "eslint \"src/**/*.{ts,tsx,js,jsx}\" \"test/**/*.mjs\" --max-warnings=0",
|
|
25
|
+
"test": "npm run build && node --test \"test/**/*.test.mjs\""
|
|
25
26
|
},
|
|
26
27
|
"repository": {
|
|
27
28
|
"type": "git",
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
"dependencies": {
|
|
40
41
|
"@andrewcaires/decorator": "^1.1.1",
|
|
41
42
|
"@andrewcaires/node": "^1.3.3",
|
|
42
|
-
"@andrewcaires/utils.js": "^0.4.
|
|
43
|
+
"@andrewcaires/utils.js": "^0.4.36",
|
|
43
44
|
"compression": "^1.8.1",
|
|
44
45
|
"cookie-parser": "^1.4.7",
|
|
45
46
|
"cors": "^2.8.6",
|
|
@@ -60,10 +61,11 @@
|
|
|
60
61
|
"@types/express": "^5.0.6",
|
|
61
62
|
"@types/express-session": "^1.19.0",
|
|
62
63
|
"@types/multer": "^2.1.0",
|
|
63
|
-
"@types/node": "^25.6.
|
|
64
|
+
"@types/node": "^25.6.2",
|
|
64
65
|
"@types/request-ip": "^0.0.41",
|
|
65
66
|
"@types/swagger-ui-express": "^4.1.8",
|
|
66
67
|
"eslint": "^10.3.0",
|
|
68
|
+
"globals": "^17.6.0",
|
|
67
69
|
"rollup-plugin-dts": "^6.4.1",
|
|
68
70
|
"swagger-ui-express": "^5.0.1",
|
|
69
71
|
"tslib": "^2.8.1",
|