@heavybit/shared-lib 1.3.2 → 2.7.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 (366) hide show
  1. package/README.md +261 -0
  2. package/dist/cjs/access/index.js +9 -1
  3. package/dist/cjs/access/index.js.map +1 -1
  4. package/dist/cjs/approvals/index.js +137 -0
  5. package/dist/cjs/approvals/index.js.map +1 -0
  6. package/dist/cjs/audit/index.js +74 -0
  7. package/dist/cjs/audit/index.js.map +1 -0
  8. package/dist/cjs/cache/index.js +90 -16
  9. package/dist/cjs/cache/index.js.map +1 -1
  10. package/dist/cjs/cache/keyspace.js +101 -0
  11. package/dist/cjs/cache/keyspace.js.map +1 -0
  12. package/dist/cjs/common/circuit-breaker.js +74 -0
  13. package/dist/cjs/common/circuit-breaker.js.map +1 -0
  14. package/dist/cjs/common/errors.js +44 -5
  15. package/dist/cjs/common/errors.js.map +1 -1
  16. package/dist/cjs/common/index.js +4 -0
  17. package/dist/cjs/common/index.js.map +1 -1
  18. package/dist/cjs/common/internal-client.js +177 -0
  19. package/dist/cjs/common/internal-client.js.map +1 -0
  20. package/dist/cjs/common/internal-constants.js +12 -0
  21. package/dist/cjs/common/internal-constants.js.map +1 -0
  22. package/dist/cjs/common/internal-service-auth.js +160 -0
  23. package/dist/cjs/common/internal-service-auth.js.map +1 -0
  24. package/dist/cjs/common/money.js +215 -0
  25. package/dist/cjs/common/money.js.map +1 -0
  26. package/dist/cjs/common/phone.js +63 -11
  27. package/dist/cjs/common/phone.js.map +1 -1
  28. package/dist/cjs/common/response.js +78 -5
  29. package/dist/cjs/common/response.js.map +1 -1
  30. package/dist/cjs/common/time.js +28 -2
  31. package/dist/cjs/common/time.js.map +1 -1
  32. package/dist/cjs/config/index.js +140 -20
  33. package/dist/cjs/config/index.js.map +1 -1
  34. package/dist/cjs/context/index.js +49 -0
  35. package/dist/cjs/context/index.js.map +1 -0
  36. package/dist/cjs/contracts/index.js +0 -2
  37. package/dist/cjs/contracts/index.js.map +1 -1
  38. package/dist/cjs/contracts/notification-dispatch.js +87 -63
  39. package/dist/cjs/contracts/notification-dispatch.js.map +1 -1
  40. package/dist/cjs/database/db.js +37 -0
  41. package/dist/cjs/database/db.js.map +1 -0
  42. package/dist/cjs/database/index.js +22 -51
  43. package/dist/cjs/database/index.js.map +1 -1
  44. package/dist/cjs/database/pagination.js +88 -0
  45. package/dist/cjs/database/pagination.js.map +1 -0
  46. package/dist/cjs/database/pool.js +60 -0
  47. package/dist/cjs/database/pool.js.map +1 -0
  48. package/dist/cjs/database/scoped-repository.js +132 -0
  49. package/dist/cjs/database/scoped-repository.js.map +1 -0
  50. package/dist/cjs/database/scopes.js +166 -0
  51. package/dist/cjs/database/scopes.js.map +1 -0
  52. package/dist/cjs/database/table-names.js +14 -0
  53. package/dist/cjs/database/table-names.js.map +1 -0
  54. package/dist/cjs/database/tables.js +71 -0
  55. package/dist/cjs/database/tables.js.map +1 -0
  56. package/dist/cjs/express/auth.js +88 -41
  57. package/dist/cjs/express/auth.js.map +1 -1
  58. package/dist/cjs/express/index.js +3 -0
  59. package/dist/cjs/express/index.js.map +1 -1
  60. package/dist/cjs/express/internal-caller.js +52 -0
  61. package/dist/cjs/express/internal-caller.js.map +1 -0
  62. package/dist/cjs/express/middleware.js +154 -34
  63. package/dist/cjs/express/middleware.js.map +1 -1
  64. package/dist/cjs/express/respond.js +47 -0
  65. package/dist/cjs/express/respond.js.map +1 -0
  66. package/dist/cjs/express/step-up.js +41 -0
  67. package/dist/cjs/express/step-up.js.map +1 -0
  68. package/dist/cjs/http/index.js +3 -71
  69. package/dist/cjs/http/index.js.map +1 -1
  70. package/dist/cjs/identity/index.js +269 -67
  71. package/dist/cjs/identity/index.js.map +1 -1
  72. package/dist/cjs/identity/step-up.js +52 -0
  73. package/dist/cjs/identity/step-up.js.map +1 -0
  74. package/dist/cjs/index.js +7 -0
  75. package/dist/cjs/index.js.map +1 -1
  76. package/dist/cjs/knex/columns.js +36 -0
  77. package/dist/cjs/knex/columns.js.map +1 -0
  78. package/dist/cjs/knex/index.js +26 -43
  79. package/dist/cjs/knex/index.js.map +1 -1
  80. package/dist/cjs/knex/migration-helpers.js +57 -0
  81. package/dist/cjs/knex/migration-helpers.js.map +1 -0
  82. package/dist/cjs/logging/index.js +76 -40
  83. package/dist/cjs/logging/index.js.map +1 -1
  84. package/dist/cjs/logging/redact.js +112 -0
  85. package/dist/cjs/logging/redact.js.map +1 -0
  86. package/dist/cjs/messaging/base-consumer.js +36 -0
  87. package/dist/cjs/messaging/base-consumer.js.map +1 -0
  88. package/dist/cjs/messaging/consumer.js +142 -73
  89. package/dist/cjs/messaging/consumer.js.map +1 -1
  90. package/dist/cjs/messaging/envelope.js +53 -10
  91. package/dist/cjs/messaging/envelope.js.map +1 -1
  92. package/dist/cjs/messaging/idempotency.js +95 -8
  93. package/dist/cjs/messaging/idempotency.js.map +1 -1
  94. package/dist/cjs/messaging/index.js +3 -1
  95. package/dist/cjs/messaging/index.js.map +1 -1
  96. package/dist/cjs/messaging/outbox.js +97 -55
  97. package/dist/cjs/messaging/outbox.js.map +1 -1
  98. package/dist/cjs/messaging/publisher.js +86 -38
  99. package/dist/cjs/messaging/publisher.js.map +1 -1
  100. package/dist/cjs/messaging/staff-notifier.js +36 -44
  101. package/dist/cjs/messaging/staff-notifier.js.map +1 -1
  102. package/dist/cjs/messaging/staff-recipients.js +57 -0
  103. package/dist/cjs/messaging/staff-recipients.js.map +1 -0
  104. package/dist/cjs/messaging/topology.js +41 -5
  105. package/dist/cjs/messaging/topology.js.map +1 -1
  106. package/dist/cjs/rate-limit/index.js +57 -6
  107. package/dist/cjs/rate-limit/index.js.map +1 -1
  108. package/dist/cjs/rate-limit/keys.js +47 -0
  109. package/dist/cjs/rate-limit/keys.js.map +1 -0
  110. package/dist/cjs/socket/index.js +127 -16
  111. package/dist/cjs/socket/index.js.map +1 -1
  112. package/dist/cjs/socket/ticket.js +124 -0
  113. package/dist/cjs/socket/ticket.js.map +1 -0
  114. package/dist/cjs/testing/index.js +23 -14
  115. package/dist/cjs/testing/index.js.map +1 -1
  116. package/dist/cjs/validation/index.js +27 -3
  117. package/dist/cjs/validation/index.js.map +1 -1
  118. package/dist/esm/access/index.js +9 -1
  119. package/dist/esm/access/index.js.map +1 -1
  120. package/dist/esm/approvals/index.js +127 -0
  121. package/dist/esm/approvals/index.js.map +1 -0
  122. package/dist/esm/audit/index.js +70 -0
  123. package/dist/esm/audit/index.js.map +1 -0
  124. package/dist/esm/cache/index.js +70 -13
  125. package/dist/esm/cache/index.js.map +1 -1
  126. package/dist/esm/cache/keyspace.js +95 -0
  127. package/dist/esm/cache/keyspace.js.map +1 -0
  128. package/dist/esm/common/circuit-breaker.js +70 -0
  129. package/dist/esm/common/circuit-breaker.js.map +1 -0
  130. package/dist/esm/common/errors.js +42 -4
  131. package/dist/esm/common/errors.js.map +1 -1
  132. package/dist/esm/common/index.js +4 -0
  133. package/dist/esm/common/index.js.map +1 -1
  134. package/dist/esm/common/internal-client.js +173 -0
  135. package/dist/esm/common/internal-client.js.map +1 -0
  136. package/dist/esm/common/internal-constants.js +9 -0
  137. package/dist/esm/common/internal-constants.js.map +1 -0
  138. package/dist/esm/common/internal-service-auth.js +150 -0
  139. package/dist/esm/common/internal-service-auth.js.map +1 -0
  140. package/dist/esm/common/money.js +207 -0
  141. package/dist/esm/common/money.js.map +1 -0
  142. package/dist/esm/common/phone.js +63 -11
  143. package/dist/esm/common/phone.js.map +1 -1
  144. package/dist/esm/common/response.js +75 -5
  145. package/dist/esm/common/response.js.map +1 -1
  146. package/dist/esm/common/time.js +27 -2
  147. package/dist/esm/common/time.js.map +1 -1
  148. package/dist/esm/config/index.js +136 -19
  149. package/dist/esm/config/index.js.map +1 -1
  150. package/dist/esm/context/index.js +44 -0
  151. package/dist/esm/context/index.js.map +1 -0
  152. package/dist/esm/contracts/index.js +0 -2
  153. package/dist/esm/contracts/index.js.map +1 -1
  154. package/dist/esm/contracts/notification-dispatch.js +85 -62
  155. package/dist/esm/contracts/notification-dispatch.js.map +1 -1
  156. package/dist/esm/database/db.js +32 -0
  157. package/dist/esm/database/db.js.map +1 -0
  158. package/dist/esm/database/index.js +9 -45
  159. package/dist/esm/database/index.js.map +1 -1
  160. package/dist/esm/database/pagination.js +81 -0
  161. package/dist/esm/database/pagination.js.map +1 -0
  162. package/dist/esm/database/pool.js +51 -0
  163. package/dist/esm/database/pool.js.map +1 -0
  164. package/dist/esm/database/scoped-repository.js +128 -0
  165. package/dist/esm/database/scoped-repository.js.map +1 -0
  166. package/dist/esm/database/scopes.js +157 -0
  167. package/dist/esm/database/scopes.js.map +1 -0
  168. package/dist/esm/database/table-names.js +11 -0
  169. package/dist/esm/database/table-names.js.map +1 -0
  170. package/dist/esm/database/tables.js +61 -0
  171. package/dist/esm/database/tables.js.map +1 -0
  172. package/dist/esm/express/auth.js +87 -40
  173. package/dist/esm/express/auth.js.map +1 -1
  174. package/dist/esm/express/index.js +3 -0
  175. package/dist/esm/express/index.js.map +1 -1
  176. package/dist/esm/express/internal-caller.js +49 -0
  177. package/dist/esm/express/internal-caller.js.map +1 -0
  178. package/dist/esm/express/middleware.js +146 -27
  179. package/dist/esm/express/middleware.js.map +1 -1
  180. package/dist/esm/express/respond.js +42 -0
  181. package/dist/esm/express/respond.js.map +1 -0
  182. package/dist/esm/express/step-up.js +38 -0
  183. package/dist/esm/express/step-up.js.map +1 -0
  184. package/dist/esm/http/index.js +3 -70
  185. package/dist/esm/http/index.js.map +1 -1
  186. package/dist/esm/identity/index.js +246 -64
  187. package/dist/esm/identity/index.js.map +1 -1
  188. package/dist/esm/identity/step-up.js +47 -0
  189. package/dist/esm/identity/step-up.js.map +1 -0
  190. package/dist/esm/index.js +7 -0
  191. package/dist/esm/index.js.map +1 -1
  192. package/dist/esm/knex/columns.js +28 -0
  193. package/dist/esm/knex/columns.js.map +1 -0
  194. package/dist/esm/knex/index.js +8 -34
  195. package/dist/esm/knex/index.js.map +1 -1
  196. package/dist/esm/knex/migration-helpers.js +51 -0
  197. package/dist/esm/knex/migration-helpers.js.map +1 -0
  198. package/dist/esm/logging/index.js +68 -39
  199. package/dist/esm/logging/index.js.map +1 -1
  200. package/dist/esm/logging/redact.js +106 -0
  201. package/dist/esm/logging/redact.js.map +1 -0
  202. package/dist/esm/messaging/base-consumer.js +32 -0
  203. package/dist/esm/messaging/base-consumer.js.map +1 -0
  204. package/dist/esm/messaging/consumer.js +139 -71
  205. package/dist/esm/messaging/consumer.js.map +1 -1
  206. package/dist/esm/messaging/envelope.js +50 -10
  207. package/dist/esm/messaging/envelope.js.map +1 -1
  208. package/dist/esm/messaging/idempotency.js +91 -7
  209. package/dist/esm/messaging/idempotency.js.map +1 -1
  210. package/dist/esm/messaging/index.js +3 -1
  211. package/dist/esm/messaging/index.js.map +1 -1
  212. package/dist/esm/messaging/outbox.js +97 -54
  213. package/dist/esm/messaging/outbox.js.map +1 -1
  214. package/dist/esm/messaging/publisher.js +86 -38
  215. package/dist/esm/messaging/publisher.js.map +1 -1
  216. package/dist/esm/messaging/staff-notifier.js +36 -43
  217. package/dist/esm/messaging/staff-notifier.js.map +1 -1
  218. package/dist/esm/messaging/staff-recipients.js +53 -0
  219. package/dist/esm/messaging/staff-recipients.js.map +1 -0
  220. package/dist/esm/messaging/topology.js +39 -4
  221. package/dist/esm/messaging/topology.js.map +1 -1
  222. package/dist/esm/rate-limit/index.js +41 -6
  223. package/dist/esm/rate-limit/index.js.map +1 -1
  224. package/dist/esm/rate-limit/keys.js +43 -0
  225. package/dist/esm/rate-limit/keys.js.map +1 -0
  226. package/dist/esm/socket/index.js +112 -17
  227. package/dist/esm/socket/index.js.map +1 -1
  228. package/dist/esm/socket/ticket.js +117 -0
  229. package/dist/esm/socket/ticket.js.map +1 -0
  230. package/dist/esm/testing/index.js +24 -15
  231. package/dist/esm/testing/index.js.map +1 -1
  232. package/dist/esm/validation/index.js +27 -2
  233. package/dist/esm/validation/index.js.map +1 -1
  234. package/dist/types/access/index.d.ts +9 -3
  235. package/dist/types/access/index.d.ts.map +1 -1
  236. package/dist/types/alerting/index.d.ts +1 -1
  237. package/dist/types/alerting/index.d.ts.map +1 -1
  238. package/dist/types/approvals/index.d.ts +99 -0
  239. package/dist/types/approvals/index.d.ts.map +1 -0
  240. package/dist/types/audit/index.d.ts +82 -0
  241. package/dist/types/audit/index.d.ts.map +1 -0
  242. package/dist/types/cache/index.d.ts +64 -14
  243. package/dist/types/cache/index.d.ts.map +1 -1
  244. package/dist/types/cache/keyspace.d.ts +84 -0
  245. package/dist/types/cache/keyspace.d.ts.map +1 -0
  246. package/dist/types/common/circuit-breaker.d.ts +51 -0
  247. package/dist/types/common/circuit-breaker.d.ts.map +1 -0
  248. package/dist/types/common/errors.d.ts +48 -7
  249. package/dist/types/common/errors.d.ts.map +1 -1
  250. package/dist/types/common/index.d.ts +4 -0
  251. package/dist/types/common/index.d.ts.map +1 -1
  252. package/dist/types/common/internal-client.d.ts +116 -0
  253. package/dist/types/common/internal-client.d.ts.map +1 -0
  254. package/dist/types/common/internal-constants.d.ts +9 -0
  255. package/dist/types/common/internal-constants.d.ts.map +1 -0
  256. package/dist/types/common/internal-service-auth.d.ts +102 -0
  257. package/dist/types/common/internal-service-auth.d.ts.map +1 -0
  258. package/dist/types/common/money.d.ts +104 -0
  259. package/dist/types/common/money.d.ts.map +1 -0
  260. package/dist/types/common/phone.d.ts +45 -6
  261. package/dist/types/common/phone.d.ts.map +1 -1
  262. package/dist/types/common/response.d.ts +66 -5
  263. package/dist/types/common/response.d.ts.map +1 -1
  264. package/dist/types/common/time.d.ts +20 -2
  265. package/dist/types/common/time.d.ts.map +1 -1
  266. package/dist/types/config/index.d.ts +252 -28
  267. package/dist/types/config/index.d.ts.map +1 -1
  268. package/dist/types/context/index.d.ts +39 -0
  269. package/dist/types/context/index.d.ts.map +1 -0
  270. package/dist/types/contracts/index.d.ts +0 -2
  271. package/dist/types/contracts/index.d.ts.map +1 -1
  272. package/dist/types/contracts/notification-dispatch.d.ts +204 -86
  273. package/dist/types/contracts/notification-dispatch.d.ts.map +1 -1
  274. package/dist/types/database/db.d.ts +46 -0
  275. package/dist/types/database/db.d.ts.map +1 -0
  276. package/dist/types/database/index.d.ts +9 -22
  277. package/dist/types/database/index.d.ts.map +1 -1
  278. package/dist/types/database/pagination.d.ts +68 -0
  279. package/dist/types/database/pagination.d.ts.map +1 -0
  280. package/dist/types/database/pool.d.ts +39 -0
  281. package/dist/types/database/pool.d.ts.map +1 -0
  282. package/dist/types/database/scoped-repository.d.ts +92 -0
  283. package/dist/types/database/scoped-repository.d.ts.map +1 -0
  284. package/dist/types/database/scopes.d.ts +159 -0
  285. package/dist/types/database/scopes.d.ts.map +1 -0
  286. package/dist/types/database/table-names.d.ts +13 -0
  287. package/dist/types/database/table-names.d.ts.map +1 -0
  288. package/dist/types/database/tables.d.ts +748 -0
  289. package/dist/types/database/tables.d.ts.map +1 -0
  290. package/dist/types/express/auth.d.ts +63 -11
  291. package/dist/types/express/auth.d.ts.map +1 -1
  292. package/dist/types/express/index.d.ts +3 -0
  293. package/dist/types/express/index.d.ts.map +1 -1
  294. package/dist/types/express/internal-caller.d.ts +53 -0
  295. package/dist/types/express/internal-caller.d.ts.map +1 -0
  296. package/dist/types/express/middleware.d.ts +86 -7
  297. package/dist/types/express/middleware.d.ts.map +1 -1
  298. package/dist/types/express/respond.d.ts +41 -0
  299. package/dist/types/express/respond.d.ts.map +1 -0
  300. package/dist/types/express/step-up.d.ts +38 -0
  301. package/dist/types/express/step-up.d.ts.map +1 -0
  302. package/dist/types/http/index.d.ts +3 -31
  303. package/dist/types/http/index.d.ts.map +1 -1
  304. package/dist/types/identity/index.d.ts +159 -21
  305. package/dist/types/identity/index.d.ts.map +1 -1
  306. package/dist/types/identity/step-up.d.ts +41 -0
  307. package/dist/types/identity/step-up.d.ts.map +1 -0
  308. package/dist/types/index.d.ts +7 -0
  309. package/dist/types/index.d.ts.map +1 -1
  310. package/dist/types/knex/columns.d.ts +15 -0
  311. package/dist/types/knex/columns.d.ts.map +1 -0
  312. package/dist/types/knex/index.d.ts +3 -11
  313. package/dist/types/knex/index.d.ts.map +1 -1
  314. package/dist/types/knex/migration-helpers.d.ts +28 -0
  315. package/dist/types/knex/migration-helpers.d.ts.map +1 -0
  316. package/dist/types/logging/index.d.ts +30 -4
  317. package/dist/types/logging/index.d.ts.map +1 -1
  318. package/dist/types/logging/redact.d.ts +54 -0
  319. package/dist/types/logging/redact.d.ts.map +1 -0
  320. package/dist/types/messaging/base-consumer.d.ts +33 -0
  321. package/dist/types/messaging/base-consumer.d.ts.map +1 -0
  322. package/dist/types/messaging/consumer.d.ts +59 -21
  323. package/dist/types/messaging/consumer.d.ts.map +1 -1
  324. package/dist/types/messaging/envelope.d.ts +50 -11
  325. package/dist/types/messaging/envelope.d.ts.map +1 -1
  326. package/dist/types/messaging/idempotency.d.ts +60 -3
  327. package/dist/types/messaging/idempotency.d.ts.map +1 -1
  328. package/dist/types/messaging/index.d.ts +8 -0
  329. package/dist/types/messaging/index.d.ts.map +1 -1
  330. package/dist/types/messaging/outbox.d.ts +62 -22
  331. package/dist/types/messaging/outbox.d.ts.map +1 -1
  332. package/dist/types/messaging/publisher.d.ts +54 -21
  333. package/dist/types/messaging/publisher.d.ts.map +1 -1
  334. package/dist/types/messaging/staff-notifier.d.ts +69 -38
  335. package/dist/types/messaging/staff-notifier.d.ts.map +1 -1
  336. package/dist/types/messaging/staff-recipients.d.ts +50 -0
  337. package/dist/types/messaging/staff-recipients.d.ts.map +1 -0
  338. package/dist/types/messaging/topology.d.ts +40 -8
  339. package/dist/types/messaging/topology.d.ts.map +1 -1
  340. package/dist/types/rate-limit/index.d.ts +40 -4
  341. package/dist/types/rate-limit/index.d.ts.map +1 -1
  342. package/dist/types/rate-limit/keys.d.ts +52 -0
  343. package/dist/types/rate-limit/keys.d.ts.map +1 -0
  344. package/dist/types/socket/index.d.ts +86 -2
  345. package/dist/types/socket/index.d.ts.map +1 -1
  346. package/dist/types/socket/ticket.d.ts +90 -0
  347. package/dist/types/socket/ticket.d.ts.map +1 -0
  348. package/dist/types/testing/index.d.ts +31 -10
  349. package/dist/types/testing/index.d.ts.map +1 -1
  350. package/dist/types/types/index.d.ts +62 -15
  351. package/dist/types/types/index.d.ts.map +1 -1
  352. package/dist/types/validation/index.d.ts +33 -2
  353. package/dist/types/validation/index.d.ts.map +1 -1
  354. package/package.json +3 -1
  355. package/dist/cjs/contracts/editorial-draft.js +0 -120
  356. package/dist/cjs/contracts/editorial-draft.js.map +0 -1
  357. package/dist/cjs/contracts/upload-import.js +0 -54
  358. package/dist/cjs/contracts/upload-import.js.map +0 -1
  359. package/dist/esm/contracts/editorial-draft.js +0 -117
  360. package/dist/esm/contracts/editorial-draft.js.map +0 -1
  361. package/dist/esm/contracts/upload-import.js +0 -51
  362. package/dist/esm/contracts/upload-import.js.map +0 -1
  363. package/dist/types/contracts/editorial-draft.d.ts +0 -610
  364. package/dist/types/contracts/editorial-draft.d.ts.map +0 -1
  365. package/dist/types/contracts/upload-import.d.ts +0 -96
  366. package/dist/types/contracts/upload-import.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","sourceRoot":"","sources":["../../../src/common/time.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../../src/common/time.ts"],"names":[],"mappings":"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"}
