jimpex 8.0.0 → 9.0.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/CHANGELOG.md +13 -0
- package/README.md +2 -2
- package/dist/app/index.d.mts +14 -0
- package/dist/app/index.d.ts +5 -4
- package/dist/app/index.js +4 -0
- package/dist/app/jimpex.d.mts +14 -0
- package/dist/app/jimpex.d.ts +3 -2
- package/dist/app/jimpex.js +225 -0
- package/dist/app/jimpex.js.map +1 -1
- package/dist/controllers/common/config.d.mts +79 -0
- package/dist/controllers/common/config.d.ts +3 -2
- package/dist/controllers/common/config.js +18 -0
- package/dist/controllers/common/config.js.map +1 -1
- package/dist/controllers/common/health.d.mts +83 -0
- package/dist/controllers/common/health.d.ts +4 -3
- package/dist/controllers/common/health.js +18 -0
- package/dist/controllers/common/health.js.map +1 -1
- package/dist/controllers/common/index.d.mts +21 -0
- package/dist/controllers/common/index.d.ts +4 -4
- package/dist/controllers/common/index.js +6 -0
- package/dist/controllers/common/statics.d.mts +215 -0
- package/dist/controllers/common/statics.d.ts +4 -4
- package/dist/controllers/common/statics.js +51 -0
- package/dist/controllers/common/statics.js.map +1 -1
- package/dist/controllers/index.d.mts +24 -0
- package/dist/controllers/index.d.ts +4 -4
- package/dist/controllers/index.js +5 -0
- package/dist/controllers/utils/gateway.d.mts +725 -0
- package/dist/controllers/utils/gateway.d.ts +4 -3
- package/dist/controllers/utils/gateway.js +152 -0
- package/dist/controllers/utils/gateway.js.map +1 -1
- package/dist/controllers/utils/index.d.mts +17 -0
- package/dist/controllers/utils/index.d.ts +4 -3
- package/dist/controllers/utils/index.js +4 -0
- package/dist/esm/app/jimpex.js +222 -1
- package/dist/esm/app/jimpex.js.map +1 -1
- package/dist/esm/{chunk-T2T6Q22Z.js → chunk-2B2CG5KL.js} +1 -1
- package/dist/esm/controllers/common/config.js +19 -1
- package/dist/esm/controllers/common/config.js.map +1 -1
- package/dist/esm/controllers/common/health.js +19 -1
- package/dist/esm/controllers/common/health.js.map +1 -1
- package/dist/esm/controllers/common/statics.js +48 -1
- package/dist/esm/controllers/common/statics.js.map +1 -1
- package/dist/esm/controllers/utils/gateway.js +153 -1
- package/dist/esm/controllers/utils/gateway.js.map +1 -1
- package/dist/esm/middlewares/common/errorHandler.js +25 -1
- package/dist/esm/middlewares/common/errorHandler.js.map +1 -1
- package/dist/esm/middlewares/common/forceHTTPS.js +13 -1
- package/dist/esm/middlewares/common/forceHTTPS.js.map +1 -1
- package/dist/esm/middlewares/common/hsts.js +22 -1
- package/dist/esm/middlewares/common/hsts.js.map +1 -1
- package/dist/esm/middlewares/html/fastHTML.js +55 -1
- package/dist/esm/middlewares/html/fastHTML.js.map +1 -1
- package/dist/esm/middlewares/html/showHTML.js +33 -1
- package/dist/esm/middlewares/html/showHTML.js.map +1 -1
- package/dist/esm/middlewares/utils/versionValidator.js +35 -1
- package/dist/esm/middlewares/utils/versionValidator.js.map +1 -1
- package/dist/esm/services/common/appError.js +48 -2
- package/dist/esm/services/common/appError.js.map +1 -1
- package/dist/esm/services/common/httpError.js +10 -1
- package/dist/esm/services/common/httpError.js.map +1 -1
- package/dist/esm/services/common/index.js +1 -1
- package/dist/esm/services/common/sendFile.js +1 -1
- package/dist/esm/services/frontend/frontendFs.js +29 -1
- package/dist/esm/services/frontend/frontendFs.js.map +1 -1
- package/dist/esm/services/frontend/index.js +1 -1
- package/dist/esm/services/html/htmlGenerator.js +51 -1
- package/dist/esm/services/html/htmlGenerator.js.map +1 -1
- package/dist/esm/services/html/index.js +1 -1
- package/dist/esm/services/http/apiClient.js +27 -1
- package/dist/esm/services/http/apiClient.js.map +1 -1
- package/dist/esm/services/http/http.js +50 -1
- package/dist/esm/services/http/http.js.map +1 -1
- package/dist/esm/services/http/index.js +1 -1
- package/dist/esm/services/http/responsesBuilder.js +49 -2
- package/dist/esm/services/http/responsesBuilder.js.map +1 -1
- package/dist/esm/services/utils/ensureBearerToken.js +17 -1
- package/dist/esm/services/utils/ensureBearerToken.js.map +1 -1
- package/dist/esm/services/utils/index.js +1 -1
- package/dist/esm/utils/fns/others.js +1 -1
- package/dist/esm/utils/fns/routes.js +1 -1
- package/dist/esm/utils/fns/routes.js.map +1 -1
- package/dist/esm/utils/fns/statuses.js +1 -1
- package/dist/esm/utils/fns/text.js +1 -1
- package/dist/esm/utils/wrappers.js +1 -1
- package/dist/{jimpex-7eaee271.d.ts → index-b2a04c78.d.ts} +9 -5
- package/dist/index-efeb437e.d.ts +1282 -0
- package/dist/index.d.mts +46 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -0
- package/dist/middlewares/common/errorHandler.d.mts +132 -0
- package/dist/middlewares/common/errorHandler.d.ts +4 -3
- package/dist/middlewares/common/errorHandler.js +24 -0
- package/dist/middlewares/common/errorHandler.js.map +1 -1
- package/dist/middlewares/common/forceHTTPS.d.mts +69 -0
- package/dist/middlewares/common/forceHTTPS.d.ts +5 -4
- package/dist/middlewares/common/forceHTTPS.js +12 -0
- package/dist/middlewares/common/forceHTTPS.js.map +1 -1
- package/dist/middlewares/common/hsts.d.mts +110 -0
- package/dist/middlewares/common/hsts.d.ts +5 -4
- package/dist/middlewares/common/hsts.js +21 -0
- package/dist/middlewares/common/hsts.js.map +1 -1
- package/dist/middlewares/common/index.d.mts +22 -0
- package/dist/middlewares/common/index.d.ts +4 -3
- package/dist/middlewares/common/index.js +6 -0
- package/dist/middlewares/html/fastHTML.d.mts +180 -0
- package/dist/middlewares/html/fastHTML.d.ts +4 -4
- package/dist/middlewares/html/fastHTML.js +54 -0
- package/dist/middlewares/html/fastHTML.js.map +1 -1
- package/dist/middlewares/html/index.d.mts +21 -0
- package/dist/middlewares/html/index.d.ts +4 -4
- package/dist/middlewares/html/index.js +5 -0
- package/dist/middlewares/html/showHTML.d.mts +127 -0
- package/dist/middlewares/html/showHTML.d.ts +4 -4
- package/dist/middlewares/html/showHTML.js +32 -0
- package/dist/middlewares/html/showHTML.js.map +1 -1
- package/dist/middlewares/index.d.mts +30 -0
- package/dist/middlewares/index.d.ts +4 -4
- package/dist/middlewares/index.js +6 -0
- package/dist/middlewares/utils/index.d.mts +20 -0
- package/dist/middlewares/utils/index.d.ts +4 -3
- package/dist/middlewares/utils/index.js +4 -0
- package/dist/middlewares/utils/versionValidator.d.mts +215 -0
- package/dist/middlewares/utils/versionValidator.d.ts +4 -3
- package/dist/middlewares/utils/versionValidator.js +34 -0
- package/dist/middlewares/utils/versionValidator.js.map +1 -1
- package/dist/services/common/appError.d.mts +139 -0
- package/dist/services/common/appError.d.ts +4 -3
- package/dist/services/common/appError.js +47 -1
- package/dist/services/common/appError.js.map +1 -1
- package/dist/services/common/httpError.d.mts +80 -0
- package/dist/services/common/httpError.d.ts +4 -3
- package/dist/services/common/httpError.js +9 -0
- package/dist/services/common/httpError.js.map +1 -1
- package/dist/services/common/index.d.mts +47 -0
- package/dist/services/common/index.d.ts +4 -4
- package/dist/services/common/index.js +4 -1
- package/dist/services/common/sendFile.d.mts +102 -0
- package/dist/services/common/sendFile.d.ts +3 -3
- package/dist/services/frontend/frontendFs.d.mts +96 -0
- package/dist/services/frontend/frontendFs.d.ts +3 -3
- package/dist/services/frontend/frontendFs.js +32 -0
- package/dist/services/frontend/frontendFs.js.map +1 -1
- package/dist/services/frontend/index.d.mts +40 -0
- package/dist/services/frontend/index.d.ts +4 -4
- package/dist/services/frontend/index.js +2 -1
- package/dist/services/html/htmlGenerator.d.mts +237 -0
- package/dist/services/html/htmlGenerator.d.ts +2 -2
- package/dist/services/html/htmlGenerator.js +50 -0
- package/dist/services/html/htmlGenerator.js.map +1 -1
- package/dist/services/html/index.d.mts +43 -0
- package/dist/services/html/index.d.ts +4 -4
- package/dist/services/html/index.js +2 -1
- package/dist/services/http/apiClient.d.mts +170 -0
- package/dist/services/http/apiClient.d.ts +4 -3
- package/dist/services/http/apiClient.js +26 -0
- package/dist/services/http/apiClient.js.map +1 -1
- package/dist/services/http/http.d.mts +176 -0
- package/dist/services/http/http.d.ts +4 -3
- package/dist/services/http/http.js +53 -0
- package/dist/services/http/http.js.map +1 -1
- package/dist/services/http/index.d.mts +51 -0
- package/dist/services/http/index.d.ts +4 -3
- package/dist/services/http/index.js +4 -1
- package/dist/services/http/responsesBuilder.d.mts +179 -0
- package/dist/services/http/responsesBuilder.d.ts +3 -2
- package/dist/services/http/responsesBuilder.js +48 -1
- package/dist/services/http/responsesBuilder.js.map +1 -1
- package/dist/services/index.d.mts +33 -0
- package/dist/services/index.d.ts +4 -4
- package/dist/services/index.js +8 -0
- package/dist/services/utils/ensureBearerToken.d.mts +158 -0
- package/dist/services/utils/ensureBearerToken.d.ts +5 -4
- package/dist/services/utils/ensureBearerToken.js +16 -0
- package/dist/services/utils/ensureBearerToken.js.map +1 -1
- package/dist/services/utils/index.d.mts +44 -0
- package/dist/services/utils/index.d.ts +4 -3
- package/dist/services/utils/index.js +2 -1
- package/dist/types/events.d.mts +14 -0
- package/dist/types/events.d.ts +5 -4
- package/dist/types/express.d.mts +10 -0
- package/dist/types/http.d.mts +79 -0
- package/dist/types/index.d.mts +14 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +9 -0
- package/dist/types/options.d.mts +14 -0
- package/dist/types/options.d.ts +4 -3
- package/dist/types/utils.d.mts +48 -0
- package/dist/types/wootils.d.mts +4 -0
- package/dist/utils/fns/index.d.mts +5 -0
- package/dist/utils/fns/index.js +7 -0
- package/dist/utils/fns/others.d.mts +17 -0
- package/dist/utils/fns/routes.d.mts +39 -0
- package/dist/utils/fns/routes.js.map +1 -1
- package/dist/utils/fns/statuses.d.mts +45 -0
- package/dist/utils/fns/statuses.js +4 -0
- package/dist/utils/fns/statuses.js.map +1 -1
- package/dist/utils/fns/text.d.mts +9 -0
- package/dist/utils/index.d.mts +19 -0
- package/dist/utils/index.d.ts +5 -4
- package/dist/utils/index.js +5 -0
- package/dist/utils/wrappers.d.mts +14 -0
- package/dist/utils/wrappers.d.ts +4 -3
- package/package.json +43 -43
- /package/dist/esm/{chunk-T2T6Q22Z.js.map → chunk-2B2CG5KL.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/controllers/common/health.ts"],"sourcesContent":["import { controller, type Statuses } from '../../utils';\nimport type { ResponsesBuilder } from '../../services';\nimport type { JimpexHealthStatus, Config, AsyncExpressMiddleware } from '../../types';\n/**\n * A function that will return the health status of the application.\n *\n * @group Controllers/Health\n */\nexport type GetHealthStatus = () => Promise<JimpexHealthStatus>;\n/**\n * The options to contruct a {@link HealthController}.\n *\n * @group Controllers/Health\n */\nexport type HealthControllerOptions = {\n /**\n * A dictionary with the dependencies to inject.\n */\n inject: {\n getHealthStatus: GetHealthStatus;\n responsesBuilder: ResponsesBuilder;\n config: Config;\n statuses: Statuses;\n };\n};\n/**\n * The controller class that shows the application health status.\n *\n * @group Controller Classes\n * @group Controllers/Health\n * @prettierignore\n */\nexport class HealthController {\n /**\n * The function that returns the health status of the application.\n */\n protected readonly _getHealthStatus: GetHealthStatus;\n /**\n * The service in charge or building the responses.\n */\n protected readonly _responsesBuilder: ResponsesBuilder;\n /**\n * The service in charge of the configuration.\n */\n protected readonly _config: Config;\n /**\n * The uility service to get HTTP status codes.\n */\n protected readonly _statuses: Statuses;\n /**\n * @param options The options to construct the controller.\n */\n constructor({ inject }: HealthControllerOptions) {\n this._getHealthStatus = inject.getHealthStatus;\n this._responsesBuilder = inject.responsesBuilder;\n this._config = inject.config;\n this._statuses = inject.statuses;\n }\n /**\n * Creates the middleware the shows the application health status.\n */\n showHealth(): AsyncExpressMiddleware {\n return async (_, res) => {\n const healthStatus = await this._getHealthStatus();\n let isHealthy: boolean;\n let extras: Record<string, unknown>;\n if (typeof healthStatus === 'boolean') {\n isHealthy = healthStatus;\n extras = {};\n } else {\n if (typeof healthStatus.isHealthy === 'boolean') {\n isHealthy = healthStatus.isHealthy;\n } else if (healthStatus.services) {\n isHealthy = Object.values(healthStatus.services).every(\n (value) => value === true,\n );\n } else {\n isHealthy = true;\n }\n\n extras = {\n ...healthStatus.services,\n };\n }\n\n const { name: config, version } = this._config.get<{\n name: string;\n version: string;\n }>(['name', 'version']);\n\n const status = isHealthy\n ? this._statuses('ok')\n : this._statuses('service unavailable');\n\n this._responsesBuilder.json({\n res,\n status,\n data: {\n isHealthy,\n status,\n config,\n version,\n ...extras,\n },\n });\n };\n }\n}\n/**\n * The controller that once mounted, it will add an endpoint to show the application\n * health status.\n *\n * @group Controllers\n * @group Controllers/Health\n */\nexport const healthController = controller((app) => {\n const router = app.getRouter();\n const ctrl = new HealthController({\n inject: {\n getHealthStatus: app.isHealthy.bind(app),\n responsesBuilder: app.get('responsesBuilder'),\n config: app.get('config'),\n statuses: app.get('statuses'),\n },\n });\n\n return router.get('/', ctrl.showHealth());\n});\n"],"mappings":";;;AAAA,SAAS,kBAAiC;AAgCnC,MAAM,iBAAiB;AAAA,EAoB5B,YAAY,EAAE,OAAO,GAA4B;AAhBjD,wBAAmB;AAInB,wBAAmB;AAInB,wBAAmB;AAInB,wBAAmB;AAKjB,SAAK,mBAAmB,OAAO;AAC/B,SAAK,oBAAoB,OAAO;AAChC,SAAK,UAAU,OAAO;AACtB,SAAK,YAAY,OAAO;AAAA,EAC1B;AAAA,EAIA,aAAqC;AACnC,WAAO,OAAO,GAAG,QAAQ;AACvB,YAAM,eAAe,MAAM,KAAK,iBAAiB;AACjD,UAAI;AACJ,UAAI;AACJ,UAAI,OAAO,iBAAiB,WAAW;AACrC,oBAAY;AACZ,iBAAS,CAAC;AAAA,MACZ,OAAO;AACL,YAAI,OAAO,aAAa,cAAc,WAAW;AAC/C,sBAAY,aAAa;AAAA,QAC3B,WAAW,aAAa,UAAU;AAChC,sBAAY,OAAO,OAAO,aAAa,QAAQ,EAAE;AAAA,YAC/C,CAAC,UAAU,UAAU;AAAA,UACvB;AAAA,QACF,OAAO;AACL,sBAAY;AAAA,QACd;AAEA,iBAAS;AAAA,UACP,GAAG,aAAa;AAAA,QAClB;AAAA,MACF;AAEA,YAAM,EAAE,MAAM,QAAQ,QAAQ,IAAI,KAAK,QAAQ,IAG5C,CAAC,QAAQ,SAAS,CAAC;AAEtB,YAAM,SAAS,YACX,KAAK,UAAU,IAAI,IACnB,KAAK,UAAU,qBAAqB;AAExC,WAAK,kBAAkB,KAAK;AAAA,QAC1B;AAAA,QACA;AAAA,QACA,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,GAAG;AAAA,QACL;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAQO,MAAM,mBAAmB,WAAW,CAAC,QAAQ;AAClD,QAAM,SAAS,IAAI,UAAU;AAC7B,QAAM,OAAO,IAAI,iBAAiB;AAAA,IAChC,QAAQ;AAAA,MACN,iBAAiB,IAAI,UAAU,KAAK,GAAG;AAAA,MACvC,kBAAkB,IAAI,IAAI,kBAAkB;AAAA,MAC5C,QAAQ,IAAI,IAAI,QAAQ;AAAA,MACxB,UAAU,IAAI,IAAI,UAAU;AAAA,IAC9B;AAAA,EACF,CAAC;AAED,SAAO,OAAO,IAAI,KAAK,KAAK,WAAW,CAAC;AAC1C,CAAC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/controllers/common/health.ts"],"sourcesContent":["import { controller, type Statuses } from '../../utils';\nimport type { ResponsesBuilder } from '../../services';\nimport type { JimpexHealthStatus, Config, AsyncExpressMiddleware } from '../../types';\n/**\n * A function that will return the health status of the application.\n *\n * @group Controllers/Health\n */\nexport type GetHealthStatus = () => Promise<JimpexHealthStatus>;\n/**\n * The options to contruct a {@link HealthController}.\n *\n * @group Controllers/Health\n */\nexport type HealthControllerOptions = {\n /**\n * A dictionary with the dependencies to inject.\n */\n inject: {\n getHealthStatus: GetHealthStatus;\n responsesBuilder: ResponsesBuilder;\n config: Config;\n statuses: Statuses;\n };\n};\n/**\n * The controller class that shows the application health status.\n *\n * @group Controller Classes\n * @group Controllers/Health\n * @prettierignore\n */\nexport class HealthController {\n /**\n * The function that returns the health status of the application.\n */\n protected readonly _getHealthStatus: GetHealthStatus;\n /**\n * The service in charge or building the responses.\n */\n protected readonly _responsesBuilder: ResponsesBuilder;\n /**\n * The service in charge of the configuration.\n */\n protected readonly _config: Config;\n /**\n * The uility service to get HTTP status codes.\n */\n protected readonly _statuses: Statuses;\n /**\n * @param options The options to construct the controller.\n */\n constructor({ inject }: HealthControllerOptions) {\n this._getHealthStatus = inject.getHealthStatus;\n this._responsesBuilder = inject.responsesBuilder;\n this._config = inject.config;\n this._statuses = inject.statuses;\n }\n /**\n * Creates the middleware the shows the application health status.\n */\n showHealth(): AsyncExpressMiddleware {\n return async (_, res) => {\n const healthStatus = await this._getHealthStatus();\n let isHealthy: boolean;\n let extras: Record<string, unknown>;\n if (typeof healthStatus === 'boolean') {\n isHealthy = healthStatus;\n extras = {};\n } else {\n if (typeof healthStatus.isHealthy === 'boolean') {\n isHealthy = healthStatus.isHealthy;\n } else if (healthStatus.services) {\n isHealthy = Object.values(healthStatus.services).every(\n (value) => value === true,\n );\n } else {\n isHealthy = true;\n }\n\n extras = {\n ...healthStatus.services,\n };\n }\n\n const { name: config, version } = this._config.get<{\n name: string;\n version: string;\n }>(['name', 'version']);\n\n const status = isHealthy\n ? this._statuses('ok')\n : this._statuses('service unavailable');\n\n this._responsesBuilder.json({\n res,\n status,\n data: {\n isHealthy,\n status,\n config,\n version,\n ...extras,\n },\n });\n };\n }\n}\n/**\n * The controller that once mounted, it will add an endpoint to show the application\n * health status.\n *\n * @group Controllers\n * @group Controllers/Health\n */\nexport const healthController = controller((app) => {\n const router = app.getRouter();\n const ctrl = new HealthController({\n inject: {\n getHealthStatus: app.isHealthy.bind(app),\n responsesBuilder: app.get('responsesBuilder'),\n config: app.get('config'),\n statuses: app.get('statuses'),\n },\n });\n\n return router.get('/', ctrl.showHealth());\n});\n"],"mappings":";;;AAAA,SAAS,kBAAiC;AAgCnC,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAoB5B,YAAY,EAAE,OAAO,GAA4B;AAhBjD;AAAA;AAAA;AAAA,wBAAmB;AAInB;AAAA;AAAA;AAAA,wBAAmB;AAInB;AAAA;AAAA;AAAA,wBAAmB;AAInB;AAAA;AAAA;AAAA,wBAAmB;AAKjB,SAAK,mBAAmB,OAAO;AAC/B,SAAK,oBAAoB,OAAO;AAChC,SAAK,UAAU,OAAO;AACtB,SAAK,YAAY,OAAO;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAIA,aAAqC;AACnC,WAAO,OAAO,GAAG,QAAQ;AACvB,YAAM,eAAe,MAAM,KAAK,iBAAiB;AACjD,UAAI;AACJ,UAAI;AACJ,UAAI,OAAO,iBAAiB,WAAW;AACrC,oBAAY;AACZ,iBAAS,CAAC;AAAA,MACZ,OAAO;AACL,YAAI,OAAO,aAAa,cAAc,WAAW;AAC/C,sBAAY,aAAa;AAAA,QAC3B,WAAW,aAAa,UAAU;AAChC,sBAAY,OAAO,OAAO,aAAa,QAAQ,EAAE;AAAA,YAC/C,CAAC,UAAU,UAAU;AAAA,UACvB;AAAA,QACF,OAAO;AACL,sBAAY;AAAA,QACd;AAEA,iBAAS;AAAA,UACP,GAAG,aAAa;AAAA,QAClB;AAAA,MACF;AAEA,YAAM,EAAE,MAAM,QAAQ,QAAQ,IAAI,KAAK,QAAQ,IAG5C,CAAC,QAAQ,SAAS,CAAC;AAEtB,YAAM,SAAS,YACX,KAAK,UAAU,IAAI,IACnB,KAAK,UAAU,qBAAqB;AAExC,WAAK,kBAAkB,KAAK;AAAA,QAC1B;AAAA,QACA;AAAA,QACA,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,GAAG;AAAA,QACL;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAQO,MAAM,mBAAmB,WAAW,CAAC,QAAQ;AAClD,QAAM,SAAS,IAAI,UAAU;AAC7B,QAAM,OAAO,IAAI,iBAAiB;AAAA,IAChC,QAAQ;AAAA,MACN,iBAAiB,IAAI,UAAU,KAAK,GAAG;AAAA,MACvC,kBAAkB,IAAI,IAAI,kBAAkB;AAAA,MAC5C,QAAQ,IAAI,IAAI,QAAQ;AAAA,MACxB,UAAU,IAAI,IAAI,UAAU;AAAA,IAC9B;AAAA,EACF,CAAC;AAED,SAAO,OAAO,IAAI,KAAK,KAAK,WAAW,CAAC;AAC1C,CAAC;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__publicField
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-2B2CG5KL.js";
|
|
4
4
|
import * as path from "path";
|
|
5
5
|
import * as mime from "mime";
|
|
6
6
|
import { deepAssignWithOverwrite } from "@homer0/deep-assign";
|
|
@@ -10,9 +10,22 @@ import {
|
|
|
10
10
|
notUndefined
|
|
11
11
|
} from "../../utils";
|
|
12
12
|
class StaticsController {
|
|
13
|
+
/**
|
|
14
|
+
* @param options The options to construct the controller.
|
|
15
|
+
*/
|
|
13
16
|
constructor({ inject, ...options }) {
|
|
17
|
+
/**
|
|
18
|
+
* The service that serves static files.
|
|
19
|
+
*/
|
|
14
20
|
__publicField(this, "_sendFile");
|
|
21
|
+
/**
|
|
22
|
+
* The controller customization options.
|
|
23
|
+
*/
|
|
15
24
|
__publicField(this, "_options");
|
|
25
|
+
/**
|
|
26
|
+
* A dictionary with the formatted definitions of the files that will be served.
|
|
27
|
+
* It uses the files' routes as keys, for easy access in the middleware.
|
|
28
|
+
*/
|
|
16
29
|
__publicField(this, "files");
|
|
17
30
|
this._sendFile = inject.sendFile;
|
|
18
31
|
this._options = this._validateOptions(
|
|
@@ -33,6 +46,13 @@ class StaticsController {
|
|
|
33
46
|
);
|
|
34
47
|
this.files = this._createFiles();
|
|
35
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Mounts the middlewares in the router in order to serve the files.
|
|
51
|
+
*
|
|
52
|
+
* @param router A reference to the application router.
|
|
53
|
+
* @param middlewares A list of extra middlewares to execute before the file
|
|
54
|
+
* middleware.
|
|
55
|
+
*/
|
|
36
56
|
addRoutes(router, middlewares = []) {
|
|
37
57
|
const { methods } = this._options;
|
|
38
58
|
const use = methods.all ? ["all"] : Object.keys(methods).reduce((acc, name) => {
|
|
@@ -51,9 +71,17 @@ class StaticsController {
|
|
|
51
71
|
});
|
|
52
72
|
return router;
|
|
53
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* The controller options.
|
|
76
|
+
*/
|
|
54
77
|
get options() {
|
|
55
78
|
return { ...this._options };
|
|
56
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Generates the middleware that will serve the file.
|
|
82
|
+
*
|
|
83
|
+
* @param file The definition of the file to serve.
|
|
84
|
+
*/
|
|
57
85
|
_getMiddleware(file) {
|
|
58
86
|
return (_, res, next) => {
|
|
59
87
|
const extension = path.parse(file.path).ext.substring(1);
|
|
@@ -71,6 +99,11 @@ class StaticsController {
|
|
|
71
99
|
});
|
|
72
100
|
};
|
|
73
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Mounts the middleware(s) for a file in the router.
|
|
104
|
+
*
|
|
105
|
+
* @param options The information of the file and how it needs to be added.
|
|
106
|
+
*/
|
|
74
107
|
_addRoute({
|
|
75
108
|
router,
|
|
76
109
|
method,
|
|
@@ -81,6 +114,16 @@ class StaticsController {
|
|
|
81
114
|
const { route } = file;
|
|
82
115
|
router[method](route, [...middlewares, fileMiddleware]);
|
|
83
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Validates and formats the options sent to the constructor in order to get the final
|
|
119
|
+
* set that will be stored in the controller.
|
|
120
|
+
*
|
|
121
|
+
* @param options The options to validate.
|
|
122
|
+
* @throws If no files are specified.
|
|
123
|
+
* @throws If methods is not defined.
|
|
124
|
+
* @throws If no methods are enabled.
|
|
125
|
+
* @throws If there's an invalid HTTP method.
|
|
126
|
+
*/
|
|
84
127
|
_validateOptions(options) {
|
|
85
128
|
if (!options.files || !options.files.length) {
|
|
86
129
|
throw new Error("You need to specify a list of files");
|
|
@@ -120,6 +163,10 @@ class StaticsController {
|
|
|
120
163
|
methods: newMethods
|
|
121
164
|
};
|
|
122
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Parses the files received from the constructor's options, and formats them into
|
|
168
|
+
* proper definitions the controller can use.
|
|
169
|
+
*/
|
|
123
170
|
_createFiles() {
|
|
124
171
|
const { files, paths } = this._options;
|
|
125
172
|
const routePath = removeSlashes(paths.route, false, true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/controllers/common/statics.ts"],"sourcesContent":["import * as path from 'path';\nimport * as mime from 'mime';\nimport { deepAssignWithOverwrite } from '@homer0/deep-assign';\nimport {\n controllerCreator,\n removeSlashes,\n notUndefined,\n type MiddlewareLike,\n} from '../../utils';\nimport type { SendFile } from '../../services';\nimport type { Jimpex } from '../../app';\nimport type { DeepPartial, ExpressMiddleware, Router, RouterMethod } from '../../types';\n/**\n * The definition for each file the controller handles.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerFile = {\n /**\n * The route, relative to the controller root, to the file.\n */\n route: string;\n /**\n * The path to the file in the filesystem. Since the file is served using the\n * {@link SendFile} service, whether the file is relative to the project root or the\n * application executable depends on how the service is configured (relative to the\n * executable by default).\n */\n path: string;\n /**\n * A dictionary of headers for the response.\n */\n headers?: Record<string, string>;\n};\n/**\n * These are like \"master paths\" that get prepended to all the file paths and routes the\n * controller use.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerPathsOptions = {\n /**\n * A custom route to prefix all the file routes with.\n */\n route: string;\n /**\n * A custom path to prefix all the file paths with.\n */\n source: string;\n};\n/**\n * The options to customize the controller.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerOptions = {\n /**\n * A list of filenames, or definitions for the files to handle.\n */\n files: Array<string | StaticsControllerFile>;\n /**\n * A dictionary with the allowed router (HTTP) methods the controller can use to serve\n * the files. If `all` is set to `true`, the rest of the values will be ignored.\n *\n * @default {get: true, all: false}\n */\n methods: Partial<Record<RouterMethod, boolean>>;\n /**\n * The \"master paths\" the controller can use to prefix the file paths and routes.\n *\n * @default {route: '', source: './',}\n */\n paths: StaticsControllerPathsOptions;\n};\n/**\n * The options to construct a {@link StaticsController}.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerConstructorOptions =\n DeepPartial<StaticsControllerOptions> & {\n /**\n * A dictionary with the dependencies to inject.\n */\n inject: {\n sendFile: SendFile;\n };\n };\n/**\n * A function to generate a list of middlewares that can be executed before the tontroller\n * main middleware.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerGetMiddlewaresFn = (app: Jimpex) => MiddlewareLike[];\n/**\n * The options for the controller creator that mounts {@link StaticsController}.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerCreatorOptions = DeepPartial<StaticsControllerOptions> & {\n /**\n * A function to generate a list of middlewares that can be executed before the\n * tontroller main middleware.\n */\n getMiddlewares?: StaticsControllerGetMiddlewaresFn;\n};\n/**\n * The options for {@link StaticsController._addRoute}.\n *\n * @access protected\n * @group Controllers/Statics\n */\nexport type AddStaticRouteOptions = {\n /**\n * The reference for the router in which the middlewares will be added.\n */\n router: Router;\n /**\n * The router method in which the middlewares will be added.\n */\n method: RouterMethod;\n /**\n * The definition of the file to serve.\n */\n file: StaticsControllerFile;\n /**\n * The middleware created by {@link StaticsController}, that will serve the file.\n */\n fileMiddleware: ExpressMiddleware;\n /**\n * A list of extra middlewares to execute before the file middleware.\n */\n middlewares: ExpressMiddleware[];\n};\n\n/**\n * The controller class that allows the application to serve specific files from any\n * folder to any route without the need of mounting directories as \"static\".\n *\n * @group Controller Classes\n * @group Controllers/Statics\n * @prettierignore\n */\nexport class StaticsController {\n /**\n * The service that serves static files.\n */\n protected readonly _sendFile: SendFile;\n /**\n * The controller customization options.\n */\n protected _options: StaticsControllerOptions;\n /**\n * A dictionary with the formatted definitions of the files that will be served.\n * It uses the files' routes as keys, for easy access in the middleware.\n */\n protected files: Record<string, StaticsControllerFile>;\n /**\n * @param options The options to construct the controller.\n */\n constructor({ inject, ...options }: StaticsControllerConstructorOptions) {\n this._sendFile = inject.sendFile;\n this._options = this._validateOptions(\n deepAssignWithOverwrite(\n {\n files: ['favicon.ico', 'index.html'],\n methods: options.methods || {\n all: false,\n get: true,\n },\n paths: {\n route: '',\n source: './',\n },\n },\n options,\n ),\n );\n this.files = this._createFiles();\n }\n /**\n * Mounts the middlewares in the router in order to serve the files.\n *\n * @param router A reference to the application router.\n * @param middlewares A list of extra middlewares to execute before the file\n * middleware.\n */\n addRoutes(router: Router, middlewares: ExpressMiddleware[] = []): Router {\n const { methods } = this._options;\n const use: RouterMethod[] = methods.all\n ? ['all']\n : Object.keys(methods).reduce<RouterMethod[]>((acc, name) => {\n const methodName = name as RouterMethod;\n if (methods[methodName]) {\n acc.push(methodName);\n }\n\n return acc;\n }, []);\n\n Object.keys(this.files).forEach((route) => {\n const file = this.files[route as keyof typeof this.files]!;\n const fileMiddleware = this._getMiddleware(file);\n use.forEach((method) =>\n this._addRoute({ router, method, file, fileMiddleware, middlewares }),\n );\n });\n\n return router;\n }\n /**\n * The controller options.\n */\n get options(): Readonly<StaticsControllerOptions> {\n return { ...this._options };\n }\n /**\n * Generates the middleware that will serve the file.\n *\n * @param file The definition of the file to serve.\n */\n protected _getMiddleware(file: StaticsControllerFile): ExpressMiddleware {\n return (_, res, next) => {\n const extension = path.parse(file.path).ext.substring(1);\n const headers = {\n 'Content-Type': mime.getType(extension) || 'text/html',\n ...file.headers,\n };\n\n Object.entries(headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n\n this._sendFile({\n res,\n filepath: file.path,\n next,\n });\n };\n }\n /**\n * Mounts the middleware(s) for a file in the router.\n *\n * @param options The information of the file and how it needs to be added.\n */\n protected _addRoute({\n router,\n method,\n file,\n fileMiddleware,\n middlewares,\n }: AddStaticRouteOptions): void {\n const { route } = file;\n router[method](route, [...middlewares, fileMiddleware]);\n }\n /**\n * Validates and formats the options sent to the constructor in order to get the final\n * set that will be stored in the controller.\n *\n * @param options The options to validate.\n * @throws If no files are specified.\n * @throws If methods is not defined.\n * @throws If no methods are enabled.\n * @throws If there's an invalid HTTP method.\n */\n protected _validateOptions(\n options: StaticsControllerOptions,\n ): StaticsControllerOptions {\n if (!options.files || !options.files.length) {\n throw new Error('You need to specify a list of files');\n }\n\n if (!options.methods) {\n throw new Error('You need to specify which HTTP methods are allowed for the files');\n }\n\n const methods = Object.keys(options.methods) as RouterMethod[];\n\n const atLeastOne = methods.some((method) => options.methods[method]);\n if (!atLeastOne) {\n throw new Error('You need to enable at least one HTTP method to serve the files');\n }\n\n const allowedMethods: RouterMethod[] = [\n 'all',\n 'get',\n 'head',\n 'post',\n 'patch',\n 'put',\n 'delete',\n 'connect',\n 'options',\n 'trace',\n ];\n\n const invalid = methods.find(\n (method) => !allowedMethods.includes(method.toLowerCase() as RouterMethod),\n );\n\n if (invalid) {\n throw new Error(`${invalid} is not a valid HTTP method`);\n }\n\n const newMethods = methods.reduce<Record<string, boolean>>((acc, method) => {\n acc[method.toLowerCase()] = !!options.methods[method];\n return acc;\n }, {});\n\n return {\n ...options,\n methods: newMethods,\n };\n }\n /**\n * Parses the files received from the constructor's options, and formats them into\n * proper definitions the controller can use.\n */\n protected _createFiles(): Record<string, StaticsControllerFile> {\n const { files, paths } = this._options;\n const routePath = removeSlashes(paths.route, false, true);\n return files.reduce<Record<string, StaticsControllerFile>>((acc, file) => {\n let src;\n let route;\n let headers;\n if (typeof file === 'object') {\n ({ route, path: src, headers } = file);\n } else {\n src = file;\n route = file;\n }\n\n src = path.join(paths.source, src);\n route = removeSlashes(route, true, false);\n route = `${routePath}/${route}`;\n acc[route] = {\n path: src,\n route,\n headers: headers || {},\n };\n\n return acc;\n }, {});\n }\n}\n/**\n * A controller that allows the application to server specific files from any folder to\n * any route without the need of mounting directories as \"static\" folders.\n *\n * @group Controllers\n * @group Controllers/Statics\n */\nexport const staticsController = controllerCreator(\n ({ getMiddlewares, ...options }: StaticsControllerCreatorOptions = {}) =>\n (app) => {\n const router = app.getRouter();\n const ctrl = new StaticsController({\n inject: {\n sendFile: app.get('sendFile'),\n },\n ...options,\n });\n\n let useMiddlewares: ExpressMiddleware[] | undefined;\n if (getMiddlewares) {\n useMiddlewares = getMiddlewares(app)\n .map((middleware) => {\n if ('middleware' in middleware) {\n return middleware.connect(app) as ExpressMiddleware | undefined;\n }\n\n return middleware as ExpressMiddleware;\n })\n .filter(notUndefined);\n }\n\n return ctrl.addRoutes(router, useMiddlewares);\n },\n);\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/controllers/common/statics.ts"],"sourcesContent":["import * as path from 'path';\nimport * as mime from 'mime';\nimport { deepAssignWithOverwrite } from '@homer0/deep-assign';\nimport {\n controllerCreator,\n removeSlashes,\n notUndefined,\n type MiddlewareLike,\n} from '../../utils';\nimport type { SendFile } from '../../services';\nimport type { Jimpex } from '../../app';\nimport type { DeepPartial, ExpressMiddleware, Router, RouterMethod } from '../../types';\n/**\n * The definition for each file the controller handles.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerFile = {\n /**\n * The route, relative to the controller root, to the file.\n */\n route: string;\n /**\n * The path to the file in the filesystem. Since the file is served using the\n * {@link SendFile} service, whether the file is relative to the project root or the\n * application executable depends on how the service is configured (relative to the\n * executable by default).\n */\n path: string;\n /**\n * A dictionary of headers for the response.\n */\n headers?: Record<string, string>;\n};\n/**\n * These are like \"master paths\" that get prepended to all the file paths and routes the\n * controller use.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerPathsOptions = {\n /**\n * A custom route to prefix all the file routes with.\n */\n route: string;\n /**\n * A custom path to prefix all the file paths with.\n */\n source: string;\n};\n/**\n * The options to customize the controller.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerOptions = {\n /**\n * A list of filenames, or definitions for the files to handle.\n */\n files: Array<string | StaticsControllerFile>;\n /**\n * A dictionary with the allowed router (HTTP) methods the controller can use to serve\n * the files. If `all` is set to `true`, the rest of the values will be ignored.\n *\n * @default {get: true, all: false}\n */\n methods: Partial<Record<RouterMethod, boolean>>;\n /**\n * The \"master paths\" the controller can use to prefix the file paths and routes.\n *\n * @default {route: '', source: './',}\n */\n paths: StaticsControllerPathsOptions;\n};\n/**\n * The options to construct a {@link StaticsController}.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerConstructorOptions =\n DeepPartial<StaticsControllerOptions> & {\n /**\n * A dictionary with the dependencies to inject.\n */\n inject: {\n sendFile: SendFile;\n };\n };\n/**\n * A function to generate a list of middlewares that can be executed before the tontroller\n * main middleware.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerGetMiddlewaresFn = (app: Jimpex) => MiddlewareLike[];\n/**\n * The options for the controller creator that mounts {@link StaticsController}.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerCreatorOptions = DeepPartial<StaticsControllerOptions> & {\n /**\n * A function to generate a list of middlewares that can be executed before the\n * tontroller main middleware.\n */\n getMiddlewares?: StaticsControllerGetMiddlewaresFn;\n};\n/**\n * The options for {@link StaticsController._addRoute}.\n *\n * @access protected\n * @group Controllers/Statics\n */\nexport type AddStaticRouteOptions = {\n /**\n * The reference for the router in which the middlewares will be added.\n */\n router: Router;\n /**\n * The router method in which the middlewares will be added.\n */\n method: RouterMethod;\n /**\n * The definition of the file to serve.\n */\n file: StaticsControllerFile;\n /**\n * The middleware created by {@link StaticsController}, that will serve the file.\n */\n fileMiddleware: ExpressMiddleware;\n /**\n * A list of extra middlewares to execute before the file middleware.\n */\n middlewares: ExpressMiddleware[];\n};\n\n/**\n * The controller class that allows the application to serve specific files from any\n * folder to any route without the need of mounting directories as \"static\".\n *\n * @group Controller Classes\n * @group Controllers/Statics\n * @prettierignore\n */\nexport class StaticsController {\n /**\n * The service that serves static files.\n */\n protected readonly _sendFile: SendFile;\n /**\n * The controller customization options.\n */\n protected _options: StaticsControllerOptions;\n /**\n * A dictionary with the formatted definitions of the files that will be served.\n * It uses the files' routes as keys, for easy access in the middleware.\n */\n protected files: Record<string, StaticsControllerFile>;\n /**\n * @param options The options to construct the controller.\n */\n constructor({ inject, ...options }: StaticsControllerConstructorOptions) {\n this._sendFile = inject.sendFile;\n this._options = this._validateOptions(\n deepAssignWithOverwrite(\n {\n files: ['favicon.ico', 'index.html'],\n methods: options.methods || {\n all: false,\n get: true,\n },\n paths: {\n route: '',\n source: './',\n },\n },\n options,\n ),\n );\n this.files = this._createFiles();\n }\n /**\n * Mounts the middlewares in the router in order to serve the files.\n *\n * @param router A reference to the application router.\n * @param middlewares A list of extra middlewares to execute before the file\n * middleware.\n */\n addRoutes(router: Router, middlewares: ExpressMiddleware[] = []): Router {\n const { methods } = this._options;\n const use: RouterMethod[] = methods.all\n ? ['all']\n : Object.keys(methods).reduce<RouterMethod[]>((acc, name) => {\n const methodName = name as RouterMethod;\n if (methods[methodName]) {\n acc.push(methodName);\n }\n\n return acc;\n }, []);\n\n Object.keys(this.files).forEach((route) => {\n const file = this.files[route as keyof typeof this.files]!;\n const fileMiddleware = this._getMiddleware(file);\n use.forEach((method) =>\n this._addRoute({ router, method, file, fileMiddleware, middlewares }),\n );\n });\n\n return router;\n }\n /**\n * The controller options.\n */\n get options(): Readonly<StaticsControllerOptions> {\n return { ...this._options };\n }\n /**\n * Generates the middleware that will serve the file.\n *\n * @param file The definition of the file to serve.\n */\n protected _getMiddleware(file: StaticsControllerFile): ExpressMiddleware {\n return (_, res, next) => {\n const extension = path.parse(file.path).ext.substring(1);\n const headers = {\n 'Content-Type': mime.getType(extension) || 'text/html',\n ...file.headers,\n };\n\n Object.entries(headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n\n this._sendFile({\n res,\n filepath: file.path,\n next,\n });\n };\n }\n /**\n * Mounts the middleware(s) for a file in the router.\n *\n * @param options The information of the file and how it needs to be added.\n */\n protected _addRoute({\n router,\n method,\n file,\n fileMiddleware,\n middlewares,\n }: AddStaticRouteOptions): void {\n const { route } = file;\n router[method](route, [...middlewares, fileMiddleware]);\n }\n /**\n * Validates and formats the options sent to the constructor in order to get the final\n * set that will be stored in the controller.\n *\n * @param options The options to validate.\n * @throws If no files are specified.\n * @throws If methods is not defined.\n * @throws If no methods are enabled.\n * @throws If there's an invalid HTTP method.\n */\n protected _validateOptions(\n options: StaticsControllerOptions,\n ): StaticsControllerOptions {\n if (!options.files || !options.files.length) {\n throw new Error('You need to specify a list of files');\n }\n\n if (!options.methods) {\n throw new Error('You need to specify which HTTP methods are allowed for the files');\n }\n\n const methods = Object.keys(options.methods) as RouterMethod[];\n\n const atLeastOne = methods.some((method) => options.methods[method]);\n if (!atLeastOne) {\n throw new Error('You need to enable at least one HTTP method to serve the files');\n }\n\n const allowedMethods: RouterMethod[] = [\n 'all',\n 'get',\n 'head',\n 'post',\n 'patch',\n 'put',\n 'delete',\n 'connect',\n 'options',\n 'trace',\n ];\n\n const invalid = methods.find(\n (method) => !allowedMethods.includes(method.toLowerCase() as RouterMethod),\n );\n\n if (invalid) {\n throw new Error(`${invalid} is not a valid HTTP method`);\n }\n\n const newMethods = methods.reduce<Record<string, boolean>>((acc, method) => {\n acc[method.toLowerCase()] = !!options.methods[method];\n return acc;\n }, {});\n\n return {\n ...options,\n methods: newMethods,\n };\n }\n /**\n * Parses the files received from the constructor's options, and formats them into\n * proper definitions the controller can use.\n */\n protected _createFiles(): Record<string, StaticsControllerFile> {\n const { files, paths } = this._options;\n const routePath = removeSlashes(paths.route, false, true);\n return files.reduce<Record<string, StaticsControllerFile>>((acc, file) => {\n let src;\n let route;\n let headers;\n if (typeof file === 'object') {\n ({ route, path: src, headers } = file);\n } else {\n src = file;\n route = file;\n }\n\n src = path.join(paths.source, src);\n route = removeSlashes(route, true, false);\n route = `${routePath}/${route}`;\n acc[route] = {\n path: src,\n route,\n headers: headers || {},\n };\n\n return acc;\n }, {});\n }\n}\n/**\n * A controller that allows the application to server specific files from any folder to\n * any route without the need of mounting directories as \"static\" folders.\n *\n * @group Controllers\n * @group Controllers/Statics\n */\nexport const staticsController = controllerCreator(\n ({ getMiddlewares, ...options }: StaticsControllerCreatorOptions = {}) =>\n (app) => {\n const router = app.getRouter();\n const ctrl = new StaticsController({\n inject: {\n sendFile: app.get('sendFile'),\n },\n ...options,\n });\n\n let useMiddlewares: ExpressMiddleware[] | undefined;\n if (getMiddlewares) {\n useMiddlewares = getMiddlewares(app)\n .map((middleware) => {\n if ('middleware' in middleware) {\n return middleware.connect(app) as ExpressMiddleware | undefined;\n }\n\n return middleware as ExpressMiddleware;\n })\n .filter(notUndefined);\n }\n\n return ctrl.addRoutes(router, useMiddlewares);\n },\n);\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__publicField
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-2B2CG5KL.js";
|
|
4
4
|
import { deepAssignWithOverwrite } from "@homer0/deep-assign";
|
|
5
5
|
import { flat, unflat } from "@homer0/object-utils";
|
|
6
6
|
import {
|
|
@@ -11,21 +11,59 @@ import {
|
|
|
11
11
|
notUndefined
|
|
12
12
|
} from "../../utils";
|
|
13
13
|
class GatewayController {
|
|
14
|
+
/**
|
|
15
|
+
* @param options The options to construct the controller.
|
|
16
|
+
*/
|
|
14
17
|
constructor({
|
|
15
18
|
inject,
|
|
16
19
|
route,
|
|
17
20
|
gatewayConfig,
|
|
18
21
|
...options
|
|
19
22
|
}) {
|
|
23
|
+
/**
|
|
24
|
+
* The service that makes HTTP requests.
|
|
25
|
+
*/
|
|
20
26
|
__publicField(this, "http");
|
|
27
|
+
/**
|
|
28
|
+
* A function to get a possible helper service. This is injected as a "getter" to not
|
|
29
|
+
* interrupt the DIC "lifecycle": controllers are initialized right when the app
|
|
30
|
+
* starts, and injecting a reference would force the service to be initialized too,
|
|
31
|
+
* even if a request is not being made.
|
|
32
|
+
*/
|
|
21
33
|
__publicField(this, "_getHelperService");
|
|
34
|
+
/**
|
|
35
|
+
* The information, url and endpoints, for the gateway the controller will make requests to.
|
|
36
|
+
*/
|
|
22
37
|
__publicField(this, "_gatewayConfig");
|
|
38
|
+
/**
|
|
39
|
+
* The route in which the controller is mounted.
|
|
40
|
+
*/
|
|
23
41
|
__publicField(this, "_route");
|
|
42
|
+
/**
|
|
43
|
+
* A regular expression that will be used to remove the controller route from a
|
|
44
|
+
* request path. This will allow the main middleware to extract the path to where the
|
|
45
|
+
* request should be made.
|
|
46
|
+
*/
|
|
24
47
|
__publicField(this, "_routeExpression");
|
|
48
|
+
/**
|
|
49
|
+
* The controller customization options.
|
|
50
|
+
*/
|
|
25
51
|
__publicField(this, "_options");
|
|
52
|
+
/**
|
|
53
|
+
* A flat dictionary with the endpoints information.
|
|
54
|
+
*/
|
|
26
55
|
__publicField(this, "_endpoints");
|
|
56
|
+
/**
|
|
57
|
+
* The entry URL for the API client configuration the controller can generate.
|
|
58
|
+
*/
|
|
27
59
|
__publicField(this, "_apiConfigUrl");
|
|
60
|
+
/**
|
|
61
|
+
* The generated endpoints for the API client configuration the controller can generate.
|
|
62
|
+
*/
|
|
28
63
|
__publicField(this, "_apiConfigEndpoints");
|
|
64
|
+
/**
|
|
65
|
+
* The list of routes the controller can handle.
|
|
66
|
+
*/
|
|
29
67
|
__publicField(this, "_routes");
|
|
30
68
|
this.http = inject.http;
|
|
31
69
|
this._getHelperService = inject.getHelperService || (() => void 0);
|
|
@@ -60,6 +98,11 @@ class GatewayController {
|
|
|
60
98
|
this._apiConfigUrl = url;
|
|
61
99
|
this._apiConfigEndpoints = endpoints;
|
|
62
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Generates an API client configuration based on the controller routes.
|
|
103
|
+
*
|
|
104
|
+
* @param options The options to customize the generated configuration.
|
|
105
|
+
*/
|
|
63
106
|
getAPIConfig({
|
|
64
107
|
setting,
|
|
65
108
|
placeholders = {}
|
|
@@ -82,6 +125,13 @@ class GatewayController {
|
|
|
82
125
|
}
|
|
83
126
|
};
|
|
84
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Mounts the middlewares in the router in order to make the requests.
|
|
130
|
+
*
|
|
131
|
+
* @param router A reference to the application router.
|
|
132
|
+
* @param middlewares A list of extra middlewares to execute before the gateway
|
|
133
|
+
* middleware.
|
|
134
|
+
*/
|
|
85
135
|
addRoutes(router, middlewares = []) {
|
|
86
136
|
this._routes.forEach((route) => {
|
|
87
137
|
route.methods.forEach((info) => {
|
|
@@ -96,12 +146,24 @@ class GatewayController {
|
|
|
96
146
|
});
|
|
97
147
|
return router;
|
|
98
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* The customization options.
|
|
151
|
+
*/
|
|
99
152
|
get options() {
|
|
100
153
|
return { ...this._options };
|
|
101
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* The configuration for the gateway the controller will make requests to.
|
|
157
|
+
*/
|
|
102
158
|
get gatewayConfig() {
|
|
103
159
|
return { ...this._gatewayConfig };
|
|
104
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Generates a middleware that will make the request to an endpoint and stream the
|
|
163
|
+
* response.
|
|
164
|
+
*
|
|
165
|
+
* @param endpoint The information of the endpoint the middleware will handle.
|
|
166
|
+
*/
|
|
105
167
|
_createGatewayMiddleware(endpoint) {
|
|
106
168
|
return async (req, res, next) => {
|
|
107
169
|
const {
|
|
@@ -189,6 +251,11 @@ class GatewayController {
|
|
|
189
251
|
}
|
|
190
252
|
};
|
|
191
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Mounts the middleware(s) for an endpoint in the router.
|
|
256
|
+
*
|
|
257
|
+
* @param options The information of the endpoint and how it needs to be added.
|
|
258
|
+
*/
|
|
192
259
|
_addRoute({
|
|
193
260
|
router,
|
|
194
261
|
method,
|
|
@@ -198,6 +265,9 @@ class GatewayController {
|
|
|
198
265
|
}) {
|
|
199
266
|
router[method](route, [...middlewares, gatewayMiddleware]);
|
|
200
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Formats the endpoints for the gateway into a flat dictionary without nesting.
|
|
270
|
+
*/
|
|
201
271
|
_formatEndpoints() {
|
|
202
272
|
return flat({
|
|
203
273
|
target: this._gatewayConfig.gateway,
|
|
@@ -207,6 +277,13 @@ class GatewayController {
|
|
|
207
277
|
}
|
|
208
278
|
});
|
|
209
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Based on the information from the endpoints, this method will create the routes the
|
|
282
|
+
* controller will later add on a router.
|
|
283
|
+
*
|
|
284
|
+
* @throws If there's more than one endpoint using the same path with the same HTTP
|
|
285
|
+
* method.
|
|
286
|
+
*/
|
|
210
287
|
_createRoutes() {
|
|
211
288
|
const routes = {};
|
|
212
289
|
Object.keys(this._endpoints).forEach((name) => {
|
|
@@ -256,6 +333,18 @@ class GatewayController {
|
|
|
256
333
|
};
|
|
257
334
|
});
|
|
258
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* This is a "proxy method" to call the helper service's function that can modify an
|
|
338
|
+
* endpoint request before it gets made.
|
|
339
|
+
*
|
|
340
|
+
* The reason this is a "proxy method" is in case the controller gets subclassed and
|
|
341
|
+
* "used itself as a helper" instead of relying on a difference one.
|
|
342
|
+
*
|
|
343
|
+
* If the helper doesn't implement `reduceEndpointRequest`, it will just return
|
|
344
|
+
* information for the request.
|
|
345
|
+
*
|
|
346
|
+
* @param options The information of the request and the reference to the helper.
|
|
347
|
+
*/
|
|
259
348
|
_reduceEndpointRequest({
|
|
260
349
|
helper,
|
|
261
350
|
...options
|
|
@@ -265,6 +354,18 @@ class GatewayController {
|
|
|
265
354
|
}
|
|
266
355
|
return Promise.resolve(options.endpointReq);
|
|
267
356
|
}
|
|
357
|
+
/**
|
|
358
|
+
* This is a "proxy method" to call the helper service's function that can modify an
|
|
359
|
+
* endpoint response before it gets processed.
|
|
360
|
+
*
|
|
361
|
+
* The reason this is a "proxy method" is in case the controller gets subclassed and
|
|
362
|
+
* "used itself as a helper" instead of relying on a difference one.
|
|
363
|
+
*
|
|
364
|
+
* If the helper doesn't implement `reduceEndpointResponse`, it will just return
|
|
365
|
+
* information for the response.
|
|
366
|
+
*
|
|
367
|
+
* @param options The information of the response and the reference to the helper.
|
|
368
|
+
*/
|
|
268
369
|
_reduceEndpointResponse({
|
|
269
370
|
helper,
|
|
270
371
|
...options
|
|
@@ -274,6 +375,18 @@ class GatewayController {
|
|
|
274
375
|
}
|
|
275
376
|
return Promise.resolve(options.endpointRes);
|
|
276
377
|
}
|
|
378
|
+
/**
|
|
379
|
+
* This is a "proxy method" to call the helper service's function that can decide if an
|
|
380
|
+
* endpoint response should be streamed or not.
|
|
381
|
+
*
|
|
382
|
+
* The reason this is a "proxy method" is in case the controller gets subclassed and
|
|
383
|
+
* "used itself as a helper" instead of relying on a difference one.
|
|
384
|
+
*
|
|
385
|
+
* If the helper doesn't implement `shouldStreamEndpointResponse`, it will just return
|
|
386
|
+
* `true`.
|
|
387
|
+
*
|
|
388
|
+
* @param options The information of the response and the reference to the helper.
|
|
389
|
+
*/
|
|
277
390
|
_shouldStreamEndpointResponse({
|
|
278
391
|
helper,
|
|
279
392
|
...options
|
|
@@ -283,6 +396,19 @@ class GatewayController {
|
|
|
283
396
|
}
|
|
284
397
|
return Promise.resolve(true);
|
|
285
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* This is a "proxy method" to call the helper service's function that handles a
|
|
401
|
+
* response in case it already said that a response shouldn't be streamed.
|
|
402
|
+
*
|
|
403
|
+
* The reason this is a "proxy method" is in case the controller gets subclassed and
|
|
404
|
+
* "used itself as a helper" instead of relying on a difference one.
|
|
405
|
+
*
|
|
406
|
+
* If the helper doesn't implement `shouldStreamEndpointResponse`, it will throw an
|
|
407
|
+
* error.
|
|
408
|
+
*
|
|
409
|
+
* @param options The information of the response and the reference to the helper.
|
|
410
|
+
* @throws If the helper doesn't implement `handleEndpointResponse`.
|
|
411
|
+
*/
|
|
286
412
|
_handleEndpointResponse({
|
|
287
413
|
helper,
|
|
288
414
|
...options
|
|
@@ -292,6 +418,18 @@ class GatewayController {
|
|
|
292
418
|
}
|
|
293
419
|
return helper.handleEndpointResponse(options);
|
|
294
420
|
}
|
|
421
|
+
/**
|
|
422
|
+
* This is a "proxy method" to call the helper service's function that handles an error
|
|
423
|
+
* on an endpoint request.
|
|
424
|
+
*
|
|
425
|
+
* The reason this is a "proxy method" is in case the controller gets subclassed and
|
|
426
|
+
* "used itself as a helper" instead of relying on a difference one.
|
|
427
|
+
*
|
|
428
|
+
* If the helper doesn't implement `handleEndpointError`, it will just send the error to
|
|
429
|
+
* the next middleware/error handler.
|
|
430
|
+
*
|
|
431
|
+
* @param options The information of the response and the reference to the helper.
|
|
432
|
+
*/
|
|
295
433
|
_handleEndpointError({
|
|
296
434
|
helper,
|
|
297
435
|
...options
|
|
@@ -301,6 +439,11 @@ class GatewayController {
|
|
|
301
439
|
}
|
|
302
440
|
return options.next(options.error);
|
|
303
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* Validates and formats the customization options sent to the controller.
|
|
444
|
+
*
|
|
445
|
+
* @param options The options sent to the constructor.
|
|
446
|
+
*/
|
|
304
447
|
_formatOptions(options) {
|
|
305
448
|
if (options.root) {
|
|
306
449
|
const root = removeSlashes(options.root).trim();
|
|
@@ -308,6 +451,12 @@ class GatewayController {
|
|
|
308
451
|
}
|
|
309
452
|
return options;
|
|
310
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Validates a router/HTTP method that the controller intends to use for an endpoint. If
|
|
456
|
+
* it's not valid, it will return `all`.
|
|
457
|
+
*
|
|
458
|
+
* @param method The HTTP method for the endpoint.
|
|
459
|
+
*/
|
|
311
460
|
_validateHTTPMethod(method) {
|
|
312
461
|
const newMethod = method.toLowerCase();
|
|
313
462
|
return [
|
|
@@ -322,6 +471,9 @@ class GatewayController {
|
|
|
322
471
|
"trace"
|
|
323
472
|
].includes(newMethod) ? newMethod : "all";
|
|
324
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* Creates the API client configuration based on the controller routes.
|
|
476
|
+
*/
|
|
325
477
|
_createAPIConfig() {
|
|
326
478
|
let endpoints;
|
|
327
479
|
const { root } = this._options;
|