zibri 2.4.1 → 2.5.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 (496) hide show
  1. package/dist/cjs/application-options.model.d.ts +2 -2
  2. package/dist/cjs/application-options.model.d.ts.map +1 -1
  3. package/dist/cjs/application.d.ts.map +1 -1
  4. package/dist/cjs/application.js +0 -1
  5. package/dist/cjs/application.js.map +1 -1
  6. package/dist/cjs/assets/asset.service.d.ts.map +1 -1
  7. package/dist/cjs/assets/asset.service.js +3 -1
  8. package/dist/cjs/assets/asset.service.js.map +1 -1
  9. package/dist/cjs/auth/2fa/methods/otp/otp-credentials.model.d.ts +1 -1
  10. package/dist/cjs/auth/2fa/methods/otp/otp-credentials.model.d.ts.map +1 -1
  11. package/dist/cjs/auth/2fa/methods/otp/otp-credentials.model.js.map +1 -1
  12. package/dist/cjs/auth/2fa/methods/otp/otp.two-factor-method.js +1 -1
  13. package/dist/cjs/auth/2fa/methods/otp/otp.two-factor-method.js.map +1 -1
  14. package/dist/cjs/auth/strategies/cookie/cookie-auth.controller.js +1 -1
  15. package/dist/cjs/auth/strategies/cookie/cookie-auth.controller.js.map +1 -1
  16. package/dist/cjs/auth/strategies/jwt/jwt-auth.controller.js +1 -1
  17. package/dist/cjs/auth/strategies/jwt/jwt-auth.controller.js.map +1 -1
  18. package/dist/cjs/auth/strategies/jwt/jwt.auth-strategy.js +1 -1
  19. package/dist/cjs/auth/strategies/jwt/jwt.auth-strategy.js.map +1 -1
  20. package/dist/cjs/backup/backup-resource-entity.model.d.ts +1 -1
  21. package/dist/cjs/backup/backup-resource-entity.model.d.ts.map +1 -1
  22. package/dist/cjs/backup/backup-resource-entity.model.js.map +1 -1
  23. package/dist/cjs/change-sets/models/change-set.model.d.ts +1 -1
  24. package/dist/cjs/change-sets/models/change-set.model.d.ts.map +1 -1
  25. package/dist/cjs/change-sets/models/change-set.model.js +1 -1
  26. package/dist/cjs/change-sets/models/change-set.model.js.map +1 -1
  27. package/dist/cjs/change-sets/models/change.model.d.ts +2 -2
  28. package/dist/cjs/change-sets/models/change.model.d.ts.map +1 -1
  29. package/dist/cjs/change-sets/models/change.model.js.map +1 -1
  30. package/dist/cjs/context/cache/cache.context.d.ts +2 -2
  31. package/dist/cjs/context/cache/cache.context.d.ts.map +1 -1
  32. package/dist/cjs/context/cache/cache.context.js +2 -2
  33. package/dist/cjs/context/cache/cache.context.js.map +1 -1
  34. package/dist/cjs/context/request/request-context-token.model.js +1 -1
  35. package/dist/cjs/context/request/request-context-token.model.js.map +1 -1
  36. package/dist/cjs/cron/cron-job-entity.model.d.ts +2 -2
  37. package/dist/cjs/cron/cron-job-entity.model.d.ts.map +1 -1
  38. package/dist/cjs/cron/cron-job-entity.model.js.map +1 -1
  39. package/dist/cjs/data-source/data-sources/postgres-typeorm-data-source.model.d.ts +1 -0
  40. package/dist/cjs/data-source/data-sources/postgres-typeorm-data-source.model.d.ts.map +1 -1
  41. package/dist/cjs/data-source/data-sources/postgres-typeorm-data-source.model.js +9 -0
  42. package/dist/cjs/data-source/data-sources/postgres-typeorm-data-source.model.js.map +1 -1
  43. package/dist/cjs/data-source/data-sources/typeorm-base-data-source.model.d.ts.map +1 -1
  44. package/dist/cjs/data-source/data-sources/typeorm-base-data-source.model.js +3 -3
  45. package/dist/cjs/data-source/data-sources/typeorm-base-data-source.model.js.map +1 -1
  46. package/dist/cjs/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.d.ts +2 -1
  47. package/dist/cjs/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.d.ts.map +1 -1
  48. package/dist/cjs/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.js +20 -0
  49. package/dist/cjs/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.js.map +1 -1
  50. package/dist/cjs/data-source/data-sources/where-converter/typeorm-where-filter.converter.d.ts +4 -0
  51. package/dist/cjs/data-source/data-sources/where-converter/typeorm-where-filter.converter.d.ts.map +1 -1
  52. package/dist/cjs/data-source/data-sources/where-converter/typeorm-where-filter.converter.js +3 -1
  53. package/dist/cjs/data-source/data-sources/where-converter/typeorm-where-filter.converter.js.map +1 -1
  54. package/dist/cjs/data-source/migration/migration-entity.model.d.ts +2 -2
  55. package/dist/cjs/data-source/migration/migration-entity.model.d.ts.map +1 -1
  56. package/dist/cjs/data-source/migration/migration-entity.model.js.map +1 -1
  57. package/dist/cjs/data-source/migration/migration.model.d.ts +2 -2
  58. package/dist/cjs/data-source/migration/migration.model.d.ts.map +1 -1
  59. package/dist/cjs/data-source/models/where/date-where-filter.model.d.ts +10 -2
  60. package/dist/cjs/data-source/models/where/date-where-filter.model.d.ts.map +1 -1
  61. package/dist/cjs/data-source/models/where/string-where-filter.model.d.ts +17 -0
  62. package/dist/cjs/data-source/models/where/string-where-filter.model.d.ts.map +1 -1
  63. package/dist/cjs/data-source/models/where/where-filter-keys.model.d.ts.map +1 -1
  64. package/dist/cjs/data-source/models/where/where-filter-keys.model.js +3 -0
  65. package/dist/cjs/data-source/models/where/where-filter-keys.model.js.map +1 -1
  66. package/dist/cjs/di/default/zibri-di-providers.default.d.ts.map +1 -1
  67. package/dist/cjs/di/default/zibri-di-providers.default.js +4 -0
  68. package/dist/cjs/di/default/zibri-di-providers.default.js.map +1 -1
  69. package/dist/cjs/di/default/zibri-di-tokens.default.d.ts +3 -0
  70. package/dist/cjs/di/default/zibri-di-tokens.default.d.ts.map +1 -1
  71. package/dist/cjs/di/default/zibri-di-tokens.default.js +2 -0
  72. package/dist/cjs/di/default/zibri-di-tokens.default.js.map +1 -1
  73. package/dist/cjs/email/email.service.d.ts +1 -1
  74. package/dist/cjs/email/email.service.d.ts.map +1 -1
  75. package/dist/cjs/email/email.service.js +4 -4
  76. package/dist/cjs/email/email.service.js.map +1 -1
  77. package/dist/cjs/email/models/email.model.d.ts +4 -4
  78. package/dist/cjs/email/models/email.model.d.ts.map +1 -1
  79. package/dist/cjs/email/models/email.model.js +4 -4
  80. package/dist/cjs/email/models/email.model.js.map +1 -1
  81. package/dist/cjs/entity/generation/generate-entity-file.function.js +1 -1
  82. package/dist/cjs/entity/generation/generate-entity-file.function.js.map +1 -1
  83. package/dist/cjs/event/event-subscriber-run.model.d.ts +1 -1
  84. package/dist/cjs/event/event-subscriber-run.model.d.ts.map +1 -1
  85. package/dist/cjs/event/event-subscriber-run.model.js +1 -1
  86. package/dist/cjs/event/event-subscriber-run.model.js.map +1 -1
  87. package/dist/cjs/global/global-registry.d.ts +2 -2
  88. package/dist/cjs/global/global-registry.d.ts.map +1 -1
  89. package/dist/cjs/http/http-request.model.d.ts +2 -2
  90. package/dist/cjs/http/http-request.model.d.ts.map +1 -1
  91. package/dist/cjs/http/known-header.enum.d.ts +1 -0
  92. package/dist/cjs/http/known-header.enum.d.ts.map +1 -1
  93. package/dist/cjs/http/known-header.enum.js +1 -0
  94. package/dist/cjs/http/known-header.enum.js.map +1 -1
  95. package/dist/cjs/http-client/http-client.d.ts.map +1 -1
  96. package/dist/cjs/http-client/http-client.js.map +1 -1
  97. package/dist/cjs/index.d.ts +7 -3
  98. package/dist/cjs/index.d.ts.map +1 -1
  99. package/dist/cjs/index.js +8 -3
  100. package/dist/cjs/index.js.map +1 -1
  101. package/dist/cjs/localization/formatting/format-price.function.d.ts.map +1 -1
  102. package/dist/cjs/localization/formatting/format-price.function.js.map +1 -1
  103. package/dist/cjs/logging/log-context.model.d.ts +6 -6
  104. package/dist/cjs/logging/log-context.model.d.ts.map +1 -1
  105. package/dist/cjs/logging/log-context.model.js +6 -6
  106. package/dist/cjs/logging/log-context.model.js.map +1 -1
  107. package/dist/cjs/logging/logger.js +1 -1
  108. package/dist/cjs/logging/logger.js.map +1 -1
  109. package/dist/cjs/multithreading/models/thread-job-entity.model.d.ts +5 -5
  110. package/dist/cjs/multithreading/models/thread-job-entity.model.d.ts.map +1 -1
  111. package/dist/cjs/multithreading/models/thread-job-entity.model.js +4 -4
  112. package/dist/cjs/multithreading/models/thread-job-entity.model.js.map +1 -1
  113. package/dist/cjs/multithreading/services/thread-job.d.ts +4 -4
  114. package/dist/cjs/multithreading/services/thread-job.d.ts.map +1 -1
  115. package/dist/cjs/multithreading/services/thread-job.js.map +1 -1
  116. package/dist/cjs/open-api/open-api-service.interface.d.ts +2 -1
  117. package/dist/cjs/open-api/open-api-service.interface.d.ts.map +1 -1
  118. package/dist/cjs/open-api/open-api.service.d.ts +5 -2
  119. package/dist/cjs/open-api/open-api.service.d.ts.map +1 -1
  120. package/dist/cjs/open-api/open-api.service.js +256 -139
  121. package/dist/cjs/open-api/open-api.service.js.map +1 -1
  122. package/dist/cjs/parsing/html/csp-options.model.d.ts +1 -1
  123. package/dist/cjs/parsing/html/csp-options.model.d.ts.map +1 -1
  124. package/dist/cjs/parsing/html/csp-options.model.js.map +1 -1
  125. package/dist/cjs/parsing/parser.js +3 -3
  126. package/dist/cjs/parsing/parser.js.map +1 -1
  127. package/dist/cjs/plugin/invoicing/models/invoice-address.model.d.ts +2 -2
  128. package/dist/cjs/plugin/invoicing/models/invoice-address.model.d.ts.map +1 -1
  129. package/dist/cjs/plugin/invoicing/models/invoice-address.model.js +2 -2
  130. package/dist/cjs/plugin/invoicing/models/invoice-address.model.js.map +1 -1
  131. package/dist/cjs/plugin/invoicing/models/vat.model.d.ts +1 -1
  132. package/dist/cjs/plugin/invoicing/models/vat.model.d.ts.map +1 -1
  133. package/dist/cjs/plugin/invoicing/models/vat.model.js +1 -1
  134. package/dist/cjs/plugin/invoicing/models/vat.model.js.map +1 -1
  135. package/dist/cjs/plugin/mailing-list/mailing-list.controller.js +1 -1
  136. package/dist/cjs/plugin/mailing-list/mailing-list.controller.js.map +1 -1
  137. package/dist/cjs/plugin/mailing-list/models/mailing-list-subscriber.model.d.ts +1 -1
  138. package/dist/cjs/plugin/mailing-list/models/mailing-list-subscriber.model.d.ts.map +1 -1
  139. package/dist/cjs/plugin/mailing-list/models/mailing-list-subscriber.model.js +1 -1
  140. package/dist/cjs/plugin/mailing-list/models/mailing-list-subscriber.model.js.map +1 -1
  141. package/dist/cjs/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.d.ts +1 -1
  142. package/dist/cjs/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.d.ts.map +1 -1
  143. package/dist/cjs/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.js +1 -1
  144. package/dist/cjs/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.js.map +1 -1
  145. package/dist/cjs/plugin/payment/models/payment.model.d.ts +2 -2
  146. package/dist/cjs/plugin/payment/models/payment.model.d.ts.map +1 -1
  147. package/dist/cjs/plugin/payment/models/payment.model.js +1 -1
  148. package/dist/cjs/plugin/payment/models/payment.model.js.map +1 -1
  149. package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal-client.d.ts +17 -17
  150. package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal-client.d.ts.map +1 -1
  151. package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal-client.js +17 -17
  152. package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal-client.js.map +1 -1
  153. package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal.payment-provider.js +1 -1
  154. package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal.payment-provider.js.map +1 -1
  155. package/dist/cjs/preact/preact.utilities.js +1 -1
  156. package/dist/cjs/preact/preact.utilities.js.map +1 -1
  157. package/dist/cjs/preact/validate-email-templates.function.js +1 -1
  158. package/dist/cjs/preact/validate-email-templates.function.js.map +1 -1
  159. package/dist/cjs/rate-limiting/rate-limiter.d.ts +10 -5
  160. package/dist/cjs/rate-limiting/rate-limiter.d.ts.map +1 -1
  161. package/dist/cjs/rate-limiting/rate-limiter.js +22 -12
  162. package/dist/cjs/rate-limiting/rate-limiter.js.map +1 -1
  163. package/dist/cjs/routing/controller-route-configuration.model.d.ts +5 -0
  164. package/dist/cjs/routing/controller-route-configuration.model.d.ts.map +1 -1
  165. package/dist/cjs/routing/decorators/controller.decorator.d.ts +5 -0
  166. package/dist/cjs/routing/decorators/controller.decorator.d.ts.map +1 -1
  167. package/dist/cjs/routing/decorators/controller.decorator.js +3 -2
  168. package/dist/cjs/routing/decorators/controller.decorator.js.map +1 -1
  169. package/dist/cjs/routing/decorators/create-http-decorator.function.d.ts +2 -1
  170. package/dist/cjs/routing/decorators/create-http-decorator.function.d.ts.map +1 -1
  171. package/dist/cjs/routing/decorators/create-http-decorator.function.js +2 -2
  172. package/dist/cjs/routing/decorators/create-http-decorator.function.js.map +1 -1
  173. package/dist/cjs/routing/decorators/delete.decorator.d.ts +3 -1
  174. package/dist/cjs/routing/decorators/delete.decorator.d.ts.map +1 -1
  175. package/dist/cjs/routing/decorators/delete.decorator.js +3 -2
  176. package/dist/cjs/routing/decorators/delete.decorator.js.map +1 -1
  177. package/dist/cjs/routing/decorators/get.decorator.d.ts +3 -1
  178. package/dist/cjs/routing/decorators/get.decorator.d.ts.map +1 -1
  179. package/dist/cjs/routing/decorators/get.decorator.js +3 -2
  180. package/dist/cjs/routing/decorators/get.decorator.js.map +1 -1
  181. package/dist/cjs/routing/decorators/http-decorator-option-input.model.d.ts +11 -0
  182. package/dist/cjs/routing/decorators/http-decorator-option-input.model.d.ts.map +1 -0
  183. package/dist/cjs/routing/decorators/http-decorator-option-input.model.js +3 -0
  184. package/dist/cjs/routing/decorators/http-decorator-option-input.model.js.map +1 -0
  185. package/dist/cjs/routing/decorators/patch.decorator.d.ts +3 -1
  186. package/dist/cjs/routing/decorators/patch.decorator.d.ts.map +1 -1
  187. package/dist/cjs/routing/decorators/patch.decorator.js +3 -2
  188. package/dist/cjs/routing/decorators/patch.decorator.js.map +1 -1
  189. package/dist/cjs/routing/decorators/post.decorator.d.ts +3 -1
  190. package/dist/cjs/routing/decorators/post.decorator.d.ts.map +1 -1
  191. package/dist/cjs/routing/decorators/post.decorator.js +3 -2
  192. package/dist/cjs/routing/decorators/post.decorator.js.map +1 -1
  193. package/dist/cjs/routing/resolve-route-params.function.js +1 -0
  194. package/dist/cjs/routing/resolve-route-params.function.js.map +1 -1
  195. package/dist/cjs/routing/route-configuration.model.d.ts +11 -1
  196. package/dist/cjs/routing/route-configuration.model.d.ts.map +1 -1
  197. package/dist/cjs/routing/router.d.ts +6 -2
  198. package/dist/cjs/routing/router.d.ts.map +1 -1
  199. package/dist/cjs/routing/router.js +173 -88
  200. package/dist/cjs/routing/router.js.map +1 -1
  201. package/dist/cjs/utilities/fs.utilities.d.ts +1 -1
  202. package/dist/cjs/utilities/fs.utilities.js +1 -1
  203. package/dist/cjs/utilities/sem-ver.utilities.d.ts +46 -0
  204. package/dist/cjs/utilities/sem-ver.utilities.d.ts.map +1 -0
  205. package/dist/cjs/utilities/sem-ver.utilities.js +204 -0
  206. package/dist/cjs/utilities/sem-ver.utilities.js.map +1 -0
  207. package/dist/cjs/utilities/uuid.utilities.js +2 -2
  208. package/dist/cjs/utilities/uuid.utilities.js.map +1 -1
  209. package/dist/cjs/versioning/route-with-version-data.model.d.ts +15 -0
  210. package/dist/cjs/versioning/route-with-version-data.model.d.ts.map +1 -0
  211. package/dist/cjs/versioning/route-with-version-data.model.js +3 -0
  212. package/dist/cjs/versioning/route-with-version-data.model.js.map +1 -0
  213. package/dist/cjs/versioning/supported-versions-options.model.d.ts +17 -0
  214. package/dist/cjs/versioning/supported-versions-options.model.d.ts.map +1 -0
  215. package/dist/cjs/versioning/supported-versions-options.model.js +3 -0
  216. package/dist/cjs/versioning/supported-versions-options.model.js.map +1 -0
  217. package/dist/cjs/versioning/version.model.d.ts +29 -0
  218. package/dist/cjs/versioning/version.model.d.ts.map +1 -0
  219. package/dist/{esm/types/version.type.js → cjs/versioning/version.model.js} +1 -1
  220. package/dist/cjs/versioning/version.model.js.map +1 -0
  221. package/dist/cjs/versioning/versioning-service.interface.d.ts +31 -0
  222. package/dist/cjs/versioning/versioning-service.interface.d.ts.map +1 -0
  223. package/dist/cjs/versioning/versioning-service.interface.js +3 -0
  224. package/dist/cjs/versioning/versioning-service.interface.js.map +1 -0
  225. package/dist/cjs/versioning/versioning.service.d.ts +41 -0
  226. package/dist/cjs/versioning/versioning.service.d.ts.map +1 -0
  227. package/dist/cjs/versioning/versioning.service.js +366 -0
  228. package/dist/cjs/versioning/versioning.service.js.map +1 -0
  229. package/dist/cjs/websocket/decorators/websocket-controller.decorator.d.ts +10 -0
  230. package/dist/cjs/websocket/decorators/websocket-controller.decorator.d.ts.map +1 -1
  231. package/dist/cjs/websocket/decorators/websocket-controller.decorator.js +2 -2
  232. package/dist/cjs/websocket/decorators/websocket-controller.decorator.js.map +1 -1
  233. package/dist/cjs/websocket/decorators/websocket-route.decorator.d.ts +13 -1
  234. package/dist/cjs/websocket/decorators/websocket-route.decorator.d.ts.map +1 -1
  235. package/dist/cjs/websocket/decorators/websocket-route.decorator.js +3 -2
  236. package/dist/cjs/websocket/decorators/websocket-route.decorator.js.map +1 -1
  237. package/dist/cjs/websocket/models/connection/base-websocket-connection.model.d.ts +5 -0
  238. package/dist/cjs/websocket/models/connection/base-websocket-connection.model.d.ts.map +1 -1
  239. package/dist/cjs/websocket/models/connection/socket-io-websocket-connection.model.d.ts +3 -1
  240. package/dist/cjs/websocket/models/connection/socket-io-websocket-connection.model.d.ts.map +1 -1
  241. package/dist/cjs/websocket/models/connection/socket-io-websocket-connection.model.js +3 -1
  242. package/dist/cjs/websocket/models/connection/socket-io-websocket-connection.model.js.map +1 -1
  243. package/dist/cjs/websocket/models/websocket-controller-route-configuration.model.d.ts +6 -0
  244. package/dist/cjs/websocket/models/websocket-controller-route-configuration.model.d.ts.map +1 -1
  245. package/dist/cjs/websocket/models/websocket-message.model.d.ts +2 -2
  246. package/dist/cjs/websocket/models/websocket-message.model.d.ts.map +1 -1
  247. package/dist/cjs/websocket/models/websocket-message.model.js.map +1 -1
  248. package/dist/cjs/websocket/models/websocket-request.model.d.ts +3 -3
  249. package/dist/cjs/websocket/models/websocket-request.model.d.ts.map +1 -1
  250. package/dist/cjs/websocket/models/websocket-request.model.js +1 -1
  251. package/dist/cjs/websocket/models/websocket-request.model.js.map +1 -1
  252. package/dist/cjs/websocket/services/websocket.service.d.ts +6 -4
  253. package/dist/cjs/websocket/services/websocket.service.d.ts.map +1 -1
  254. package/dist/cjs/websocket/services/websocket.service.js +121 -33
  255. package/dist/cjs/websocket/services/websocket.service.js.map +1 -1
  256. package/dist/esm/application.js +0 -1
  257. package/dist/esm/application.js.map +1 -1
  258. package/dist/esm/assets/asset.service.js +3 -1
  259. package/dist/esm/assets/asset.service.js.map +1 -1
  260. package/dist/esm/auth/2fa/methods/otp/otp-credentials.model.js.map +1 -1
  261. package/dist/esm/auth/2fa/methods/otp/otp.two-factor-method.js +1 -1
  262. package/dist/esm/auth/2fa/methods/otp/otp.two-factor-method.js.map +1 -1
  263. package/dist/esm/auth/strategies/cookie/cookie-auth.controller.js +1 -1
  264. package/dist/esm/auth/strategies/cookie/cookie-auth.controller.js.map +1 -1
  265. package/dist/esm/auth/strategies/jwt/jwt-auth.controller.js +1 -1
  266. package/dist/esm/auth/strategies/jwt/jwt-auth.controller.js.map +1 -1
  267. package/dist/esm/auth/strategies/jwt/jwt.auth-strategy.js +1 -1
  268. package/dist/esm/auth/strategies/jwt/jwt.auth-strategy.js.map +1 -1
  269. package/dist/esm/backup/backup-resource-entity.model.js.map +1 -1
  270. package/dist/esm/change-sets/models/change-set.model.js +1 -1
  271. package/dist/esm/change-sets/models/change-set.model.js.map +1 -1
  272. package/dist/esm/change-sets/models/change.model.js.map +1 -1
  273. package/dist/esm/context/cache/cache.context.js +2 -2
  274. package/dist/esm/context/cache/cache.context.js.map +1 -1
  275. package/dist/esm/context/request/request-context-token.model.js +1 -1
  276. package/dist/esm/context/request/request-context-token.model.js.map +1 -1
  277. package/dist/esm/cron/cron-job-entity.model.js.map +1 -1
  278. package/dist/esm/data-source/data-sources/postgres-typeorm-data-source.model.js +9 -0
  279. package/dist/esm/data-source/data-sources/postgres-typeorm-data-source.model.js.map +1 -1
  280. package/dist/esm/data-source/data-sources/typeorm-base-data-source.model.js +3 -3
  281. package/dist/esm/data-source/data-sources/typeorm-base-data-source.model.js.map +1 -1
  282. package/dist/esm/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.js +20 -0
  283. package/dist/esm/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.js.map +1 -1
  284. package/dist/esm/data-source/data-sources/where-converter/typeorm-where-filter.converter.js +3 -1
  285. package/dist/esm/data-source/data-sources/where-converter/typeorm-where-filter.converter.js.map +1 -1
  286. package/dist/esm/data-source/migration/migration-entity.model.js.map +1 -1
  287. package/dist/esm/data-source/models/where/where-filter-keys.model.js +3 -0
  288. package/dist/esm/data-source/models/where/where-filter-keys.model.js.map +1 -1
  289. package/dist/esm/di/default/zibri-di-providers.default.js +4 -0
  290. package/dist/esm/di/default/zibri-di-providers.default.js.map +1 -1
  291. package/dist/esm/di/default/zibri-di-tokens.default.js +2 -0
  292. package/dist/esm/di/default/zibri-di-tokens.default.js.map +1 -1
  293. package/dist/esm/email/email.service.js +4 -4
  294. package/dist/esm/email/email.service.js.map +1 -1
  295. package/dist/esm/email/models/email.model.js +4 -4
  296. package/dist/esm/email/models/email.model.js.map +1 -1
  297. package/dist/esm/entity/generation/generate-entity-file.function.js +1 -1
  298. package/dist/esm/entity/generation/generate-entity-file.function.js.map +1 -1
  299. package/dist/esm/event/event-subscriber-run.model.js +1 -1
  300. package/dist/esm/event/event-subscriber-run.model.js.map +1 -1
  301. package/dist/esm/http/known-header.enum.js +1 -0
  302. package/dist/esm/http/known-header.enum.js.map +1 -1
  303. package/dist/esm/http-client/http-client.js.map +1 -1
  304. package/dist/esm/index.js +8 -3
  305. package/dist/esm/index.js.map +1 -1
  306. package/dist/esm/localization/formatting/format-price.function.js.map +1 -1
  307. package/dist/esm/logging/log-context.model.js +6 -6
  308. package/dist/esm/logging/log-context.model.js.map +1 -1
  309. package/dist/esm/logging/logger.js +1 -1
  310. package/dist/esm/logging/logger.js.map +1 -1
  311. package/dist/esm/multithreading/models/thread-job-entity.model.js +4 -4
  312. package/dist/esm/multithreading/models/thread-job-entity.model.js.map +1 -1
  313. package/dist/esm/multithreading/services/thread-job.js.map +1 -1
  314. package/dist/esm/open-api/open-api.service.js +256 -139
  315. package/dist/esm/open-api/open-api.service.js.map +1 -1
  316. package/dist/esm/parsing/html/csp-options.model.js.map +1 -1
  317. package/dist/esm/parsing/parser.js +3 -3
  318. package/dist/esm/parsing/parser.js.map +1 -1
  319. package/dist/esm/plugin/invoicing/models/invoice-address.model.js +2 -2
  320. package/dist/esm/plugin/invoicing/models/invoice-address.model.js.map +1 -1
  321. package/dist/esm/plugin/invoicing/models/vat.model.js +1 -1
  322. package/dist/esm/plugin/invoicing/models/vat.model.js.map +1 -1
  323. package/dist/esm/plugin/mailing-list/mailing-list.controller.js +1 -1
  324. package/dist/esm/plugin/mailing-list/mailing-list.controller.js.map +1 -1
  325. package/dist/esm/plugin/mailing-list/models/mailing-list-subscriber.model.js +1 -1
  326. package/dist/esm/plugin/mailing-list/models/mailing-list-subscriber.model.js.map +1 -1
  327. package/dist/esm/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.js +1 -1
  328. package/dist/esm/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.js.map +1 -1
  329. package/dist/esm/plugin/payment/models/payment.model.js +1 -1
  330. package/dist/esm/plugin/payment/models/payment.model.js.map +1 -1
  331. package/dist/esm/plugin/payment/providers/pay-pal/pay-pal-client.js +17 -17
  332. package/dist/esm/plugin/payment/providers/pay-pal/pay-pal-client.js.map +1 -1
  333. package/dist/esm/plugin/payment/providers/pay-pal/pay-pal.payment-provider.js +1 -1
  334. package/dist/esm/plugin/payment/providers/pay-pal/pay-pal.payment-provider.js.map +1 -1
  335. package/dist/esm/preact/preact.utilities.js +1 -1
  336. package/dist/esm/preact/preact.utilities.js.map +1 -1
  337. package/dist/esm/preact/validate-email-templates.function.js +1 -1
  338. package/dist/esm/preact/validate-email-templates.function.js.map +1 -1
  339. package/dist/esm/rate-limiting/rate-limiter.js +22 -12
  340. package/dist/esm/rate-limiting/rate-limiter.js.map +1 -1
  341. package/dist/esm/routing/decorators/controller.decorator.js +3 -2
  342. package/dist/esm/routing/decorators/controller.decorator.js.map +1 -1
  343. package/dist/esm/routing/decorators/create-http-decorator.function.js +2 -2
  344. package/dist/esm/routing/decorators/create-http-decorator.function.js.map +1 -1
  345. package/dist/esm/routing/decorators/delete.decorator.js +3 -2
  346. package/dist/esm/routing/decorators/delete.decorator.js.map +1 -1
  347. package/dist/esm/routing/decorators/get.decorator.js +3 -2
  348. package/dist/esm/routing/decorators/get.decorator.js.map +1 -1
  349. package/dist/esm/routing/decorators/http-decorator-option-input.model.js +3 -0
  350. package/dist/esm/routing/decorators/http-decorator-option-input.model.js.map +1 -0
  351. package/dist/esm/routing/decorators/patch.decorator.js +3 -2
  352. package/dist/esm/routing/decorators/patch.decorator.js.map +1 -1
  353. package/dist/esm/routing/decorators/post.decorator.js +3 -2
  354. package/dist/esm/routing/decorators/post.decorator.js.map +1 -1
  355. package/dist/esm/routing/resolve-route-params.function.js +1 -0
  356. package/dist/esm/routing/resolve-route-params.function.js.map +1 -1
  357. package/dist/esm/routing/router.js +173 -88
  358. package/dist/esm/routing/router.js.map +1 -1
  359. package/dist/esm/utilities/fs.utilities.js +1 -1
  360. package/dist/esm/utilities/sem-ver.utilities.js +204 -0
  361. package/dist/esm/utilities/sem-ver.utilities.js.map +1 -0
  362. package/dist/esm/utilities/uuid.utilities.js +2 -2
  363. package/dist/esm/utilities/uuid.utilities.js.map +1 -1
  364. package/dist/esm/versioning/route-with-version-data.model.js +3 -0
  365. package/dist/esm/versioning/route-with-version-data.model.js.map +1 -0
  366. package/dist/esm/versioning/supported-versions-options.model.js +3 -0
  367. package/dist/esm/versioning/supported-versions-options.model.js.map +1 -0
  368. package/dist/{cjs/types/version.type.js → esm/versioning/version.model.js} +1 -1
  369. package/dist/esm/versioning/version.model.js.map +1 -0
  370. package/dist/esm/versioning/versioning-service.interface.js +3 -0
  371. package/dist/esm/versioning/versioning-service.interface.js.map +1 -0
  372. package/dist/esm/versioning/versioning.service.js +366 -0
  373. package/dist/esm/versioning/versioning.service.js.map +1 -0
  374. package/dist/esm/websocket/decorators/websocket-controller.decorator.js +2 -2
  375. package/dist/esm/websocket/decorators/websocket-controller.decorator.js.map +1 -1
  376. package/dist/esm/websocket/decorators/websocket-route.decorator.js +3 -2
  377. package/dist/esm/websocket/decorators/websocket-route.decorator.js.map +1 -1
  378. package/dist/esm/websocket/models/connection/socket-io-websocket-connection.model.js +3 -1
  379. package/dist/esm/websocket/models/connection/socket-io-websocket-connection.model.js.map +1 -1
  380. package/dist/esm/websocket/models/websocket-message.model.js.map +1 -1
  381. package/dist/esm/websocket/models/websocket-request.model.js +1 -1
  382. package/dist/esm/websocket/models/websocket-request.model.js.map +1 -1
  383. package/dist/esm/websocket/services/websocket.service.js +121 -33
  384. package/dist/esm/websocket/services/websocket.service.js.map +1 -1
  385. package/package.json +17 -19
  386. package/src/__testing__/test-server/providers.ts +25 -1
  387. package/src/__testing__/test-server/start-test-server.function.ts +76 -8
  388. package/src/application-options.model.ts +2 -2
  389. package/src/application.ts +0 -1
  390. package/src/assets/asset.service.ts +3 -1
  391. package/src/auth/2fa/methods/otp/otp-credentials.model.ts +1 -1
  392. package/src/auth/2fa/methods/otp/otp.two-factor-method.ts +1 -1
  393. package/src/auth/strategies/cookie/cookie-auth.controller.ts +1 -1
  394. package/src/auth/strategies/jwt/jwt-auth.controller.ts +1 -1
  395. package/src/auth/strategies/jwt/jwt.auth-strategy.ts +1 -1
  396. package/src/backup/backup-resource-entity.model.ts +1 -1
  397. package/src/backup/backup-service.test.ts +2 -1
  398. package/src/change-sets/models/change-set.model.ts +1 -1
  399. package/src/change-sets/models/change.model.ts +2 -2
  400. package/src/context/cache/cache.context.ts +2 -2
  401. package/src/context/request/request-context-token.model.ts +1 -1
  402. package/src/cron/cron-job-entity.model.ts +2 -2
  403. package/src/data-source/data-sources/postgres-typeorm-data-source.model.ts +10 -0
  404. package/src/data-source/data-sources/typeorm-base-data-source.model.ts +4 -5
  405. package/src/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.ts +35 -2
  406. package/src/data-source/data-sources/where-converter/typeorm-where-filter.converter.ts +14 -1
  407. package/src/data-source/hooks/hooks.test.ts +1 -1
  408. package/src/data-source/migration/migration-entity.model.ts +2 -2
  409. package/src/data-source/migration/migration.model.ts +2 -2
  410. package/src/data-source/migration/migration.test.ts +2 -2
  411. package/src/data-source/models/where/date-where-filter.model.ts +11 -3
  412. package/src/data-source/models/where/string-where-filter.model.ts +18 -1
  413. package/src/data-source/models/where/where-filter-keys.model.ts +3 -0
  414. package/src/data-source/nested-where-filter.test.ts +8 -3
  415. package/src/data-source/repository.test.ts +2 -2
  416. package/src/data-source/where-filter.test.ts +17 -7
  417. package/src/di/default/zibri-di-providers.default.ts +4 -0
  418. package/src/di/default/zibri-di-tokens.default.ts +3 -0
  419. package/src/email/email.service.ts +5 -5
  420. package/src/email/models/email.model.ts +4 -4
  421. package/src/entity/generation/generate-entity-file.function.ts +1 -1
  422. package/src/event/event-subscriber-run.model.ts +1 -1
  423. package/src/global/global-registry.ts +2 -2
  424. package/src/http/http-request.model.ts +2 -2
  425. package/src/http/known-header.enum.ts +1 -0
  426. package/src/http-client/http-client.ts +0 -1
  427. package/src/index.ts +9 -3
  428. package/src/localization/formatting/format-price.function.ts +2 -3
  429. package/src/logging/log-context.model.ts +6 -6
  430. package/src/logging/logger.ts +1 -1
  431. package/src/multithreading/models/thread-job-entity.model.ts +5 -5
  432. package/src/multithreading/services/thread-job.ts +4 -4
  433. package/src/open-api/open-api-service.interface.ts +2 -1
  434. package/src/open-api/open-api.service.ts +263 -141
  435. package/src/parsing/html/csp-options.model.ts +3 -0
  436. package/src/parsing/parser.ts +3 -3
  437. package/src/plugin/invoicing/models/invoice-address.model.ts +2 -2
  438. package/src/plugin/invoicing/models/vat.model.ts +1 -1
  439. package/src/plugin/mailing-list/mailing-list.controller.ts +1 -1
  440. package/src/plugin/mailing-list/models/mailing-list-subscriber.model.ts +1 -1
  441. package/src/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.ts +1 -1
  442. package/src/plugin/payment/models/payment.model.ts +2 -2
  443. package/src/plugin/payment/providers/pay-pal/pay-pal-client.ts +17 -17
  444. package/src/plugin/payment/providers/pay-pal/pay-pal.payment-provider.test.ts +1 -1
  445. package/src/plugin/payment/providers/pay-pal/pay-pal.payment-provider.ts +1 -1
  446. package/src/preact/preact.utilities.ts +1 -1
  447. package/src/preact/validate-email-templates.function.ts +1 -1
  448. package/src/rate-limiting/rate-limiter.ts +23 -12
  449. package/src/routing/controller-route-configuration.model.ts +6 -1
  450. package/src/routing/decorators/controller.decorator.ts +8 -2
  451. package/src/routing/decorators/create-http-decorator.function.ts +3 -2
  452. package/src/routing/decorators/delete.decorator.ts +4 -2
  453. package/src/routing/decorators/get.decorator.ts +4 -2
  454. package/src/routing/decorators/http-decorator-option-input.model.ts +11 -0
  455. package/src/routing/decorators/patch.decorator.ts +4 -2
  456. package/src/routing/decorators/post.decorator.ts +4 -2
  457. package/src/routing/resolve-route-params.function.ts +1 -0
  458. package/src/routing/route-configuration.model.ts +13 -3
  459. package/src/routing/router.ts +265 -134
  460. package/src/utilities/fs.utilities.ts +1 -1
  461. package/src/utilities/sem-ver.utilities.ts +270 -0
  462. package/src/utilities/uuid.utilities.ts +2 -2
  463. package/src/versioning/route-with-version-data.model.ts +15 -0
  464. package/src/versioning/supported-versions-options.model.ts +25 -0
  465. package/src/versioning/version.model.ts +30 -0
  466. package/src/versioning/versioning-service.interface.ts +39 -0
  467. package/src/versioning/versioning-websocket.test.ts +351 -0
  468. package/src/versioning/versioning.service.test.ts +582 -0
  469. package/src/versioning/versioning.service.ts +496 -0
  470. package/src/websocket/decorators/websocket-controller.decorator.ts +13 -3
  471. package/src/websocket/decorators/websocket-route.decorator.ts +15 -2
  472. package/src/websocket/models/connection/base-websocket-connection.model.ts +6 -0
  473. package/src/websocket/models/connection/socket-io-websocket-connection.model.ts +8 -1
  474. package/src/websocket/models/websocket-controller-route-configuration.model.ts +8 -1
  475. package/src/websocket/models/websocket-message.model.ts +2 -2
  476. package/src/websocket/models/websocket-request.model.ts +4 -3
  477. package/src/websocket/services/websocket.service.ts +143 -38
  478. package/dist/cjs/types/version.type.d.ts +0 -5
  479. package/dist/cjs/types/version.type.d.ts.map +0 -1
  480. package/dist/cjs/types/version.type.js.map +0 -1
  481. package/dist/cjs/utilities/compare-versions.function.d.ts +0 -9
  482. package/dist/cjs/utilities/compare-versions.function.d.ts.map +0 -1
  483. package/dist/cjs/utilities/compare-versions.function.js +0 -33
  484. package/dist/cjs/utilities/compare-versions.function.js.map +0 -1
  485. package/dist/cjs/utilities/is-version.function.d.ts +0 -7
  486. package/dist/cjs/utilities/is-version.function.d.ts.map +0 -1
  487. package/dist/cjs/utilities/is-version.function.js +0 -18
  488. package/dist/cjs/utilities/is-version.function.js.map +0 -1
  489. package/dist/esm/types/version.type.js.map +0 -1
  490. package/dist/esm/utilities/compare-versions.function.js +0 -33
  491. package/dist/esm/utilities/compare-versions.function.js.map +0 -1
  492. package/dist/esm/utilities/is-version.function.js +0 -18
  493. package/dist/esm/utilities/is-version.function.js.map +0 -1
  494. package/src/types/version.type.ts +0 -4
  495. package/src/utilities/compare-versions.function.ts +0 -33
  496. package/src/utilities/is-version.function.ts +0 -16
