jimpex 9.0.0 → 10.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.
Files changed (142) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/app/index.d.mts +1 -1
  3. package/dist/app/index.d.ts +1 -1
  4. package/dist/app/jimpex.d.mts +1 -1
  5. package/dist/app/jimpex.d.ts +1 -1
  6. package/dist/app/jimpex.js +13 -2
  7. package/dist/app/jimpex.js.map +1 -1
  8. package/dist/controllers/common/config.d.mts +2 -2
  9. package/dist/controllers/common/config.d.ts +2 -2
  10. package/dist/controllers/common/health.d.mts +3 -3
  11. package/dist/controllers/common/health.d.ts +3 -3
  12. package/dist/controllers/common/index.d.mts +2 -1
  13. package/dist/controllers/common/index.d.ts +2 -1
  14. package/dist/controllers/common/statics.d.mts +10 -2
  15. package/dist/controllers/common/statics.d.ts +10 -2
  16. package/dist/controllers/common/statics.js +9 -3
  17. package/dist/controllers/common/statics.js.map +1 -1
  18. package/dist/controllers/index.d.mts +2 -1
  19. package/dist/controllers/index.d.ts +2 -1
  20. package/dist/controllers/utils/gateway.d.mts +2 -2
  21. package/dist/controllers/utils/gateway.d.ts +2 -2
  22. package/dist/controllers/utils/gateway.js +3 -0
  23. package/dist/controllers/utils/gateway.js.map +1 -1
  24. package/dist/controllers/utils/index.d.mts +1 -1
  25. package/dist/controllers/utils/index.d.ts +1 -1
  26. package/dist/esm/app/jimpex.js +14 -3
  27. package/dist/esm/app/jimpex.js.map +1 -1
  28. package/dist/esm/{chunk-2B2CG5KL.js → chunk-F3FYYIAV.js} +1 -1
  29. package/dist/esm/controllers/common/config.js +1 -1
  30. package/dist/esm/controllers/common/health.js +1 -1
  31. package/dist/esm/controllers/common/statics.js +10 -4
  32. package/dist/esm/controllers/common/statics.js.map +1 -1
  33. package/dist/esm/controllers/utils/gateway.js +4 -1
  34. package/dist/esm/controllers/utils/gateway.js.map +1 -1
  35. package/dist/esm/middlewares/common/errorHandler.js +1 -1
  36. package/dist/esm/middlewares/common/forceHTTPS.js +1 -1
  37. package/dist/esm/middlewares/common/hsts.js +1 -1
  38. package/dist/esm/middlewares/html/fastHTML.js +1 -1
  39. package/dist/esm/middlewares/html/showHTML.js +1 -1
  40. package/dist/esm/middlewares/utils/versionValidator.js +1 -1
  41. package/dist/esm/services/common/appError.js +1 -1
  42. package/dist/esm/services/common/httpError.js +1 -1
  43. package/dist/esm/services/common/index.js +1 -1
  44. package/dist/esm/services/common/sendFile.js +1 -1
  45. package/dist/esm/services/frontend/frontendFs.js +1 -1
  46. package/dist/esm/services/frontend/index.js +1 -1
  47. package/dist/esm/services/html/htmlGenerator.js +1 -1
  48. package/dist/esm/services/html/index.js +1 -1
  49. package/dist/esm/services/http/apiClient.js +1 -1
  50. package/dist/esm/services/http/http.js +11 -5
  51. package/dist/esm/services/http/http.js.map +1 -1
  52. package/dist/esm/services/http/index.js +1 -1
  53. package/dist/esm/services/http/responsesBuilder.js +1 -1
  54. package/dist/esm/services/utils/ensureBearerToken.js +1 -1
  55. package/dist/esm/services/utils/index.js +1 -1
  56. package/dist/esm/utils/fns/others.js +1 -1
  57. package/dist/esm/utils/fns/routes.js +1 -1
  58. package/dist/esm/utils/fns/statuses.js +1 -1
  59. package/dist/esm/utils/fns/text.js +1 -1
  60. package/dist/esm/utils/wrappers.js +1 -1
  61. package/dist/{index-efeb437e.d.ts → index-Bwf7JHu9.d.mts} +6 -1
  62. package/dist/{index-b2a04c78.d.ts → index-C6I3NCC-.d.ts} +6 -1
  63. package/dist/index.d.mts +3 -2
  64. package/dist/index.d.ts +3 -2
  65. package/dist/middlewares/common/errorHandler.d.mts +3 -3
  66. package/dist/middlewares/common/errorHandler.d.ts +3 -3
  67. package/dist/middlewares/common/forceHTTPS.d.mts +3 -3
  68. package/dist/middlewares/common/forceHTTPS.d.ts +3 -3
  69. package/dist/middlewares/common/hsts.d.mts +3 -3
  70. package/dist/middlewares/common/hsts.d.ts +3 -3
  71. package/dist/middlewares/common/index.d.mts +1 -1
  72. package/dist/middlewares/common/index.d.ts +1 -1
  73. package/dist/middlewares/html/fastHTML.d.mts +2 -2
  74. package/dist/middlewares/html/fastHTML.d.ts +2 -2
  75. package/dist/middlewares/html/index.d.mts +1 -1
  76. package/dist/middlewares/html/index.d.ts +1 -1
  77. package/dist/middlewares/html/showHTML.d.mts +2 -2
  78. package/dist/middlewares/html/showHTML.d.ts +2 -2
  79. package/dist/middlewares/index.d.mts +1 -1
  80. package/dist/middlewares/index.d.ts +1 -1
  81. package/dist/middlewares/utils/index.d.mts +1 -1
  82. package/dist/middlewares/utils/index.d.ts +1 -1
  83. package/dist/middlewares/utils/versionValidator.d.mts +2 -2
  84. package/dist/middlewares/utils/versionValidator.d.ts +2 -2
  85. package/dist/services/common/appError.d.mts +2 -2
  86. package/dist/services/common/appError.d.ts +2 -2
  87. package/dist/services/common/httpError.d.mts +2 -2
  88. package/dist/services/common/httpError.d.ts +2 -2
  89. package/dist/services/common/index.d.mts +1 -1
  90. package/dist/services/common/index.d.ts +1 -1
  91. package/dist/services/common/sendFile.d.mts +2 -2
  92. package/dist/services/common/sendFile.d.ts +2 -2
  93. package/dist/services/frontend/frontendFs.d.mts +2 -2
  94. package/dist/services/frontend/frontendFs.d.ts +2 -2
  95. package/dist/services/frontend/index.d.mts +1 -1
  96. package/dist/services/frontend/index.d.ts +1 -1
  97. package/dist/services/html/htmlGenerator.d.mts +2 -2
  98. package/dist/services/html/htmlGenerator.d.ts +2 -2
  99. package/dist/services/html/index.d.mts +1 -1
  100. package/dist/services/html/index.d.ts +1 -1
  101. package/dist/services/http/apiClient.d.mts +2 -2
  102. package/dist/services/http/apiClient.d.ts +2 -2
  103. package/dist/services/http/http.d.mts +14 -8
  104. package/dist/services/http/http.d.ts +14 -8
  105. package/dist/services/http/http.js +10 -4
  106. package/dist/services/http/http.js.map +1 -1
  107. package/dist/services/http/index.d.mts +1 -1
  108. package/dist/services/http/index.d.ts +1 -1
  109. package/dist/services/http/responsesBuilder.d.mts +2 -2
  110. package/dist/services/http/responsesBuilder.d.ts +2 -2
  111. package/dist/services/index.d.mts +1 -1
  112. package/dist/services/index.d.ts +1 -1
  113. package/dist/services/utils/ensureBearerToken.d.mts +3 -3
  114. package/dist/services/utils/ensureBearerToken.d.ts +3 -3
  115. package/dist/services/utils/index.d.mts +1 -1
  116. package/dist/services/utils/index.d.ts +1 -1
  117. package/dist/types/events.d.mts +1 -1
  118. package/dist/types/events.d.ts +1 -1
  119. package/dist/types/express.d.mts +1 -1
  120. package/dist/types/express.d.ts +1 -1
  121. package/dist/types/http.d.mts +5 -2
  122. package/dist/types/http.d.ts +5 -2
  123. package/dist/types/http.js.map +1 -1
  124. package/dist/types/index.d.mts +2 -2
  125. package/dist/types/index.d.ts +2 -2
  126. package/dist/types/options.d.mts +1 -1
  127. package/dist/types/options.d.ts +1 -1
  128. package/dist/types/utils.d.mts +1 -1
  129. package/dist/types/utils.d.ts +1 -1
  130. package/dist/utils/fns/statuses.d.mts +1 -1
  131. package/dist/utils/fns/statuses.d.ts +1 -1
  132. package/dist/utils/index.d.mts +1 -1
  133. package/dist/utils/index.d.ts +1 -1
  134. package/dist/utils/wrappers.d.mts +1 -1
  135. package/dist/utils/wrappers.d.ts +1 -1
  136. package/package.json +45 -44
  137. package/src/app/jimpex.ts +15 -2
  138. package/src/controllers/common/statics.ts +13 -2
  139. package/src/controllers/utils/gateway.ts +4 -0
  140. package/src/services/http/http.ts +13 -4
  141. package/src/types/http.ts +3 -0
  142. /package/dist/esm/{chunk-2B2CG5KL.js.map → chunk-F3FYYIAV.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ # [10.0.0](https://github.com/homer0/jimpex/compare/9.0.0...10.0.0) (2024-04-07)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * load node-fetch and mime on start ([01a39dd](https://github.com/homer0/jimpex/commit/01a39dd9f0e5a6300fda79ca85b771c2762470f3))
7
+ * throw if the gateway response body is null ([32bcd95](https://github.com/homer0/jimpex/commit/32bcd95c56f236dd13e32b5025b2b02ff8fbe2c1))
8
+ * update all dependencies ([7b833ff](https://github.com/homer0/jimpex/commit/7b833fff52971a254f25f45374373c2ec514936b))
9
+ * use mime from the container in the statics controller ([033b15c](https://github.com/homer0/jimpex/commit/033b15cb08209b9353aa467cfdbd72fd729c491f))
10
+ * use node-fetch from the container in the http service ([f8237e4](https://github.com/homer0/jimpex/commit/f8237e4f85490b2a473c23c591e2a9d4ae77b7f8))
11
+ * use ts-async-import ([95cf29b](https://github.com/homer0/jimpex/commit/95cf29bc4ac80cbf7e2946c8f0d760a36c4e6bf3))
12
+
13
+
14
+ ### BREAKING CHANGES
15
+
16
+ * The HTTP service change its 'inject' options in order to
17
+ include 'node-fetch'.
18
+ * StaticsController changed its 'inject' options in order to
19
+ include 'mime'.
20
+
1
21
  # [9.0.0](https://github.com/homer0/jimpex/compare/8.0.0...9.0.0) (2023-10-02)
2
22
 
3
23
 
@@ -1,4 +1,4 @@
1
- export { J as Jimpex, j as jimpex } from '../index-efeb437e.js';
1
+ export { J as Jimpex, j as jimpex } from '../index-Bwf7JHu9.mjs';
2
2
  import '../types/express.mjs';
3
3
  import 'express';
4
4
  import '../types/http.mjs';
@@ -1,4 +1,4 @@
1
- export { J as Jimpex, j as jimpex } from '../index-b2a04c78.js';
1
+ export { J as Jimpex, j as jimpex } from '../index-C6I3NCC-.js';
2
2
  import '../types/express.js';
3
3
  import 'express';
4
4
  import '../types/http.js';
@@ -1,6 +1,6 @@
1
1
  import '@homer0/jimple';
2
2
  import '@homer0/events-hub';
3
- export { J as Jimpex, j as jimpex } from '../index-efeb437e.js';
3
+ export { J as Jimpex, j as jimpex } from '../index-Bwf7JHu9.mjs';
4
4
  import 'express';
5
5
  import '../types/http.mjs';
6
6
  import '../types/utils.mjs';
@@ -1,6 +1,6 @@
1
1
  import '@homer0/jimple';
2
2
  import '@homer0/events-hub';
3
- export { J as Jimpex, j as jimpex } from '../index-b2a04c78.js';
3
+ export { J as Jimpex, j as jimpex } from '../index-C6I3NCC-.js';
4
4
  import 'express';
5
5
  import '../types/http.js';
6
6
  import '../types/utils.js';
@@ -47,6 +47,7 @@ var import_env_utils = require("@homer0/env-utils");
47
47
  var import_package_info = require("@homer0/package-info");
48
48
  var import_path_utils = require("@homer0/path-utils");
49
49
  var import_root_file = require("@homer0/root-file");
50
+ var import_ts_async_import = require("@homer0/ts-async-import");
50
51
  var import_events_hub = require("@homer0/events-hub");
51
52
  var import_simple_config = require("@homer0/simple-config");
52
53
  var import_compression = __toESM(require("compression"));
@@ -170,7 +171,7 @@ class Jimpex extends import_jimple.Jimple {
170
171
  * @returns The server instance.
171
172
  */
172
173
  async start(onStart) {
173
- await this._setupConfig();
174
+ await Promise.all([this._setupConfig(), this._loadESMModules()]);
174
175
  const config = this.getConfig();
175
176
  const port = config.get("port");
176
177
  if (!port) {
@@ -203,7 +204,7 @@ class Jimpex extends import_jimple.Jimple {
203
204
  */
204
205
  async listen(port, onStart) {
205
206
  if (port) {
206
- await this._setupConfig();
207
+ await Promise.all([this._setupConfig(), this._loadESMModules()]);
207
208
  const config = this.getConfig();
208
209
  config.set("port", port);
209
210
  }
@@ -553,6 +554,16 @@ class Jimpex extends import_jimple.Jimple {
553
554
  await config.loadFromEnv();
554
555
  }
555
556
  }
557
+ /**
558
+ * Loads the ESM modules that are needed by Jimpex. This is called just before the starting
559
+ * the application so they'll be available for all the services.
560
+ */
561
+ async _loadESMModules() {
562
+ const { default: nodeFetch } = await (0, import_ts_async_import.tsAsyncImport)("node-fetch");
563
+ const { default: mime } = await (0, import_ts_async_import.tsAsyncImport)("mime");
564
+ this.set("node-fetch", () => nodeFetch);
565
+ this.set("mime", () => mime);
566
+ }
556
567
  /**
557
568
  * Processes the resources from the mount queue (added with {@link Jimpex.mount} and
558
569
  * {@link Jimpex.use}), and adds them to the Express application.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/app/jimpex.ts"],"sourcesContent":["import * as path from 'path';\nimport fs from 'fs/promises';\nimport { createServer as createHTTPSServer } from 'https';\nimport { Jimple } from '@homer0/jimple';\nimport { deepAssignWithOverwrite } from '@homer0/deep-assign';\nimport { appLoggerProvider } from '@homer0/simple-logger';\nimport { envUtilsProvider } from '@homer0/env-utils';\nimport { packageInfoProvider } from '@homer0/package-info';\nimport { pathUtilsProvider } from '@homer0/path-utils';\nimport { rootFileProvider } from '@homer0/root-file';\nimport { EventsHub } from '@homer0/events-hub';\nimport { simpleConfigProvider } from '@homer0/simple-config';\nimport compression from 'compression';\nimport bodyParser from 'body-parser';\nimport multer from 'multer';\nimport {\n createServer as createSpdyServer,\n type ServerOptions as SpdyServerOptions,\n} from 'spdy';\nimport express from 'express';\nimport {\n commonServicesProvider,\n httpServicesProvider,\n utilsServicesProvider,\n} from '../services';\nimport {\n statuses,\n type Controller,\n type ControllerLike,\n type MiddlewareLike,\n type MiddlewareProvider,\n type Middleware,\n} from '../utils';\nimport type {\n DeepPartial,\n Express,\n ExpressMiddlewareLike,\n PathUtils,\n Config,\n Logger,\n JimpexOptions,\n JimpexHTTPSCredentials,\n JimpexHTTP2Options,\n JimpexHTTPSOptions,\n JimpexStartCallback,\n JimpexServer,\n JimpexServerInstance,\n JimpexEventName,\n JimpexEventPayload,\n DeepReadonly,\n JimpexReducerEventName,\n JimpexReducerEventPayload,\n JimpexReducerEventTarget,\n JimpexEventNameLike,\n JimpexEventListener,\n JimpexHealthCheckFn,\n Router,\n} from '../types';\n/**\n * Jimpex is a mix of Jimple, a Javascript port of Pimple dependency injection container,\n * and Express, one of the most popular web frameworks for Node.\n *\n * @group Jimpex\n * @todo Implement `helmet`.\n */\nexport class Jimpex extends Jimple {\n /**\n * The customization settings for the application.\n */\n protected _options: JimpexOptions;\n /**\n * The Express application Jimpex uses under the hood.\n */\n protected _express: Express;\n /**\n * Since the configuration service has an async initialization, the class uses this flag\n * internally to validate if the configuration has been initialized or not.\n */\n protected _configReady: boolean = false;\n /**\n * A reference to the actuall HTTP the application will use. This can vary depending on\n * whether HTTPS, or HTTP2 are enabled. If HTTPS is not enabled, it will be the same as\n * the `express` property; if HTTPS is enabled, it will be an `https` server; and if\n * HTTP2 is enabled, it will be an `spdy` server.\n */\n protected _server?: JimpexServer;\n /**\n * The instance of the server that is listening for requests.\n */\n protected _instance?: JimpexServerInstance;\n /**\n * A list of functions that implement controllers and middlewares. When the application\n * starts, the queue will be processed and those controllers and middlewares will be\n * added to the server instance. The reason they are not added directly like with a\n * regular Express implementation is that services on Jimple use lazy loading, and\n * adding middlewares and controllers as they come could cause errors if they depend on\n * services that are not yet registered.\n */\n protected _mountQueue: Array<(server: Express) => void> = [];\n /**\n * A list with all the top routes controlled by the application. Every time a controller\n * is mounted, its route will be added here.\n */\n protected _controlledRoutes: string[] = [];\n /**\n * @param options Preferences to customize the application.\n * @param config The default settings for the configuration service. It's a\n * shortcuit for `options.config.default`\n */\n constructor(options: DeepPartial<JimpexOptions> = {}, config: unknown = {}) {\n super();\n\n this._options = deepAssignWithOverwrite(\n {\n filesizeLimit: '15MB',\n boot: true,\n path: {\n appPath: '',\n useParentPath: true,\n },\n config: {\n default: options?.config?.default || config,\n name: 'app',\n path: 'config/',\n hasFolder: false,\n loadFromEnvironment: true,\n environmentVariable: 'CONFIG',\n defaultConfigFilename: '[app-name].config.js',\n filenameFormat: '[app-name].[config-name].config.js',\n },\n statics: {\n enabled: true,\n onHome: false,\n route: 'statics',\n },\n express: {\n trustProxy: true,\n disableXPoweredBy: true,\n compression: true,\n bodyParser: true,\n multer: true,\n },\n services: {\n common: true,\n http: true,\n utils: true,\n },\n healthCheck: () => Promise.resolve(true),\n },\n options,\n this._initOptions(),\n );\n\n this._express = express();\n\n this._setupCoreServices();\n this._setupExpress();\n this._configurePath();\n\n this._init();\n if (this._options.boot) {\n this.boot();\n }\n }\n /**\n * This is where the app would register all its specific services, middlewares and controllers.\n */\n boot(): void {}\n /**\n * Disables the server TLS validation. Meant to be used for development purposes.\n */\n disableTLSValidation() {\n // eslint-disable-next-line no-process-env, dot-notation\n process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';\n this.logger.warn('TLS validation has been disabled');\n }\n /**\n * Starts the app server.\n *\n * @param onStart A callback function to be called when the server actually starts.\n * @returns The server instance.\n */\n async start(onStart?: JimpexStartCallback): Promise<JimpexServerInstance> {\n await this._setupConfig();\n const config = this.getConfig();\n const port = config.get<number | undefined>('port');\n if (!port) {\n throw new Error('No port configured');\n }\n this._emitEvent('beforeStart', { app: this });\n this._server = await this._createServer();\n this._instance = this._server!.listen(port, () => {\n this._emitEvent('start', { app: this });\n this._mountResources();\n this.logger.success(`Starting on port ${port}`);\n this._emitEvent('afterStart', { app: this });\n if (onStart) {\n onStart(config);\n }\n this._emitEvent('afterStartCallback', { app: this });\n });\n\n return this._instance!;\n }\n /**\n * This is an alias of `start`. The idea is for it to be used on serverless platforms,\n * where you don't get to start your app, you just have export it.\n *\n * @param port In case the configuration doesn't already have it,\n * this is the port where the application will use to run. If this\n * parameter is used, the method will overwrite the `port`\n * setting on the configuration service.\n * @param onStart A callback function to be called when the server starts.\n * @returns The server instance.\n */\n async listen(\n port?: number,\n onStart?: JimpexStartCallback,\n ): Promise<JimpexServerInstance> {\n if (port) {\n await this._setupConfig();\n const config = this.getConfig();\n config.set('port', port);\n }\n\n return this.start(onStart);\n }\n /**\n * Stops the server instance.\n */\n stop(): void {\n if (!this._instance) return;\n this._emitEvent('beforeStop', { app: this });\n this._instance.close();\n this._instance = undefined;\n this._emitEvent('afterStop', { app: this });\n }\n /**\n * Mounts a route controller or a middleware into a server routes.\n *\n * @param route The route for the controller/middleware.\n * @param controller The controller/middleware resource to be mounted.\n */\n mount(route: string, controller: ControllerLike): void {\n let useController: Controller | Middleware;\n if (\n 'register' in controller &&\n typeof controller.register === 'function' &&\n controller.provider === true\n ) {\n useController = controller.register(this, route);\n } else if (\n 'connect' in controller &&\n typeof controller.connect === 'function' &&\n (('middleware' in controller && controller.middleware === true) ||\n ('controller' in controller && controller.controller === true))\n ) {\n useController = controller;\n } else {\n useController = {\n middleware: true,\n connect: () => controller as ExpressMiddlewareLike,\n };\n }\n\n this._mountQueue.push((server) => {\n const connected = useController.connect(this, route);\n if (!connected) return;\n const router = this._reduceWithEvent('controllerWillBeMounted', connected, {\n route,\n controller: useController,\n app: this,\n });\n server.use(route, router);\n this._emitEvent('routeAdded', { route, app: this });\n this._controlledRoutes.push(route);\n });\n }\n /**\n * Adds a global middleware to the application.\n *\n * @param middleware The middleware resource to be added.\n */\n use(middleware: MiddlewareLike): void {\n const useMiddleware =\n 'register' in middleware && typeof middleware.register === 'function'\n ? (middleware as MiddlewareProvider).register(this)\n : (middleware as Middleware | ExpressMiddlewareLike);\n this._mountQueue.push((server) => {\n if ('connect' in useMiddleware && typeof useMiddleware.connect === 'function') {\n const handler = useMiddleware.connect(this);\n if (handler) {\n server.use(\n this._reduceWithEvent('middlewareWillBeUsed', handler, { app: this }),\n );\n }\n\n return;\n }\n\n server.use(\n this._reduceWithEvent(\n 'middlewareWillBeUsed',\n useMiddleware as ExpressMiddlewareLike,\n { app: this },\n ),\n );\n });\n }\n\n getConfig(): Config;\n getConfig<T = unknown>(setting: string | string[], asArray?: boolean): T;\n /**\n * Gets a setting from the configuration, or the configuration itself.\n *\n * @param setting The setting or settings to be retrieved. If is not specified, it\n * will return the entire configuration.\n * @param asArray If `true` and `setting` is an array, it will return the values as\n * an array instead of an object.\n * @template T The type of the setting to be retrieved.\n */\n getConfig<T = unknown>(\n setting?: string | string[],\n asArray: boolean = false,\n ): Config | T {\n const config = this.try<Config>('config');\n if (!config) {\n throw new Error('The config service is not available until the app starts');\n }\n if (typeof setting === 'undefined') {\n return config;\n }\n\n return config.get<T>(setting, asArray);\n }\n /**\n * Creates a new router instance.\n */\n getRouter(): Router {\n return this.get('router');\n }\n /**\n * The logger service.\n */\n get logger(): Logger {\n return this.get<Logger>('logger');\n }\n /**\n * The Express application Jimpex uses under the hood.\n */\n get express(): Express {\n return this._express;\n }\n /**\n * The server instance that gets created when the app is started.\n */\n get instance(): JimpexServerInstance | undefined {\n return this._instance;\n }\n /**\n * The application customization options.\n */\n get options(): DeepReadonly<JimpexOptions> {\n return deepAssignWithOverwrite({}, this._options);\n }\n /**\n * Gets the events service.\n */\n get eventsHub(): EventsHub {\n return this.get<EventsHub>('events');\n }\n /**\n * A list of the routes that have controllers mounted on them.\n */\n get routes(): string[] {\n return this._controlledRoutes.slice();\n }\n /**\n * Adds a listener for an application event.\n *\n * @param eventName The name of the event to listen for.\n * @param listener The listener function.\n * @returns A function to unsubscribe the listener.\n * @template EventName The name of the event, to match the type of the listener\n * function.\n */\n on<EventName extends JimpexEventNameLike>(\n eventName: EventName,\n listener: JimpexEventListener<EventName>,\n ): () => boolean {\n return this.eventsHub.on(eventName, listener);\n }\n /**\n * Adds a listener for an application event that will only be execuded once: the first\n * time the event is triggered.\n *\n * @param eventName The name of the event to listen for.\n * @param listener The listener function.\n * @returns A function to unsubscribe the listener.\n * @template EventName The name of the event, to match the type of the listener\n * function.\n */\n once<EventName extends JimpexEventNameLike>(\n eventName: EventName,\n listener: JimpexEventListener<EventName>,\n ): () => boolean {\n return this.eventsHub.once(eventName, listener);\n }\n /**\n * Based on the application options, it returns wheter the application is healthy or\n * not.\n */\n isHealthy(): ReturnType<JimpexHealthCheckFn> {\n return this._options.healthCheck(this);\n }\n /**\n * This method is like a \"lifecycle method\", it gets executed on the constructor right\n * before the \"boot step\". The idea is for the method to be a helper when the\n * application is defined by subclassing {@link Jimpex}: the application could register\n * all important services here and the routes on boot, then, if the implementation needs\n * to access or overwrite a something, it can send `boot: false`, access/register what\n * it needs, and then call `boot()`. That would be impossible for an application without\n * overwriting the constructor and the boot functionality.\n */\n protected _init(): void {}\n /**\n * It generates overwrites for the application options when it gets created. This method\n * is a helper for when the application is defined by subclassing {@link Jimpex}: It's\n * highly probable that if the application needs to change the default options, it would\n * want to do it right from the class, instead of having to do it on every\n * implementation. A way to do it would be overwriting the constructor and calling\n * `super` with the custom overwrites, but this method exists so that won't be\n * necessary: when creating the `options`, the constructor will merge the result of this\n * method on top of the default ones.\n */\n protected _initOptions(): DeepPartial<JimpexOptions> {\n return {};\n }\n /**\n * Registers the \"core services\" on the container: logger, events, utils, etc.\n */\n protected _setupCoreServices(): void {\n this.register(\n appLoggerProvider({\n serviceName: 'logger',\n }),\n );\n this.register(envUtilsProvider);\n this.register(packageInfoProvider);\n this.register(pathUtilsProvider);\n this.register(rootFileProvider);\n const { services: enabledServices } = this._options;\n if (enabledServices.common) this.register(commonServicesProvider);\n if (enabledServices.http) this.register(httpServicesProvider);\n if (enabledServices.utils) this.register(utilsServicesProvider);\n\n this.set('events', () => new EventsHub());\n this.set('statuses', () => statuses);\n }\n /**\n * Configures the Express application based on the class options.\n */\n protected _setupExpress(): void {\n const { statics, filesizeLimit, express: expressOptions } = this._options;\n if (expressOptions.trustProxy) {\n this._express.enable('trust proxy');\n }\n\n if (expressOptions.disableXPoweredBy) {\n this._express.disable('x-powered-by');\n }\n\n if (expressOptions.compression) {\n this._express.use(compression());\n }\n\n if (statics.enabled) {\n this._addStaticsFolder(statics.route, statics.folder, statics.onHome);\n }\n\n if (expressOptions.bodyParser) {\n this._express.use(\n bodyParser.json({\n limit: filesizeLimit,\n }),\n );\n this._express.use(\n bodyParser.urlencoded({\n extended: true,\n limit: filesizeLimit,\n }),\n );\n }\n\n if (expressOptions.multer) {\n this._express.use(multer().any());\n }\n\n this.set(\n 'router',\n this.factory(() => express.Router()),\n );\n }\n /**\n * Adds a static folder to the application.\n *\n * @param route The route to add the folder to.\n * @param folder The path to the folder in the file system. If not defined, it will\n * be use the same value as `route`. The path could be relative to the\n * project root, or where the application executable is located,\n * depending on the value of the `onHome` parameter.\n * @param onHome If `true`, the path to the folder will be relative to the project\n * root. If `false`, it will be relative to where the application\n * executable is located.\n */\n protected _addStaticsFolder(\n route: string,\n folder: string = '',\n onHome: boolean = false,\n ) {\n const location = onHome ? 'home' : 'app';\n const staticRoute = route.replace(/^\\/+/, '');\n const pathUtils = this.get<PathUtils>('pathUtils');\n const staticFolder = pathUtils.joinFrom(location, folder || staticRoute);\n this.mount(`/${staticRoute}`, {\n connect: () => express.static(staticFolder),\n controller: true,\n });\n }\n /**\n * This helper method validates the `path` options in order to register the `app`\n * location in the `pathUtils` service. The `app` location should be the path to where\n * the application executable is located, but due to how ESM works, we can't infer it\n * from the `module` object, so we need either recieved as the `appPath` setting, or try\n * to get it from the parent module.\n *\n * @throws If the method should use the path from the parent module, but can't find\n * it.\n */\n protected _configurePath(): void {\n const pathUtils = this.get<PathUtils>('pathUtils');\n const {\n path: { appPath, useParentPath },\n } = this._options;\n if (appPath) {\n pathUtils.addLocation('app', appPath);\n return;\n }\n let foundPath = false;\n if (useParentPath) {\n const stack = new Error().stack!;\n const stackList = stack.split('\\n');\n stackList.shift();\n const parentFromStack = stackList.find((line) => !line.includes(__filename));\n if (parentFromStack) {\n const parentFile = parentFromStack.replace(/^.*?\\s\\(([^\\s]+):\\d+:\\d+\\)/, '$1');\n if (parentFile !== parentFromStack) {\n foundPath = true;\n pathUtils.addLocation('app', path.dirname(parentFile));\n }\n }\n }\n\n if (!foundPath) {\n throw new Error(\n 'The app location cannot be determined. Please specify the appPath option.',\n );\n }\n }\n /**\n * Setups the configuration service. The new configuration service requires async calls\n * in order to load the configuration files (as it uses `import` instead of `require`),\n * so it can't be instantiated as the other services.\n * This method is called just before starting the application.\n */\n protected async _setupConfig(): Promise<void> {\n if (this._configReady) return;\n this._configReady = true;\n const { config: options } = this._options;\n\n let configsPath = options.path.replace(/\\/$/, '');\n if (options.hasFolder) {\n configsPath = `${configsPath}${path.sep}${options.name}${path.sep}`;\n }\n\n const filenameFormat = options.filenameFormat\n .replace(/\\[app-name\\]/gi, options.name)\n .replace(/\\[config-name\\]/gi, '[name]');\n const defaultConfigFilename = options.defaultConfigFilename.replace(\n /\\[app-name\\]/gi,\n options.name,\n );\n\n this.register(\n simpleConfigProvider({\n name: options.name,\n defaultConfig: options.default,\n defaultConfigFilename,\n envVarName: options.environmentVariable,\n path: configsPath,\n filenameFormat,\n }),\n );\n\n const config = this.getConfig();\n await config.loadFromFile('', true, false);\n if (options.loadFromEnvironment) {\n await config.loadFromEnv();\n }\n }\n /**\n * Processes the resources from the mount queue (added with {@link Jimpex.mount} and\n * {@link Jimpex.use}), and adds them to the Express application.\n */\n protected _mountResources(): void {\n this._mountQueue.forEach((mount) => mount(this._express));\n this._mountQueue.length = 0;\n }\n /**\n * Emits an event using the `events` service.\n *\n * @param name The name of the event to emit.\n * @param payload The event payload.\n * @template EventName The literal name of the event, to type the event payload.\n */\n protected _emitEvent<EventName extends JimpexEventName>(\n name: EventName,\n payload: JimpexEventPayload<EventName>,\n ): void {\n this.eventsHub.emit(name, payload);\n }\n /**\n * Sends a target object to a list of reducer events so they can modify or replace it.\n *\n * @param name The name of the event to use.\n * @param target The object to reduce with the event.\n * @param payload Extra context for the listeners.\n */\n protected _reduceWithEvent<EventName extends JimpexReducerEventName>(\n name: EventName,\n target: JimpexReducerEventTarget<EventName>,\n payload: JimpexReducerEventPayload<EventName>,\n ): JimpexReducerEventTarget<EventName> {\n return this.eventsHub.reduceSync(name, target, payload);\n }\n /**\n * Loads the contents of a dictionary of credentials files that need to be used to\n * configure HTTPS.\n *\n * @param credentialsInfo The dictionary where the keys are the type of credentials\n * (`ca`, `cert`, `key`) and the values are the paths to the\n * files.\n * @param onHome If this is `true`, the path of the files will be relative\n * to the project root. If it is `false`, it will be relative\n * to where the application executable is located.\n * @returns\n */\n protected async _loadCredentials(\n credentialsInfo: JimpexHTTPSCredentials,\n onHome: boolean = true,\n ): Promise<JimpexHTTPSCredentials> {\n const location = onHome ? 'home' : 'app';\n const pathUtils = this.get<PathUtils>('pathUtils');\n const keys: Array<keyof JimpexHTTPSCredentials> = ['ca', 'cert', 'key'];\n const info = await Promise.all(\n keys.map(async (key) => {\n const filepath = credentialsInfo[key];\n if (!filepath) return undefined;\n const file = await fs.readFile(pathUtils.joinFrom(location, filepath), 'utf8');\n return {\n key,\n file,\n };\n }),\n );\n\n return info.reduce<JimpexHTTPSCredentials>((acc, item) => {\n if (item) {\n acc[item.key] = item.file;\n }\n\n return acc;\n }, {});\n }\n /**\n * Validates the configuration and chooses the server the application needs to use: If\n * HTTP2 is enabled, it will use Spdy; if HTTPS is enabled but HTTP is not, it will use\n * the native HTTPS server; otherwise, it will be just the Express instance.\n *\n * @returns {Server}\n * @throws {Error} If HTTP2 is enabled but HTTPS is not.\n * @throws {Error} If HTTPS is enabled but there's no `https.credentials` object.\n * @throws {Error} If HTTPS is enabled and no creadentials are found.\n * @access protected\n * @ignore\n */\n protected async _createServer(): Promise<JimpexServer> {\n const [http2Config = {}, httpsConfig = {}] = this.getConfig<\n [JimpexHTTP2Options, JimpexHTTPSOptions]\n >(['http2', 'https'], true);\n\n if (!http2Config.enabled && !httpsConfig.enabled) {\n return this._express;\n }\n\n if (http2Config.enabled && !httpsConfig.enabled) {\n throw new Error('HTTP2 requires for HTTPS to be enabled');\n }\n\n if (!httpsConfig.credentials) {\n throw new Error('The `credentials` object on the HTTPS settings is missing');\n }\n\n const credentials = await this._loadCredentials(\n httpsConfig.credentials,\n httpsConfig.credentials.onHome,\n );\n\n if (!Object.keys(credentials).length) {\n throw new Error('No credentials were found for HTTPS');\n }\n\n if (http2Config.enabled) {\n const serverOptions: SpdyServerOptions = {\n ...credentials,\n spdy: http2Config.spdy,\n };\n\n return createSpdyServer(serverOptions, this._express);\n }\n\n return createHTTPSServer(credentials, this._express);\n }\n}\n/**\n * Shorthand for `new Jimpex()`.\n *\n * @param args The same parameters as the {@link Jimpex} constructor.\n * @returns A new instance of {@link Jimpex}.\n * @group Jimpex\n */\nexport const jimpex = (...args: ConstructorParameters<typeof Jimpex>): Jimpex =>\n new Jimpex(...args);\n"],"mappings":"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","names":["express","compression","bodyParser","multer","fs","createSpdyServer","createHTTPSServer"]}
1
+ {"version":3,"sources":["../../src/app/jimpex.ts"],"sourcesContent":["import * as path from 'path';\nimport fs from 'fs/promises';\nimport { createServer as createHTTPSServer } from 'https';\nimport { Jimple } from '@homer0/jimple';\nimport { deepAssignWithOverwrite } from '@homer0/deep-assign';\nimport { appLoggerProvider } from '@homer0/simple-logger';\nimport { envUtilsProvider } from '@homer0/env-utils';\nimport { packageInfoProvider } from '@homer0/package-info';\nimport { pathUtilsProvider } from '@homer0/path-utils';\nimport { rootFileProvider } from '@homer0/root-file';\nimport { tsAsyncImport } from '@homer0/ts-async-import';\nimport { EventsHub } from '@homer0/events-hub';\nimport { simpleConfigProvider } from '@homer0/simple-config';\nimport compression from 'compression';\nimport bodyParser from 'body-parser';\nimport multer from 'multer';\nimport {\n createServer as createSpdyServer,\n type ServerOptions as SpdyServerOptions,\n} from 'spdy';\nimport express from 'express';\nimport {\n commonServicesProvider,\n httpServicesProvider,\n utilsServicesProvider,\n} from '../services';\nimport {\n statuses,\n type Controller,\n type ControllerLike,\n type MiddlewareLike,\n type MiddlewareProvider,\n type Middleware,\n} from '../utils';\nimport type {\n DeepPartial,\n Express,\n ExpressMiddlewareLike,\n PathUtils,\n Config,\n Logger,\n JimpexOptions,\n JimpexHTTPSCredentials,\n JimpexHTTP2Options,\n JimpexHTTPSOptions,\n JimpexStartCallback,\n JimpexServer,\n JimpexServerInstance,\n JimpexEventName,\n JimpexEventPayload,\n DeepReadonly,\n JimpexReducerEventName,\n JimpexReducerEventPayload,\n JimpexReducerEventTarget,\n JimpexEventNameLike,\n JimpexEventListener,\n JimpexHealthCheckFn,\n Router,\n} from '../types';\n/**\n * Jimpex is a mix of Jimple, a Javascript port of Pimple dependency injection container,\n * and Express, one of the most popular web frameworks for Node.\n *\n * @group Jimpex\n * @todo Implement `helmet`.\n */\nexport class Jimpex extends Jimple {\n /**\n * The customization settings for the application.\n */\n protected _options: JimpexOptions;\n /**\n * The Express application Jimpex uses under the hood.\n */\n protected _express: Express;\n /**\n * Since the configuration service has an async initialization, the class uses this flag\n * internally to validate if the configuration has been initialized or not.\n */\n protected _configReady: boolean = false;\n /**\n * A reference to the actuall HTTP the application will use. This can vary depending on\n * whether HTTPS, or HTTP2 are enabled. If HTTPS is not enabled, it will be the same as\n * the `express` property; if HTTPS is enabled, it will be an `https` server; and if\n * HTTP2 is enabled, it will be an `spdy` server.\n */\n protected _server?: JimpexServer;\n /**\n * The instance of the server that is listening for requests.\n */\n protected _instance?: JimpexServerInstance;\n /**\n * A list of functions that implement controllers and middlewares. When the application\n * starts, the queue will be processed and those controllers and middlewares will be\n * added to the server instance. The reason they are not added directly like with a\n * regular Express implementation is that services on Jimple use lazy loading, and\n * adding middlewares and controllers as they come could cause errors if they depend on\n * services that are not yet registered.\n */\n protected _mountQueue: Array<(server: Express) => void> = [];\n /**\n * A list with all the top routes controlled by the application. Every time a controller\n * is mounted, its route will be added here.\n */\n protected _controlledRoutes: string[] = [];\n /**\n * @param options Preferences to customize the application.\n * @param config The default settings for the configuration service. It's a\n * shortcuit for `options.config.default`\n */\n constructor(options: DeepPartial<JimpexOptions> = {}, config: unknown = {}) {\n super();\n\n this._options = deepAssignWithOverwrite(\n {\n filesizeLimit: '15MB',\n boot: true,\n path: {\n appPath: '',\n useParentPath: true,\n },\n config: {\n default: options?.config?.default || config,\n name: 'app',\n path: 'config/',\n hasFolder: false,\n loadFromEnvironment: true,\n environmentVariable: 'CONFIG',\n defaultConfigFilename: '[app-name].config.js',\n filenameFormat: '[app-name].[config-name].config.js',\n },\n statics: {\n enabled: true,\n onHome: false,\n route: 'statics',\n },\n express: {\n trustProxy: true,\n disableXPoweredBy: true,\n compression: true,\n bodyParser: true,\n multer: true,\n },\n services: {\n common: true,\n http: true,\n utils: true,\n },\n healthCheck: () => Promise.resolve(true),\n },\n options,\n this._initOptions(),\n );\n\n this._express = express();\n\n this._setupCoreServices();\n this._setupExpress();\n this._configurePath();\n\n this._init();\n if (this._options.boot) {\n this.boot();\n }\n }\n /**\n * This is where the app would register all its specific services, middlewares and controllers.\n */\n boot(): void {}\n /**\n * Disables the server TLS validation. Meant to be used for development purposes.\n */\n disableTLSValidation() {\n // eslint-disable-next-line no-process-env, dot-notation\n process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';\n this.logger.warn('TLS validation has been disabled');\n }\n /**\n * Starts the app server.\n *\n * @param onStart A callback function to be called when the server actually starts.\n * @returns The server instance.\n */\n async start(onStart?: JimpexStartCallback): Promise<JimpexServerInstance> {\n await Promise.all([this._setupConfig(), this._loadESMModules()]);\n const config = this.getConfig();\n const port = config.get<number | undefined>('port');\n if (!port) {\n throw new Error('No port configured');\n }\n this._emitEvent('beforeStart', { app: this });\n this._server = await this._createServer();\n this._instance = this._server!.listen(port, () => {\n this._emitEvent('start', { app: this });\n this._mountResources();\n this.logger.success(`Starting on port ${port}`);\n this._emitEvent('afterStart', { app: this });\n if (onStart) {\n onStart(config);\n }\n this._emitEvent('afterStartCallback', { app: this });\n });\n\n return this._instance!;\n }\n /**\n * This is an alias of `start`. The idea is for it to be used on serverless platforms,\n * where you don't get to start your app, you just have export it.\n *\n * @param port In case the configuration doesn't already have it,\n * this is the port where the application will use to run. If this\n * parameter is used, the method will overwrite the `port`\n * setting on the configuration service.\n * @param onStart A callback function to be called when the server starts.\n * @returns The server instance.\n */\n async listen(\n port?: number,\n onStart?: JimpexStartCallback,\n ): Promise<JimpexServerInstance> {\n if (port) {\n await Promise.all([this._setupConfig(), this._loadESMModules()]);\n const config = this.getConfig();\n config.set('port', port);\n }\n\n return this.start(onStart);\n }\n /**\n * Stops the server instance.\n */\n stop(): void {\n if (!this._instance) return;\n this._emitEvent('beforeStop', { app: this });\n this._instance.close();\n this._instance = undefined;\n this._emitEvent('afterStop', { app: this });\n }\n /**\n * Mounts a route controller or a middleware into a server routes.\n *\n * @param route The route for the controller/middleware.\n * @param controller The controller/middleware resource to be mounted.\n */\n mount(route: string, controller: ControllerLike): void {\n let useController: Controller | Middleware;\n if (\n 'register' in controller &&\n typeof controller.register === 'function' &&\n controller.provider === true\n ) {\n useController = controller.register(this, route);\n } else if (\n 'connect' in controller &&\n typeof controller.connect === 'function' &&\n (('middleware' in controller && controller.middleware === true) ||\n ('controller' in controller && controller.controller === true))\n ) {\n useController = controller;\n } else {\n useController = {\n middleware: true,\n connect: () => controller as ExpressMiddlewareLike,\n };\n }\n\n this._mountQueue.push((server) => {\n const connected = useController.connect(this, route);\n if (!connected) return;\n const router = this._reduceWithEvent('controllerWillBeMounted', connected, {\n route,\n controller: useController,\n app: this,\n });\n server.use(route, router);\n this._emitEvent('routeAdded', { route, app: this });\n this._controlledRoutes.push(route);\n });\n }\n /**\n * Adds a global middleware to the application.\n *\n * @param middleware The middleware resource to be added.\n */\n use(middleware: MiddlewareLike): void {\n const useMiddleware =\n 'register' in middleware && typeof middleware.register === 'function'\n ? (middleware as MiddlewareProvider).register(this)\n : (middleware as Middleware | ExpressMiddlewareLike);\n this._mountQueue.push((server) => {\n if ('connect' in useMiddleware && typeof useMiddleware.connect === 'function') {\n const handler = useMiddleware.connect(this);\n if (handler) {\n server.use(\n this._reduceWithEvent('middlewareWillBeUsed', handler, { app: this }),\n );\n }\n\n return;\n }\n\n server.use(\n this._reduceWithEvent(\n 'middlewareWillBeUsed',\n useMiddleware as ExpressMiddlewareLike,\n { app: this },\n ),\n );\n });\n }\n\n getConfig(): Config;\n getConfig<T = unknown>(setting: string | string[], asArray?: boolean): T;\n /**\n * Gets a setting from the configuration, or the configuration itself.\n *\n * @param setting The setting or settings to be retrieved. If is not specified, it\n * will return the entire configuration.\n * @param asArray If `true` and `setting` is an array, it will return the values as\n * an array instead of an object.\n * @template T The type of the setting to be retrieved.\n */\n getConfig<T = unknown>(\n setting?: string | string[],\n asArray: boolean = false,\n ): Config | T {\n const config = this.try<Config>('config');\n if (!config) {\n throw new Error('The config service is not available until the app starts');\n }\n if (typeof setting === 'undefined') {\n return config;\n }\n\n return config.get<T>(setting, asArray);\n }\n /**\n * Creates a new router instance.\n */\n getRouter(): Router {\n return this.get('router');\n }\n /**\n * The logger service.\n */\n get logger(): Logger {\n return this.get<Logger>('logger');\n }\n /**\n * The Express application Jimpex uses under the hood.\n */\n get express(): Express {\n return this._express;\n }\n /**\n * The server instance that gets created when the app is started.\n */\n get instance(): JimpexServerInstance | undefined {\n return this._instance;\n }\n /**\n * The application customization options.\n */\n get options(): DeepReadonly<JimpexOptions> {\n return deepAssignWithOverwrite({}, this._options);\n }\n /**\n * Gets the events service.\n */\n get eventsHub(): EventsHub {\n return this.get<EventsHub>('events');\n }\n /**\n * A list of the routes that have controllers mounted on them.\n */\n get routes(): string[] {\n return this._controlledRoutes.slice();\n }\n /**\n * Adds a listener for an application event.\n *\n * @param eventName The name of the event to listen for.\n * @param listener The listener function.\n * @returns A function to unsubscribe the listener.\n * @template EventName The name of the event, to match the type of the listener\n * function.\n */\n on<EventName extends JimpexEventNameLike>(\n eventName: EventName,\n listener: JimpexEventListener<EventName>,\n ): () => boolean {\n return this.eventsHub.on(eventName, listener);\n }\n /**\n * Adds a listener for an application event that will only be execuded once: the first\n * time the event is triggered.\n *\n * @param eventName The name of the event to listen for.\n * @param listener The listener function.\n * @returns A function to unsubscribe the listener.\n * @template EventName The name of the event, to match the type of the listener\n * function.\n */\n once<EventName extends JimpexEventNameLike>(\n eventName: EventName,\n listener: JimpexEventListener<EventName>,\n ): () => boolean {\n return this.eventsHub.once(eventName, listener);\n }\n /**\n * Based on the application options, it returns wheter the application is healthy or\n * not.\n */\n isHealthy(): ReturnType<JimpexHealthCheckFn> {\n return this._options.healthCheck(this);\n }\n /**\n * This method is like a \"lifecycle method\", it gets executed on the constructor right\n * before the \"boot step\". The idea is for the method to be a helper when the\n * application is defined by subclassing {@link Jimpex}: the application could register\n * all important services here and the routes on boot, then, if the implementation needs\n * to access or overwrite a something, it can send `boot: false`, access/register what\n * it needs, and then call `boot()`. That would be impossible for an application without\n * overwriting the constructor and the boot functionality.\n */\n protected _init(): void {}\n /**\n * It generates overwrites for the application options when it gets created. This method\n * is a helper for when the application is defined by subclassing {@link Jimpex}: It's\n * highly probable that if the application needs to change the default options, it would\n * want to do it right from the class, instead of having to do it on every\n * implementation. A way to do it would be overwriting the constructor and calling\n * `super` with the custom overwrites, but this method exists so that won't be\n * necessary: when creating the `options`, the constructor will merge the result of this\n * method on top of the default ones.\n */\n protected _initOptions(): DeepPartial<JimpexOptions> {\n return {};\n }\n /**\n * Registers the \"core services\" on the container: logger, events, utils, etc.\n */\n protected _setupCoreServices(): void {\n this.register(\n appLoggerProvider({\n serviceName: 'logger',\n }),\n );\n this.register(envUtilsProvider);\n this.register(packageInfoProvider);\n this.register(pathUtilsProvider);\n this.register(rootFileProvider);\n const { services: enabledServices } = this._options;\n if (enabledServices.common) this.register(commonServicesProvider);\n if (enabledServices.http) this.register(httpServicesProvider);\n if (enabledServices.utils) this.register(utilsServicesProvider);\n\n this.set('events', () => new EventsHub());\n this.set('statuses', () => statuses);\n }\n /**\n * Configures the Express application based on the class options.\n */\n protected _setupExpress(): void {\n const { statics, filesizeLimit, express: expressOptions } = this._options;\n if (expressOptions.trustProxy) {\n this._express.enable('trust proxy');\n }\n\n if (expressOptions.disableXPoweredBy) {\n this._express.disable('x-powered-by');\n }\n\n if (expressOptions.compression) {\n this._express.use(compression());\n }\n\n if (statics.enabled) {\n this._addStaticsFolder(statics.route, statics.folder, statics.onHome);\n }\n\n if (expressOptions.bodyParser) {\n this._express.use(\n bodyParser.json({\n limit: filesizeLimit,\n }),\n );\n this._express.use(\n bodyParser.urlencoded({\n extended: true,\n limit: filesizeLimit,\n }),\n );\n }\n\n if (expressOptions.multer) {\n this._express.use(multer().any());\n }\n\n this.set(\n 'router',\n this.factory(() => express.Router()),\n );\n }\n /**\n * Adds a static folder to the application.\n *\n * @param route The route to add the folder to.\n * @param folder The path to the folder in the file system. If not defined, it will\n * be use the same value as `route`. The path could be relative to the\n * project root, or where the application executable is located,\n * depending on the value of the `onHome` parameter.\n * @param onHome If `true`, the path to the folder will be relative to the project\n * root. If `false`, it will be relative to where the application\n * executable is located.\n */\n protected _addStaticsFolder(\n route: string,\n folder: string = '',\n onHome: boolean = false,\n ) {\n const location = onHome ? 'home' : 'app';\n const staticRoute = route.replace(/^\\/+/, '');\n const pathUtils = this.get<PathUtils>('pathUtils');\n const staticFolder = pathUtils.joinFrom(location, folder || staticRoute);\n this.mount(`/${staticRoute}`, {\n connect: () => express.static(staticFolder),\n controller: true,\n });\n }\n /**\n * This helper method validates the `path` options in order to register the `app`\n * location in the `pathUtils` service. The `app` location should be the path to where\n * the application executable is located, but due to how ESM works, we can't infer it\n * from the `module` object, so we need either recieved as the `appPath` setting, or try\n * to get it from the parent module.\n *\n * @throws If the method should use the path from the parent module, but can't find\n * it.\n */\n protected _configurePath(): void {\n const pathUtils = this.get<PathUtils>('pathUtils');\n const {\n path: { appPath, useParentPath },\n } = this._options;\n if (appPath) {\n pathUtils.addLocation('app', appPath);\n return;\n }\n let foundPath = false;\n if (useParentPath) {\n const stack = new Error().stack!;\n const stackList = stack.split('\\n');\n stackList.shift();\n const parentFromStack = stackList.find((line) => !line.includes(__filename));\n if (parentFromStack) {\n const parentFile = parentFromStack.replace(/^.*?\\s\\(([^\\s]+):\\d+:\\d+\\)/, '$1');\n if (parentFile !== parentFromStack) {\n foundPath = true;\n pathUtils.addLocation('app', path.dirname(parentFile));\n }\n }\n }\n\n if (!foundPath) {\n throw new Error(\n 'The app location cannot be determined. Please specify the appPath option.',\n );\n }\n }\n /**\n * Setups the configuration service. The new configuration service requires async calls\n * in order to load the configuration files (as it uses `import` instead of `require`),\n * so it can't be instantiated as the other services.\n * This method is called just before starting the application.\n */\n protected async _setupConfig(): Promise<void> {\n if (this._configReady) return;\n this._configReady = true;\n const { config: options } = this._options;\n\n let configsPath = options.path.replace(/\\/$/, '');\n if (options.hasFolder) {\n configsPath = `${configsPath}${path.sep}${options.name}${path.sep}`;\n }\n\n const filenameFormat = options.filenameFormat\n .replace(/\\[app-name\\]/gi, options.name)\n .replace(/\\[config-name\\]/gi, '[name]');\n const defaultConfigFilename = options.defaultConfigFilename.replace(\n /\\[app-name\\]/gi,\n options.name,\n );\n\n this.register(\n simpleConfigProvider({\n name: options.name,\n defaultConfig: options.default,\n defaultConfigFilename,\n envVarName: options.environmentVariable,\n path: configsPath,\n filenameFormat,\n }),\n );\n\n const config = this.getConfig();\n await config.loadFromFile('', true, false);\n if (options.loadFromEnvironment) {\n await config.loadFromEnv();\n }\n }\n /**\n * Loads the ESM modules that are needed by Jimpex. This is called just before the starting\n * the application so they'll be available for all the services.\n */\n protected async _loadESMModules(): Promise<void> {\n const { default: nodeFetch } =\n await tsAsyncImport<typeof import('node-fetch')>('node-fetch');\n const { default: mime } = await tsAsyncImport<typeof import('mime')>('mime');\n\n this.set('node-fetch', () => nodeFetch);\n this.set('mime', () => mime);\n }\n /**\n * Processes the resources from the mount queue (added with {@link Jimpex.mount} and\n * {@link Jimpex.use}), and adds them to the Express application.\n */\n protected _mountResources(): void {\n this._mountQueue.forEach((mount) => mount(this._express));\n this._mountQueue.length = 0;\n }\n /**\n * Emits an event using the `events` service.\n *\n * @param name The name of the event to emit.\n * @param payload The event payload.\n * @template EventName The literal name of the event, to type the event payload.\n */\n protected _emitEvent<EventName extends JimpexEventName>(\n name: EventName,\n payload: JimpexEventPayload<EventName>,\n ): void {\n this.eventsHub.emit(name, payload);\n }\n /**\n * Sends a target object to a list of reducer events so they can modify or replace it.\n *\n * @param name The name of the event to use.\n * @param target The object to reduce with the event.\n * @param payload Extra context for the listeners.\n */\n protected _reduceWithEvent<EventName extends JimpexReducerEventName>(\n name: EventName,\n target: JimpexReducerEventTarget<EventName>,\n payload: JimpexReducerEventPayload<EventName>,\n ): JimpexReducerEventTarget<EventName> {\n return this.eventsHub.reduceSync(name, target, payload);\n }\n /**\n * Loads the contents of a dictionary of credentials files that need to be used to\n * configure HTTPS.\n *\n * @param credentialsInfo The dictionary where the keys are the type of credentials\n * (`ca`, `cert`, `key`) and the values are the paths to the\n * files.\n * @param onHome If this is `true`, the path of the files will be relative\n * to the project root. If it is `false`, it will be relative\n * to where the application executable is located.\n * @returns\n */\n protected async _loadCredentials(\n credentialsInfo: JimpexHTTPSCredentials,\n onHome: boolean = true,\n ): Promise<JimpexHTTPSCredentials> {\n const location = onHome ? 'home' : 'app';\n const pathUtils = this.get<PathUtils>('pathUtils');\n const keys: Array<keyof JimpexHTTPSCredentials> = ['ca', 'cert', 'key'];\n const info = await Promise.all(\n keys.map(async (key) => {\n const filepath = credentialsInfo[key];\n if (!filepath) return undefined;\n const file = await fs.readFile(pathUtils.joinFrom(location, filepath), 'utf8');\n return {\n key,\n file,\n };\n }),\n );\n\n return info.reduce<JimpexHTTPSCredentials>((acc, item) => {\n if (item) {\n acc[item.key] = item.file;\n }\n\n return acc;\n }, {});\n }\n /**\n * Validates the configuration and chooses the server the application needs to use: If\n * HTTP2 is enabled, it will use Spdy; if HTTPS is enabled but HTTP is not, it will use\n * the native HTTPS server; otherwise, it will be just the Express instance.\n *\n * @returns {Server}\n * @throws {Error} If HTTP2 is enabled but HTTPS is not.\n * @throws {Error} If HTTPS is enabled but there's no `https.credentials` object.\n * @throws {Error} If HTTPS is enabled and no creadentials are found.\n * @access protected\n * @ignore\n */\n protected async _createServer(): Promise<JimpexServer> {\n const [http2Config = {}, httpsConfig = {}] = this.getConfig<\n [JimpexHTTP2Options, JimpexHTTPSOptions]\n >(['http2', 'https'], true);\n\n if (!http2Config.enabled && !httpsConfig.enabled) {\n return this._express;\n }\n\n if (http2Config.enabled && !httpsConfig.enabled) {\n throw new Error('HTTP2 requires for HTTPS to be enabled');\n }\n\n if (!httpsConfig.credentials) {\n throw new Error('The `credentials` object on the HTTPS settings is missing');\n }\n\n const credentials = await this._loadCredentials(\n httpsConfig.credentials,\n httpsConfig.credentials.onHome,\n );\n\n if (!Object.keys(credentials).length) {\n throw new Error('No credentials were found for HTTPS');\n }\n\n if (http2Config.enabled) {\n const serverOptions: SpdyServerOptions = {\n ...credentials,\n spdy: http2Config.spdy,\n };\n\n return createSpdyServer(serverOptions, this._express);\n }\n\n return createHTTPSServer(credentials, this._express);\n }\n}\n/**\n * Shorthand for `new Jimpex()`.\n *\n * @param args The same parameters as the {@link Jimpex} constructor.\n * @returns A new instance of {@link Jimpex}.\n * @group Jimpex\n */\nexport const jimpex = (...args: ConstructorParameters<typeof Jimpex>): Jimpex =>\n new Jimpex(...args);\n"],"mappings":"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","names":["express","compression","bodyParser","multer","fs","createSpdyServer","createHTTPSServer"]}
@@ -1,5 +1,5 @@
1
1
  import * as _homer0_jimple from '@homer0/jimple';
2
- import { C as ControllerConnectFn } from '../../index-efeb437e.js';
2
+ import { C as ControllerConnectFn } from '../../index-Bwf7JHu9.mjs';
3
3
  import { ExpressMiddleware, AsyncExpressMiddleware } from '../../types/express.mjs';
4
4
  import { SimpleConfig } from '@homer0/simple-config';
5
5
  import { ResponsesBuilder } from '../../services/http/responsesBuilder.mjs';
@@ -76,4 +76,4 @@ declare class ConfigController {
76
76
  */
77
77
  declare const configController: _homer0_jimple.Resource<"controller", "connect", ControllerConnectFn>;
78
78
 
79
- export { ConfigController, ConfigControllerOptions, configController };
79
+ export { ConfigController, type ConfigControllerOptions, configController };
@@ -1,5 +1,5 @@
1
1
  import * as _homer0_jimple from '@homer0/jimple';
2
- import { C as ControllerConnectFn } from '../../index-b2a04c78.js';
2
+ import { C as ControllerConnectFn } from '../../index-C6I3NCC-.js';
3
3
  import { ExpressMiddleware, AsyncExpressMiddleware } from '../../types/express.js';
4
4
  import { SimpleConfig } from '@homer0/simple-config';
5
5
  import { ResponsesBuilder } from '../../services/http/responsesBuilder.js';
@@ -76,4 +76,4 @@ declare class ConfigController {
76
76
  */
77
77
  declare const configController: _homer0_jimple.Resource<"controller", "connect", ControllerConnectFn>;
78
78
 
79
- export { ConfigController, ConfigControllerOptions, configController };
79
+ export { ConfigController, type ConfigControllerOptions, configController };
@@ -1,6 +1,6 @@
1
1
  import * as _homer0_jimple from '@homer0/jimple';
2
2
  import { Statuses } from '../../utils/fns/statuses.mjs';
3
- import { r as JimpexHealthStatus, C as ControllerConnectFn } from '../../index-efeb437e.js';
3
+ import { r as JimpexHealthStatus, C as ControllerConnectFn } from '../../index-Bwf7JHu9.mjs';
4
4
  import { AsyncExpressMiddleware } from '../../types/express.mjs';
5
5
  import { SimpleConfig } from '@homer0/simple-config';
6
6
  import { ResponsesBuilder } from '../../services/http/responsesBuilder.mjs';
@@ -9,8 +9,8 @@ import '../../types/http.mjs';
9
9
  import 'https';
10
10
  import 'http';
11
11
  import 'spdy';
12
- import 'express';
13
12
  import 'node-fetch';
13
+ import 'express';
14
14
  import '../../types/utils.mjs';
15
15
  import '@homer0/path-utils';
16
16
  import '@homer0/simple-logger';
@@ -80,4 +80,4 @@ declare class HealthController {
80
80
  */
81
81
  declare const healthController: _homer0_jimple.Resource<"controller", "connect", ControllerConnectFn>;
82
82
 
83
- export { GetHealthStatus, HealthController, HealthControllerOptions, healthController };
83
+ export { type GetHealthStatus, HealthController, type HealthControllerOptions, healthController };
@@ -1,6 +1,6 @@
1
1
  import * as _homer0_jimple from '@homer0/jimple';
2
2
  import { Statuses } from '../../utils/fns/statuses.js';
3
- import { r as JimpexHealthStatus, C as ControllerConnectFn } from '../../index-b2a04c78.js';
3
+ import { r as JimpexHealthStatus, C as ControllerConnectFn } from '../../index-C6I3NCC-.js';
4
4
  import { AsyncExpressMiddleware } from '../../types/express.js';
5
5
  import { SimpleConfig } from '@homer0/simple-config';
6
6
  import { ResponsesBuilder } from '../../services/http/responsesBuilder.js';
@@ -9,8 +9,8 @@ import '../../types/http.js';
9
9
  import 'https';
10
10
  import 'http';
11
11
  import 'spdy';
12
- import 'express';
13
12
  import 'node-fetch';
13
+ import 'express';
14
14
  import '../../types/utils.js';
15
15
  import '@homer0/path-utils';
16
16
  import '@homer0/simple-logger';
@@ -80,4 +80,4 @@ declare class HealthController {
80
80
  */
81
81
  declare const healthController: _homer0_jimple.Resource<"controller", "connect", ControllerConnectFn>;
82
82
 
83
- export { GetHealthStatus, HealthController, HealthControllerOptions, healthController };
83
+ export { type GetHealthStatus, HealthController, type HealthControllerOptions, healthController };
@@ -2,7 +2,7 @@ export { ConfigController, ConfigControllerOptions, configController } from './c
2
2
  export { GetHealthStatus, HealthController, HealthControllerOptions, healthController } from './health.mjs';
3
3
  export { AddStaticRouteOptions, StaticsController, StaticsControllerConstructorOptions, StaticsControllerCreatorOptions, StaticsControllerFile, StaticsControllerGetMiddlewaresFn, StaticsControllerOptions, StaticsControllerPathsOptions, staticsController } from './statics.mjs';
4
4
  import '@homer0/jimple';
5
- import '../../index-efeb437e.js';
5
+ import '../../index-Bwf7JHu9.mjs';
6
6
  import '../../types/express.mjs';
7
7
  import 'express';
8
8
  import '../../types/http.mjs';
@@ -18,4 +18,5 @@ import '@homer0/events-hub';
18
18
  import '../../services/http/responsesBuilder.mjs';
19
19
  import '../../utils/fns/statuses.mjs';
20
20
  import 'statuses';
21
+ import 'mime';
21
22
  import '../../services/common/sendFile.mjs';
@@ -2,7 +2,7 @@ export { ConfigController, ConfigControllerOptions, configController } from './c
2
2
  export { GetHealthStatus, HealthController, HealthControllerOptions, healthController } from './health.js';
3
3
  export { AddStaticRouteOptions, StaticsController, StaticsControllerConstructorOptions, StaticsControllerCreatorOptions, StaticsControllerFile, StaticsControllerGetMiddlewaresFn, StaticsControllerOptions, StaticsControllerPathsOptions, staticsController } from './statics.js';
4
4
  import '@homer0/jimple';
5
- import '../../index-b2a04c78.js';
5
+ import '../../index-C6I3NCC-.js';
6
6
  import '../../types/express.js';
7
7
  import 'express';
8
8
  import '../../types/http.js';
@@ -18,4 +18,5 @@ import '@homer0/events-hub';
18
18
  import '../../services/http/responsesBuilder.js';
19
19
  import '../../utils/fns/statuses.js';
20
20
  import 'statuses';
21
+ import 'mime';
21
22
  import '../../services/common/sendFile.js';
@@ -1,5 +1,6 @@
1
1
  import * as _homer0_jimple from '@homer0/jimple';
2
- import { J as Jimpex, a1 as MiddlewareLike, C as ControllerConnectFn } from '../../index-efeb437e.js';
2
+ import { J as Jimpex, a1 as MiddlewareLike, C as ControllerConnectFn } from '../../index-Bwf7JHu9.mjs';
3
+ import mime from 'mime';
3
4
  import { RouterMethod, ExpressMiddleware } from '../../types/express.mjs';
4
5
  import { DeepPartial } from '../../types/utils.mjs';
5
6
  import { SendFile } from '../../services/common/sendFile.mjs';
@@ -14,6 +15,7 @@ import '@homer0/simple-logger';
14
15
  import '@homer0/simple-config';
15
16
  import '@homer0/events-hub';
16
17
 
18
+ type Mime = typeof mime;
17
19
  /**
18
20
  * The definition for each file the controller handles.
19
21
  *
@@ -87,6 +89,7 @@ type StaticsControllerConstructorOptions = DeepPartial<StaticsControllerOptions>
87
89
  */
88
90
  inject: {
89
91
  sendFile: SendFile;
92
+ mime: Mime;
90
93
  };
91
94
  };
92
95
  /**
@@ -149,6 +152,11 @@ declare class StaticsController {
149
152
  * The service that serves static files.
150
153
  */
151
154
  protected readonly _sendFile: SendFile;
155
+ /**
156
+ * The MIME type library. Since it's an ESM only module, Jimpex loads it on boot and makes
157
+ * it available on the container.
158
+ */
159
+ protected readonly _mime: Mime;
152
160
  /**
153
161
  * The controller customization options.
154
162
  */
@@ -212,4 +220,4 @@ declare class StaticsController {
212
220
  */
213
221
  declare const staticsController: _homer0_jimple.ResourceCreator<"controller", "connect", ({ getMiddlewares, ...options }?: StaticsControllerCreatorOptions) => <ContainerType extends Jimpex = Jimpex>(app: ContainerType) => Router, ControllerConnectFn>;
214
222
 
215
- export { AddStaticRouteOptions, StaticsController, StaticsControllerConstructorOptions, StaticsControllerCreatorOptions, StaticsControllerFile, StaticsControllerGetMiddlewaresFn, StaticsControllerOptions, StaticsControllerPathsOptions, staticsController };
223
+ export { type AddStaticRouteOptions, StaticsController, type StaticsControllerConstructorOptions, type StaticsControllerCreatorOptions, type StaticsControllerFile, type StaticsControllerGetMiddlewaresFn, type StaticsControllerOptions, type StaticsControllerPathsOptions, staticsController };
@@ -1,5 +1,6 @@
1
1
  import * as _homer0_jimple from '@homer0/jimple';
2
- import { J as Jimpex, a1 as MiddlewareLike, C as ControllerConnectFn } from '../../index-b2a04c78.js';
2
+ import { J as Jimpex, a1 as MiddlewareLike, C as ControllerConnectFn } from '../../index-C6I3NCC-.js';
3
+ import mime from 'mime';
3
4
  import { RouterMethod, ExpressMiddleware } from '../../types/express.js';
4
5
  import { DeepPartial } from '../../types/utils.js';
5
6
  import { SendFile } from '../../services/common/sendFile.js';
@@ -14,6 +15,7 @@ import '@homer0/simple-logger';
14
15
  import '@homer0/simple-config';
15
16
  import '@homer0/events-hub';
16
17
 
18
+ type Mime = typeof mime;
17
19
  /**
18
20
  * The definition for each file the controller handles.
19
21
  *
@@ -87,6 +89,7 @@ type StaticsControllerConstructorOptions = DeepPartial<StaticsControllerOptions>
87
89
  */
88
90
  inject: {
89
91
  sendFile: SendFile;
92
+ mime: Mime;
90
93
  };
91
94
  };
92
95
  /**
@@ -149,6 +152,11 @@ declare class StaticsController {
149
152
  * The service that serves static files.
150
153
  */
151
154
  protected readonly _sendFile: SendFile;
155
+ /**
156
+ * The MIME type library. Since it's an ESM only module, Jimpex loads it on boot and makes
157
+ * it available on the container.
158
+ */
159
+ protected readonly _mime: Mime;
152
160
  /**
153
161
  * The controller customization options.
154
162
  */
@@ -212,4 +220,4 @@ declare class StaticsController {
212
220
  */
213
221
  declare const staticsController: _homer0_jimple.ResourceCreator<"controller", "connect", ({ getMiddlewares, ...options }?: StaticsControllerCreatorOptions) => <ContainerType extends Jimpex = Jimpex>(app: ContainerType) => Router, ControllerConnectFn>;
214
222
 
215
- export { AddStaticRouteOptions, StaticsController, StaticsControllerConstructorOptions, StaticsControllerCreatorOptions, StaticsControllerFile, StaticsControllerGetMiddlewaresFn, StaticsControllerOptions, StaticsControllerPathsOptions, staticsController };
223
+ export { type AddStaticRouteOptions, StaticsController, type StaticsControllerConstructorOptions, type StaticsControllerCreatorOptions, type StaticsControllerFile, type StaticsControllerGetMiddlewaresFn, type StaticsControllerOptions, type StaticsControllerPathsOptions, staticsController };
@@ -38,7 +38,6 @@ __export(statics_exports, {
38
38
  });
39
39
  module.exports = __toCommonJS(statics_exports);
40
40
  var path = __toESM(require("path"));
41
- var mime = __toESM(require("mime"));
42
41
  var import_deep_assign = require("@homer0/deep-assign");
43
42
  var import_utils = require("../../utils");
44
43
  class StaticsController {
@@ -50,6 +49,11 @@ class StaticsController {
50
49
  * The service that serves static files.
51
50
  */
52
51
  __publicField(this, "_sendFile");
52
+ /**
53
+ * The MIME type library. Since it's an ESM only module, Jimpex loads it on boot and makes
54
+ * it available on the container.
55
+ */
56
+ __publicField(this, "_mime");
53
57
  /**
54
58
  * The controller customization options.
55
59
  */
@@ -60,6 +64,7 @@ class StaticsController {
60
64
  */
61
65
  __publicField(this, "files");
62
66
  this._sendFile = inject.sendFile;
67
+ this._mime = inject.mime;
63
68
  this._options = this._validateOptions(
64
69
  (0, import_deep_assign.deepAssignWithOverwrite)(
65
70
  {
@@ -118,7 +123,7 @@ class StaticsController {
118
123
  return (_, res, next) => {
119
124
  const extension = path.parse(file.path).ext.substring(1);
120
125
  const headers = {
121
- "Content-Type": mime.getType(extension) || "text/html",
126
+ "Content-Type": this._mime.getType(extension) || "text/html",
122
127
  ...file.headers
123
128
  };
124
129
  Object.entries(headers).forEach(([key, value]) => {
@@ -229,7 +234,8 @@ const staticsController = (0, import_utils.controllerCreator)(
229
234
  const router = app.getRouter();
230
235
  const ctrl = new StaticsController({
231
236
  inject: {
232
- sendFile: app.get("sendFile")
237
+ sendFile: app.get("sendFile"),
238
+ mime: app.get("mime")
233
239
  },
234
240
  ...options
235
241
  });
@@ -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 type 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\ntype Mime = typeof mime;\n\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 mime: Mime;\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 MIME type library. Since it's an ESM only module, Jimpex loads it on boot and makes\n * it available on the container.\n */\n protected readonly _mime: Mime;\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._mime = inject.mime;\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': this._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 mime: app.get('mime'),\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":[]}
@@ -3,7 +3,7 @@ export { GetHealthStatus, HealthController, HealthControllerOptions, healthContr
3
3
  export { AddStaticRouteOptions, StaticsController, StaticsControllerConstructorOptions, StaticsControllerCreatorOptions, StaticsControllerFile, StaticsControllerGetMiddlewaresFn, StaticsControllerOptions, StaticsControllerPathsOptions, staticsController } from './common/statics.mjs';
4
4
  export { AddGatewayRouteOptions, GatewayConfig, GatewayConfigEndpointDefinition, GatewayConfigEndpointProps, GatewayConfigEndpoints, GatewayController, GatewayControllerAPIConfig, GatewayControllerAPIConfigOptions, GatewayControllerConstructorOptions, GatewayControllerCreatorOptions, GatewayControllerEndpointInfo, GatewayControllerExtraOptions, GatewayControllerGetMiddlewaresFn, GatewayControllerHeaderOptions, GatewayControllerHelperOptions, GatewayControllerOptions, GatewayControllerRequest, GatewayControllerRoute, GatewayControllerRouteMethod, GatewayHelperService, GatewayHelperServiceBaseFnOptions, GatewayHelperServiceErrorHandler, GatewayHelperServiceErrorHandlerOptions, GatewayHelperServiceRequestReducer, GatewayHelperServiceRequestReducerOptions, GatewayHelperServiceResponseHandler, GatewayHelperServiceResponseReducer, GatewayHelperServiceResponseReducerOptions, GatewayHelperServiceStreamVerification, gatewayController } from './utils/gateway.mjs';
5
5
  import '@homer0/jimple';
6
- import '../index-efeb437e.js';
6
+ import '../index-Bwf7JHu9.mjs';
7
7
  import '../types/express.mjs';
8
8
  import 'express';
9
9
  import '../types/http.mjs';
@@ -19,6 +19,7 @@ import '@homer0/events-hub';
19
19
  import '../services/http/responsesBuilder.mjs';
20
20
  import '../utils/fns/statuses.mjs';
21
21
  import 'statuses';
22
+ import 'mime';
22
23
  import '../services/common/sendFile.mjs';
23
24
  import '@homer0/api-utils';
24
25
  import '../services/http/http.mjs';