@andrewcaires/express 2.2.0 → 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 +22 -7
- package/dist/index.esm.js +2 -2
- package/package.json +8 -6
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 y{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:{}}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(){return`${this.req.protocol}://${this.req.get("host")}${this.req.originalUrl}`}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)}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 x{static extends(t){return e.metadata(x.EXTENDS,t,[])}static middleware(t){return e.metadata(x.MIDDLEWARE,t,[])}static parameters(t){return e.metadata(x.PARAMETERS,t,[])}static path(t,s){return e.metadata(x.PATH,t,s)}static routers(t){return e.metadata(x.ROUTERS,t,[])}}x.EXTENDS=Symbol("EXTENDS"),x.MIDDLEWARE=Symbol("MIDDLEWARE"),x.PARAMETERS=Symbol("PARAMETERS"),x.PATH=Symbol("PATH"),x.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,hybrid:!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._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=x.parameters(e);this._collectExtends(e).forEach(e=>{r.push(...this._collectMiddlewares(e)),o.push(...x.parameters(e))}),x.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 y(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=>{x.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 y(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(x.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 y(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 x.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[...x.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:this._options.hybrid?"hybrid":"https":"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 b=e=>t=>(s,r,o)=>{x.parameters(s).push({callback:e,key:t,propertyKey:r,parameterIndex:o})},C=b(({app:e})=>e),D=b(({argument:e})=>e),P=b(({ctx:e,key:t})=>t?e.getBodyValue(t):e.getBody()),U=b(({ctx:e,key:t})=>t?e.getCookie(t):e.getCookies()),L=b(({ctx:e})=>e),M=b(({ctx:e})=>e.getFiles()),F=b(({ctx:e,key:t})=>t?e.getHeader(t):e.getHeaders()),q=b(({ctx:e,key:t})=>t?e.getParam(t):e.getParams()),k=b(({ctx:e,key:t})=>t?e.getQuery(t):e.getQueries()),w=b(({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),x.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)=>{x.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=C,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=y,exports.Controller=e=>t=>{x.path(t,(null==e?void 0:e.length)?e:"/")},exports.Cookies=U,exports.Ctx=L,exports.Delete=K,exports.Extends=e=>t=>{x.extends(t).push(e)},exports.Files=M,exports.ForbiddenError=class extends N{constructor(e="Forbidden"){super(e,g.FORBIDDEN)}},exports.Get=G,exports.Head=Q,exports.Headers=F,exports.HttpResponse=A,exports.InternalServerError=class extends N{constructor(e="Internal server error"){super(e,g.INTERNAL_SERVER_ERROR)}},exports.Metadata=x,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])}x.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=b;
|
|
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
|
}
|
|
@@ -31,10 +36,10 @@ interface ExpressOptions {
|
|
|
31
36
|
cookie?: ICookie;
|
|
32
37
|
cross?: boolean | CorsOptions;
|
|
33
38
|
host?: string;
|
|
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;
|
|
@@ -75,6 +80,7 @@ declare class Context<T = any, A extends Application = Application> {
|
|
|
75
80
|
getCookie(key: string): string | undefined;
|
|
76
81
|
getCookies<T = TypeAnyObject>(): T;
|
|
77
82
|
getFiles<F extends FileUpload = FileUpload, T = TypeObject<Array<F>>>(): T;
|
|
83
|
+
getFullUrl(): string;
|
|
78
84
|
getHeader(key: string): string | undefined;
|
|
79
85
|
getHeaders<T = TypeAnyObject>(): T;
|
|
80
86
|
getIp(): string;
|
|
@@ -88,6 +94,7 @@ declare class Context<T = any, A extends Application = Application> {
|
|
|
88
94
|
private normalize;
|
|
89
95
|
ok<T = any>(data: T, meta?: TypeAnyObject): void;
|
|
90
96
|
prepare(status: number, value: TypeAnyObject | Array<TypeAnyObject>): void;
|
|
97
|
+
redirect(url: string): void;
|
|
91
98
|
send(status: number, value?: TypeAnyObject | Array<TypeAnyObject>): void;
|
|
92
99
|
setCookie(key: string, value: string, options?: CookieOptions): void;
|
|
93
100
|
status(value?: number): number;
|
|
@@ -426,10 +433,12 @@ interface HttpResponseCreated extends HttpResponseBase<{
|
|
|
426
433
|
interface HttpResponseError {
|
|
427
434
|
success: false;
|
|
428
435
|
status: number;
|
|
429
|
-
|
|
436
|
+
statusText: string;
|
|
430
437
|
message: string;
|
|
431
|
-
path
|
|
432
|
-
timestamp
|
|
438
|
+
path: string;
|
|
439
|
+
timestamp: string;
|
|
440
|
+
code?: string;
|
|
441
|
+
name?: string;
|
|
433
442
|
stack?: string;
|
|
434
443
|
}
|
|
435
444
|
|
|
@@ -438,6 +447,10 @@ interface HttpResponseOptions {
|
|
|
438
447
|
meta?: TypeAnyObject;
|
|
439
448
|
}
|
|
440
449
|
|
|
450
|
+
interface UploadError extends ExpressError {
|
|
451
|
+
field?: string;
|
|
452
|
+
}
|
|
453
|
+
|
|
441
454
|
interface UploadOptions {
|
|
442
455
|
count?: number;
|
|
443
456
|
path?: string;
|
|
@@ -569,6 +582,8 @@ declare class HttpResponse {
|
|
|
569
582
|
static noContent(res: Response): void;
|
|
570
583
|
static ok<T = TypeAnyObject | Array<TypeAnyObject>>(res: Response, data: T, options?: HttpResponseOptions): HttpResponseBase<T>;
|
|
571
584
|
static error(req: Request, res: Response, error: unknown): HttpResponseError;
|
|
585
|
+
private static getErrorCode;
|
|
586
|
+
private static getErrorName;
|
|
572
587
|
private static isDev;
|
|
573
588
|
private static normalizeError;
|
|
574
589
|
private static safeStatus;
|
|
@@ -714,4 +729,4 @@ declare class StatusText {
|
|
|
714
729
|
}
|
|
715
730
|
|
|
716
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 };
|
|
717
|
-
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,EventEmitter as h,isConstructor as c,merge as p,isFunction as E,noop as _,isArray as v,Validation as m}from"@andrewcaires/utils.js";import R from"compression";import T from"cookie-parser";import g from"cors";import N,{Router as O,json as S,urlencoded as f}from"express";import A from"express-session";import{existsSync as I}from"fs";import*as y from"http";import*as D from"https";import*as C from"net";import{resolve as P,join as L}from"path";import{getClientIp as b}from"request-ip";import U,{diskStorage as x}from"multer";function M(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 F{}F.CONTINUE=100,F.SWITCHING_PROTOCOLS=101,F.PROCESSING=102,F.OK=200,F.CREATED=201,F.ACCEPTED=202,F.NON_AUTHORITATIVE_INFORMATION=203,F.NO_CONTENT=204,F.RESET_CONTENT=205,F.PARTIAL_CONTENT=206,F.MULTI_STATUS=207,F.ALREADY_REPORTED=208,F.IM_USED=226,F.MULTIPLE_CHOICES=300,F.MOVED_PERMANENTLY=301,F.FOUND=302,F.SEE_OTHER=303,F.NOT_MODIFIED=304,F.USE_PROXY=305,F.TEMPORARY_REDIRECT=307,F.PERMANENT_REDIRECT=308,F.BAD_REQUEST=400,F.UNAUTHORIZED=401,F.PAYMENT_REQUIRED=402,F.FORBIDDEN=403,F.NOT_FOUND=404,F.METHOD_NOT_ALLOWED=405,F.NOT_ACCEPTABLE=406,F.PROXY_AUTHENTICATION_REQUIRED=407,F.REQUEST_TIMEOUT=408,F.CONFLICT=409,F.GONE=410,F.LENGTH_REQUIRED=411,F.PRECONDITION_FAILED=412,F.PAYLOAD_TOO_LARGE=413,F.REQUEST_URI_TOO_LONG=414,F.UNSUPPORTED_MEDIA_TYPE=415,F.REQUESTED_RANGE_NOT_SATISFIABLE=416,F.EXPECTATION_FAILED=417,F.IM_A_TEAPOT=418,F.MISDIRECTED_REQUEST=421,F.UNPROCESSABLE_ENTITY=422,F.LOCKED=423,F.FAILED_DEPENDENCY=424,F.UPGRADE_REQUIRED=426,F.PRECONDITION_REQUIRED=428,F.TOO_MANY_REQUESTS=429,F.REQUEST_HEADER_FIELDS_TOO_LARGE=431,F.CONNECTION_CLOSED_WITHOUT_RESPONSE=444,F.UNAVAILABLE_FOR_LEGAL_REASONS=451,F.CLIENT_CLOSED_REQUEST=499,F.INTERNAL_SERVER_ERROR=500,F.NOT_IMPLEMENTED=501,F.BAD_GATEWAY=502,F.SERVICE_UNAVAILABLE=503,F.GATEWAY_TIMEOUT=504,F.HTTP_VERSION_NOT_SUPPORTED=505,F.VARIANT_ALSO_NEGOCIATES=506,F.INSUFFICIENT_STORAGE=507,F.LOOP_DETECTED=508,F.NOT_EXTENDED=510,F.NETWORK_AUTHENTICATION_REQUIRED=511,F.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 w extends Error{constructor(e,t=F.INTERNAL_SERVER_ERROR){super(e),this.status=t}}class H extends w{constructor(e="Bad Request"){super(e,F.BAD_REQUEST)}}class q extends w{constructor(e="Forbidden"){super(e,F.FORBIDDEN)}}class B extends w{constructor(e="Internal server error"){super(e,F.INTERNAL_SERVER_ERROR)}}class K extends w{constructor(e="Not Found"){super(e,F.NOT_FOUND)}}class G extends w{constructor(e="Unauthorized"){super(e,F.UNAUTHORIZED)}}class Q extends w{constructor(e){super(e,F.UNPROCESSABLE_ENTITY)}}class V{static created(e,t,s){var r,o;const i=F.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(F.NO_CONTENT).end()}static ok(e,t,s){var r,o;const i=F.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=F.INTERNAL_SERVER_ERROR,s=k[500];if(e instanceof w)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 F.INTERNAL_SERVER_ERROR;const t=Math.trunc(e);return t<400||t>599?F.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 ${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()||V.error(this.req,this.res,e)}file(e){this.isResponded()||(this.status(F.OK),this.res.sendFile(P(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:{}}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(){return`${this.req.protocol}://${this.req.get("host")}${this.req.originalUrl}`}isResponded(){return this.res.headersSent||this.res.writableEnded}json(e){this.send(F.OK,e)}normalize(e){if(!u(e)&&!d(e))return i(e)?JSON.stringify(e):String(e)}ok(e,t){this.isResponded()||V.ok(this.res,e,t)}prepare(e,t){this.isResponded()||(this.status(e),this.storage=t)}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(F.OK,{message:e})}}class j{static extends(t){return e(j.EXTENDS,t,[])}static middleware(t){return e(j.MIDDLEWARE,t,[])}static parameters(t){return e(j.PARAMETERS,t,[])}static path(t,s){return e(j.PATH,t,s)}static routers(t){return e(j.ROUTERS,t,[])}}j.EXTENDS=Symbol("EXTENDS"),j.MIDDLEWARE=Symbol("MIDDLEWARE"),j.PARAMETERS=Symbol("PARAMETERS"),j.PATH=Symbol("PATH"),j.ROUTERS=Symbol("ROUTERS");class Y extends h{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=N(),this._boundServers=[],this._options={},this._baseRouter=O(),this._globalRouter=O(),this._controllers=[],this._controllers.push(...e.map(e=>c(e)?new e(...t(e)):e)),this._options=p({},{cross:!1,hybrid:!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._app.use(f({extended:!0})),this._options.cross&&this._app.use(g(i(this._options.cross)?this._options.cross:{})),this._app.use(R(this._options.compression)),this._app.use(T(null===(r=this._options.cookie)||void 0===r?void 0:r.secret,this._options.cookie)),this._app.use(A(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):V.error(e,t,new K("Endpoint Not Found"))}),this._options.public){const e=P(this._options.public);I(e)&&this._app.use(N.static(e)),this._app.get("*path",(t,s)=>{I(e)?s.sendFile(e+"/index.html"):this._options.notfound?s.redirect(this._options.notfound):V.error(t,s,new K('FILE "index.html" Not Found'))})}else this._app.all("*path",(e,t)=>{this._options.redirect?t.redirect(this._options.redirect):V.error(e,t,new K("Endpoint not found"))});this._controllers.forEach(e=>{const t=O(),s=this._collectMiddlewares(e),r=j.parameters(e);this._collectExtends(e).forEach(e=>{s.push(...this._collectMiddlewares(e)),r.push(...j.parameters(e))}),j.routers(e).forEach(o=>{const n=o.propertyKey.toString();if(E(e[n])){if(!E(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)=>M(this,void 0,void 0,function*(){const a=new $(t,s,o,this,e),l=this._resolveArgs(a,this._filterParamsByKey(n,r)),u=yield e[n](...l);a.close(v(u)||i(u)?u:void 0)}))}this._logRouteNotFound(`${e.name}.${n}`)}),this._collectExtends(e).forEach(o=>{j.routers(o).forEach(o=>{const n=o.propertyKey.toString();if(E(e[n])){if(!E(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)=>M(this,void 0,void 0,function*(){const a=new $(t,s,o,this,e),l=this._resolveArgs(a,this._filterParamsByKey(n,r)),u=yield e[n](...l);a.close(v(u)||i(u)?u:void 0)}))}this._logRouteNotFound(`${e.constructor.name}.${n}`)})}),this._baseRouter.use(j.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!=_){const s=this._filterParamsByKey(t.method,r);return(r,o,n)=>M(this,void 0,void 0,function*(){const a=new $(r,o,n,this,e),l=E(t.argument)?t.argument(a):t.argument,u=yield t.callback.call(e,...this._resolveArgs(a,s,l));(v(u)||i(u))&&a.close(u)})}this._logRouteNotFound(t.method)}).filter(E)}_collectExtends(e){return j.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[...j.middleware(e)].reverse()}_logRouteNotFound(e){this.error(new Error(`Router "${e}" not found`),"express")}_formatListeningMessage(e){return`Server listening on port ${e}`}listen(){return M(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 M(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:this._options.hybrid?"hybrid":"https":"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 M(this,void 0,void 0,function*(){var e;const t=y.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 M(this,void 0,void 0,function*(){var e;const t=D.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 M(this,void 0,void 0,function*(){var e,t;const s=D.createServer(this._resolveTls(),this._app),r=y.createServer((e,t)=>{var s,r;const o=(null!==(s=e.headers.host)&&void 0!==s?s:"").split(":")[0];t.writeHead(F.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 M(this,void 0,void 0,function*(){var e;const t=y.createServer(this._app),s=D.createServer(this._resolveTls(),this._app),r=C.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 W=e=>t=>{j.path(t,(null==e?void 0:e.length)?e:"/")},z=e=>t=>{j.extends(t).push(e)},X=e=>t=>(s,r,o)=>{j.parameters(s).push({callback:e,key:t,propertyKey:r,parameterIndex:o})},Z=X(({app:e})=>e),J=X(({argument:e})=>e),ee=X(({ctx:e,key:t})=>t?e.getBodyValue(t):e.getBody()),te=X(({ctx:e,key:t})=>t?e.getCookie(t):e.getCookies()),se=X(({ctx:e})=>e),re=X(({ctx:e})=>e.getFiles()),oe=X(({ctx:e,key:t})=>t?e.getHeader(t):e.getHeaders()),ie=X(({ctx:e,key:t})=>t?e.getParam(t):e.getParams()),ne=X(({ctx:e,key:t})=>t?e.getQuery(t):e.getQueries()),ae=X(({ctx:e})=>{var t;return null===(t=e.req)||void 0===t?void 0:t.session}),le=(e,t)=>(s,r)=>{const o=n();se()(s,o,0),j.middleware(s).push({method:o,argument:t,propertyKey:r,callback:e})},ue=e=>(t,s,r)=>{le(t=>{t.cache(Object.assign({},e)),t.next()})(t,s,r)},de={ALL:"all",GET:"get",POST:"post",PUT:"put",HEAD:"head",DELETE:"delete",OPTIONS:"options",PATCH:"patch"},he=e=>t=>(s,r)=>{j.routers(s).push({method:e,path:(null==t?void 0:t.length)?t:"/",propertyKey:r})},ce=he(de.ALL),pe=he(de.DELETE),Ee=he(de.GET),_e=he(de.HEAD),ve=he(de.OPTIONS),me=he(de.PATCH),Re=he(de.POST),Te=he(de.PUT),ge=(e,t)=>(s,r)=>{let i=_;if(o(r)){const t=s;E(t[e])&&(i=t[e])}j.middleware(s).push({method:e,argument:t,propertyKey:r,callback:i})},Ne=e=>{var t;return(null===(t=e.split(".").pop())||void 0===t?void 0:t.toLowerCase())||"bin"},Oe=(e,t)=>{var s;return null!==(s=e[t])&&void 0!==s?s:null},Se=(e,t)=>{const s=n()+"."+t;return I(L(e,s))?Se(e,t):s},fe=e=>{const t=p({},e),s=x({destination(e,s,r){var o;const i=Oe(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=Oe(t,s.fieldname);r(null,Se(null!==(o=null==i?void 0:i.path)&&void 0!==o?o:"./",Ne(s.originalname)))}}),r=Math.max(...Object.values(t).map(e=>{var t;return null!==(t=e.size)&&void 0!==t?t:0})),o=U({storage:s,fileFilter(e,s,r){var o;const i=Oe(t,s.fieldname);return i?((e,t)=>!t.length||t.includes(Ne(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)=>{le(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)}},Ae=e=>{const t=m.object(E(e)?e(m):e).parse();return(e,s,r)=>{le(e=>M(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 Q(null!=i?i:o));e.req.body=n,e.next()}))(e,s,r)}};export{ce as All,Z as App,Y as Application,J as Argument,H as BadRequestError,ee as Body,ue as Cache,$ as Context,W as Controller,te as Cookies,se as Ctx,pe as Delete,z as Extends,re as Files,q as ForbiddenError,Ee as Get,_e as Head,oe as Headers,V as HttpResponse,B as InternalServerError,j as Metadata,de as Methods,ge as Middleware,K as NotFoundError,ve as Options,ie as Params,me as Patch,Re as Post,Te as Put,ne as Query,w as ResponseError,ae as Session,F as StatusCodes,k as StatusText,G as UnauthorizedError,fe as Upload,le as Use,Ae as Validate,Q as ValidationError,he as methodFactory,X 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",
|
|
@@ -53,20 +54,21 @@
|
|
|
53
54
|
"@rollup/plugin-commonjs": "^29.0.2",
|
|
54
55
|
"@rollup/plugin-terser": "^1.0.0",
|
|
55
56
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
56
|
-
"@rollup/rollup-darwin-arm64": "^4.60.
|
|
57
|
+
"@rollup/rollup-darwin-arm64": "^4.60.3",
|
|
57
58
|
"@types/compression": "^1.8.1",
|
|
58
59
|
"@types/cookie-parser": "^1.4.10",
|
|
59
60
|
"@types/cors": "^2.8.19",
|
|
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",
|
|
70
|
-
"typescript-eslint": "^8.59.
|
|
72
|
+
"typescript-eslint": "^8.59.2"
|
|
71
73
|
}
|
|
72
74
|
}
|