@@ -1,24 +1,38 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { resolve } from 'node:path';
3
3
  import { z } from 'zod';
4
- /**
5
- * Environment building blocks. Services compose the pieces they need:
4
+ import { MIN_INTERNAL_CREDENTIAL_LENGTH, SERVICE_NAME_PATTERN } from '../common/internal-constants.js';
5
+ /*
6
+ * Environment building blocks. `loadEnv(schema)` merges a service's schema onto `baseEnv`;
7
+ * `parseEnv(schema)` validates any composition of the blocks without the base:
6
8
  *
7
- * const env = loadEnv(serviceEnv.merge(databaseEnv).merge(messagingEnv).extend({ MY_VAR: z.string() }));
9
+ * const config = loadEnv(z.object({ MY_VAR: z.string() }));
8
10
  */
11
+ /** Service identity, logging, CORS and the gateway signing secret. */
9
12
  export const serviceEnv = z.object({
10
13
  NODE_ENV: z.enum(['development', 'test', 'staging', 'production']).default('development'),
11
14
  PORT: z.coerce.number().int().positive(),
12
15
  SERVICE_NAME: z.string().min(1),
13
- /** Short app identifier used in exchange names and key prefixes (e.g. `showbiz`). */
16
+ /** Short app identifier used in exchange names and key prefixes (e.g. `myapp`). */
14
17
  APP_NAME: z.string().min(1).default('app'),
15
18
  LOG_LEVEL: z.enum(['error', 'warn', 'info', 'http', 'debug']).optional(),
16
19
  CORS_ORIGINS: z.string().default(''),
17
- /** Verifies gateway-signed identity headers. */
18
- GATEWAY_SHARED_SECRET: z.string().min(16),
19
- /** Authenticates service-to-service `/internal/*` calls. */
20
- INTERNAL_SERVICE_SECRET: z.string().min(16),
20
+ /** Verifies gateway-signed identity headers (v2); at least 32 characters, same value on the gateway and every service. */
21
+ GATEWAY_SIGNING_SECRET: z.string().min(32),
21
22
  });