@@ -1,3 +1,4 @@
1
+ import assert from 'node:assert';
1
2
  import { Readable } from 'stream';
2
3
 
3
4
  import { NextFunction, RequestHandler, Router as ExpressRouter } from 'express';
@@ -16,6 +17,7 @@ import { Inject } from '../di/decorators/inject.decorator';
16
17
  import { Injectable } from '../di/decorators/injectable.decorator';
17
18
  import { ZIBRI_DI_TOKENS } from '../di/default/zibri-di-tokens.default';
18
19
  import { inject } from '../di/inject.function';
20
+ import { NotFoundError } from '../error-handling/errors/not-found.error';
19
21
  import { GlobalRegistry } from '../global/global-registry';
20
22
  import { OnAppInit } from '../global/on-app-init.interface';
21
23
  import { OnAppStart } from '../global/on-app-start.interface';
@@ -33,12 +35,22 @@ import type { ParserInterface } from '../parsing/parser.interface';
33
35
  import { Newable } from '../types/newable.type';
34
36
  import { MetadataUtilities } from '../utilities/metadata.utilities';
35
37
  import { Ms } from '../utilities/ms';
38
+ import { SemVerVersion } from '../utilities/sem-ver.utilities';
36
39
  import type { ValidationServiceInterface } from '../validation/validation-service.interface';
