@bgord/bun 0.30.1 → 1.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 (503) hide show
  1. package/dist/antivirus-clamav.adapter.d.ts.map +1 -1
  2. package/dist/antivirus-clamav.adapter.js +6 -6
  3. package/dist/antivirus-clamav.adapter.js.map +1 -1
  4. package/dist/antivirus.port.d.ts +3 -6
  5. package/dist/antivirus.port.d.ts.map +1 -1
  6. package/dist/antivirus.port.js +1 -12
  7. package/dist/antivirus.port.js.map +1 -1
  8. package/dist/api-version.middleware.d.ts +4 -2
  9. package/dist/api-version.middleware.d.ts.map +1 -1
  10. package/dist/api-version.middleware.js.map +1 -1
  11. package/dist/basic-auth-password.vo.d.ts +9 -0
  12. package/dist/basic-auth-password.vo.d.ts.map +1 -0
  13. package/dist/basic-auth-password.vo.js +12 -0
  14. package/dist/basic-auth-password.vo.js.map +1 -0
  15. package/dist/basic-auth-username.vo.d.ts +9 -0
  16. package/dist/basic-auth-username.vo.d.ts.map +1 -0
  17. package/dist/basic-auth-username.vo.js +12 -0
  18. package/dist/basic-auth-username.vo.js.map +1 -0
  19. package/dist/basic-auth.service.d.ts +5 -22
  20. package/dist/basic-auth.service.d.ts.map +1 -1
  21. package/dist/basic-auth.service.js +0 -15
  22. package/dist/basic-auth.service.js.map +1 -1
  23. package/dist/better-auth-logger.service.d.ts.map +1 -1
  24. package/dist/better-auth-logger.service.js +4 -2
  25. package/dist/better-auth-logger.service.js.map +1 -1
  26. package/dist/binary.vo.d.ts +10 -0
  27. package/dist/binary.vo.d.ts.map +1 -0
  28. package/dist/binary.vo.js +16 -0
  29. package/dist/binary.vo.js.map +1 -0
  30. package/dist/build-info-repository.service.d.ts +2 -1
  31. package/dist/build-info-repository.service.d.ts.map +1 -1
  32. package/dist/build-info-repository.service.js +2 -5
  33. package/dist/build-info-repository.service.js.map +1 -1
  34. package/dist/cache-file.service.d.ts.map +1 -1
  35. package/dist/cache-file.service.js +1 -1
  36. package/dist/cache-file.service.js.map +1 -1
  37. package/dist/cache-response.middleware.d.ts.map +1 -1
  38. package/dist/cache-response.middleware.js.map +1 -1
  39. package/dist/certificate-inspector-tls.adapter.d.ts +1 -1
  40. package/dist/certificate-inspector-tls.adapter.d.ts.map +1 -1
  41. package/dist/certificate-inspector-tls.adapter.js +2 -2
  42. package/dist/certificate-inspector-tls.adapter.js.map +1 -1
  43. package/dist/client-from-hono.adapter.d.ts +1 -1
  44. package/dist/client-from-hono.adapter.d.ts.map +1 -1
  45. package/dist/client-from-hono.adapter.js +1 -1
  46. package/dist/client-from-hono.adapter.js.map +1 -1
  47. package/dist/clock-system.adapter.d.ts.map +1 -1
  48. package/dist/clock-system.adapter.js +1 -2
  49. package/dist/clock-system.adapter.js.map +1 -1
  50. package/dist/clock.port.d.ts.map +1 -1
  51. package/dist/context.middleware.d.ts.map +1 -1
  52. package/dist/context.middleware.js.map +1 -1
  53. package/dist/correlation-id.vo.d.ts.map +1 -1
  54. package/dist/correlation-storage.service.d.ts +3 -0
  55. package/dist/correlation-storage.service.d.ts.map +1 -1
  56. package/dist/correlation-storage.service.js +2 -1
  57. package/dist/correlation-storage.service.js.map +1 -1
  58. package/dist/env-validator.service.d.ts +3 -1
  59. package/dist/env-validator.service.d.ts.map +1 -1
  60. package/dist/env-validator.service.js +2 -2
  61. package/dist/env-validator.service.js.map +1 -1
  62. package/dist/etag-extractor.middleware.js +2 -2
  63. package/dist/etag-extractor.middleware.js.map +1 -1
  64. package/dist/event-store-like.types.d.ts.map +1 -1
  65. package/dist/event-stream.vo.d.ts +4 -2
  66. package/dist/event-stream.vo.d.ts.map +1 -1
  67. package/dist/event-stream.vo.js +8 -4
  68. package/dist/event-stream.vo.js.map +1 -1
  69. package/dist/file-cleaner-bun-forgiving.adapter.d.ts +6 -0
  70. package/dist/file-cleaner-bun-forgiving.adapter.d.ts.map +1 -0
  71. package/dist/file-cleaner-bun-forgiving.adapter.js +9 -0
  72. package/dist/file-cleaner-bun-forgiving.adapter.js.map +1 -0
  73. package/dist/file-cleaner-bun.adapter.d.ts +6 -0
  74. package/dist/file-cleaner-bun.adapter.d.ts.map +1 -0
  75. package/dist/file-cleaner-bun.adapter.js +6 -0
  76. package/dist/file-cleaner-bun.adapter.js.map +1 -0
  77. package/dist/file-cleaner-noop.adapter.d.ts +6 -0
  78. package/dist/file-cleaner-noop.adapter.d.ts.map +1 -0
  79. package/dist/file-cleaner-noop.adapter.js +4 -0
  80. package/dist/file-cleaner-noop.adapter.js.map +1 -0
  81. package/dist/file-cleaner.port.d.ts +5 -0
  82. package/dist/file-cleaner.port.d.ts.map +1 -0
  83. package/dist/file-cleaner.port.js +2 -0
  84. package/dist/file-cleaner.port.js.map +1 -0
  85. package/dist/file-draft.service.js +2 -2
  86. package/dist/file-draft.service.js.map +1 -1
  87. package/dist/file-renamer-fs-forgiving.adapter.d.ts +6 -0
  88. package/dist/file-renamer-fs-forgiving.adapter.d.ts.map +1 -0
  89. package/dist/file-renamer-fs-forgiving.adapter.js +12 -0
  90. package/dist/file-renamer-fs-forgiving.adapter.js.map +1 -0
  91. package/dist/file-renamer-fs.adapter.d.ts +6 -0
  92. package/dist/file-renamer-fs.adapter.d.ts.map +1 -0
  93. package/dist/file-renamer-fs.adapter.js +9 -0
  94. package/dist/file-renamer-fs.adapter.js.map +1 -0
  95. package/dist/file-renamer-noop.adapter.d.ts +6 -0
  96. package/dist/file-renamer-noop.adapter.d.ts.map +1 -0
  97. package/dist/file-renamer-noop.adapter.js +4 -0
  98. package/dist/file-renamer-noop.adapter.js.map +1 -0
  99. package/dist/file-renamer.port.d.ts +5 -0
  100. package/dist/file-renamer.port.d.ts.map +1 -0
  101. package/dist/file-renamer.port.js +2 -0
  102. package/dist/file-renamer.port.js.map +1 -0
  103. package/dist/graceful-shutdown.service.d.ts.map +1 -1
  104. package/dist/graceful-shutdown.service.js +1 -3
  105. package/dist/graceful-shutdown.service.js.map +1 -1
  106. package/dist/hcaptcha-secret-key.vo.d.ts +8 -0
  107. package/dist/hcaptcha-secret-key.vo.d.ts.map +1 -0
  108. package/dist/hcaptcha-secret-key.vo.js +10 -0
  109. package/dist/hcaptcha-secret-key.vo.js.map +1 -0
  110. package/dist/hcaptcha-site-key.vo.d.ts +8 -0
  111. package/dist/hcaptcha-site-key.vo.d.ts.map +1 -0
  112. package/dist/hcaptcha-site-key.vo.js +10 -0
  113. package/dist/hcaptcha-site-key.vo.js.map +1 -0
  114. package/dist/healthcheck.service.d.ts +4 -0
  115. package/dist/healthcheck.service.d.ts.map +1 -1
  116. package/dist/healthcheck.service.js +3 -3
  117. package/dist/healthcheck.service.js.map +1 -1
  118. package/dist/http-logger.middleware.d.ts.map +1 -1
  119. package/dist/http-logger.middleware.js +9 -9
  120. package/dist/http-logger.middleware.js.map +1 -1
  121. package/dist/i18n.service.d.ts +10 -3
  122. package/dist/i18n.service.d.ts.map +1 -1
  123. package/dist/i18n.service.js +7 -11
  124. package/dist/i18n.service.js.map +1 -1
  125. package/dist/id-provider-deterministic.adapter.d.ts +3 -0
  126. package/dist/id-provider-deterministic.adapter.d.ts.map +1 -1
  127. package/dist/id-provider-deterministic.adapter.js +4 -1
  128. package/dist/id-provider-deterministic.adapter.js.map +1 -1
  129. package/dist/image-alpha-noop.adapter.d.ts +1 -1
  130. package/dist/image-alpha-sharp.adapter.d.ts +8 -1
  131. package/dist/image-alpha-sharp.adapter.d.ts.map +1 -1
  132. package/dist/image-alpha-sharp.adapter.js +6 -3
  133. package/dist/image-alpha-sharp.adapter.js.map +1 -1
  134. package/dist/image-blur-noop.adapter.d.ts +1 -1
  135. package/dist/image-blur-sharp.adapter.d.ts +8 -1
  136. package/dist/image-blur-sharp.adapter.d.ts.map +1 -1
  137. package/dist/image-blur-sharp.adapter.js +6 -3
  138. package/dist/image-blur-sharp.adapter.js.map +1 -1
  139. package/dist/image-compressor-noop.adapter.d.ts +1 -1
  140. package/dist/image-compressor-sharp.adapter.d.ts +8 -1
  141. package/dist/image-compressor-sharp.adapter.d.ts.map +1 -1
  142. package/dist/image-compressor-sharp.adapter.js +5 -2
  143. package/dist/image-compressor-sharp.adapter.js.map +1 -1
  144. package/dist/image-exif-clear-noop.adapter.d.ts +1 -1
  145. package/dist/image-exif-clear-sharp.adapter.d.ts +8 -1
  146. package/dist/image-exif-clear-sharp.adapter.d.ts.map +1 -1
  147. package/dist/image-exif-clear-sharp.adapter.js +5 -2
  148. package/dist/image-exif-clear-sharp.adapter.js.map +1 -1
  149. package/dist/image-formatter-sharp.adapter.d.ts +10 -1
  150. package/dist/image-formatter-sharp.adapter.d.ts.map +1 -1
  151. package/dist/image-formatter-sharp.adapter.js +8 -5
  152. package/dist/image-formatter-sharp.adapter.js.map +1 -1
  153. package/dist/image-info-noop.adapter.d.ts +2 -2
  154. package/dist/image-info-sharp.adapter.d.ts +2 -2
  155. package/dist/image-info-sharp.adapter.d.ts.map +1 -1
  156. package/dist/image-info-sharp.adapter.js +5 -9
  157. package/dist/image-info-sharp.adapter.js.map +1 -1
  158. package/dist/image-processor-sharp.adapter.d.ts +9 -0
  159. package/dist/image-processor-sharp.adapter.d.ts.map +1 -1
  160. package/dist/image-processor-sharp.adapter.js +8 -5
  161. package/dist/image-processor-sharp.adapter.js.map +1 -1
  162. package/dist/image-resizer-noop.adapter.d.ts +1 -1
  163. package/dist/image-resizer-sharp.adapter.d.ts +8 -1
  164. package/dist/image-resizer-sharp.adapter.d.ts.map +1 -1
  165. package/dist/image-resizer-sharp.adapter.js +5 -2
  166. package/dist/image-resizer-sharp.adapter.js.map +1 -1
  167. package/dist/index.d.ts +25 -5
  168. package/dist/index.d.ts.map +1 -1
  169. package/dist/index.js +25 -5
  170. package/dist/index.js.map +1 -1
  171. package/dist/json-file-reader-bun-forgiving.adapter.d.ts +6 -0
  172. package/dist/json-file-reader-bun-forgiving.adapter.d.ts.map +1 -0
  173. package/dist/json-file-reader-bun-forgiving.adapter.js +11 -0
  174. package/dist/json-file-reader-bun-forgiving.adapter.js.map +1 -0
  175. package/dist/json-file-reader-bun.adapter.d.ts +6 -0
  176. package/dist/json-file-reader-bun.adapter.d.ts.map +1 -0
  177. package/dist/json-file-reader-bun.adapter.js +6 -0
  178. package/dist/json-file-reader-bun.adapter.js.map +1 -0
  179. package/dist/json-file-reader-noop.adapter.d.ts +8 -0
  180. package/dist/json-file-reader-noop.adapter.d.ts.map +1 -0
  181. package/dist/json-file-reader-noop.adapter.js +10 -0
  182. package/dist/json-file-reader-noop.adapter.js.map +1 -0
  183. package/dist/json-file-reader.port.d.ts +5 -0
  184. package/dist/json-file-reader.port.d.ts.map +1 -0
  185. package/dist/json-file-reader.port.js +2 -0
  186. package/dist/json-file-reader.port.js.map +1 -0
  187. package/dist/logger-format-error.service.d.ts +1 -1
  188. package/dist/logger-format-error.service.d.ts.map +1 -1
  189. package/dist/logger-format-error.service.js +9 -9
  190. package/dist/logger-format-error.service.js.map +1 -1
  191. package/dist/logger.port.d.ts +0 -4
  192. package/dist/logger.port.d.ts.map +1 -1
  193. package/dist/mailer-smtp-with-logger.adapter.d.ts.map +1 -1
  194. package/dist/mailer-smtp-with-logger.adapter.js.map +1 -1
  195. package/dist/mailer-smtp.adapter.d.ts +2 -23
  196. package/dist/mailer-smtp.adapter.d.ts.map +1 -1
  197. package/dist/mailer-smtp.adapter.js +0 -10
  198. package/dist/mailer-smtp.adapter.js.map +1 -1
  199. package/dist/mailer.vo.d.ts +34 -0
  200. package/dist/mailer.vo.d.ts.map +1 -0
  201. package/dist/mailer.vo.js +21 -0
  202. package/dist/mailer.vo.js.map +1 -0
  203. package/dist/modules/history/event-handlers/onHistoryPopulatedEvent.d.ts.map +1 -1
  204. package/dist/modules/history/event-handlers/onHistoryPopulatedEvent.js.map +1 -1
  205. package/dist/modules/history/events/HISTORY_CLEARED_EVENT.d.ts +4 -4
  206. package/dist/modules/history/events/HISTORY_CLEARED_EVENT.d.ts.map +1 -1
  207. package/dist/modules/history/events/HISTORY_CLEARED_EVENT.js +2 -8
  208. package/dist/modules/history/events/HISTORY_CLEARED_EVENT.js.map +1 -1
  209. package/dist/modules/history/events/HISTORY_POPULATED_EVENT.d.ts +6 -6
  210. package/dist/modules/history/events/HISTORY_POPULATED_EVENT.d.ts.map +1 -1
  211. package/dist/modules/history/events/HISTORY_POPULATED_EVENT.js +2 -8
  212. package/dist/modules/history/events/HISTORY_POPULATED_EVENT.js.map +1 -1
  213. package/dist/modules/history/ports/history-writer.d.ts.map +1 -1
  214. package/dist/modules/history/value-objects/history-subject.d.ts.map +1 -1
  215. package/dist/modules/preferences/open-host-queries/user-language.d.ts.map +1 -1
  216. package/dist/modules/preferences/open-host-queries/user-language.js.map +1 -1
  217. package/dist/modules/preferences/ports/user-language-resolver.d.ts +3 -3
  218. package/dist/modules/preferences/ports/user-language-resolver.d.ts.map +1 -1
  219. package/dist/modules/preferences/ports/user-language-resolver.js +2 -7
  220. package/dist/modules/preferences/ports/user-language-resolver.js.map +1 -1
  221. package/dist/modules/preferences/value-objects/supported-languages-set.d.ts +3 -3
  222. package/dist/modules/preferences/value-objects/supported-languages-set.d.ts.map +1 -1
  223. package/dist/modules/preferences/value-objects/supported-languages-set.js +2 -7
  224. package/dist/modules/preferences/value-objects/supported-languages-set.js.map +1 -1
  225. package/dist/pdf-generator-noop.adapter.d.ts +1 -1
  226. package/dist/pdf-generator-noop.adapter.d.ts.map +1 -1
  227. package/dist/pdf-generator-noop.adapter.js +1 -1
  228. package/dist/pdf-generator-noop.adapter.js.map +1 -1
  229. package/dist/port.vo.d.ts +4 -0
  230. package/dist/port.vo.d.ts.map +1 -1
  231. package/dist/port.vo.js +7 -1
  232. package/dist/port.vo.js.map +1 -1
  233. package/dist/prerequisites/binary.d.ts +2 -5
  234. package/dist/prerequisites/binary.d.ts.map +1 -1
  235. package/dist/prerequisites/binary.js +1 -8
  236. package/dist/prerequisites/binary.js.map +1 -1
  237. package/dist/prerequisites/dependency-vulnerabilities.js +3 -3
  238. package/dist/prerequisites/dependency-vulnerabilities.js.map +1 -1
  239. package/dist/prerequisites/directory.d.ts.map +1 -1
  240. package/dist/prerequisites/directory.js.map +1 -1
  241. package/dist/prerequisites/jobs.d.ts.map +1 -1
  242. package/dist/prerequisites/jobs.js +1 -2
  243. package/dist/prerequisites/jobs.js.map +1 -1
  244. package/dist/prerequisites/log-file.d.ts.map +1 -1
  245. package/dist/prerequisites/log-file.js.map +1 -1
  246. package/dist/prerequisites/mailer.d.ts.map +1 -1
  247. package/dist/prerequisites/mailer.js.map +1 -1
  248. package/dist/prerequisites/memory.js +1 -1
  249. package/dist/prerequisites/memory.js.map +1 -1
  250. package/dist/prerequisites/node.d.ts.map +1 -1
  251. package/dist/prerequisites/node.js.map +1 -1
  252. package/dist/prerequisites/port.d.ts.map +1 -1
  253. package/dist/prerequisites/port.js.map +1 -1
  254. package/dist/prerequisites/ram.d.ts.map +1 -1
  255. package/dist/prerequisites/ram.js +1 -1
  256. package/dist/prerequisites/ram.js.map +1 -1
  257. package/dist/prerequisites/running-user.d.ts.map +1 -1
  258. package/dist/prerequisites/running-user.js.map +1 -1
  259. package/dist/prerequisites/space.d.ts.map +1 -1
  260. package/dist/prerequisites/space.js +1 -1
  261. package/dist/prerequisites/space.js.map +1 -1
  262. package/dist/prerequisites/sqlite.d.ts.map +1 -1
  263. package/dist/prerequisites/sqlite.js +1 -1
  264. package/dist/prerequisites/sqlite.js.map +1 -1
  265. package/dist/prerequisites/ssl-certificate-expiry.js +1 -1
  266. package/dist/prerequisites/ssl-certificate-expiry.js.map +1 -1
  267. package/dist/prerequisites/timezone-utc.d.ts.map +1 -1
  268. package/dist/prerequisites/timezone-utc.js.map +1 -1
  269. package/dist/prerequisites/translations.d.ts +10 -3
  270. package/dist/prerequisites/translations.d.ts.map +1 -1
  271. package/dist/prerequisites/translations.js +15 -10
  272. package/dist/prerequisites/translations.js.map +1 -1
  273. package/dist/prerequisites.service.d.ts +3 -0
  274. package/dist/prerequisites.service.d.ts.map +1 -1
  275. package/dist/prerequisites.service.js +3 -3
  276. package/dist/prerequisites.service.js.map +1 -1
  277. package/dist/rate-limit-store-node-cache.adapter.d.ts +2 -2
  278. package/dist/rate-limit-store-node-cache.adapter.d.ts.map +1 -1
  279. package/dist/rate-limit-store-node-cache.adapter.js +1 -1
  280. package/dist/rate-limit-store-node-cache.adapter.js.map +1 -1
  281. package/dist/rate-limit-store.port.d.ts +1 -1
  282. package/dist/rate-limit-store.port.d.ts.map +1 -1
  283. package/dist/recaptcha-secret-key.vo.d.ts +8 -0
  284. package/dist/recaptcha-secret-key.vo.d.ts.map +1 -0
  285. package/dist/recaptcha-secret-key.vo.js +10 -0
  286. package/dist/recaptcha-secret-key.vo.js.map +1 -0
  287. package/dist/recaptcha-site-key.vo.d.ts +8 -0
  288. package/dist/recaptcha-site-key.vo.d.ts.map +1 -0
  289. package/dist/recaptcha-site-key.vo.js +10 -0
  290. package/dist/recaptcha-site-key.vo.js.map +1 -0
  291. package/dist/redactor-encrypt.adapter.js +2 -2
  292. package/dist/redactor-encrypt.adapter.js.map +1 -1
  293. package/dist/redactor-mask.adapter.d.ts.map +1 -1
  294. package/dist/redactor-mask.adapter.js +0 -3
  295. package/dist/redactor-mask.adapter.js.map +1 -1
  296. package/dist/remote-file-storage-disk.adapter.d.ts +9 -2
  297. package/dist/remote-file-storage-disk.adapter.d.ts.map +1 -1
  298. package/dist/remote-file-storage-disk.adapter.js +7 -9
  299. package/dist/remote-file-storage-disk.adapter.js.map +1 -1
  300. package/dist/safe-parse-body.service.d.ts.map +1 -1
  301. package/dist/safe-parse-body.service.js +1 -1
  302. package/dist/safe-parse-body.service.js.map +1 -1
  303. package/dist/setup.service.d.ts +3 -1
  304. package/dist/setup.service.d.ts.map +1 -1
  305. package/dist/setup.service.js +1 -1
  306. package/dist/setup.service.js.map +1 -1
  307. package/dist/shield-api-key.middleware.d.ts.map +1 -1
  308. package/dist/shield-api-key.middleware.js +1 -2
  309. package/dist/shield-api-key.middleware.js.map +1 -1
  310. package/dist/shield-auth.middleware.d.ts.map +1 -1
  311. package/dist/shield-auth.middleware.js +1 -3
  312. package/dist/shield-auth.middleware.js.map +1 -1
  313. package/dist/shield-captcha-hcaptcha-local.adapter.d.ts +2 -2
  314. package/dist/shield-captcha-hcaptcha-local.adapter.d.ts.map +1 -1
  315. package/dist/shield-captcha-hcaptcha-local.adapter.js +2 -2
  316. package/dist/shield-captcha-hcaptcha-local.adapter.js.map +1 -1
  317. package/dist/shield-captcha-hcaptcha.adapter.d.ts +2 -8
  318. package/dist/shield-captcha-hcaptcha.adapter.d.ts.map +1 -1
  319. package/dist/shield-captcha-hcaptcha.adapter.js +2 -6
  320. package/dist/shield-captcha-hcaptcha.adapter.js.map +1 -1
  321. package/dist/shield-captcha-noop.adapter.d.ts +1 -1
  322. package/dist/shield-captcha-noop.adapter.d.ts.map +1 -1
  323. package/dist/shield-captcha-noop.adapter.js +1 -1
  324. package/dist/shield-captcha-noop.adapter.js.map +1 -1
  325. package/dist/shield-captcha-recaptcha.adapter.d.ts +3 -7
  326. package/dist/shield-captcha-recaptcha.adapter.d.ts.map +1 -1
  327. package/dist/shield-captcha-recaptcha.adapter.js +12 -17
  328. package/dist/shield-captcha-recaptcha.adapter.js.map +1 -1
  329. package/dist/shield-rate-limit.middleware.d.ts +2 -2
  330. package/dist/shield-rate-limit.middleware.d.ts.map +1 -1
  331. package/dist/slower.middleware.d.ts.map +1 -1
  332. package/dist/slower.middleware.js.map +1 -1
  333. package/dist/temporary-file-absolute.adapter.d.ts +11 -3
  334. package/dist/temporary-file-absolute.adapter.d.ts.map +1 -1
  335. package/dist/temporary-file-absolute.adapter.js +11 -14
  336. package/dist/temporary-file-absolute.adapter.js.map +1 -1
  337. package/dist/temporary-file-noop.adapter.d.ts +1 -1
  338. package/dist/temporary-file-noop.adapter.d.ts.map +1 -1
  339. package/dist/temporary-file-noop.adapter.js +1 -1
  340. package/dist/temporary-file-noop.adapter.js.map +1 -1
  341. package/dist/temporary-file.port.d.ts +1 -1
  342. package/dist/temporary-file.port.d.ts.map +1 -1
  343. package/dist/time-zone-offset.middleware.d.ts.map +1 -1
  344. package/dist/time-zone-offset.middleware.js +2 -2
  345. package/dist/time-zone-offset.middleware.js.map +1 -1
  346. package/dist/translations.service.d.ts +8 -1
  347. package/dist/translations.service.d.ts.map +1 -1
  348. package/dist/translations.service.js +2 -2
  349. package/dist/translations.service.js.map +1 -1
  350. package/dist/tsconfig.tsbuildinfo +1 -1
  351. package/dist/uptime.service.js +3 -3
  352. package/dist/uptime.service.js.map +1 -1
  353. package/dist/uuid.vo.d.ts +3 -0
  354. package/dist/uuid.vo.d.ts.map +1 -1
  355. package/dist/uuid.vo.js +2 -1
  356. package/dist/uuid.vo.js.map +1 -1
  357. package/dist/visitor-id-hash-hono.adapter.d.ts +1 -1
  358. package/dist/visitor-id-hash-hono.adapter.d.ts.map +1 -1
  359. package/dist/visitor-id-hash-hono.adapter.js +4 -4
  360. package/dist/visitor-id-hash-hono.adapter.js.map +1 -1
  361. package/dist/visitor-id-hash.adapter.d.ts +1 -1
  362. package/dist/visitor-id-hash.adapter.d.ts.map +1 -1
  363. package/dist/visitor-id-hash.adapter.js +3 -3
  364. package/dist/visitor-id-hash.adapter.js.map +1 -1
  365. package/dist/weak-etag-extractor.middleware.js +2 -2
  366. package/dist/weak-etag-extractor.middleware.js.map +1 -1
  367. package/package.json +7 -7
  368. package/readme.md +20 -5
  369. package/src/antivirus-clamav.adapter.ts +7 -12
  370. package/src/antivirus.port.ts +1 -13
  371. package/src/api-version.middleware.ts +4 -4
  372. package/src/basic-auth-password.vo.ts +15 -0
  373. package/src/basic-auth-username.vo.ts +15 -0
  374. package/src/basic-auth.service.ts +3 -22
  375. package/src/better-auth-logger.service.ts +4 -3
  376. package/src/binary.vo.ts +20 -0
  377. package/src/build-info-repository.service.ts +5 -7
  378. package/src/cache-file.service.ts +2 -1
  379. package/src/cache-response.middleware.ts +3 -0
  380. package/src/certificate-inspector-tls.adapter.ts +3 -2
  381. package/src/client-from-hono.adapter.ts +1 -1
  382. package/src/clock-system.adapter.ts +2 -2
  383. package/src/clock.port.ts +1 -0
  384. package/src/context.middleware.ts +1 -0
  385. package/src/correlation-id.vo.ts +1 -0
  386. package/src/correlation-storage.service.ts +4 -1
  387. package/src/env-validator.service.ts +2 -2
  388. package/src/etag-extractor.middleware.ts +2 -2
  389. package/src/event-store-like.types.ts +1 -0
  390. package/src/event-stream.vo.ts +9 -4
  391. package/src/file-cleaner-bun-forgiving.adapter.ts +10 -0
  392. package/src/file-cleaner-bun.adapter.ts +8 -0
  393. package/src/file-cleaner-noop.adapter.ts +6 -0
  394. package/src/file-cleaner.port.ts +5 -0
  395. package/src/file-draft.service.ts +2 -2
  396. package/src/file-renamer-fs-forgiving.adapter.ts +17 -0
  397. package/src/file-renamer-fs.adapter.ts +15 -0
  398. package/src/file-renamer-noop.adapter.ts +9 -0
  399. package/src/file-renamer.port.ts +8 -0
  400. package/src/graceful-shutdown.service.ts +1 -3
  401. package/src/hcaptcha-secret-key.vo.ts +13 -0
  402. package/src/hcaptcha-site-key.vo.ts +13 -0
  403. package/src/healthcheck.service.ts +6 -4
  404. package/src/http-logger.middleware.ts +9 -10
  405. package/src/i18n.service.ts +14 -11
  406. package/src/id-provider-deterministic.adapter.ts +5 -1
  407. package/src/image-alpha-sharp.adapter.ts +7 -4
  408. package/src/image-blur-sharp.adapter.ts +7 -4
  409. package/src/image-compressor-sharp.adapter.ts +6 -2
  410. package/src/image-exif-clear-sharp.adapter.ts +6 -2
  411. package/src/image-formatter-sharp.adapter.ts +10 -5
  412. package/src/image-info-sharp.adapter.ts +5 -11
  413. package/src/image-processor-sharp.adapter.ts +10 -5
  414. package/src/image-resizer-sharp.adapter.ts +6 -3
  415. package/src/index.ts +25 -5
  416. package/src/json-file-reader-bun-forgiving.adapter.ts +12 -0
  417. package/src/json-file-reader-bun.adapter.ts +8 -0
  418. package/src/json-file-reader-noop.adapter.ts +10 -0
  419. package/src/json-file-reader.port.ts +5 -0
  420. package/src/logger-format-error.service.ts +10 -9
  421. package/src/logger.port.ts +0 -4
  422. package/src/mailer-smtp-with-logger.adapter.ts +2 -0
  423. package/src/mailer-smtp.adapter.ts +2 -31
  424. package/src/mailer.vo.ts +38 -0
  425. package/src/modules/history/event-handlers/onHistoryPopulatedEvent.ts +1 -0
  426. package/src/modules/history/events/HISTORY_CLEARED_EVENT.ts +2 -8
  427. package/src/modules/history/events/HISTORY_POPULATED_EVENT.ts +2 -8
  428. package/src/modules/history/ports/history-writer.ts +1 -0
  429. package/src/modules/history/value-objects/history-subject.ts +1 -0
  430. package/src/modules/preferences/open-host-queries/user-language.ts +1 -0
  431. package/src/modules/preferences/ports/user-language-resolver.ts +2 -7
  432. package/src/modules/preferences/value-objects/supported-languages-set.ts +2 -8
  433. package/src/pdf-generator-noop.adapter.ts +1 -1
  434. package/src/port.vo.ts +9 -1
  435. package/src/prerequisites/binary.ts +4 -14
  436. package/src/prerequisites/dependency-vulnerabilities.ts +3 -3
  437. package/src/prerequisites/directory.ts +1 -0
  438. package/src/prerequisites/jobs.ts +2 -4
  439. package/src/prerequisites/log-file.ts +1 -0
  440. package/src/prerequisites/mailer.ts +1 -0
  441. package/src/prerequisites/memory.ts +1 -1
  442. package/src/prerequisites/node.ts +1 -0
  443. package/src/prerequisites/port.ts +1 -0
  444. package/src/prerequisites/ram.ts +2 -1
  445. package/src/prerequisites/running-user.ts +1 -0
  446. package/src/prerequisites/space.ts +2 -1
  447. package/src/prerequisites/sqlite.ts +1 -2
  448. package/src/prerequisites/ssl-certificate-expiry.ts +1 -1
  449. package/src/prerequisites/timezone-utc.ts +1 -0
  450. package/src/prerequisites/translations.ts +29 -17
  451. package/src/prerequisites.service.ts +4 -4
  452. package/src/rate-limit-store-node-cache.adapter.ts +2 -2
  453. package/src/rate-limit-store.port.ts +1 -1
  454. package/src/recaptcha-secret-key.vo.ts +13 -0
  455. package/src/recaptcha-site-key.vo.ts +13 -0
  456. package/src/redactor-encrypt.adapter.ts +2 -2
  457. package/src/redactor-mask.adapter.ts +0 -3
  458. package/src/remote-file-storage-disk.adapter.ts +13 -14
  459. package/src/safe-parse-body.service.ts +2 -1
  460. package/src/setup.service.ts +3 -1
  461. package/src/shield-api-key.middleware.ts +1 -3
  462. package/src/shield-auth.middleware.ts +5 -3
  463. package/src/shield-captcha-hcaptcha-local.adapter.ts +4 -3
  464. package/src/shield-captcha-hcaptcha.adapter.ts +5 -13
  465. package/src/shield-captcha-noop.adapter.ts +1 -1
  466. package/src/shield-captcha-recaptcha.adapter.ts +15 -25
  467. package/src/shield-rate-limit.middleware.ts +2 -2
  468. package/src/slower.middleware.ts +1 -0
  469. package/src/temporary-file-absolute.adapter.ts +16 -14
  470. package/src/temporary-file-noop.adapter.ts +1 -1
  471. package/src/temporary-file.port.ts +2 -1
  472. package/src/time-zone-offset.middleware.ts +2 -5
  473. package/src/translations.service.ts +7 -4
  474. package/src/uptime.service.ts +3 -3
  475. package/src/uuid.vo.ts +4 -1
  476. package/src/visitor-id-hash-hono.adapter.ts +5 -5
  477. package/src/visitor-id-hash.adapter.ts +3 -3
  478. package/src/weak-etag-extractor.middleware.ts +2 -2
  479. package/dist/encryption.service.d.ts +0 -25
  480. package/dist/encryption.service.d.ts.map +0 -1
  481. package/dist/encryption.service.js +0 -35
  482. package/dist/encryption.service.js.map +0 -1
  483. package/dist/gzip.service.d.ts +0 -13
  484. package/dist/gzip.service.d.ts.map +0 -1
  485. package/dist/gzip.service.js +0 -18
  486. package/dist/gzip.service.js.map +0 -1
  487. package/dist/open-graph.service.d.ts +0 -104
  488. package/dist/open-graph.service.d.ts.map +0 -1
  489. package/dist/open-graph.service.js +0 -159
  490. package/dist/open-graph.service.js.map +0 -1
  491. package/dist/sitemap.service.d.ts +0 -28
  492. package/dist/sitemap.service.d.ts.map +0 -1
  493. package/dist/sitemap.service.js +0 -57
  494. package/dist/sitemap.service.js.map +0 -1
  495. package/dist/url-wo-trailing-slash.vo.d.ts +0 -4
  496. package/dist/url-wo-trailing-slash.vo.d.ts.map +0 -1
  497. package/dist/url-wo-trailing-slash.vo.js +0 -8
  498. package/dist/url-wo-trailing-slash.vo.js.map +0 -1
  499. package/src/encryption.service.ts +0 -45
  500. package/src/gzip.service.ts +0 -23
  501. package/src/open-graph.service.ts +0 -242
  502. package/src/sitemap.service.ts +0 -91
  503. package/src/url-wo-trailing-slash.vo.ts +0 -9