23
+ /**
24
+ * Service-to-service credentials. Optional here because development may run without them;
25
+ * `assertInternalServiceAuthConfigured` enforces them in staging and production.
26
+ */
27
+ export const internalServiceEnv = z.object({
28
+ /** This service's own name (its compose service name), sent with every internal call. */
29
+ INTERNAL_SERVICE_NAME: z.string().regex(SERVICE_NAME_PATTERN).optional(),
30
+ /** This service's own secret (at least 32 characters), sent with every internal call. */
31
+ INTERNAL_SERVICE_CREDENTIAL: z.string().min(MIN_INTERNAL_CREDENTIAL_LENGTH).optional(),
32
+ /** JSON map of caller name → secret this service accepts from that caller. */
33
+ INTERNAL_SERVICE_CREDENTIALS: z.string().optional(),
34
+ });
35
+ /** Database connection env vars (MySQL defaults). */
22
36
  export const databaseEnv = z.object({
23
37
  DB_HOST: z.string().default('127.0.0.1'),
24
38
  DB_PORT: z.coerce.number().int().positive().default(3306),
@@ -27,6 +41,7 @@ export const databaseEnv = z.object({
27
41
  DB_NAME: z.string().min(1),
28
42
  DB_POOL_MAX: z.coerce.number().int().positive().default(10),
29
43
  });
44
+ /** RabbitMQ connection and queue-prefix env vars. */
30
45
  export const messagingEnv = z.object({
31
46
  RABBITMQ_URL: z.string().optional(),
32
47
  RABBITMQ_HOST: z.string().default('127.0.0.1'),
@@ -38,20 +53,39 @@ export const messagingEnv = z.object({
38
53
  QUEUE_PREFIX: z.string().default('dev'),
39
54
  RABBITMQ_ENABLED: z.enum(['true', 'false']).default('true').transform((v) => v === 'true'),
40
55
  });
56
+ /** Redis connection env vars. Keys are prefixed by the keyspace (`createRedisKeyspace`), never by the client. */
41
57
  export const redisEnv = z.object({
58
+ /** Full connection URL; overrides host/port/password when set. */
42
59
  REDIS_URL: z.string().optional(),
60
+ REDIS_HOST: z.string().default('127.0.0.1'),
61
+ REDIS_PORT: z.coerce.number().int().positive().default(6379),
62
+ REDIS_PASSWORD: z.string().optional(),
43
63
  REDIS_DB: z.coerce.number().int().min(0).default(0),
44
- /** Key prefix, e.g. `app:dev:` — never share one between apps or environments. */
45
- REDIS_PREFIX: z.string().default(''),
64
+ /**
65
+ * Environment segment of every Redis key (`{app}:{env}:{service}:…`), e.g. `dev`, `staging`, `prod`.
66
+ * Required in staging and production; never share one between environments.
67
+ */
68
+ CACHE_KEY_PREFIX: z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).optional(),
46
69
  });
47
- /** Builds an AMQP URL from discrete env vars (or returns RABBITMQ_URL when set). */
70
+ /**
71
+ * Builds an AMQP URL from discrete env vars (or returns RABBITMQ_URL when set). User, password and vhost are URL-encoded.
72
+ *
73
+ * @param env Parsed {@link messagingEnv} values.
74
+ * @returns An `amqp://` URL.
75
+ * @example const url = amqpUrlFromEnv(parseEnv(messagingEnv));
76
+ */
48
77
  export function amqpUrlFromEnv(env) {
49
78
  if (env.RABBITMQ_URL)
50
79
  return env.RABBITMQ_URL;
51
80
  const vhost = env.RABBITMQ_VHOST === '/' ? '%2F' : encodeURIComponent(env.RABBITMQ_VHOST.replace(/^\//, ''));
52
81
  return `amqp://${encodeURIComponent(env.RABBITMQ_USER)}:${encodeURIComponent(env.RABBITMQ_PASSWORD)}@${env.RABBITMQ_HOST}:${env.RABBITMQ_PORT}/${vhost}`;
53
82
  }
54
- /** Reads `KEY=value` lines from a dotenv file into process.env without overriding set values. */
83
+ /**
84
+ * Reads `KEY=value` lines from a dotenv file into process.env without overriding set values. Missing file is a no-op.
85
+ *
86
+ * @param path Dotenv file (default `./.env`).
87
+ * @example loadDotEnv(resolve(__dirname, '../.env.test'));
88
+ */
55
89
  export function loadDotEnv(path = resolve(process.cwd(), '.env')) {
56
90
  if (!existsSync(path))
57
91
  return;
@@ -70,19 +104,102 @@ export function loadDotEnv(path = resolve(process.cwd(), '.env')) {
70
104
  process.env[key] = value;
71
105
  }
72
106
  }
107
+ /** Thrown by the env loader when required variables are missing or invalid; lists every problem. */
73
108
  export class ConfigError extends Error {
74
109
  }
75
- /** Loads `.env` (if present) and validates process.env. Throws ConfigError listing every problem. */
76
- export function loadEnv(schema, source = process.env, options = {}) {
110
+ /**
111
+ * The base environment every service validates: service identity, gateway secret, database, Redis,
112
+ * RabbitMQ and internal-service credentials. `loadEnv` merges a service's own schema onto it.
113
+ */
114
+ export const baseEnv = serviceEnv.merge(databaseEnv).merge(redisEnv).merge(messagingEnv).merge(internalServiceEnv);
115
+ /** Variables that have a development default but must be set explicitly in staging and production. */
116
+ export const DEPLOYED_REQUIRED_ENV = Object.freeze(['CACHE_KEY_PREFIX', 'QUEUE_PREFIX']);
117
+ const DEPLOYED_NODE_ENVS = new Set(['staging', 'production']);
118
+ /**
119
+ * True for NODE_ENV values that must name their environments explicitly (staging, production).
120
+ *
121
+ * @param nodeEnv NODE_ENV value (default `process.env.NODE_ENV`).
122
+ * @returns Whether it is a deployed environment.
123
+ * @example isDeployedNodeEnv('production') // true
124
+ */
125
+ export function isDeployedNodeEnv(nodeEnv = process.env.NODE_ENV) {
126
+ return DEPLOYED_NODE_ENVS.has((nodeEnv ?? '').trim());
127
+ }
128
+ function collectProblems(issues, source) {
129
+ const byName = new Map();
130
+ for (const issue of issues) {
131
+ const name = String(issue.path[0] ?? '(root)');
132
+ const raw = source[name];
133
+ byName.set(name, { name, problem: raw === undefined || raw === '' ? 'missing' : 'invalid' });
134
+ }
135
+ return [...byName.values()];
136
+ }
137
+ function deployedProblems(source, required) {
138
+ if (!isDeployedNodeEnv(source.NODE_ENV))
139
+ return [];
140
+ return required.filter((name) => !source[name]?.trim()).map((name) => ({ name, problem: 'missing' }));
141
+ }
142
+ /**
143
+ * Formats problems as `NAME: missing|invalid` lines (names only — values are never printed, because
144
+ * Zod's own messages can echo them).
145
+ *
146
+ * @param problems Problems from validation.
147
+ * @returns A multi-line message.
148
+ * @example formatEnvProblems([{ name: 'DB_NAME', problem: 'missing' }]) // 'Invalid environment configuration:\n DB_NAME: missing'
149
+ */
150
+ export function formatEnvProblems(problems) {
151
+ return `Invalid environment configuration:\n${problems.map((p) => ` ${p.name}: ${p.problem}`).join('\n')}`;
152
+ }
153
+ /**
154
+ * Validates `source` against `schema` without merging the base or exiting. Use for partial configs
155
+ * (scripts, tests) and wherever the caller handles the error.
156
+ *
157
+ * @param schema Any Zod schema over the env object.
158
+ * @param source Values to validate (default process.env).
159
+ * @param options Dotenv and deployed-environment checks.
160
+ * @returns The parsed, typed config.
161
+ * @throws ConfigError listing every missing or invalid variable by name (never its value).
162
+ * @example const env = parseEnv(databaseEnv, { DB_NAME: 'app_test' });
163
+ */
164
+ export function parseEnv(schema, source = process.env, options = {}) {
77
165
  if (options.dotenv !== false && source === process.env)
78
166
  loadDotEnv();
79
167
  const result = schema.safeParse(source);
80
- if (!result.success) {
81
- const lines = result.error.issues.map((i) => ` ${i.path.join('.')}: ${i.message}`).join('\n');
82
- throw new ConfigError(`Invalid environment configuration:\n${lines}`);
83
- }
168
+ const problems = [...(result.success ? [] : collectProblems(result.error.issues, source)), ...deployedProblems(source, options.deployedRequired ?? DEPLOYED_REQUIRED_ENV)];
169
+ const unique = [...new Map(problems.map((p) => [p.name, p])).values()];
170
+ if (unique.length || !result.success)
171
+ throw new ConfigError(formatEnvProblems(unique));
84
172
  return result.data;
85
173
  }
86
- /** Comma-separated env value → trimmed, non-empty list. */
174
+ /**
175
+ * Service startup config: merges the base env schema with the service's own, validates, and on
176
+ * failure prints the missing/invalid variable **names** (never values) and exits non-zero.
177
+ *
178
+ * @param schema The service's own variables (default none).
179
+ * @param options Source, base override and injectable write/exit for tests.
180
+ * @returns The parsed, typed config (base + service variables).
181
+ * @example
182
+ * export const config = loadEnv(z.object({ UPSTREAM_INTERNAL_URL: z.string().url() }));
183
+ */
184
+ export function loadEnv(schema, options = {}) {
185
+ const base = (options.base ?? baseEnv);
186
+ const merged = schema ? base.merge(schema) : base;
187
+ try {
188
+ return parseEnv(merged, options.source ?? process.env, options);
189
+ }
190
+ catch (error) {
191
+ if (!(error instanceof ConfigError))
192
+ throw error;
193
+ (options.write ?? ((text) => process.stderr.write(text)))(`${error.message}\n`);
194
+ return (options.exit ?? ((code) => process.exit(code)))(1);
195
+ }
196
+ }
197
+ /**
198
+ * Comma-separated env value → trimmed, non-empty list.
199
+ *
200
+ * @param value Raw env value.
201
+ * @returns The list (empty when unset).
202
+ * @example listFromEnv(' a, b ,,c') // ['a', 'b', 'c']
203
+ */
87
204
  export const listFromEnv = (value) => (value ?? '').split(',').map((s) => s.trim()).filter(Boolean);
88
205
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ const storage = new AsyncLocalStorage();
3
+ /**
4
+ * Runs `fn` (and all async work it starts) inside `context`. Use it at every entry point that is not an
5
+ * HTTP request: queue consumers, jobs and scripts.
6
+ *
7
+ * @param context Values for the duration of `fn`; the object is copied, so later edits don't leak back.
8
+ * @param fn Work to run inside the context.
9
+ * @returns Whatever `fn` returns.
10
+ * @example await runWithContext({ correlationId: msg.correlationId, service: 'worker' }, () => handle(msg));
11
+ */
12
+ export function runWithContext(context, fn) {
13
+ return storage.run({ ...context, scopes: context.scopes ? { ...context.scopes } : undefined }, fn);
14
+ }
15
+ /**
16
+ * The current request context.
17
+ *
18
+ * @returns The context, or undefined outside {@link runWithContext} / `correlationMiddleware`.
19
+ * @example const id = getRequestContext()?.correlationId;
20
+ */
21
+ export function getRequestContext() {
22
+ return storage.getStore();
23
+ }
24
+ /**
25
+ * Adds values to the current context, for example the user id and scopes once auth has run. A no-op
26
+ * outside a context. The correlation id can't be changed once set.
27
+ *
28
+ * @param patch Values to add or replace; `scopes` are merged key by key.
29
+ * @returns True when a context was active and updated.
30
+ * @example updateRequestContext({ userId: user.id, scopes: user.scopes });
31
+ */
32
+ export function updateRequestContext(patch) {
33
+ const current = storage.getStore();
34
+ if (!current)
35
+ return false;
36
+ if (patch.service !== undefined)
37
+ current.service = patch.service;
38
+ if (patch.userId !== undefined)
39
+ current.userId = patch.userId;
40
+ if (patch.scopes)
41
+ current.scopes = { ...current.scopes, ...patch.scopes };
42
+ return true;
43
+ }
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAerD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAkB,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAI,OAAuB,EAAE,EAAW;IACpE,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;AACrG,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAqD;IACxF,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IACnC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IACjE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9D,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,CAAC,MAAM,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;IAC1E,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1,4 +1,2 @@
1
- export * from './editorial-draft.js';
2
1
  export * from './notification-dispatch.js';
3
- export * from './upload-import.js';
4
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
@@ -1,89 +1,112 @@
1
+ /**
2
+ * Notification dispatch: a generic command contract (shared plumbing, no app vocabulary).
3
+ *
4
+ * Services never send email, SMS or push themselves. They stage one dispatch command (default
5
+ * `notification:dispatch`) through their outbox, and the app's notification-service renders a seeded
6
+ * template and delivers it. Both sides build their schema from {@link createNotificationDispatchSchema},
7
+ * so producers and the consumer cannot drift.
8
+ *
9
+ * App-specific parts are parameters: the app passes its own categories (e.g. `security`, `order`) and
10
+ * channels (e.g. `email`, `sms`, `in_app`). Template slugs and their variables also belong to the app
11
+ * (keep a table next to the notification-service seeds and test both sides against it).
12
+ */
1
13
  import { z } from 'zod';
2
14
  /**
3
- * `notification:dispatch` — the one command every Showbiz service stages (through its outbox) to have
4
- * notification-service render a seeded template and deliver it by email and/or the in-app feed. No
5
- * other service sends email itself. One contract for both sides: producers type their payload with it
6
- * and notification-service validates against it, so the two cannot drift.
15
+ * Default command name for a dispatch. An app may use another name and pass it to its producers.
16
+ *
17
+ * @example await outbox.command(tx, NOTIFICATION_DISPATCH, dispatch, { correlationId });
7
18
  */
8
19
  export const NOTIFICATION_DISPATCH = 'notification:dispatch';
9
- /** Channels a dispatch may ask for. `in_app` needs a recipient `userId` (the bell feed is per user). */
10
- export const DISPATCH_CHANNELS = ['email', 'in_app'];
11
20
  /**
12
- * What a dispatch is about. Account mail (`security`, `account`, `team`, `marketing`) goes to a user;
13
- * `staff` is an operational alert to a configured staff address.
21
+ * Size limits that keep a dispatch small enough for a queue message and safe to render.
22
+ *
23
+ * @example z.string().max(DISPATCH_LIMITS.template)
14
24
  */
15
- export const NOTIFICATION_CATEGORIES = ['security', 'account', 'team', 'marketing', 'staff'];
16
25
  export const DISPATCH_LIMITS = {
17
26
  template: 100,
18
27
  email: 254,
19
28
  name: 200,
29
+ userId: 36,
20
30
  dataKeys: 40,
21
31
  dataKey: 64,
22
32
  dataValue: 2000,
23
33
  secretKeys: 10,
24
34
  permission: 100,
25
35
  };
26
- /** Template variables are flat scalars: they are printed into the copy, never serialised objects. */
36
+ /**
37
+ * Template variables are flat scalars: they are printed into the copy, never serialised objects.
38
+ *
39
+ * @example dispatchValueSchema.parse('1250.00')
40
+ */
27
41
  export const dispatchValueSchema = z.union([z.string().max(DISPATCH_LIMITS.dataValue), z.number().finite(), z.boolean(), z.null()]);
42
+ /**
43
+ * Who receives a dispatch. `userId` is needed for per-user channels such as an in-app feed;
44
+ * addresses with no account behind them carry only `email`.
45
+ *
46
+ * @example { email: 'ada@example.com', name: 'Ada', userId: '01J…', timezone: 'Europe/Lisbon' }
47
+ */
28
48
  export const dispatchRecipientSchema = z.object({
29
49
  email: z.string().trim().email().max(DISPATCH_LIMITS.email),
30
50
  name: z.string().trim().max(DISPATCH_LIMITS.name).optional(),
31
- userId: z.string().max(36).nullish(),
51
+ userId: z.string().max(DISPATCH_LIMITS.userId).nullish(),
32
52
  locale: z.string().max(20).nullish(),
33
53
  /** IANA zone; time variables are rendered in it. */
34
54
  timezone: z.string().max(64).nullish(),
35
55
  });
36
- const dataKey = z.string().regex(/^[A-Za-z][A-Za-z0-9_]*$/, 'Use a template variable name').max(DISPATCH_LIMITS.dataKey);
37
- export const notificationDispatchSchema = z
38
- .object({
39
- /** Seeded `notification_templates.slug`. */
40
- template: z.string().trim().min(1).max(DISPATCH_LIMITS.template),
41
- category: z.enum(NOTIFICATION_CATEGORIES),
42
- recipient: dispatchRecipientSchema,
43
- channels: z.array(z.enum(DISPATCH_CHANNELS)).min(1).max(DISPATCH_CHANNELS.length),
44
- data: z
45
- .record(dataKey, dispatchValueSchema)
46
- .default({})
47
- .refine((data) => Object.keys(data).length <= DISPATCH_LIMITS.dataKeys, `At most ${DISPATCH_LIMITS.dataKeys} variables`),
48
- /**
49
- * Keys of `data` holding a one-time secret (a sign-in code, a reset or confirm link). They are used to
50
- * render the email and nothing else: notification-service never stores them and never puts them in the
51
- * in-app feed, and email-service masks them in what it keeps.
52
- */
53
- secretKeys: z.array(dataKey).max(DISPATCH_LIMITS.secretKeys).default([]),
54
- /** Security and staff alerts are always delivered, whatever the recipient's preferences. */
55
- bypassPreferences: z.boolean().optional(),
56
- /** The permission staff recipients hold; informational until recipients are resolved by permission. */
57
- targetPermission: z.string().max(DISPATCH_LIMITS.permission).optional(),
58
- })
59
- .superRefine((dispatch, ctx) => {
60
- for (const key of dispatch.secretKeys) {
61
- if (!(key in dispatch.data)) {
62
- ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['secretKeys'], message: `Secret key "${key}" is not in data` });
63
- }
64
- }
65
- });
66
56
  /**
67
- * The seeded templates Showbiz services dispatch, with the variables (`data` keys) each dispatch carries.
68
- * Producers send exactly these keys; a seeded template may use any subset (notification-service dead-letters
69
- * a dispatch missing a variable its template uses). Both sides test against this table.
57
+ * A template variable name the renderer can match.
58
+ *
59
+ * @example dispatchDataKeySchema.parse('expiresInMinutes')
70
60
  */
71
- export const DISPATCH_TEMPLATE_VARIABLES = {
72
- // auth-admin-service: account and security mail
73
- 'account-activation': ['name', 'code', 'expiresInHours'],
74
- 'login-otp': ['name', 'code', 'expiresInMinutes', 'device'],
75
- 'password-reset': ['name', 'resetUrl', 'expiresInMinutes'],
76
- 'staff-invitation': ['name', 'resetUrl', 'expiresInMinutes'],
77
- 'password-changed': ['name', 'changedAt'],
78
- 'new-device-login': ['name', 'device', 'ip', 'country', 'occurredAt', 'confirmUrl', 'disputeUrl'],
79
- 'team-member-added': ['name', 'profileName', 'role', 'invitedBy'],
80
- 'account-suspended': ['name', 'reason'],
81
- 'welcome-listener': ['name'],
82
- 'welcome-creator': ['name'],
83
- // ai / newswire / editorial: staff alerts
84
- 'ai_budget_threshold': ['requester', 'period', 'threshold_pct', 'spent_usd', 'limit_usd'],
85
- 'newswire_source_unhealthy': ['source_name', 'source_slug', 'consecutive_failures', 'last_error', 'last_success_at'],
86
- 'newswire_block_rate_high': ['blocked', 'total', 'block_rate_pct', 'window_hours'],
87
- 'autopublish_audit_alert': ['problem_rate_pct', 'problem_count', 'sample_count', 'window_days', 'action_taken'],
88
- };
61
+ export const dispatchDataKeySchema = z.string().regex(/^[A-Za-z][A-Za-z0-9_]*$/, 'Use a template variable name').max(DISPATCH_LIMITS.dataKey);
62
+ /**
63
+ * Build the dispatch schema for an app's categories and channels. Producers type their payload with it;
64
+ * the notification-service validates incoming commands with the same schema.
65
+ *
66
+ * Rules every app gets: a seeded `template` slug; one or more distinct channels; at most 40 flat-scalar `data`
67
+ * variables with renderer-safe names; `secretKeys` (one-time codes, reset links) must be keys of `data`;
68
+ * the consumer must use them only to render, never store them or show them in a feed.
69
+ *
70
+ * @typeParam C The app's categories (inferred as literals).
71
+ * @typeParam Ch The app's channels (inferred as literals).
72
+ * @param vocabulary The app's categories and channels.
73
+ * @returns A Zod schema; `data` defaults to `{}` and `secretKeys` to `[]`.
74
+ * @example
75
+ * export const dispatchSchema = createNotificationDispatchSchema({
76
+ * categories: ['security', 'account', 'order', 'staff'],
77
+ * channels: ['email', 'sms'],
78
+ * });
79
+ * export type Dispatch = z.input<typeof dispatchSchema>;
80
+ */
81
+ export function createNotificationDispatchSchema(vocabulary) {
82
+ return z
83
+ .object({
84
+ /** Seeded template slug in the notification-service. */
85
+ template: z.string().trim().min(1).max(DISPATCH_LIMITS.template),
86
+ category: z.enum([...vocabulary.categories]),
87
+ recipient: dispatchRecipientSchema,
88
+ channels: z
89
+ .array(z.enum([...vocabulary.channels]))
90
+ .min(1)
91
+ .max(vocabulary.channels.length)
92
+ .refine((channels) => new Set(channels).size === channels.length, 'Each channel at most once'),
93
+ data: z
94
+ .record(dispatchDataKeySchema, dispatchValueSchema)
95
+ .default({})
96
+ .refine((data) => Object.keys(data).length <= DISPATCH_LIMITS.dataKeys, `At most ${DISPATCH_LIMITS.dataKeys} variables`),
97
+ /** Keys of `data` holding a one-time secret: used to render, never stored or shown in a feed. */
98
+ secretKeys: z.array(dispatchDataKeySchema).max(DISPATCH_LIMITS.secretKeys).default([]),
99
+ /** Deliver whatever the recipient's notification preferences say (for mail the recipient cannot opt out of). */
100
+ bypassPreferences: z.boolean().optional(),
101
+ /** The permission the recipients were resolved by, when they were (traceability only). */
102
+ targetPermission: z.string().max(DISPATCH_LIMITS.permission).optional(),
103
+ })
104
+ .superRefine((dispatch, ctx) => {
105
+ for (const key of dispatch.secretKeys) {
106
+ if (!(key in dispatch.data)) {
107
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['secretKeys'], message: `Secret key "${key}" is not in data` });
108
+ }
109
+ }
110
+ });
111
+ }
89
112
  //# sourceMappingURL=notification-dispatch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"notification-dispatch.js","sourceRoot":"","sources":["../../../src/contracts/notification-dispatch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"notification-dispatch.js","sourceRoot":"","sources":["../../../src/contracts/notification-dispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { drizzle } from 'drizzle-orm/mysql2';
2
+ import { createKnexConfig, createMysqlPool, pingMysql } from './pool.js';
3
+ /**
4
+ * Creates the service's Drizzle database. There is no module-level singleton: call it once in
5
+ * `container.ts` and inject `db` into repositories.
6
+ *
7
+ * @example const { db, ping, close } = createDb({ env: config, schema });
8
+ */
9
+ export function createDb(options) {
10
+ const { env, schema } = options;
11
+ const pool = options.pool ?? createMysqlPool(connectionOptions(env));
12
+ const db = drizzle(pool, { schema, mode: 'default' });
13
+ return {
14
+ db,
15
+ ping: () => pingMysql(pool),
16
+ close: () => pool.end(),
17
+ };
18
+ }
19
+ /**
20
+ * Knex config for a service's `knexfile.js`. Knex runs **migrations and seeds only** (`.cjs` files
21
+ * in `./migrations` and `./seeds`); repositories use Drizzle.
22
+ *
23
+ * @example module.exports = knexConfig(config);
24
+ */
25
+ export function knexConfig(env) {
26
+ return createKnexConfig(connectionOptions(env));
27
+ }
28
+ /** Maps the validated `DB_*` env to connection options. */
29
+ export function connectionOptions(env) {
30
+ return { host: env.DB_HOST, port: env.DB_PORT, user: env.DB_USER, password: env.DB_PASSWORD, database: env.DB_NAME, poolMax: env.DB_POOL_MAX };
31
+ }
32
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/database/db.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAuB,MAAM,oBAAoB,CAAC;AAIlE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAA+B,MAAM,WAAW,CAAC;AA8BtG;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAA0C,OAAiC;IACjG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAsB,CAAC;IAC3E,OAAO;QACL,EAAE;QACF,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;QAC3B,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;KACxB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,GAAgB;IACzC,OAAO,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,iBAAiB,CAAC,GAAgB;IAChD,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC;AACjJ,CAAC"}
@@ -1,48 +1,12 @@
1
- import mysql from 'mysql2/promise';
2
1
  /**
3
- * mysql2 pool for Drizzle. Sessions run in UTC and utf8mb4 so timestamps and emoji round-trip
4
- * unchanged regardless of server defaults.
2
+ * `@heavybit/shared-lib/database`: Drizzle data access for services. Repositories use Drizzle
3
+ * through {@link ScopedRepository} and the scopes in `scopes.ts`; raw scoped queries and Knex in
4
+ * `src/` are forbidden. Knex is for migrations and seeds only (`knexConfig`, `@heavybit/shared-lib/knex`).
5
5
  */
6
- export function createMysqlPool(options) {
7
- return mysql.createPool({
8
- host: options.host,
9
- port: options.port,
10
- user: options.user,
11
- password: options.password,
12
- database: options.database,
13
- connectionLimit: options.poolMax ?? 10,
14
- waitForConnections: true,
15
- enableKeepAlive: true,
16
- timezone: 'Z',
17
- charset: 'utf8mb4_unicode_ci',
18
- dateStrings: false,
19
- supportBigNumbers: true,
20
- });
21
- }
22
- /** Knex config for migrations/seeds and query-builder use (same session settings as the pool). */
23
- export function createKnexConfig(options) {
24
- return {
25
- client: 'mysql2',
26
- connection: {
27
- host: options.host,
28
- port: options.port,
29
- user: options.user,
30
- password: options.password,
31
- database: options.database,
32
- timezone: 'Z',
33
- charset: 'utf8mb4',
34
- },
35
- pool: { min: 0, max: options.poolMax ?? 10 },
36
- migrations: { directory: options.migrationsDir ?? './migrations', tableName: 'knex_migrations', loadExtensions: ['.cjs', '.js'] },
37
- seeds: { directory: options.seedsDir ?? './seeds', loadExtensions: ['.cjs', '.js'] },
38
- };
39
- }
40
- /** Readiness probe helper. */
41
- export async function pingMysql(pool) {
42
- await pool.query('SELECT 1');
43
- }
44
- /** Escapes `%`, `_` and `\` for use inside a LIKE pattern. */
45
- export function escapeLike(value) {
46
- return value.replace(/[\\%_]/g, (ch) => `\\${ch}`);
47
- }
6
+ export * from './pool.js';
7
+ export * from './db.js';
8
+ export * from './scopes.js';
9
+ export * from './scoped-repository.js';
10
+ export * from './pagination.js';
11
+ export * from './tables.js';
48
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/database/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,gBAAgB,CAAC;AAWnC;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAA+B;IAC7D,OAAO,KAAK,CAAC,UAAU,CAAC;QACtB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,eAAe,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;QACtC,kBAAkB,EAAE,IAAI;QACxB,eAAe,EAAE,IAAI;QACrB,QAAQ,EAAE,GAAG;QACb,OAAO,EAAE,oBAAoB;QAC7B,WAAW,EAAE,KAAK;QAClB,iBAAiB,EAAE,IAAI;KACxB,CAAC,CAAC;AACL,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,gBAAgB,CAAC,OAA+E;IAC9G,OAAO;QACL,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE;YACV,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,GAAG;YACb,OAAO,EAAE,SAAS;SACnB;QACD,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE;QAC5C,UAAU,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,aAAa,IAAI,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;QACjI,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,IAAI,SAAS,EAAE,cAAc,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;KACrF,CAAC;AACJ,CAAC;AAED,8BAA8B;AAC9B,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAgB;IAC9C,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAC/B,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/database/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}