37
40
  import { ControllerData } from './decorators/controller.decorator';
38
41
  import { AlsUtilities } from '../context/als.utilities';
39
42
  import { HttpRequestContext } from '../context/request/http-request.context';
40
43
  import { JsonUtilities } from '../utilities/json.utilities';
41
44
  import { ObjectUtilities } from '../utilities/object.utilities';
45
+ import { RouteWithVersionData } from '../versioning/route-with-version-data.model';
46
+ import { SupportedVersionsOptions } from '../versioning/supported-versions-options.model';
47
+ import { Version } from '../versioning/version.model';
48
+ import { type VersioningServiceInterface } from '../versioning/versioning-service.interface';
49
+
50
+ /**
51
+ * Handler for a specific route and version.
52
+ */
53
+ type ControllerInnerHandler = (context: HttpRequestContext, next: NextFunction) => Promise<void>;
42
54
 
43
55
  /**
44
56
  * Default router implementation of Zibri.
@@ -46,8 +58,9 @@ import { ObjectUtilities } from '../utilities/object.utilities';
46
58
  @Injectable({ register: 'onUse' })
47
59
  export class Router implements RouterInterface, OnAppInit, OnAppStart {
48
60
  private readonly expressRouter: ExpressRouter = ExpressRouter();
49
- private readonly allBaseRoutes: string[] = [];
50
- private readonly allFinalRoutes: string[] = [];
61
+ private readonly allBaseRoutes: RouteWithVersionData[] = [];
62
+ private readonly allFinalRoutes: RouteWithVersionData[] = [];
63
+ private initComplete: boolean = false;
51
64
  // eslint-disable-next-line jsdoc/require-jsdoc
52
65
  readonly manuallyRegisteredRoutes: RouteConfiguration<
53
66
  BodyMetadata,
@@ -55,6 +68,18 @@ export class Router implements RouterInterface, OnAppInit, OnAppStart {
55
68
  Record<string, QueryParamMetadata>,
56
69
  Record<string, HeaderParamMetadata>
57
70
  >[] = [];
71
+ private readonly pendingRouteGroups: Map<string, {
72
+ // eslint-disable-next-line jsdoc/require-jsdoc
73
+ httpMethod: HttpMethod,
74
+ // eslint-disable-next-line jsdoc/require-jsdoc
75
+ finalRoute: string,
76
+ // eslint-disable-next-line jsdoc/require-jsdoc
77
+ entries: { versions: SupportedVersionsOptions, innerHandler: ControllerInnerHandler }[]
78
+ }> = new Map();
79
+
80
+ private get versioningService(): VersioningServiceInterface {
81
+ return inject(ZIBRI_DI_TOKENS.VERSIONING_SERVICE);
82
+ }
58
83
 
59
84
  constructor(
60
85
  @Inject(ZIBRI_DI_TOKENS.LOGGER)
@@ -76,6 +101,13 @@ export class Router implements RouterInterface, OnAppInit, OnAppStart {
76
101
  await this.registerController(controller);
77
102
  }
78
103
  this.checkForOrphanedControllers(app.options.controllers);
104
+
105
+ for (const group of this.pendingRouteGroups.values()) {
106
+ const dispatchHandler: RequestHandler = this.createDispatchHandler(group.entries);
107
+ await this.logger.debug(`- mounting ${group.httpMethod.toUpperCase()} ${group.finalRoute}`);
108
+ this.expressRouter[group.httpMethod](group.finalRoute, dispatchHandler);
109
+ }
110
+ this.initComplete = true;
79
111
  }
80
112
 
81
113
  // eslint-disable-next-line jsdoc/require-jsdoc
@@ -107,10 +139,37 @@ export class Router implements RouterInterface, OnAppInit, OnAppStart {
107
139
  >(
108
140
  input: RouteConfigurationInput<BodyMetaInputObject, PathMetaInputObject, QueryMetaInputObject, HeaderMetaInputObject>
109
141
  ): Promise<void> {
110
- if (this.allFinalRoutes.includes(`${input.httpMethod.toUpperCase()} ${input.route}`)) {
111
- throw new Error(`The route "${input.httpMethod.toUpperCase()} ${input.route}" has been defined more than once.`);
142
+ const key: string = `${input.httpMethod.toUpperCase()} ${input.route}`;
143
+ const versions: SupportedVersionsOptions = input.versions ?? ['^latest'];
144
+ const currentLatest: SemVerVersion | undefined = GlobalRegistry.getAppData('version');
145
+ assert(currentLatest);
146
+
147
+ const overlappingRoute: RouteWithVersionData | undefined = this.allFinalRoutes.find(
148
+ r => r.key === key && this.versioningService.hasOverlappingVersions(r.versions, versions, currentLatest)
149
+ );
150
+ if (overlappingRoute) {
151
+ const overlappingVersions: SupportedVersionsOptions = this.versioningService.findOverlappingVersions(
152
+ overlappingRoute.versions,
153
+ versions,
154
+ currentLatest
155
+ );
156
+ if (overlappingVersions === 'all') {
157
+ throw new Error([
158
+ `The route "${key}"`,
159
+ // eslint-disable-next-line sonar/no-duplicate-string
160
+ 'has been defined more than once.',
161
+ // eslint-disable-next-line sonar/no-duplicate-string
162
+ '(versions: \'all\' has been used)'
163
+ ].join(' '));
164
+ }
165
+
166
+ throw new Error([
167
+ `The route "${key}"`,
168
+ `for the ${overlappingVersions.length > 1 ? 'versions' : 'version'} "${overlappingVersions.join(', ')}"`,
169
+ 'has been defined more than once.'
170
+ ].join(' '));
112
171
  }
113
- this.allFinalRoutes.push(`${input.httpMethod.toUpperCase()} ${input.route}`);
172
+ this.allFinalRoutes.push({ key, versions });
114
173
 
115
174
  const pathParams: Record<string, PathParamMetadata> = {};
116
175
  for (const key in input.pathParams) {
@@ -127,6 +186,7 @@ export class Router implements RouterInterface, OnAppInit, OnAppStart {
127
186
 
128
187
  // eslint-disable-next-line typescript/no-explicit-any
129
188
  const route: RouteConfiguration<any, any, any, any> = {
189
+ versions: ['^latest'],
130
190
  ...input,
131
191
  openApi: this.createOpenApiRouteConfiguration(input.openApi, input.httpMethod),
132
192
  bodyMetadata: input.bodyMetadata
@@ -146,8 +206,8 @@ export class Router implements RouterInterface, OnAppInit, OnAppStart {
146
206
  queryParams,
147
207
  headerParams
148
208
  };
149
- const handler: RequestHandler = this.routeToRequestHandler(route);
150
- await this.logger.debug(`- mounting ${route.httpMethod.toUpperCase()} ${route.route}`);
209
+
210
+ await this.logger.debug(`- mounting ${key}`);
151
211
  this.manuallyRegisteredRoutes.push(
152
212
  route as RouteConfiguration<
153
213
  BodyMetadata,
@@ -156,7 +216,69 @@ export class Router implements RouterInterface, OnAppInit, OnAppStart {
156
216
  Record<string, HeaderParamMetadata>
157
217
  >
158
218
  );
159
- this.expressRouter[route.httpMethod](route.route, handler);
219
+
220
+ const innerHandler: ControllerInnerHandler = this.createManualRouteInnerHandler(route);
221
+ // eslint-disable-next-line typescript/typedef
222
+ const existing = this.pendingRouteGroups.get(key);
223
+ if (existing) {
224
+ existing.entries.push({ versions, innerHandler });
225
+ }
226
+ else {
227
+ this.pendingRouteGroups.set(key, {
228
+ httpMethod: input.httpMethod,
229
+ finalRoute: input.route,
230
+ entries: [{ versions, innerHandler }]
231
+ });
232
+ }
233
+
234
+ // If init has already completed, mount immediately since the deferred loop has already run
235
+ if (this.initComplete) {
236
+ // eslint-disable-next-line typescript/typedef, typescript/no-non-null-assertion
237
+ const group = this.pendingRouteGroups.get(key)!;
238
+ this.expressRouter[input.httpMethod](input.route, this.createDispatchHandler(group.entries));
239
+ }
240
+ }
241
+
242
+ private createManualRouteInnerHandler<
243
+ BodyMetaObject extends BodyMetadata,
244
+ PathMetaObject extends Record<string, PathParamMetadata>,
245
+ QueryMetaObject extends Record<string, QueryParamMetadata>,
246
+ HeaderMetaObject extends Record<string, HeaderParamMetadata>
247
+ >(route: RouteConfiguration<BodyMetaObject, PathMetaObject, QueryMetaObject, HeaderMetaObject>): ControllerInnerHandler {
248
+ return async (context: HttpRequestContext, next: NextFunction) => {
249
+ try {
250
+ for (const key of ObjectUtilities.keys(route.pathParams)) {
251
+ (context.request.params[key] as unknown) = this.parser.parsePathParam(context.request, route.pathParams[key]);
252
+ }
253
+ for (const key of ObjectUtilities.keys(route.queryParams)) {
254
+ (context.request.query[key] as unknown) = this.parser.parseQueryParam(context.request, route.queryParams[key]);
255
+ }
256
+ for (const key of ObjectUtilities.keys(route.headerParams)) {
257
+ (context.request.headers[key] as unknown) = this.parser.parseHeaderParam(context.request, route.headerParams[key]);
258
+ }
259
+ if (route.bodyMetadata) {
260
+ context.request.body = await this.parser.parseBody(context.request, route.bodyMetadata);
261
+ }
262
+ await Promise.all([
263
+ ...ObjectUtilities.keys(route.pathParams).map(async key => {
264
+ await this.validationService.validatePathParam(context.request.params[key], route.pathParams[key]);
265
+ }),
266
+ ...ObjectUtilities.keys(route.queryParams).map(async key => {
267
+ await this.validationService.validateQueryParam(context.request.query[key], route.queryParams[key]);
268
+ }),
269
+ ...ObjectUtilities.keys(route.headerParams).map(async key => {
270
+ await this.validationService.validateHeaderParam(context.request.headers[key], route.headerParams[key]);
271
+ }),
272
+ ...route.bodyMetadata ? [this.validationService.validateBody(context.request.body, route.bodyMetadata)] : []
273
+ ]);
274
+ // eslint-disable-next-line typescript/no-explicit-any
275
+ const result: unknown = await route.handler(context.request as HttpRequest<any, any, any, any>, context.response, next);
276
+ await this.returnResult(context.response, result, next, []);
277
+ }
278
+ catch (error) {
279
+ next(error);
280
+ }
281
+ };
160
282
  }
161
283
 
162
284
  private createOpenApiRouteConfiguration(
@@ -178,14 +300,14 @@ export class Router implements RouterInterface, OnAppInit, OnAppStart {
178
300
  switch (httpMethod) {
179
301
  case HttpMethod.HEAD:
180
302
  case HttpMethod.OPTIONS:
181
- case HttpMethod.TRACE:
182
- case HttpMethod.GET: {
303
+ case HttpMethod.TRACE: {
183
304
  return { useInOpenApi: false };
184
305
  }
185
306
  case HttpMethod.POST:
186
307
  case HttpMethod.PUT:
187
308
  case HttpMethod.PATCH:
188
- case HttpMethod.DELETE: {
309
+ case HttpMethod.DELETE:
310
+ case HttpMethod.GET: {
189
311
  return {
190
312
  responses: [],
191
313
  tags: [],
@@ -195,163 +317,172 @@ export class Router implements RouterInterface, OnAppInit, OnAppStart {
195
317
  }
196
318
  }
197
319
 
198
- // eslint-disable-next-line jsdoc/require-jsdoc
320
+ // eslint-disable-next-line jsdoc/require-jsdoc, sonar/cognitive-complexity
199
321
  async registerController(controllerClass: Newable<unknown>): Promise<void> {
200
322
  const controllerData: ControllerData | undefined = MetadataUtilities.getControllerData(controllerClass);
201
323
  if (controllerData == undefined) {
202
324
  throw new MissingBaseRouteError(controllerClass);
203
325
  }
204
- if (this.allBaseRoutes.includes(controllerData.baseRoute)) {
205
- throw new Error(`The base route "${controllerData.baseRoute}" has been defined on more than one controller.`);
326
+ const currentLatest: SemVerVersion | undefined = GlobalRegistry.getAppData('version');
327
+ assert(currentLatest);
328
+
329
+ const overlappingBaseRoute: RouteWithVersionData | undefined = this.allBaseRoutes.find(
330
+ r => r.key === controllerData.baseRoute && this.versioningService.hasOverlappingVersions(
331
+ r.versions,
332
+ controllerData.versions,
333
+ currentLatest
334
+ )
335
+ );
336
+ if (overlappingBaseRoute) {
337
+ const overlappingVersions: SupportedVersionsOptions = this.versioningService.findOverlappingVersions(
338
+ overlappingBaseRoute.versions,
339
+ controllerData.versions,
340
+ currentLatest
341
+ );
342
+ if (overlappingVersions === 'all') {
343
+ throw new Error([
344
+ `The base route "${controllerData.baseRoute}"`,
345
+ 'has been defined on more than one controller.',
346
+ '(versions: \'all\' has been used)'
347
+ ].join(' '));
348
+ }
349
+ throw new Error([
350
+ `The base route "${controllerData.baseRoute}"`,
351
+ `for the ${overlappingVersions.length > 1 ? 'versions' : 'version'} "${overlappingVersions.join(', ')}"`,
352
+ 'has been defined on more than one controller.'
353
+ ].join(' '));
206
354
  }
207
- this.allBaseRoutes.push(controllerData.baseRoute);
355
+ this.allBaseRoutes.push({ key: controllerData.baseRoute, versions: controllerData.versions });
208
356
  const routes: ControllerRouteConfiguration[] = MetadataUtilities.getControllerRoutes(controllerClass);
209
357
 
210
358
  for (const route of routes) {
211
- const handler: RequestHandler = await this.controllerRouteToRequestHandler(controllerClass, route);
212
359
  const finalRoute: string = controllerData.baseRoute === '/' ? route.route : `${controllerData.baseRoute}${route.route}`;
213
- if (this.allFinalRoutes.includes(`${route.httpMethod.toUpperCase()} ${finalRoute}`)) {
214
- throw new Error(
215
- `The route "${route.httpMethod.toUpperCase()} ${finalRoute}" has been defined more than once.`,
216
- { cause: controllerClass }
360
+ const key: string = `${route.httpMethod.toUpperCase()} ${finalRoute}`;
361
+ const versions: SupportedVersionsOptions = route.versions ?? controllerData.versions;
362
+
363
+ const overlappingRoute: RouteWithVersionData | undefined = this.allFinalRoutes.find(
364
+ r => r.key === key && this.versioningService.hasOverlappingVersions(r.versions, versions, currentLatest)
365
+ );
366
+ if (overlappingRoute) {
367
+ const overlappingVersions: SupportedVersionsOptions = this.versioningService.findOverlappingVersions(
368
+ overlappingRoute.versions,
369
+ versions,
370
+ currentLatest
217
371
  );
372
+ if (overlappingVersions === 'all') {
373
+ throw new Error([
374
+ `The route "${key}"`,
375
+ 'has been defined more than once.',
376
+ '(versions: \'all\' has been used)'
377
+ ].join(' '));
378
+ }
379
+
380
+ throw new Error([
381
+ `The route "${key}"`,
382
+ `for the ${overlappingVersions.length > 1 ? 'versions' : 'version'} "${overlappingVersions.join(', ')}"`,
383
+ 'has been defined more than once.'
384
+ ].join(' '));
385
+ }
386
+
387
+ this.allFinalRoutes.push({ key, versions });
388
+
389
+ const innerHandler: ControllerInnerHandler = await this.createControllerInnerHandler(controllerClass, route);
390
+ // eslint-disable-next-line typescript/typedef
391
+ const existing = this.pendingRouteGroups.get(key);
392
+ if (existing) {
393
+ existing.entries.push({ versions, innerHandler });
394
+ continue;
218
395
  }
219
- this.allFinalRoutes.push(`${route.httpMethod.toUpperCase()} ${finalRoute}`);
220
- await this.logger.debug(`- mounting ${route.httpMethod.toUpperCase()} ${finalRoute}`);
221
- this.expressRouter[route.httpMethod](finalRoute, handler);
396
+
397
+ this.pendingRouteGroups.set(key, {
398
+ httpMethod: route.httpMethod,
399
+ finalRoute,
400
+ entries: [{ versions, innerHandler }]
401
+ });
222
402
  }
223
403
  }
224
404
 
225
- private routeToRequestHandler<
226
- BodyMetaObject extends BodyMetadata,
227
- PathMetaObject extends Record<string, PathParamMetadata>,
228
- QueryMetaObject extends Record<string, QueryParamMetadata>,
229
- HeaderMetaObject extends Record<string, HeaderParamMetadata>
230
- >(route: RouteConfiguration<BodyMetaObject, PathMetaObject, QueryMetaObject, HeaderMetaObject>): RequestHandler {
231
- const handler: RequestHandler = (async (request: HttpRequest, res, next) => {
232
- Object.defineProperty(request, 'params', {
233
- value: { ...request.params },
234
- writable: true,
235
- configurable: true,
236
- enumerable: true
237
- });
238
- Object.defineProperty(request, 'query', {
239
- value: { ...request.query },
240
- writable: true,
241
- configurable: true,
242
- enumerable: true
243
- });
244
- Object.defineProperty(request, 'headers', {
245
- value: { ...request.headers },
246
- writable: true,
247
- configurable: true,
248
- enumerable: true
249
- });
405
+ private createDispatchHandler(
406
+ // eslint-disable-next-line jsdoc/require-jsdoc
407
+ entries: { versions: SupportedVersionsOptions, innerHandler: ControllerInnerHandler }[]
408
+ ): RequestHandler {
409
+ return (async (request: HttpRequest, res, next) => {
410
+ Object.defineProperty(
411
+ request,
412
+ 'params',
413
+ {
414
+ value: { ...request.params },
415
+ writable: true,
416
+ configurable: true,
417
+ enumerable: true
418
+ }
419
+ );
420
+ Object.defineProperty(
421
+ request,
422
+ 'query',
423
+ {
424
+ value: { ...request.query },
425
+ writable: true,
426
+ configurable: true,
427
+ enumerable: true
428
+ }
429
+ );
430
+ Object.defineProperty(
431
+ request,
432
+ 'headers',
433
+ {
434
+ value: { ...request.headers },
435
+ writable: true,
436
+ configurable: true,
437
+ enumerable: true
438
+ }
439
+ );
250
440
 
251
441
  const context: HttpRequestContext = new HttpRequestContext(request, res, undefined, undefined);
252
442
  await AlsUtilities.runWithHttpRequestContext(context, async () => {
253
443
  try {
254
- // parse
255
- for (const key of ObjectUtilities.keys(route.pathParams)) {
256
- (context.request.params[key] as unknown) = this.parser.parsePathParam(context.request, route.pathParams[key]);
257
- }
258
- for (const key of ObjectUtilities.keys(route.queryParams)) {
259
- (context.request.query[key] as unknown) = this.parser.parseQueryParam(
260
- context.request,
261
- route.queryParams[key]
262
- );
263
- }
264
- for (const key of ObjectUtilities.keys(route.headerParams)) {
265
- (context.request.headers[key] as unknown) = this.parser.parseHeaderParam(
266
- context.request,
267
- route.headerParams[key]
268
- );
444
+ const version: Version = await this.versioningService.resolveVersion(context);
445
+ // eslint-disable-next-line typescript/typedef
446
+ const match = entries.find(e => this.versioningService.matchesVersion(e.versions, version));
447
+ if (!match) {
448
+ throw new NotFoundError(`Could not find route "${request.url}" for version "${version.value}"`);
269
449
  }
270
- if (route.bodyMetadata) {
271
- context.request.body = await this.parser.parseBody(context.request, route.bodyMetadata);
272
- }
273
- // validate
274
- await Promise.all([
275
- ...ObjectUtilities.keys(route.pathParams).map(async key => {
276
- await this.validationService.validatePathParam(context.request.params[key], route.pathParams[key]);
277
- }),
278
- ...ObjectUtilities.keys(route.queryParams).map(async key => {
279
- await this.validationService.validateQueryParam(context.request.query[key], route.queryParams[key]);
280
- }),
281
- ...ObjectUtilities.keys(route.headerParams).map(async key => {
282
- await this.validationService.validateHeaderParam(context.request.headers[key], route.headerParams[key]);
283
- }),
284
- ...route.bodyMetadata ? [this.validationService.validateBody(context.request.body, route.bodyMetadata)] : []
285
- ]);
286
-
287
- // eslint-disable-next-line typescript/no-explicit-any
288
- const result: unknown = await route.handler(context.request as HttpRequest<any, any, any, any>, context.response, next);
289
- await this.returnResult(context.response, result, next, []);
450
+ await match.innerHandler(context, next);
290
451
  }
291
452
  catch (error) {
292
453
  next(error);
293
454
  }
294
455
  });
295
456
  }) as RequestHandler;
296
- return handler;
297
457
  }
298
458
 
299
- private async controllerRouteToRequestHandler(
459
+ private async createControllerInnerHandler(
300
460
  controllerClass: Newable<unknown>,
301
461
  route: ControllerRouteConfiguration
302
- ): Promise<RequestHandler> {
462
+ ): Promise<ControllerInnerHandler> {
303
463
  const responses: OpenApiResponse[] = MetadataUtilities.getRouteResponses(controllerClass, route.controllerMethod);
304
464
  if (!responses.length) {
305
465
  await this.logger.warn(`No responses defined on route ${controllerClass.name}.${route.controllerMethod}`);
306
466
  }
307
- const handler: RequestHandler = (async (request: HttpRequest, res, next) => {
308
- Object.defineProperty(request, 'params', {
309
- value: { ...request.params },
310
- writable: true,
311
- configurable: true,
312
- enumerable: true
313
- });
314
- Object.defineProperty(request, 'query', {
315
- value: { ...request.query },
316
- writable: true,
317
- configurable: true,
318
- enumerable: true
319
- });
320
- Object.defineProperty(request, 'headers', {
321
- value: { ...request.headers },
322
- writable: true,
323
- configurable: true,
324
- enumerable: true
325
- });
326
-
327
- const context: HttpRequestContext = new HttpRequestContext(
328
- request,
329
- res,
330
- controllerClass,
331
- route.controllerMethod
332
- );
333
- await AlsUtilities.runWithHttpRequestContext(context, async () => {
334
- try {
335
- await this.authService.checkAccess(controllerClass, route.controllerMethod, context);
336
- const controller: unknown = inject(controllerClass);
337
- const params: unknown[] = await resolveRouteParams(
338
- controllerClass,
339
- route.controllerMethod,
340
- // eslint-disable-next-line typescript/no-unsafe-member-access, typescript/no-explicit-any
341
- ((controller as any)[route.controllerMethod] as Function).length,
342
- context
343
- );
344
-
345
- // eslint-disable-next-line typescript/no-unsafe-call, typescript/no-explicit-any, typescript/no-unsafe-member-access
346
- const result: unknown = await ((controller as any)[route.controllerMethod] as Function)(...params);
347
- await this.returnResult(context.response, result, next, responses);
348
- }
349
- catch (error) {
350
- next(error);
351
- }
352
- });
353
- }) as RequestHandler;
354
- return handler;
467
+ return async (context: HttpRequestContext, next: NextFunction) => {
468
+ try {
469
+ await this.authService.checkAccess(controllerClass, route.controllerMethod, context);
470
+ const controller: unknown = inject(controllerClass);
471
+ const params: unknown[] = await resolveRouteParams(
472
+ controllerClass,
473
+ route.controllerMethod,
474
+ // eslint-disable-next-line typescript/no-unsafe-member-access, typescript/no-explicit-any
475
+ ((controller as any)[route.controllerMethod] as Function).length,
476
+ context
477
+ );
478
+ // eslint-disable-next-line typescript/no-unsafe-call, typescript/no-explicit-any, typescript/no-unsafe-member-access
479
+ const result: unknown = await ((controller as any)[route.controllerMethod] as Function)(...params);
480
+ await this.returnResult(context.response, result, next, responses);
481
+ }
482
+ catch (error) {
483
+ next(error);
484
+ }
485
+ };
355
486
  }
356
487
 
357
488
  private async returnResult(res: HttpResponse, result: unknown, next: NextFunction, responses: OpenApiResponse[]): Promise<void> {
@@ -173,7 +173,7 @@ export abstract class FsUtilities {
173
173
  * Creates a file at the given path.
174
174
  * @param p - The path of the new file to create.
175
175
  * @param data - The data to write into the file. Can be a raw data string or an array of lines, which are joined by \n.
176
- * @param recursive - Whether or not to recursively create the file.
176
+ * @param recursive - Whether or not to recursively create the file. Defaults to true.
177
177
  */
178
178
  static async createFile(p: FsPath, data: string | string[], recursive: boolean = true): Promise<void> {
179
179
  if (await this.exists(p)) {