@@ -1,11 +1,14 @@
1
1
  import { constants } from "node:fs";
2
2
  import fsp from "node:fs/promises";
3
3
  import type * as tools from "@bgord/tools";
4
- import * as i18n from "../i18n.service";
4
+ import type * as types from "../i18n.service";
5
+ import { I18n } from "../i18n.service";
6
+ import type { JsonFileReaderPort } from "../json-file-reader.port";
7
+ import type { LoggerPort } from "../logger.port";
5
8
  import * as prereqs from "../prerequisites.service";
6
9
 
7
10
  type PrerequisiteTranslationsProblemType = {
8
- key: i18n.TranslationsKeyType;
11
+ key: types.TranslationsKeyType;
9
12
  existsIn: tools.LanguageType;
10
13
  missingIn: tools.LanguageType;
11
14
  };
@@ -15,13 +18,18 @@ export class PrerequisiteTranslations implements prereqs.Prerequisite {
15
18
  readonly label: prereqs.PrerequisiteLabelType;
16
19
  readonly enabled?: boolean = true;
17
20
 
18
- private readonly translationsPath?: typeof i18n.I18n.DEFAULT_TRANSLATIONS_PATH;
19
- private readonly supportedLanguages: i18n.I18nConfigType["supportedLanguages"];
21
+ private readonly translationsPath?: typeof I18n.DEFAULT_TRANSLATIONS_PATH;
22
+ private readonly supportedLanguages: types.I18nConfigType["supportedLanguages"];
23
+
24
+ private readonly Logger: LoggerPort;
25
+ private readonly JsonFileReader: JsonFileReaderPort;
20
26
 
21
27
  constructor(
22
28
  config: prereqs.PrerequisiteConfigType & {
23
- translationsPath?: typeof i18n.I18n.DEFAULT_TRANSLATIONS_PATH;
24
- supportedLanguages: i18n.I18nConfigType["supportedLanguages"];
29
+ translationsPath?: typeof I18n.DEFAULT_TRANSLATIONS_PATH;
30
+ supportedLanguages: types.I18nConfigType["supportedLanguages"];
31
+ Logger: LoggerPort;
32
+ JsonFileReader: JsonFileReaderPort;
25
33
  },
26
34
  ) {
27
35
  this.label = config.label;
@@ -29,51 +37,55 @@ export class PrerequisiteTranslations implements prereqs.Prerequisite {
29
37
 
30
38
  this.translationsPath = config.translationsPath;
31
39
  this.supportedLanguages = config.supportedLanguages;
40
+
41
+ this.Logger = config.Logger;
42
+ this.JsonFileReader = config.JsonFileReader;
32
43
  }
33
44
 
34
45
  async verify(): Promise<prereqs.VerifyOutcome> {
35
46
  if (!this.enabled) return prereqs.Verification.undetermined();
36
47
 
37
- const translationsPath = this.translationsPath ?? i18n.I18n.DEFAULT_TRANSLATIONS_PATH;
48
+ const translationsPath = this.translationsPath ?? I18n.DEFAULT_TRANSLATIONS_PATH;
49
+
50
+ const supportedLanguages = Object.keys(this.supportedLanguages);
51
+ const i18n = new I18n({ Logger: this.Logger, JsonFileReader: this.JsonFileReader });
38
52
 
39
53
  try {
40
54
  await fsp.access(translationsPath, constants.R_OK);
41
55
 
42
- for (const language in this.supportedLanguages) {
43
- await fsp.access(new i18n.I18n().getTranslationPathForLanguage(language).get(), constants.R_OK);
56
+ for (const language in supportedLanguages) {
57
+ await fsp.access(i18n.getTranslationPathForLanguage(language).get(), constants.R_OK);
44
58
  }
45
59
  } catch (error) {
46
60
  return prereqs.Verification.failure(error as Error);
47
61
  }
48
62
 
49
- const supportedLanguages = Object.keys(this.supportedLanguages);
50
-
51
63
  if (supportedLanguages.length === 1) return prereqs.Verification.success();
52
64
 
53
- const languageToTranslationKeys: Record<tools.LanguageType, i18n.TranslationsKeyType[]> = {};
65
+ const languageToTranslationKeys: Record<tools.LanguageType, types.TranslationsKeyType[]> = {};
54
66
 
55
67
  const problems: PrerequisiteTranslationsProblemType[] = [];
56
68
 
57
69
  for (const language of supportedLanguages) {
58
- const translations = await new i18n.I18n().getTranslations(language);
70
+ const translations = await i18n.getTranslations(language);
59
71
  const translationKeys = Object.keys(translations);
60
72
 
61
73
  languageToTranslationKeys[language] = translationKeys;
62
74
  }
63
75
 
64
- for (const currentLanguage in languageToTranslationKeys) {
65
- const translationKeys = languageToTranslationKeys[currentLanguage] ?? [];
76
+ for (const language in languageToTranslationKeys) {
77
+ const translationKeys = languageToTranslationKeys[language] ?? [];
66
78
 
67
79
  for (const translationKey of translationKeys) {
68
80
  for (const supportedLanguage of supportedLanguages) {
69
- if (supportedLanguage === currentLanguage) continue;
81
+ if (supportedLanguage === language) continue;
70
82
 
71
83
  const translationKeyExists = languageToTranslationKeys[supportedLanguage]?.some(
72
84
  (key) => translationKey === key,
73
85
  );
74
86
 
75
87
  if (!translationKeyExists) {
76
- problems.push({ key: translationKey, existsIn: currentLanguage, missingIn: supportedLanguage });
88
+ problems.push({ key: translationKey, existsIn: language, missingIn: supportedLanguage });
77
89
  }
78
90
  }
79
91
  }
@@ -48,6 +48,8 @@ export class Verification {
48
48
 
49
49
  export type PrerequisiteConfigType = { label: string; enabled?: boolean };
50
50
 
51
+ export const PrerequisitesError = { Failure: "prerequisites.failure" } as const;
52
+
51
53
  /** @public */
52
54
  export class Prerequisites {
53
55
  private readonly base = { component: "infra", operation: "startup" };
@@ -61,9 +63,7 @@ export class Prerequisites {
61
63
 
62
64
  const failed = results.filter((result) => result.outcome.status === PrerequisiteStatusEnum.failure);
63
65
 
64
- if (failed.length === 0) {
65
- return this.logger.info({ message: "Prerequisites ok", ...this.base });
66
- }
66
+ if (failed.length === 0) return this.logger.info({ message: "Prerequisites ok", ...this.base });
67
67
 
68
68
  for (const failure of failed) {
69
69
  this.logger.error({
@@ -75,6 +75,6 @@ export class Prerequisites {
75
75
  });
76
76
  }
77
77
 
78
- throw new Error("Prerequisites failed");
78
+ throw new Error(PrerequisitesError.Failure);
79
79
  }
80
80
  }
@@ -1,8 +1,8 @@
1
1
  import type * as tools from "@bgord/tools";
2
2
  import NodeCache from "node-cache";
3
- import type { RateLimitStore, RateLimitStoreSubjectType } from "./rate-limit-store.port";
3
+ import type { RateLimitStorePort, RateLimitStoreSubjectType } from "./rate-limit-store.port";
4
4
 
5
- export class RateLimitStoreNodeCache implements RateLimitStore {
5
+ export class RateLimitStoreNodeCacheAdapter implements RateLimitStorePort {
6
6
  private readonly store: NodeCache;
7
7
 
8
8
  constructor(readonly ttl: tools.Duration) {
@@ -2,7 +2,7 @@ import type * as tools from "@bgord/tools";
2
2
 
3
3
  export type RateLimitStoreSubjectType = string;
4
4
 
5
- export interface RateLimitStore {
5
+ export interface RateLimitStorePort {
6
6
  readonly ttl: tools.Duration;
7
7
  get(subject: RateLimitStoreSubjectType): Promise<tools.RateLimiter | undefined>;
8
8
  set(subject: RateLimitStoreSubjectType, limiter: tools.RateLimiter): Promise<void>;
@@ -0,0 +1,13 @@
1
+ import { z } from "zod/v4";
2
+
3
+ export const RecaptchaSecretKeyError = {
4
+ Type: "recaptcha.secret.key.type",
5
+ Length: "recaptcha.secret.key.length",
6
+ } as const;
7
+
8
+ export const RecaptchaSecretKey = z
9
+ .string(RecaptchaSecretKeyError.Type)
10
+ .length(40, RecaptchaSecretKeyError.Length)
11
+ .brand("RecaptchaSecretKey");
12
+
13
+ export type RecaptchaSecretKeyType = z.infer<typeof RecaptchaSecretKey>;
@@ -0,0 +1,13 @@
1
+ import { z } from "zod/v4";
2
+
3
+ export const RecaptchaSiteKeyError = {
4
+ Type: "recaptcha.site.key.type",
5
+ Length: "recaptcha.site.key.length",
6
+ } as const;
7
+
8
+ export const RecaptchaSiteKey = z
9
+ .string(RecaptchaSiteKeyError.Type)
10
+ .length(40, RecaptchaSiteKeyError.Length)
11
+ .brand("RecaptchaSiteKey");
12
+
13
+ export type RecaptchaSiteKeyType = z.infer<typeof RecaptchaSiteKey>;
@@ -15,8 +15,8 @@ export class RedactorEncryptionAdapter implements RedactorPort {
15
15
  redact<T>(input: T): T {
16
16
  const rootObject = Object(input);
17
17
 
18
- return cloneDeepWith(input, (value, key, parentObj) => {
19
- if (parentObj === rootObject && typeof key === "string" && key.toLowerCase() === this.key) {
18
+ return cloneDeepWith(input, (value, key, parent) => {
19
+ if (parent === rootObject && typeof key === "string" && key.toLowerCase() === this.key) {
20
20
  const iv = randomBytes(12);
21
21
  const cipher = createCipheriv("aes-256-gcm", this.secret, iv);
22
22
  const plaintext = Buffer.from(JSON.stringify(value), "utf8");
@@ -3,7 +3,6 @@ import type { RedactorPort } from "./redactor.port";
3
3
 
4
4
  export class RedactorMaskAdapter implements RedactorPort {
5
5
  static readonly DEFAULT_KEYS: readonly string[] = [
6
- // auth & cookies
7
6
  "authorization",
8
7
  "cookie",
9
8
  "set-cookie",
@@ -13,7 +12,6 @@ export class RedactorMaskAdapter implements RedactorPort {
13
12
  "accessToken",
14
13
  "refreshToken",
15
14
 
16
- // passwords & secrets
17
15
  "password",
18
16
  "currentPassword",
19
17
  "newPassword",
@@ -21,7 +19,6 @@ export class RedactorMaskAdapter implements RedactorPort {
21
19
  "clientSecret",
22
20
  "secret",
23
21
 
24
- // one-time codes
25
22
  "otp",
26
23
  "code",
27
24
  ];
@@ -1,6 +1,8 @@
1
1
  import fs from "node:fs/promises";
2
2
  import * as tools from "@bgord/tools";
3
+ import type { FileCleanerPort } from "./file-cleaner.port";
3
4
  import type { FileHashPort } from "./file-hash.port";
5
+ import type { FileRenamerPort } from "./file-renamer.port";
4
6
  import type {
5
7
  RemoteFileStoragePort,
6
8
  RemoteHeadResult,
@@ -8,14 +10,15 @@ import type {
8
10
  RemotePutFromPathResult,
9
11
  } from "./remote-file-storage.port";
10
12
 
11
- type RemoteFileStorageDiskConfig = {
12
- root: tools.DirectoryPathAbsoluteType;
13
- hasher: FileHashPort;
14
- publicBaseUrl?: string;
15
- };
13
+ type RemoteFileStorageDiskConfig = { root: tools.DirectoryPathAbsoluteType; publicBaseUrl?: string };
14
+
15
+ type Dependencies = { FileHash: FileHashPort; FileCleaner: FileCleanerPort; FileRenamer: FileRenamerPort };
16
16
 
17
17
  export class RemoteFileStorageDiskAdapter implements RemoteFileStoragePort {
18
- constructor(private readonly config: RemoteFileStorageDiskConfig) {}
18
+ constructor(
19
+ private readonly config: RemoteFileStorageDiskConfig,
20
+ private readonly deps: Dependencies,
21
+ ) {}
19
22
 
20
23
  private resolveKeyToAbsoluteFilePath(key: tools.ObjectKeyType): tools.FilePathAbsolute {
21
24
  const parts = key.split("/");
@@ -39,16 +42,16 @@ export class RemoteFileStorageDiskAdapter implements RemoteFileStoragePort {
39
42
 
40
43
  const source = Bun.file(input.path.get());
41
44
  await Bun.write(temporary.get(), source);
42
- await fs.rename(temporary.get(), final.get());
45
+ await this.deps.FileRenamer.rename(temporary, final);
43
46
 
44
- return this.config.hasher.hash(final);
47
+ return this.deps.FileHash.hash(final);
45
48
  }
46
49
 
47
50
  async head(key: tools.ObjectKeyType): Promise<RemoteHeadResult> {
48
51
  const path = this.resolveKeyToAbsoluteFilePath(key);
49
52
 
50
53
  try {
51
- return { exists: true, ...(await this.config.hasher.hash(path)) };
54
+ return { exists: true, ...(await this.deps.FileHash.hash(path)) };
52
55
  } catch {
53
56
  return { exists: false };
54
57
  }
@@ -65,10 +68,6 @@ export class RemoteFileStorageDiskAdapter implements RemoteFileStoragePort {
65
68
  }
66
69
 
67
70
  async delete(key: tools.ObjectKeyType): Promise<void> {
68
- const path = this.resolveKeyToAbsoluteFilePath(key);
69
-
70
- try {
71
- await fs.unlink(path.get());
72
- } catch (error) {}
71
+ await this.deps.FileCleaner.delete(this.resolveKeyToAbsoluteFilePath(key));
73
72
  }
74
73
  }
@@ -3,7 +3,8 @@ import type hono from "hono";
3
3
  export async function safeParseBody(c: hono.Context): Promise<any> {
4
4
  try {
5
5
  const rawBody = await c.req.text();
6
- if (!rawBody.trim()) return {}; // handles truly empty body
6
+
7
+ if (!rawBody.trim()) return {};
7
8
  return JSON.parse(rawBody);
8
9
  } catch {
9
10
  return {};
@@ -15,6 +15,7 @@ import { ETagExtractor } from "./etag-extractor.middleware";
15
15
  import { HttpLogger, type HttpLoggerOptions } from "./http-logger.middleware";
16
16
  import type { I18nConfigType } from "./i18n.service";
17
17
  import type { IdProviderPort } from "./id-provider.port";
18
+ import type { JsonFileReaderPort } from "./json-file-reader.port";
18
19
  import type { LoggerPort } from "./logger.port";
19
20
  import { TimeZoneOffset } from "./time-zone-offset.middleware";
20
21
  import { WeakETagExtractor } from "./weak-etag-extractor.middleware";
@@ -32,6 +33,7 @@ type Dependencies = {
32
33
  IdProvider: IdProviderPort;
33
34
  I18n: I18nConfigType;
34
35
  Clock: ClockPort;
36
+ JsonFileReader: JsonFileReaderPort;
35
37
  };
36
38
 
37
39
  export class Setup {
@@ -43,7 +45,7 @@ export class Setup {
43
45
  secureHeaders(secureHeadersOptions),
44
46
  bodyLimit({ maxSize: BODY_LIMIT_MAX_SIZE }),
45
47
  uaBlocker({ blocklist: BOTS_REGEX }),
46
- ApiVersion.build({ Clock: deps.Clock }),
48
+ ApiVersion.build({ Clock: deps.Clock, JsonFileReader: deps.JsonFileReader }),
47
49
  cors(corsOptions),
48
50
  languageDetector({
49
51
  supportedLanguages: Object.keys(deps.I18n.supportedLanguages),
@@ -12,9 +12,7 @@ export class ShieldApiKey {
12
12
  constructor(private readonly config: ApiKeyShieldConfigType) {}
13
13
 
14
14
  verify = createMiddleware(async (c, next) => {
15
- if (c.req.header(ShieldApiKey.HEADER_NAME) === this.config.API_KEY) {
16
- return next();
17
- }
15
+ if (c.req.header(ShieldApiKey.HEADER_NAME) === this.config.API_KEY) return next();
18
16
 
19
17
  throw AccessDeniedApiKeyError;
20
18
  });
@@ -5,9 +5,7 @@ import type hono from "hono";
5
5
  import { createMiddleware } from "hono/factory";
6
6
  import { HTTPException } from "hono/http-exception";
7
7
 
8
- export const AccessDeniedAuthShieldError = new HTTPException(403, {
9
- message: "access_denied_auth_shield",
10
- });
8
+ export const AccessDeniedAuthShieldError = new HTTPException(403, { message: "access_denied_auth_shield" });
11
9
 
12
10
  export class ShieldAuth {
13
11
  cors = {
@@ -25,22 +23,26 @@ export class ShieldAuth {
25
23
  if (!session) {
26
24
  c.set("user", null);
27
25
  c.set("session", null);
26
+
28
27
  return next();
29
28
  }
30
29
 
31
30
  c.set("user", session.user);
32
31
  c.set("session", session.session);
32
+
33
33
  return next();
34
34
  });
35
35
 
36
36
  verify = createMiddleware(async (c: hono.Context, next: hono.Next) => {
37
37
  const user = c.get("user");
38
+
38
39
  if (!user) throw AccessDeniedAuthShieldError;
39
40
  return next();
40
41
  });
41
42
 
42
43
  reverse = createMiddleware(async (c: hono.Context, next: hono.Next) => {
43
44
  const user = c.get("user");
45
+
44
46
  if (user) throw AccessDeniedAuthShieldError;
45
47
  return next();
46
48
  });
@@ -1,22 +1,23 @@
1
1
  import hcaptcha from "hcaptcha";
2
2
  import { createMiddleware } from "hono/factory";
3
3
  import { HTTPException } from "hono/http-exception";
4
+ import type { HCaptchaSecretKeyType } from "./hcaptcha-secret-key.vo";
4
5
  import type { ShieldCaptchaPort } from "./shield-captcha.port";
5
- import type { HCaptchaSecretKeyType } from "./shield-captcha-hcaptcha.adapter";
6
6
 
7
7
  export const AccessDeniedHcaptchaLocalError = new HTTPException(403, {
8
8
  message: "access_denied_hcaptcha_local",
9
9
  });
10
10
 
11
- export class ShieldCaptchaHcaptchaLocal implements ShieldCaptchaPort {
11
+ export class ShieldCaptchaHcaptchaLocalAdapter implements ShieldCaptchaPort {
12
12
  constructor(private readonly secretKey: HCaptchaSecretKeyType) {}
13
13
 
14
14
  verify = createMiddleware(async (_c, next) => {
15
15
  try {
16
16
  const result = await hcaptcha.verify(this.secretKey, "10000000-aaaa-bbbb-cccc-000000000001");
17
+
17
18
  if (!result?.success) throw AccessDeniedHcaptchaLocalError;
18
19
  return next();
19
- } catch (_error) {
20
+ } catch {
20
21
  throw AccessDeniedHcaptchaLocalError;
21
22
  }
22
23
  });
@@ -1,31 +1,23 @@
1
1
  import hcaptcha from "hcaptcha";
2
2
  import { createMiddleware } from "hono/factory";
3
3
  import { HTTPException } from "hono/http-exception";
4
- import { z } from "zod/v4";
4
+ import type { HCaptchaSecretKeyType } from "./hcaptcha-secret-key.vo";
5
5
  import type { ShieldCaptchaPort } from "./shield-captcha.port";
6
6
 
7
- export const HCaptchaSecretKey = z.string().trim().length(42).brand("HCaptchaSecretKey");
8
- export type HCaptchaSecretKeyType = z.infer<typeof HCaptchaSecretKey>;
9
-
10
- export const HCaptchaSiteKey = z.string().trim().length(36);
11
- export type HCaptchaSiteKeyType = z.infer<typeof HCaptchaSiteKey>;
12
-
13
- export const HCaptchaResponseToken = z.string().trim();
14
- export type HCaptchaResponseTokenType = z.infer<typeof HCaptchaResponseToken>;
15
-
16
7
  export const AccessDeniedHcaptchaError = new HTTPException(403, { message: "access_denied_hcaptcha" });
17
8
 
18
- export class ShieldCaptchaHcaptcha implements ShieldCaptchaPort {
9
+ export class ShieldCaptchaHcaptchaAdapter implements ShieldCaptchaPort {
19
10
  constructor(private readonly secretKey: HCaptchaSecretKeyType) {}
20
11
 
21
12
  verify = createMiddleware(async (c, next) => {
22
13
  try {
23
14
  const form = await c.req.formData();
24
- const hcaptchaTokenFormData = form.get("h-captcha-response")?.toString() as HCaptchaResponseTokenType;
15
+ const hcaptchaTokenFormData = form.get("h-captcha-response")?.toString() as string;
25
16
  const result = await hcaptcha.verify(this.secretKey, hcaptchaTokenFormData);
17
+
26
18
  if (!result?.success) throw AccessDeniedHcaptchaError;
27
19
  return next();
28
- } catch (_error) {
20
+ } catch {
29
21
  throw AccessDeniedHcaptchaError;
30
22
  }
31
23
  });
@@ -1,6 +1,6 @@
1
1
  import { createMiddleware } from "hono/factory";
2
2
  import type { ShieldCaptchaPort } from "./shield-captcha.port";
3
3
 
4
- export class ShieldCaptchaNoop implements ShieldCaptchaPort {
4
+ export class ShieldCaptchaNoopAdapter implements ShieldCaptchaPort {
5
5
  verify = createMiddleware(async (_c, next) => next());
6
6
  }
@@ -1,42 +1,30 @@
1
1
  import { createMiddleware } from "hono/factory";
2
2
  import { HTTPException } from "hono/http-exception";
3
- import { z } from "zod/v4";
3
+ import type { RecaptchaSecretKeyType } from "./recaptcha-secret-key.vo";
4
4
  import type { ShieldCaptchaPort } from "./shield-captcha.port";
5
5
 
6
- export const RecaptchaSiteKey = z.string().trim().length(40);
7
- export type RecaptchaSiteKeyType = z.infer<typeof RecaptchaSiteKey>;
8
-
9
- export const RecaptchaSecretKey = z.string().trim().length(40).brand("RecaptchaSecretKey");
10
- export type RecaptchaSecretKeyType = z.infer<typeof RecaptchaSecretKey>;
11
-
12
6
  export type RecaptchaVerifierConfigType = { secretKey: RecaptchaSecretKeyType };
13
7
  export type RecaptchaResultType = { success: boolean; score: number };
14
8
 
15
9
  export const AccessDeniedRecaptchaError = new HTTPException(403, { message: "access_denied_recaptcha" });
16
10
 
17
- export class ShieldCaptchaRecaptcha implements ShieldCaptchaPort {
18
- private readonly secretKey: RecaptchaVerifierConfigType["secretKey"];
19
-
20
- constructor(config: RecaptchaVerifierConfigType) {
21
- this.secretKey = config.secretKey;
22
- }
11
+ export class ShieldCaptchaRecaptchaAdapter implements ShieldCaptchaPort {
12
+ constructor(private readonly config: RecaptchaVerifierConfigType) {}
23
13
 
24
14
  verify = createMiddleware(async (c, next) => {
25
15
  try {
26
- const recaptchaTokenHeader = c.req.header("x-recaptcha-token");
27
- const recaptchaTokenQuery = c.req.query("recaptchaToken");
16
+ const header = c.req.header("x-recaptcha-token");
17
+ const query = c.req.query("recaptchaToken");
18
+ const form = (await c.req.formData()).get("g-recaptcha-response")?.toString();
28
19
 
29
- const form = await c.req.formData();
30
- const recaptchaTokenFormData = form.get("g-recaptcha-response")?.toString();
31
-
32
- const xForwardedForHeader = c.req.header("x-forwarded-for");
33
- // cSpell:ignore remoteip
34
- const remoteip = xForwardedForHeader ?? "";
20
+ const token = header ?? query ?? form;
35
21
 
36
- const token = recaptchaTokenHeader ?? recaptchaTokenQuery ?? recaptchaTokenFormData;
37
22
  if (!token) throw AccessDeniedRecaptchaError;
38
23
 
39
- const params = new URLSearchParams({ secret: this.secretKey, response: token, remoteip });
24
+ // cSpell:ignore remoteip
25
+ const remoteip = c.req.header("x-forwarded-for") ?? "";
26
+
27
+ const params = new URLSearchParams({ secret: this.config.secretKey, response: token, remoteip });
40
28
 
41
29
  const response = await fetch("https://www.google.com/recaptcha/api/siteverify", {
42
30
  method: "POST",
@@ -44,10 +32,12 @@ export class ShieldCaptchaRecaptcha implements ShieldCaptchaPort {
44
32
  body: params,
45
33
  });
46
34
 
47
- const result = (await response.json()) as RecaptchaResultType;
35
+ const result: RecaptchaResultType = await response.json();
36
+
48
37
  if (!result.success || result.score < 0.5) throw AccessDeniedRecaptchaError;
38
+
49
39
  await next();
50
- } catch (_error) {
40
+ } catch {
51
41
  throw AccessDeniedRecaptchaError;
52
42
  }
53
43
  });
@@ -3,10 +3,10 @@ import type { Context } from "hono";
3
3
  import { createMiddleware } from "hono/factory";
4
4
  import { HTTPException } from "hono/http-exception";
5
5
  import type { ClockPort } from "./clock.port";
6
- import type { RateLimitStore } from "./rate-limit-store.port";
6
+ import type { RateLimitStorePort } from "./rate-limit-store.port";
7
7
 
8
8
  type SubjectResolver = (c: Context) => string;
9
- type RateLimitShieldOptionsType = { enabled: boolean; store: RateLimitStore; subject: SubjectResolver };
9
+ type RateLimitShieldOptionsType = { enabled: boolean; store: RateLimitStorePort; subject: SubjectResolver };
10
10
  type Dependencies = { Clock: ClockPort };
11
11
 
12
12
  export const AnonSubjectResolver: SubjectResolver = () => "anon";
@@ -5,6 +5,7 @@ export class Slower {
5
5
  static handle = (offset: tools.Duration) =>
6
6
  createMiddleware(async (_c, next) => {
7
7
  await Bun.sleep(offset.ms);
8
+
8
9
  return next();
9
10
  });
10
11
  }
@@ -1,25 +1,27 @@
1
- import fs from "node:fs/promises";
2
1
  import * as tools from "@bgord/tools";
2
+ import type { FileCleanerPort } from "./file-cleaner.port";
3
+ import type { FileRenamerPort } from "./file-renamer.port";
3
4
  import type { TemporaryFilePort } from "./temporary-file.port";
4
5
 
5
- export class TemporaryFileAbsolute implements TemporaryFilePort {
6
- constructor(private readonly directory: tools.DirectoryPathAbsoluteType) {}
6
+ type Dependencies = { FileCleaner: FileCleanerPort; FileRenamer: FileRenamerPort };
7
7
 
8
- async write(filename: tools.Filename, data: File) {
9
- const partPath = tools.FilePathAbsolute.fromPartsSafe(this.directory, filename.withSuffix("-part"));
10
- const finalPath = tools.FilePathAbsolute.fromPartsSafe(this.directory, filename);
8
+ export class TemporaryFileAbsoluteAdapter implements TemporaryFilePort {
9
+ constructor(
10
+ private readonly directory: tools.DirectoryPathAbsoluteType,
11
+ private readonly deps: Dependencies,
12
+ ) {}
11
13
 
12
- await Bun.write(partPath.get(), data);
13
- await fs.rename(partPath.get(), finalPath.get());
14
+ async write(filename: tools.Filename, content: File) {
15
+ const temporary = tools.FilePathAbsolute.fromPartsSafe(this.directory, filename.withSuffix("-part"));
16
+ const final = tools.FilePathAbsolute.fromPartsSafe(this.directory, filename);
14
17
 
15
- return { path: finalPath };
18
+ await Bun.write(temporary.get(), content);
19
+ await this.deps.FileRenamer.rename(temporary, final);
20
+
21
+ return { path: final };
16
22
  }
17
23
 
18
24
  async cleanup(filename: tools.Filename) {
19
- const path = tools.FilePathAbsolute.fromPartsSafe(this.directory, filename);
20
-
21
- try {
22
- await fs.unlink(path.get());
23
- } catch (error) {}
25
+ await this.deps.FileCleaner.delete(tools.FilePathAbsolute.fromPartsSafe(this.directory, filename));
24
26
  }
25
27
  }
@@ -1,7 +1,7 @@
1
1
  import * as tools from "@bgord/tools";
2
2
  import type { TemporaryFilePort } from "./temporary-file.port";
3
3
 
4
- export class TemporaryFileNoop implements TemporaryFilePort {
4
+ export class TemporaryFileNoopAdapter implements TemporaryFilePort {
5
5
  constructor(private readonly directory: tools.DirectoryPathAbsoluteType) {}
6
6
 
7
7
  async write(filename: tools.Filename) {
@@ -1,6 +1,7 @@
1
1
  import type * as tools from "@bgord/tools";
2
2
 
3
3
  export interface TemporaryFilePort {
4
- write(filename: tools.Filename, data: File): Promise<{ path: tools.FilePathAbsolute }>;
4
+ write(filename: tools.Filename, content: File): Promise<{ path: tools.FilePathAbsolute }>;
5
+
5
6
  cleanup(filename: tools.Filename): Promise<void>;
6
7
  }
@@ -7,11 +7,8 @@ export class TimeZoneOffset {
7
7
  static TIME_ZONE_OFFSET_HEADER_NAME = "time-zone-offset";
8
8
 
9
9
  static attach = createMiddleware(async (c, next) => {
10
- const timeZoneOffsetMinutes = tools.TimeZoneOffsetValue.parse(
11
- c.req.header(TimeZoneOffset.TIME_ZONE_OFFSET_HEADER_NAME),
12
- );
13
-
14
- c.set("timeZoneOffset", tools.Duration.Minutes(timeZoneOffsetMinutes));
10
+ const offset = tools.TimeZoneOffsetValue.parse(c.req.header(TimeZoneOffset.TIME_ZONE_OFFSET_HEADER_NAME));
11
+ c.set("timeZoneOffset", tools.Duration.Minutes(offset));
15
12
 
16
13
  await next();
17
14
  });
@@ -1,14 +1,17 @@
1
- import type * as tools from "@bgord/tools";
2
1
  import { createFactory } from "hono/factory";
3
2
  import { I18n } from "./i18n.service";
3
+ import type { JsonFileReaderPort } from "./json-file-reader.port";
4
+ import type { LoggerPort } from "./logger.port";
4
5
 
5
6
  const handler = createFactory();
6
7
 
8
+ type Dependencies = { JsonFileReader: JsonFileReaderPort; Logger: LoggerPort };
9
+
7
10
  export class Translations {
8
- static build = () =>
11
+ static build = (deps: Dependencies) =>
9
12
  handler.createHandlers(async (c) => {
10
- const language = c.get("language") as tools.LanguageType;
11
- const translations = await new I18n().getTranslations(language);
13
+ const language = c.get("language");
14
+ const translations = await new I18n(deps).getTranslations(language);
12
15
 
13
16
  return c.json({ translations, language });
14
17
  });
@@ -10,9 +10,9 @@ export class Uptime {
10
10
  private static readonly rounding = new tools.RoundToNearest();
11
11
 
12
12
  static get(clock: ClockPort): UptimeResultType {
13
- const uptime = tools.Duration.Seconds(Uptime.rounding.round(process.uptime()));
14
- const uptimeFormatted = tools.DateFormatters.relative(clock.now().Minus(uptime));
13
+ const duration = tools.Duration.Seconds(Uptime.rounding.round(process.uptime()));
14
+ const formatted = tools.DateFormatters.relative(clock.now().Minus(duration));
15
15
 
16
- return { duration: uptime, formatted: uptimeFormatted };
16
+ return { duration, formatted };
17
17
  }
18
18
  }