@ddd-ts-kit/kernel 0.7.0 → 0.9.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 (367) hide show
  1. package/README.md +111 -9
  2. package/dist/application/audit/tenant-scope-of.d.ts +4 -1
  3. package/dist/application/audit/tenant-scope-of.d.ts.map +1 -1
  4. package/dist/application/audit/tenant-scope-of.js +6 -2
  5. package/dist/application/audit/tenant-scope-of.js.map +1 -1
  6. package/dist/application/cache/tenant-cache-key.d.ts +5 -0
  7. package/dist/application/cache/tenant-cache-key.d.ts.map +1 -0
  8. package/dist/application/cache/tenant-cache-key.js +7 -0
  9. package/dist/application/cache/tenant-cache-key.js.map +1 -0
  10. package/dist/application/events/execution-context-of-event.d.ts +2 -1
  11. package/dist/application/events/execution-context-of-event.d.ts.map +1 -1
  12. package/dist/application/events/execution-context-of-event.js +3 -1
  13. package/dist/application/events/execution-context-of-event.js.map +1 -1
  14. package/dist/application/events/integration-event.d.ts +6 -0
  15. package/dist/application/events/integration-event.d.ts.map +1 -1
  16. package/dist/application/events/scoped-publisher.d.ts +4 -3
  17. package/dist/application/events/scoped-publisher.d.ts.map +1 -1
  18. package/dist/application/events/scoped-publisher.js +11 -5
  19. package/dist/application/events/scoped-publisher.js.map +1 -1
  20. package/dist/application/execution/execution-context.d.ts +7 -1
  21. package/dist/application/execution/execution-context.d.ts.map +1 -1
  22. package/dist/application/execution/execution-context.js +7 -2
  23. package/dist/application/execution/execution-context.js.map +1 -1
  24. package/dist/application/execution/log-fields-of.d.ts.map +1 -1
  25. package/dist/application/execution/log-fields-of.js +1 -0
  26. package/dist/application/execution/log-fields-of.js.map +1 -1
  27. package/dist/application/files/accepts-media-type.d.ts +3 -0
  28. package/dist/application/files/accepts-media-type.d.ts.map +1 -0
  29. package/dist/application/files/accepts-media-type.js +11 -0
  30. package/dist/application/files/accepts-media-type.js.map +1 -0
  31. package/dist/application/files/assert-expiry.d.ts +3 -0
  32. package/dist/application/files/assert-expiry.d.ts.map +1 -0
  33. package/dist/application/files/assert-expiry.js +10 -0
  34. package/dist/application/files/assert-expiry.js.map +1 -0
  35. package/dist/application/files/assert-file-key.d.ts +3 -0
  36. package/dist/application/files/assert-file-key.d.ts.map +1 -0
  37. package/dist/application/files/assert-file-key.js +10 -0
  38. package/dist/application/files/assert-file-key.js.map +1 -0
  39. package/dist/application/files/assert-final-key.d.ts +3 -0
  40. package/dist/application/files/assert-final-key.d.ts.map +1 -0
  41. package/dist/application/files/assert-final-key.js +11 -0
  42. package/dist/application/files/assert-final-key.js.map +1 -0
  43. package/dist/application/files/content-disposition.d.ts +3 -0
  44. package/dist/application/files/content-disposition.d.ts.map +1 -0
  45. package/dist/application/files/content-disposition.js +9 -0
  46. package/dist/application/files/content-disposition.js.map +1 -0
  47. package/dist/application/files/content-expectation.d.ts +6 -0
  48. package/dist/application/files/content-expectation.d.ts.map +1 -0
  49. package/dist/application/files/content-expectation.js +2 -0
  50. package/dist/application/files/content-expectation.js.map +1 -0
  51. package/dist/application/files/content-matches.d.ts +7 -0
  52. package/dist/application/files/content-matches.d.ts.map +1 -0
  53. package/dist/application/files/content-matches.js +39 -0
  54. package/dist/application/files/content-matches.js.map +1 -0
  55. package/dist/application/files/download-url-options.d.ts +7 -0
  56. package/dist/application/files/download-url-options.d.ts.map +1 -0
  57. package/dist/application/files/download-url-options.js +2 -0
  58. package/dist/application/files/download-url-options.js.map +1 -0
  59. package/dist/application/files/file-content.d.ts +8 -0
  60. package/dist/application/files/file-content.d.ts.map +1 -0
  61. package/dist/application/files/file-content.js +2 -0
  62. package/dist/application/files/file-content.js.map +1 -0
  63. package/dist/application/files/file-error.d.ts +28 -0
  64. package/dist/application/files/file-error.d.ts.map +1 -0
  65. package/dist/application/files/file-error.js +29 -0
  66. package/dist/application/files/file-error.js.map +1 -0
  67. package/dist/application/files/file-metadata.d.ts +10 -0
  68. package/dist/application/files/file-metadata.d.ts.map +1 -0
  69. package/dist/application/files/file-metadata.js +2 -0
  70. package/dist/application/files/file-metadata.js.map +1 -0
  71. package/dist/application/files/file-source.d.ts +4 -0
  72. package/dist/application/files/file-source.d.ts.map +1 -0
  73. package/dist/application/files/file-source.js +2 -0
  74. package/dist/application/files/file-source.js.map +1 -0
  75. package/dist/application/files/file-upload.d.ts +25 -0
  76. package/dist/application/files/file-upload.d.ts.map +1 -0
  77. package/dist/application/files/file-upload.js +36 -0
  78. package/dist/application/files/file-upload.js.map +1 -0
  79. package/dist/application/files/index.d.ts +31 -0
  80. package/dist/application/files/index.d.ts.map +1 -0
  81. package/dist/application/files/index.js +31 -0
  82. package/dist/application/files/index.js.map +1 -0
  83. package/dist/application/files/inspection-limits.d.ts +8 -0
  84. package/dist/application/files/inspection-limits.d.ts.map +1 -0
  85. package/dist/application/files/inspection-limits.js +2 -0
  86. package/dist/application/files/inspection-limits.js.map +1 -0
  87. package/dist/application/files/is-file-key.d.ts +7 -0
  88. package/dist/application/files/is-file-key.d.ts.map +1 -0
  89. package/dist/application/files/is-file-key.js +11 -0
  90. package/dist/application/files/is-file-key.js.map +1 -0
  91. package/dist/application/files/listed-file.d.ts +7 -0
  92. package/dist/application/files/listed-file.d.ts.map +1 -0
  93. package/dist/application/files/listed-file.js +2 -0
  94. package/dist/application/files/listed-file.js.map +1 -0
  95. package/dist/application/files/max-signed-url-seconds.d.ts +3 -0
  96. package/dist/application/files/max-signed-url-seconds.d.ts.map +1 -0
  97. package/dist/application/files/max-signed-url-seconds.js +3 -0
  98. package/dist/application/files/max-signed-url-seconds.js.map +1 -0
  99. package/dist/application/files/media-type-of.d.ts +3 -0
  100. package/dist/application/files/media-type-of.d.ts.map +1 -0
  101. package/dist/application/files/media-type-of.js +5 -0
  102. package/dist/application/files/media-type-of.js.map +1 -0
  103. package/dist/application/files/pending-upload-link.d.ts +10 -0
  104. package/dist/application/files/pending-upload-link.d.ts.map +1 -0
  105. package/dist/application/files/pending-upload-link.js +2 -0
  106. package/dist/application/files/pending-upload-link.js.map +1 -0
  107. package/dist/application/files/pending-upload.d.ts +15 -0
  108. package/dist/application/files/pending-upload.d.ts.map +1 -0
  109. package/dist/application/files/pending-upload.js +2 -0
  110. package/dist/application/files/pending-upload.js.map +1 -0
  111. package/dist/application/files/put-options.d.ts +7 -0
  112. package/dist/application/files/put-options.d.ts.map +1 -0
  113. package/dist/application/files/put-options.js +2 -0
  114. package/dist/application/files/put-options.js.map +1 -0
  115. package/dist/application/files/received-file.d.ts +15 -0
  116. package/dist/application/files/received-file.d.ts.map +1 -0
  117. package/dist/application/files/received-file.js +2 -0
  118. package/dist/application/files/received-file.js.map +1 -0
  119. package/dist/application/files/scan-verdict.d.ts +8 -0
  120. package/dist/application/files/scan-verdict.d.ts.map +1 -0
  121. package/dist/application/files/scan-verdict.js +2 -0
  122. package/dist/application/files/scan-verdict.js.map +1 -0
  123. package/dist/application/files/signature-of.d.ts +3 -0
  124. package/dist/application/files/signature-of.d.ts.map +1 -0
  125. package/dist/application/files/signature-of.js +28 -0
  126. package/dist/application/files/signature-of.js.map +1 -0
  127. package/dist/application/files/signed-download.d.ts +6 -0
  128. package/dist/application/files/signed-download.d.ts.map +1 -0
  129. package/dist/application/files/signed-download.js +2 -0
  130. package/dist/application/files/signed-download.js.map +1 -0
  131. package/dist/application/files/signed-upload.d.ts +9 -0
  132. package/dist/application/files/signed-upload.d.ts.map +1 -0
  133. package/dist/application/files/signed-upload.js +2 -0
  134. package/dist/application/files/signed-upload.js.map +1 -0
  135. package/dist/application/files/signed-url.d.ts +6 -0
  136. package/dist/application/files/signed-url.d.ts.map +1 -0
  137. package/dist/application/files/signed-url.js +2 -0
  138. package/dist/application/files/signed-url.js.map +1 -0
  139. package/dist/application/files/staged-key-of.d.ts +5 -0
  140. package/dist/application/files/staged-key-of.d.ts.map +1 -0
  141. package/dist/application/files/staged-key-of.js +7 -0
  142. package/dist/application/files/staged-key-of.js.map +1 -0
  143. package/dist/application/files/stored-file.d.ts +16 -0
  144. package/dist/application/files/stored-file.d.ts.map +1 -0
  145. package/dist/application/files/stored-file.js +2 -0
  146. package/dist/application/files/stored-file.js.map +1 -0
  147. package/dist/application/files/upload-url-options.d.ts +12 -0
  148. package/dist/application/files/upload-url-options.d.ts.map +1 -0
  149. package/dist/application/files/upload-url-options.js +2 -0
  150. package/dist/application/files/upload-url-options.js.map +1 -0
  151. package/dist/application/ports/file-keys.d.ts +9 -0
  152. package/dist/application/ports/file-keys.d.ts.map +1 -0
  153. package/dist/application/ports/file-keys.js +10 -0
  154. package/dist/application/ports/file-keys.js.map +1 -0
  155. package/dist/application/ports/file-scanner.d.ts +13 -0
  156. package/dist/application/ports/file-scanner.d.ts.map +1 -0
  157. package/dist/application/ports/file-scanner.js +12 -0
  158. package/dist/application/ports/file-scanner.js.map +1 -0
  159. package/dist/application/ports/file-storage.d.ts +40 -0
  160. package/dist/application/ports/file-storage.d.ts.map +1 -0
  161. package/dist/application/ports/file-storage.js +15 -0
  162. package/dist/application/ports/file-storage.js.map +1 -0
  163. package/dist/application/ports/served-file-storage.d.ts +16 -0
  164. package/dist/application/ports/served-file-storage.d.ts.map +1 -0
  165. package/dist/application/ports/served-file-storage.js +12 -0
  166. package/dist/application/ports/served-file-storage.js.map +1 -0
  167. package/dist/application/ports/tenant-directory.d.ts +8 -0
  168. package/dist/application/ports/tenant-directory.d.ts.map +1 -0
  169. package/dist/application/ports/tenant-directory.js +10 -0
  170. package/dist/application/ports/tenant-directory.js.map +1 -0
  171. package/dist/application/scheduling/execution-context-of-job.d.ts +3 -1
  172. package/dist/application/scheduling/execution-context-of-job.d.ts.map +1 -1
  173. package/dist/application/scheduling/execution-context-of-job.js +1 -1
  174. package/dist/application/scheduling/execution-context-of-job.js.map +1 -1
  175. package/dist/application/scheduling/job-execution.d.ts +2 -0
  176. package/dist/application/scheduling/job-execution.d.ts.map +1 -1
  177. package/dist/application/scheduling/job-options.d.ts +6 -0
  178. package/dist/application/scheduling/job-options.d.ts.map +1 -1
  179. package/dist/application/scheduling/job-policy.d.ts.map +1 -1
  180. package/dist/application/scheduling/job-policy.js +4 -2
  181. package/dist/application/scheduling/job-policy.js.map +1 -1
  182. package/dist/application/session/has-scope.d.ts +5 -0
  183. package/dist/application/session/has-scope.d.ts.map +1 -0
  184. package/dist/application/session/has-scope.js +5 -0
  185. package/dist/application/session/has-scope.js.map +1 -0
  186. package/dist/application/session/session-scope.d.ts +4 -0
  187. package/dist/application/session/session-scope.d.ts.map +1 -0
  188. package/dist/application/session/session-scope.js +2 -0
  189. package/dist/application/session/session-scope.js.map +1 -0
  190. package/dist/application/session/session-scopes.d.ts +11 -0
  191. package/dist/application/session/session-scopes.d.ts.map +1 -0
  192. package/dist/application/session/session-scopes.js +2 -0
  193. package/dist/application/session/session-scopes.js.map +1 -0
  194. package/dist/application/session/session.d.ts +6 -0
  195. package/dist/application/session/session.d.ts.map +1 -1
  196. package/dist/application/tenancy/across-tenants.d.ts +12 -0
  197. package/dist/application/tenancy/across-tenants.d.ts.map +1 -0
  198. package/dist/application/tenancy/across-tenants.js +47 -0
  199. package/dist/application/tenancy/across-tenants.js.map +1 -0
  200. package/dist/application/tenancy/assert-tenant-id.d.ts +3 -0
  201. package/dist/application/tenancy/assert-tenant-id.d.ts.map +1 -0
  202. package/dist/application/tenancy/assert-tenant-id.js +10 -0
  203. package/dist/application/tenancy/assert-tenant-id.js.map +1 -0
  204. package/dist/application/tenancy/elevation-options.d.ts +12 -0
  205. package/dist/application/tenancy/elevation-options.d.ts.map +1 -0
  206. package/dist/application/tenancy/elevation-options.js +2 -0
  207. package/dist/application/tenancy/elevation-options.js.map +1 -0
  208. package/dist/application/tenancy/invalid-tenant-elevation-error.d.ts +5 -0
  209. package/dist/application/tenancy/invalid-tenant-elevation-error.d.ts.map +1 -0
  210. package/dist/application/tenancy/invalid-tenant-elevation-error.js +8 -0
  211. package/dist/application/tenancy/invalid-tenant-elevation-error.js.map +1 -0
  212. package/dist/application/tenancy/invalid-tenant-id-error.d.ts +6 -0
  213. package/dist/application/tenancy/invalid-tenant-id-error.d.ts.map +1 -0
  214. package/dist/application/tenancy/invalid-tenant-id-error.js +10 -0
  215. package/dist/application/tenancy/invalid-tenant-id-error.js.map +1 -0
  216. package/dist/application/tenancy/is-tenant-id.d.ts +3 -0
  217. package/dist/application/tenancy/is-tenant-id.d.ts.map +1 -0
  218. package/dist/application/tenancy/is-tenant-id.js +12 -0
  219. package/dist/application/tenancy/is-tenant-id.js.map +1 -0
  220. package/dist/application/tenancy/is-tenant-member.d.ts +4 -0
  221. package/dist/application/tenancy/is-tenant-member.d.ts.map +1 -0
  222. package/dist/application/tenancy/is-tenant-member.js +6 -0
  223. package/dist/application/tenancy/is-tenant-member.js.map +1 -0
  224. package/dist/application/tenancy/tenant-elevation.d.ts +11 -0
  225. package/dist/application/tenancy/tenant-elevation.d.ts.map +1 -0
  226. package/dist/application/tenancy/tenant-elevation.js +2 -0
  227. package/dist/application/tenancy/tenant-elevation.js.map +1 -0
  228. package/dist/application/tenancy/tenant-key.d.ts +9 -0
  229. package/dist/application/tenancy/tenant-key.d.ts.map +1 -0
  230. package/dist/application/tenancy/tenant-key.js +11 -0
  231. package/dist/application/tenancy/tenant-key.js.map +1 -0
  232. package/dist/application/tenancy/tenant-reach-of.d.ts +9 -0
  233. package/dist/application/tenancy/tenant-reach-of.d.ts.map +1 -0
  234. package/dist/application/tenancy/tenant-reach-of.js +18 -0
  235. package/dist/application/tenancy/tenant-reach-of.js.map +1 -0
  236. package/dist/application/tenancy/tenant-reach.d.ts +12 -0
  237. package/dist/application/tenancy/tenant-reach.d.ts.map +1 -0
  238. package/dist/application/tenancy/tenant-reach.js +2 -0
  239. package/dist/application/tenancy/tenant-reach.js.map +1 -0
  240. package/dist/application/tenancy/tenants-of.d.ts +8 -0
  241. package/dist/application/tenancy/tenants-of.d.ts.map +1 -0
  242. package/dist/application/tenancy/tenants-of.js +14 -0
  243. package/dist/application/tenancy/tenants-of.js.map +1 -0
  244. package/dist/index.d.ts +42 -0
  245. package/dist/index.d.ts.map +1 -1
  246. package/dist/index.js +42 -0
  247. package/dist/index.js.map +1 -1
  248. package/dist/infrastructure/domain-events/after-commit.d.ts +10 -0
  249. package/dist/infrastructure/domain-events/after-commit.d.ts.map +1 -0
  250. package/dist/infrastructure/domain-events/after-commit.js +19 -0
  251. package/dist/infrastructure/domain-events/after-commit.js.map +1 -0
  252. package/dist/infrastructure/domain-events/at-commit.d.ts +11 -0
  253. package/dist/infrastructure/domain-events/at-commit.d.ts.map +1 -0
  254. package/dist/infrastructure/domain-events/at-commit.js +19 -0
  255. package/dist/infrastructure/domain-events/at-commit.js.map +1 -0
  256. package/dist/infrastructure/domain-events/commit-step.d.ts +10 -0
  257. package/dist/infrastructure/domain-events/commit-step.d.ts.map +1 -0
  258. package/dist/infrastructure/domain-events/commit-step.js +2 -0
  259. package/dist/infrastructure/domain-events/commit-step.js.map +1 -0
  260. package/dist/infrastructure/domain-events/unit-of-work-scope.d.ts +5 -0
  261. package/dist/infrastructure/domain-events/unit-of-work-scope.d.ts.map +1 -1
  262. package/dist/infrastructure/domain-events/unit-of-work-scope.js.map +1 -1
  263. package/dist/infrastructure/domain-events/within-unit-of-work.d.ts +3 -1
  264. package/dist/infrastructure/domain-events/within-unit-of-work.d.ts.map +1 -1
  265. package/dist/infrastructure/domain-events/within-unit-of-work.js +32 -5
  266. package/dist/infrastructure/domain-events/within-unit-of-work.js.map +1 -1
  267. package/dist/infrastructure/files/accept-every-file-scanner.d.ts +7 -0
  268. package/dist/infrastructure/files/accept-every-file-scanner.d.ts.map +1 -0
  269. package/dist/infrastructure/files/accept-every-file-scanner.js +7 -0
  270. package/dist/infrastructure/files/accept-every-file-scanner.js.map +1 -0
  271. package/dist/infrastructure/files/collect.d.ts +4 -0
  272. package/dist/infrastructure/files/collect.d.ts.map +1 -0
  273. package/dist/infrastructure/files/collect.js +11 -0
  274. package/dist/infrastructure/files/collect.js.map +1 -0
  275. package/dist/infrastructure/files/file-grant.d.ts +11 -0
  276. package/dist/infrastructure/files/file-grant.d.ts.map +1 -0
  277. package/dist/infrastructure/files/file-grant.js +2 -0
  278. package/dist/infrastructure/files/file-grant.js.map +1 -0
  279. package/dist/infrastructure/files/file-inspection.d.ts +22 -0
  280. package/dist/infrastructure/files/file-inspection.d.ts.map +1 -0
  281. package/dist/infrastructure/files/file-inspection.js +66 -0
  282. package/dist/infrastructure/files/file-inspection.js.map +1 -0
  283. package/dist/infrastructure/files/file-staging.d.ts +59 -0
  284. package/dist/infrastructure/files/file-staging.d.ts.map +1 -0
  285. package/dist/infrastructure/files/file-staging.js +142 -0
  286. package/dist/infrastructure/files/file-staging.js.map +1 -0
  287. package/dist/infrastructure/files/file-uploads-middleware.d.ts +11 -0
  288. package/dist/infrastructure/files/file-uploads-middleware.d.ts.map +1 -0
  289. package/dist/infrastructure/files/file-uploads-middleware.js +25 -0
  290. package/dist/infrastructure/files/file-uploads-middleware.js.map +1 -0
  291. package/dist/infrastructure/files/in-memory-file-storage.d.ts +25 -0
  292. package/dist/infrastructure/files/in-memory-file-storage.d.ts.map +1 -0
  293. package/dist/infrastructure/files/in-memory-file-storage.js +73 -0
  294. package/dist/infrastructure/files/in-memory-file-storage.js.map +1 -0
  295. package/dist/infrastructure/files/is-file-grant.d.ts +3 -0
  296. package/dist/infrastructure/files/is-file-grant.d.ts.map +1 -0
  297. package/dist/infrastructure/files/is-file-grant.js +16 -0
  298. package/dist/infrastructure/files/is-file-grant.js.map +1 -0
  299. package/dist/infrastructure/files/is-stored-metadata.d.ts +3 -0
  300. package/dist/infrastructure/files/is-stored-metadata.d.ts.map +1 -0
  301. package/dist/infrastructure/files/is-stored-metadata.js +8 -0
  302. package/dist/infrastructure/files/is-stored-metadata.js.map +1 -0
  303. package/dist/infrastructure/files/local-file-storage-options.d.ts +6 -0
  304. package/dist/infrastructure/files/local-file-storage-options.d.ts.map +1 -0
  305. package/dist/infrastructure/files/local-file-storage-options.js +2 -0
  306. package/dist/infrastructure/files/local-file-storage-options.js.map +1 -0
  307. package/dist/infrastructure/files/local-file-storage.d.ts +29 -0
  308. package/dist/infrastructure/files/local-file-storage.d.ts.map +1 -0
  309. package/dist/infrastructure/files/local-file-storage.js +103 -0
  310. package/dist/infrastructure/files/local-file-storage.js.map +1 -0
  311. package/dist/infrastructure/files/local-paths.d.ts +12 -0
  312. package/dist/infrastructure/files/local-paths.d.ts.map +1 -0
  313. package/dist/infrastructure/files/local-paths.js +33 -0
  314. package/dist/infrastructure/files/local-paths.js.map +1 -0
  315. package/dist/infrastructure/files/purge-staged-files.d.ts +16 -0
  316. package/dist/infrastructure/files/purge-staged-files.d.ts.map +1 -0
  317. package/dist/infrastructure/files/purge-staged-files.js +21 -0
  318. package/dist/infrastructure/files/purge-staged-files.js.map +1 -0
  319. package/dist/infrastructure/files/self-signed-file-storage.d.ts +23 -0
  320. package/dist/infrastructure/files/self-signed-file-storage.d.ts.map +1 -0
  321. package/dist/infrastructure/files/self-signed-file-storage.js +57 -0
  322. package/dist/infrastructure/files/self-signed-file-storage.js.map +1 -0
  323. package/dist/infrastructure/files/signed-file-tokens.d.ts +20 -0
  324. package/dist/infrastructure/files/signed-file-tokens.d.ts.map +1 -0
  325. package/dist/infrastructure/files/signed-file-tokens.js +45 -0
  326. package/dist/infrastructure/files/signed-file-tokens.js.map +1 -0
  327. package/dist/infrastructure/files/signed-link-options.d.ts +10 -0
  328. package/dist/infrastructure/files/signed-link-options.d.ts.map +1 -0
  329. package/dist/infrastructure/files/signed-link-options.js +2 -0
  330. package/dist/infrastructure/files/signed-link-options.js.map +1 -0
  331. package/dist/infrastructure/files/stored-metadata.d.ts +6 -0
  332. package/dist/infrastructure/files/stored-metadata.d.ts.map +1 -0
  333. package/dist/infrastructure/files/stored-metadata.js +2 -0
  334. package/dist/infrastructure/files/stored-metadata.js.map +1 -0
  335. package/dist/infrastructure/files/tenant-file-keys.d.ts +20 -0
  336. package/dist/infrastructure/files/tenant-file-keys.d.ts.map +1 -0
  337. package/dist/infrastructure/files/tenant-file-keys.js +27 -0
  338. package/dist/infrastructure/files/tenant-file-keys.js.map +1 -0
  339. package/dist/infrastructure/files/upload-desk.d.ts +8 -0
  340. package/dist/infrastructure/files/upload-desk.d.ts.map +1 -0
  341. package/dist/infrastructure/files/upload-desk.js +2 -0
  342. package/dist/infrastructure/files/upload-desk.js.map +1 -0
  343. package/dist/infrastructure/files/without-trailing-slashes.d.ts +3 -0
  344. package/dist/infrastructure/files/without-trailing-slashes.d.ts.map +1 -0
  345. package/dist/infrastructure/files/without-trailing-slashes.js +9 -0
  346. package/dist/infrastructure/files/without-trailing-slashes.js.map +1 -0
  347. package/dist/infrastructure/in-memory/in-memory-tenant-directory.d.ts +8 -0
  348. package/dist/infrastructure/in-memory/in-memory-tenant-directory.d.ts.map +1 -0
  349. package/dist/infrastructure/in-memory/in-memory-tenant-directory.js +12 -0
  350. package/dist/infrastructure/in-memory/in-memory-tenant-directory.js.map +1 -0
  351. package/dist/infrastructure/tenancy/tenant-isolation-policies.d.ts +13 -0
  352. package/dist/infrastructure/tenancy/tenant-isolation-policies.d.ts.map +1 -0
  353. package/dist/infrastructure/tenancy/tenant-isolation-policies.js +13 -0
  354. package/dist/infrastructure/tenancy/tenant-isolation-policies.js.map +1 -0
  355. package/dist/infrastructure/tenancy/tenant-policy-expressions.d.ts +11 -0
  356. package/dist/infrastructure/tenancy/tenant-policy-expressions.d.ts.map +1 -0
  357. package/dist/infrastructure/tenancy/tenant-policy-expressions.js +15 -0
  358. package/dist/infrastructure/tenancy/tenant-policy-expressions.js.map +1 -0
  359. package/dist/infrastructure/tenancy/tenant-setting-values.d.ts +13 -0
  360. package/dist/infrastructure/tenancy/tenant-setting-values.d.ts.map +1 -0
  361. package/dist/infrastructure/tenancy/tenant-setting-values.js +19 -0
  362. package/dist/infrastructure/tenancy/tenant-setting-values.js.map +1 -0
  363. package/dist/infrastructure/tenancy/tenant-settings.d.ts +13 -0
  364. package/dist/infrastructure/tenancy/tenant-settings.d.ts.map +1 -0
  365. package/dist/infrastructure/tenancy/tenant-settings.js +13 -0
  366. package/dist/infrastructure/tenancy/tenant-settings.js.map +1 -0
  367. package/package.json +1 -1
package/README.md CHANGED
@@ -552,8 +552,13 @@ The authenticated session of an actor, as plain data.
552
552
  | `authenticationStrength?` | `{ mfa?, assuranceLevel? }` |
553
553
  | `impersonatedBy?` | id of the support actor acting as `actor`; `logFieldsOf` carries it to every log line |
554
554
  | `locale?`, `timeZone?`, `client?` | BCP 47 tag, IANA zone, `{ ip?, userAgent? }` as opaque strings |
555
+ | `scopes?` | what the credential allows whoever presents it (the OAuth 2.0 `scope`): a limit on the client, never what the actor may do |
555
556
  | `extensions` | the fields of the project |
556
557
 
558
+ `hasScope(session, scope)` reads the scopes; a project names its scope vocabulary once by
559
+ declaration merging of `SessionScopes` (`interface SessionScopes { readonly 'invoices:read': true }`),
560
+ and `SessionScope`, the type a guard takes, is then that vocabulary instead of any string.
561
+
557
562
  `isExpired(session, clock.now())`, `isImpersonated(session)`, `anonymousSession()`,
558
563
  `systemSession(name, issuedAt?)`, and `isSession(value)`, the structural guard a boundary uses on
559
564
  what it received as a principal.
@@ -561,8 +566,8 @@ what it received as a principal.
561
566
  ### ExecutionContext and ExecutionScope
562
567
 
563
568
  What every unit of work carries, whatever started it: `correlationId`, `causationId?`, `actor`,
564
- `session?`, `tenantId?`, `locale?`, `deadline?`, `scheduledAt?` (for a scheduled job, the instant it
565
- was due), `origin` (`http`, `event`, `schedule`, `cli`, or a string of the project) and `extensions`. `executionContext(init)` builds one and takes the tenant
569
+ `session?`, `tenantId?`, `elevation?` (platform staff reading over tenants, see "Tenancy"),
570
+ `locale?`, `deadline?`, `scheduledAt?` (for a scheduled job, the instant it was due), `origin` (`http`, `event`, `schedule`, `cli`, or a string of the project) and `extensions`. `executionContext(init)` builds one and takes the tenant
566
571
  of the actor; `withActor(context, actor)` is the same work seen as another actor.
567
572
 
568
573
  `ExecutionScope` (`current()`, `require()`, `run(context, work)`) gives the context of the work
@@ -584,11 +589,13 @@ tenant scoping and outgoing headers.
584
589
 
585
590
  A consumed event opens its own context: `executionContextOfEvent(event, { consumer })` has
586
591
  origin `event`, the correlation of the event (its id when it names none), the event as
587
- `causationId` and `systemActor(consumer)` as actor; `inEventScope(scope, { consumer }, handler)`
592
+ `causationId`, `systemActor(consumer)` as actor and the `tenantId` of the event, so the
593
+ consumer reads and writes in that tenant only; `inEventScope(scope, { consumer }, handler)`
588
594
  wraps a handler with it. The standard envelope carries no actor, so that no personal data
589
595
  travels by default: a project whose envelopes name one passes `actorOf`. On the way out,
590
- `scopedPublisher(publisher, scope)` stamps the correlation of the work in progress on every
591
- event published without one, so everything one stimulus causes is found again across processes.
596
+ `scopedPublisher(publisher, scope)` stamps the correlation and the tenant of the work in
597
+ progress on every event published without them, so everything one stimulus causes is found
598
+ again across processes and stays in its tenant.
592
599
 
593
600
  `ActorContext` stays, unchanged. `ScopedActorContext` implements it on top of a scope: the
594
601
  current actor is the actor of the current execution context, so the two cannot disagree.
@@ -701,7 +708,8 @@ const hit: Quote | undefined = await cache.get(quoteKey('EUR-USD'));
701
708
  ```
702
709
 
703
710
  The key carries the type of its value. `InMemoryCache(clock, { maxEntries? })` expires by the
704
- `Clock` and is bounded.
711
+ `Clock` and is bounded. `tenantCacheKey<Quote>(scope, 'quote', pair)` is the same key confined to
712
+ the tenant of the work in progress: what one tenant cached is never served to another.
705
713
 
706
714
  ### Lock
707
715
 
@@ -727,6 +735,75 @@ the guard of an invariant: what must not happen twice is refused by a database c
727
735
  `Clock`: the fake, and enough for a single instance. The adapter between processes is in
728
736
  `@ddd-ts-kit/redis`. `acquiring(attempt, waitMs, waiting)` is the retry loop an adapter shares.
729
737
 
738
+ ### FileStorage, StoredFile, FileScanner
739
+
740
+ ```ts
741
+ // The command wraps what the controller received: the bus stages it before the transaction opens.
742
+ this.document = new FileUpload(received, 'appointment-documents');
743
+
744
+ // The handler, inside the unit of work:
745
+ const { file, fileName } = command.document; // a StoredFile, staged and scanned
746
+ appointment.attachDocument(unwrap(AttachedDocument.create(file, fileName, now)), now);
747
+ await appointments.save(appointment);
748
+ await staging.promoteOnCommit(file.key); // moved to its key with the commit
749
+ ```
750
+
751
+ `FileStorage` holds the content of files, never the database: `put` (a stream in, measured and
752
+ hashed, refused with `FILE_TOO_LARGE` beyond `maxBytes`, leaving nothing), `get` (a stream out),
753
+ `stat`, `delete`, `copy`, `move`, `list(prefix)`, and short signed links, `signedDownloadUrl` and
754
+ `signedUploadUrl` (at most `MAX_SIGNED_URL_SECONDS`, one hour). No method takes or returns a
755
+ whole file. A key is checked by `isFileKey` (segments of letters, digits, `.`, `-` and `_`, none
756
+ starting with a dot) before anything is touched, and `FileKeys` generates it on the server:
757
+ `TenantFileKeys(ids, clock, scope)` writes `tenants/<tenant>/<area>/<year>/<month>/<id>`, the
758
+ tenant segment only when the work in progress names one (the tenant id as it is: the kernel
759
+ refuses any other than letters, digits, `-` and `_`, so two tenants never share a prefix). The links of
760
+ `signedUploadUrl` carry a `maxBytes`, which the storages the application serves enforce.
761
+
762
+ `StoredFile` is what an aggregate keeps: `key`, `size`, `mediaType`, `checksum` (`sha256:<hex>`),
763
+ never the provider. `FileScanner` is the hook of an antivirus or a content check, called on the
764
+ staged file before it is accepted; `AcceptEveryFileScanner` is the one of a project that has
765
+ none yet. `FileError` carries the refusals: `FILE_TOO_LARGE`, `UNSUPPORTED_MEDIA_TYPE`,
766
+ `FILE_NOT_FOUND`, `INVALID_FILE_KEY`, `FILE_REJECTED`, `INVALID_FILE_URL_EXPIRY`.
767
+
768
+ A write to the storage is not rolled back with a transaction. `FileStaging(storage, scanner,
769
+ reporter)` gives the order that keeps both consistent, each step once:
770
+
771
+ - `stage(key, content, options)` writes under `staging/<key>` and scans; a refused file is
772
+ removed (`FILE_REJECTED`). A file from a client travels in its command as a `FileUpload`
773
+ (the `ReceivedFile` and the area of its key), staged by `fileUploadsMiddleware(desk)`, a bus
774
+ middleware placed after the permission and before the unit of work, so no transaction waits
775
+ on an upload. `upload.file` is the staged `StoredFile`.
776
+ - `promoteOnCommit(key)` moves the file to its key as the last step of the unit of work
777
+ (`atCommit`, a `CommitStep` of `apply` and `undo`): a promotion that fails rolls the command
778
+ back, and a transaction that rolls back after it returns the file to `staging/`. A committed
779
+ row never points into `staging/`.
780
+ - `deleteAfterCommit(key)` deletes, once committed, a file the aggregate no longer references
781
+ (`afterCommit`, at most once: a failure or a crash leaves an unreferenced file, reported).
782
+ - `purge(olderThan)` removes the staged files older than the instant, all orphans; the job
783
+ `PurgeStagedFiles` runs it (the platform registers it as `files.purge-staged`, every hour,
784
+ for files staged a day ago or more).
785
+
786
+ For a large file the client uploads straight to the storage: `uploadUrl(key, { expiresInSeconds,
787
+ mediaType, accepted, maxBytes })` answers the `link` for the client and the `pending` grant
788
+ (`PendingUpload`: key, size cap, media types) that the command records on the aggregate;
789
+ `confirm(pending)`, called by a command that reads the grant back from the aggregate, never
790
+ from the client, checks what arrived against the cap and on its bytes (`contentMatches`), scans
791
+ it, and answers the `StoredFile`. No final key may start with `staging/` (`assertFinalKey`).
792
+
793
+ `FileInspection` is the pass-through every connector streams through: it counts, hashes, and
794
+ with an expectation holds back the first bytes until they prove the declared media type
795
+ (`acceptsMediaType`, `contentMatches`: a PDF starts with `%PDF-`, office documents are zip
796
+ archives, text is UTF-8 without control characters, SVG and unknown binary formats never
797
+ match).
798
+
799
+ Connectors: `InMemoryFileStorage` for the tests (`keys()` lists what it holds) and
800
+ `LocalFileStorage({ directory, baseUrl, secret })` for development, both `ServedFileStorage`:
801
+ their signed links point at the application, which answers them with `signedFileRoutes` of
802
+ `@ddd-ts-kit/http`. The object store connector is `@ddd-ts-kit/s3`. Each passes
803
+ `fileStorageContract` of `@ddd-ts-kit/testing/contracts`. Background import and export (row by
804
+ row validation, an error report, resumption) needs a job queue the kit does not have yet: the
805
+ ports are ready for it, see `docs/concepts/file-storage.md`.
806
+
730
807
  ### JobScheduler
731
808
 
732
809
  ```ts
@@ -748,9 +825,10 @@ instead of rejecting: only an unknown name rejects (`UnknownJobError`), and a na
748
825
  twice throws (`DuplicateJobError`).
749
826
 
750
827
  A run happens inside `ExecutionScope`, in the context `executionContextOfJob(name, { correlationId,
751
- scheduledAt, deadline? })` builds: origin `schedule`, `systemActor(name)`, a correlation of its
828
+ scheduledAt, deadline?, tenantId? })` builds: origin `schedule`, `systemActor(name)`, a correlation of its
752
829
  own, and `scheduledAt`, the instant the run was due, which `ExecutionContext` carries for this
753
- origin.
830
+ origin. A job is `global` by default and runs in no tenant; `tenancy: 'per-tenant'` makes the
831
+ scheduler run it once per tenant of a `TenantDirectory`, each run in that tenant.
754
832
 
755
833
  `parseJobSchedule(schedule)` validates a schedule and answers the form occurrences are
756
834
  computed from (`InvalidJobScheduleError`, code `INVALID_JOB_SCHEDULE`, otherwise);
@@ -770,12 +848,36 @@ if (!decision.allowed) {
770
848
 
771
849
  A sliding window: at any instant, at most `limit` allowed calls in the `windowMs` before it. A
772
850
  `RateLimitDecision` is `{ allowed, remaining, retryAfterMs }`; a refused call is not counted.
773
- The key is whatever is limited: a client, a tenant, a route and an address together.
851
+ The key is whatever is limited: a client, a tenant, a route and an address together. In a
852
+ multi-tenant project, `tenantKey(scope, 'password-reset', accountId)` confines it to the tenant of
853
+ the work in progress (`tenant:<id>:password-reset:<account>`) and refuses work that names none.
774
854
 
775
855
  `InMemoryRateLimiter(clock)` counts inside one process; the adapter shared by several instances
776
856
  is in `@ddd-ts-kit/redis`. `rateLimitDecisionOf(counted, limit)` turns what an adapter counted
777
857
  into the decision.
778
858
 
859
+ ### Tenancy
860
+
861
+ The tenant of the work is `ExecutionContext.tenantId`, set at the boundary and read by
862
+ infrastructure only, like the rest of the context. The kernel holds what every strategy shares;
863
+ the isolation itself (tenant column, row-level security, schema or database per tenant) is in the
864
+ persistence packages, and the whole picture in
865
+ [Multitenancy](../../docs/concepts/multitenancy.md).
866
+
867
+ | Concept | What it does |
868
+ |---|---|
869
+ | `isTenantId(value)`, `assertTenantId(id)`, `InvalidTenantIdError` | the one grammar of a tenant id (letters, digits, `_`, `-`, at most 63): `executionContext`, `executionContextOfEvent`, `acrossTenants`, `InMemoryTenantDirectory`, `tenantScopeOf`, `tenantReachOf` and the row-level security settings refuse any other, so that no tenant id can be read as a wildcard, a list or a key separator |
870
+ | `tenantScopeOf(scope)` | the one tenant a write names; `NoCurrentTenantError` for work that names none |
871
+ | `tenantReachOf(scope)` | what a read may see: `{ kind: 'tenant', tenantId }`, or `{ kind: 'elevated', tenants }` under an elevation |
872
+ | `tenantsOf(actor)`, `isTenantMember(actor, tenantId)` | the tenants an actor belongs to: its `tenantId` and its `tenants` attribute |
873
+ | `acrossTenants({ scope, trail, clock, ids }, { reason, tenants }, work)` | platform staff reading over tenants: refused without a reason or a tenant, recorded in the `AuditTrail` (action `tenancy:elevate`) before the work runs; writes still name one tenant |
874
+ | `tenantKey(scope, ...segments)`, `tenantCacheKey(scope, ...segments)` | keys of rate limits, locks and caches confined to the tenant: `tenant:<id>:<segments>`, each segment percent-encoded, so that two lists of segments never give one key |
875
+ | `TenantDirectory`, `InMemoryTenantDirectory` | the tenants that exist, for per-tenant jobs, provisioning and migrations |
876
+ | `TENANT_SETTINGS`, `tenantSettingValues(context)`, `TENANT_ISOLATION_POLICIES`, `tenantPolicyExpressions(column)` | what the row-level security of the persistence packages shares: the three settings of a transaction (`ddd_ts_kit.tenant_id`, and for an elevation only `ddd_ts_kit.reach` and `ddd_ts_kit.every_tenant`), their values for the work in progress, the names of the four policies (one per command) and their `read` and `write` expressions |
877
+
878
+ An elevation is never implied by a role: the platform decides the permission to elevate (a use
879
+ case or a guard), then calls `acrossTenants`. A trail that fails to record it refuses it.
880
+
779
881
  ### Page and PageRequest
780
882
 
781
883
  One shape for every search, in two variants:
@@ -1,5 +1,8 @@
1
1
  import type { ExecutionScope } from '../ports/execution-scope.js';
2
2
  import type { TenantScoped } from './tenant-scoped.js';
3
- /** For a repository adapter scoping a statement: the tenant of the work in progress. */
3
+ /**
4
+ * For a repository adapter scoping a statement: the tenant of the work in progress, checked
5
+ * against the grammar of `isTenantId` again however the context was built.
6
+ */
4
7
  export declare function tenantScopeOf(scope: ExecutionScope): TenantScoped;
5
8
  //# sourceMappingURL=tenant-scope-of.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tenant-scope-of.d.ts","sourceRoot":"","sources":["../../../src/application/audit/tenant-scope-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CAQjE"}
1
+ {"version":3,"file":"tenant-scope-of.d.ts","sourceRoot":"","sources":["../../../src/application/audit/tenant-scope-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAGlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CAQjE"}
@@ -1,10 +1,14 @@
1
+ import { assertTenantId } from '../tenancy/assert-tenant-id.js';
1
2
  import { NoCurrentTenantError } from './no-current-tenant-error.js';
2
- /** For a repository adapter scoping a statement: the tenant of the work in progress. */
3
+ /**
4
+ * For a repository adapter scoping a statement: the tenant of the work in progress, checked
5
+ * against the grammar of `isTenantId` again however the context was built.
6
+ */
3
7
  export function tenantScopeOf(scope) {
4
8
  const { tenantId } = scope.require();
5
9
  if (tenantId === undefined) {
6
10
  throw new NoCurrentTenantError();
7
11
  }
8
- return { tenantId };
12
+ return { tenantId: assertTenantId(tenantId) };
9
13
  }
10
14
  //# sourceMappingURL=tenant-scope-of.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tenant-scope-of.js","sourceRoot":"","sources":["../../../src/application/audit/tenant-scope-of.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGpE,wFAAwF;AACxF,MAAM,UAAU,aAAa,CAAC,KAAqB;IACjD,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAErC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,oBAAoB,EAAE,CAAC;IACnC,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"tenant-scope-of.js","sourceRoot":"","sources":["../../../src/application/audit/tenant-scope-of.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGpE;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAqB;IACjD,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAErC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,oBAAoB,EAAE,CAAC;IACnC,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;AAChD,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ExecutionScope } from '../ports/execution-scope.js';
2
+ import { type CacheKey } from './cache-key.js';
3
+ /** `cacheKey` confined to the tenant of the work in progress: what one tenant cached is never served to another. */
4
+ export declare function tenantCacheKey<T>(scope: ExecutionScope, ...segments: readonly string[]): CacheKey<T>;
5
+ //# sourceMappingURL=tenant-cache-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-cache-key.d.ts","sourceRoot":"","sources":["../../../src/application/cache/tenant-cache-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,gBAAgB,CAAC;AAEzD,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAEpG"}
@@ -0,0 +1,7 @@
1
+ import { tenantKey } from '../tenancy/tenant-key.js';
2
+ import { cacheKey } from './cache-key.js';
3
+ /** `cacheKey` confined to the tenant of the work in progress: what one tenant cached is never served to another. */
4
+ export function tenantCacheKey(scope, ...segments) {
5
+ return cacheKey(tenantKey(scope, ...segments));
6
+ }
7
+ //# sourceMappingURL=tenant-cache-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-cache-key.js","sourceRoot":"","sources":["../../../src/application/cache/tenant-cache-key.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAiB,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEzD,oHAAoH;AACpH,MAAM,UAAU,cAAc,CAAI,KAAqB,EAAE,GAAG,QAA2B;IACrF,OAAO,QAAQ,CAAI,SAAS,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;AACpD,CAAC"}
@@ -3,7 +3,8 @@ import type { EventExecutionOptions } from './event-execution-options.js';
3
3
  import type { IntegrationEvent } from './integration-event.js';
4
4
  /**
5
5
  * The execution context of a consumed event: origin `event`, the correlation of the event (its
6
- * own id when it names none, which starts a new chain), and the event as the direct cause.
6
+ * own id when it names none, which starts a new chain), the event as the direct cause, and the
7
+ * tenant the event belongs to, so the consumer reads and writes in that tenant only.
7
8
  */
8
9
  export declare function executionContextOfEvent(event: IntegrationEvent, options: EventExecutionOptions): ExecutionContext;
9
10
  //# sourceMappingURL=execution-context-of-event.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context-of-event.d.ts","sourceRoot":"","sources":["../../../src/application/events/execution-context-of-event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAoB,MAAM,mCAAmC,CAAC;AAC5F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,qBAAqB,GAAG,gBAAgB,CAOjH"}
1
+ {"version":3,"file":"execution-context-of-event.d.ts","sourceRoot":"","sources":["../../../src/application/events/execution-context-of-event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAoB,MAAM,mCAAmC,CAAC;AAC5F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,qBAAqB,GAAG,gBAAgB,CAQjH"}
@@ -2,7 +2,8 @@ import { systemActor } from '../actor/system-actor.js';
2
2
  import { executionContext } from '../execution/execution-context.js';
3
3
  /**
4
4
  * The execution context of a consumed event: origin `event`, the correlation of the event (its
5
- * own id when it names none, which starts a new chain), and the event as the direct cause.
5
+ * own id when it names none, which starts a new chain), the event as the direct cause, and the
6
+ * tenant the event belongs to, so the consumer reads and writes in that tenant only.
6
7
  */
7
8
  export function executionContextOfEvent(event, options) {
8
9
  return executionContext({
@@ -10,6 +11,7 @@ export function executionContextOfEvent(event, options) {
10
11
  causationId: event.id,
11
12
  actor: options.actorOf?.(event) ?? systemActor(options.consumer),
12
13
  origin: 'event',
14
+ ...(event.tenantId === undefined ? {} : { tenantId: event.tenantId }),
13
15
  });
14
16
  }
15
17
  //# sourceMappingURL=execution-context-of-event.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context-of-event.js","sourceRoot":"","sources":["../../../src/application/events/execution-context-of-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAyB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAI5F;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAuB,EAAE,OAA8B;IAC7F,OAAO,gBAAgB,CAAC;QACtB,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,EAAE;QAC9C,WAAW,EAAE,KAAK,CAAC,EAAE;QACrB,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;QAChE,MAAM,EAAE,OAAO;KAChB,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"execution-context-of-event.js","sourceRoot":"","sources":["../../../src/application/events/execution-context-of-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAyB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAI5F;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAuB,EAAE,OAA8B;IAC7F,OAAO,gBAAgB,CAAC;QACtB,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,EAAE;QAC9C,WAAW,EAAE,KAAK,CAAC,EAAE;QACrB,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;QAChE,MAAM,EAAE,OAAO;QACf,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;KACtE,CAAC,CAAC;AACL,CAAC"}
@@ -13,5 +13,11 @@ export interface IntegrationEvent<Payload = unknown> {
13
13
  /** W3C traceparent captured at publication so consumers continue the same trace. */
14
14
  readonly traceparent?: string;
15
15
  readonly correlationId?: string;
16
+ /**
17
+ * The tenant the fact belongs to, stamped from the work that published it. A consumer handles
18
+ * the event in that tenant's scope, so its reads and writes stay in the tenant. Absent for a
19
+ * fact of no tenant (the platform's own).
20
+ */
21
+ readonly tenantId?: string;
16
22
  }
17
23
  //# sourceMappingURL=integration-event.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"integration-event.d.ts","sourceRoot":"","sources":["../../../src/application/events/integration-event.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,OAAO,GAAG,OAAO;IACjD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC"}
1
+ {"version":3,"file":"integration-event.d.ts","sourceRoot":"","sources":["../../../src/application/events/integration-event.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,OAAO,GAAG,OAAO;IACjD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B"}
@@ -2,9 +2,10 @@ import type { ExecutionScope } from '../ports/execution-scope.js';
2
2
  import type { IntegrationEventPublisher } from '../ports/integration-event-publisher.js';
3
3
  /**
4
4
  * Decorates a publisher: an event published without `correlationId` takes the one of the work
5
- * in progress, so everything one stimulus causes can be found again. An event that names its
6
- * correlation keeps it, and outside of any execution context nothing is stamped. The name of
7
- * the transport (`messagingSystem`) is passed on.
5
+ * in progress, so everything one stimulus causes can be found again, and one without `tenantId`
6
+ * the tenant of that work, so its consumers run in the same tenant. What an event names is
7
+ * kept, and outside of any execution context nothing is stamped. The name of the transport
8
+ * (`messagingSystem`) is passed on.
8
9
  */
9
10
  export declare function scopedPublisher(publisher: IntegrationEventPublisher, scope: ExecutionScope): IntegrationEventPublisher;
10
11
  //# sourceMappingURL=scoped-publisher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scoped-publisher.d.ts","sourceRoot":"","sources":["../../../src/application/events/scoped-publisher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AAIzF;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,yBAAyB,EACpC,KAAK,EAAE,cAAc,GACpB,yBAAyB,CAO3B"}
1
+ {"version":3,"file":"scoped-publisher.d.ts","sourceRoot":"","sources":["../../../src/application/events/scoped-publisher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AAIzF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,yBAAyB,EACpC,KAAK,EAAE,cAAc,GACpB,yBAAyB,CAO3B"}
@@ -1,9 +1,10 @@
1
1
  import { messagingSystemOf } from './messaging-system-of.js';
2
2
  /**
3
3
  * Decorates a publisher: an event published without `correlationId` takes the one of the work
4
- * in progress, so everything one stimulus causes can be found again. An event that names its
5
- * correlation keeps it, and outside of any execution context nothing is stamped. The name of
6
- * the transport (`messagingSystem`) is passed on.
4
+ * in progress, so everything one stimulus causes can be found again, and one without `tenantId`
5
+ * the tenant of that work, so its consumers run in the same tenant. What an event names is
6
+ * kept, and outside of any execution context nothing is stamped. The name of the transport
7
+ * (`messagingSystem`) is passed on.
7
8
  */
8
9
  export function scopedPublisher(publisher, scope) {
9
10
  const messagingSystem = messagingSystemOf(publisher);
@@ -13,9 +14,14 @@ export function scopedPublisher(publisher, scope) {
13
14
  };
14
15
  }
15
16
  function correlated(event, context) {
16
- if (event.correlationId !== undefined || context === undefined) {
17
+ if (context === undefined) {
17
18
  return event;
18
19
  }
19
- return { ...event, correlationId: context.correlationId };
20
+ const { correlationId, tenantId } = context;
21
+ return {
22
+ ...event,
23
+ ...(event.correlationId === undefined ? { correlationId } : {}),
24
+ ...(event.tenantId === undefined && tenantId !== undefined ? { tenantId } : {}),
25
+ };
20
26
  }
21
27
  //# sourceMappingURL=scoped-publisher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scoped-publisher.js","sourceRoot":"","sources":["../../../src/application/events/scoped-publisher.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAoC,EACpC,KAAqB;IAErB,MAAM,eAAe,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAErD,OAAO;QACL,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACjG,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB,EAAE,OAAqC;IAChF,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,EAAE,GAAG,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;AAC5D,CAAC"}
1
+ {"version":3,"file":"scoped-publisher.js","sourceRoot":"","sources":["../../../src/application/events/scoped-publisher.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAoC,EACpC,KAAqB;IAErB,MAAM,eAAe,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAErD,OAAO;QACL,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACjG,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB,EAAE,OAAqC;IAChF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE5C,OAAO;QACL,GAAG,KAAK;QACR,GAAG,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChF,CAAC;AACJ,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import type { Actor } from '../actor/actor.js';
2
2
  import type { Session } from '../session/session.js';
3
+ import type { TenantElevation } from '../tenancy/tenant-elevation.js';
3
4
  import type { ExecutionContextExtensionValues } from './execution-context-extension-values.js';
4
5
  import type { ExecutionOrigin } from './execution-origin.js';
5
6
  /**
@@ -14,6 +15,8 @@ export interface ExecutionContext {
14
15
  readonly actor: Actor;
15
16
  readonly session?: Session;
16
17
  readonly tenantId?: string;
18
+ /** Platform staff reading over tenants, opened by `acrossTenants` and audited. Absent otherwise. */
19
+ readonly elevation?: TenantElevation;
17
20
  readonly locale?: string;
18
21
  /** The instant after which the result is useless to the caller. */
19
22
  readonly deadline?: Date;
@@ -23,6 +26,9 @@ export interface ExecutionContext {
23
26
  readonly extensions: ExecutionContextExtensionValues;
24
27
  }
25
28
  export type ExecutionContextInit = Omit<ExecutionContext, 'extensions' | 'tenantId'> & Partial<Pick<ExecutionContext, 'extensions' | 'tenantId'>>;
26
- /** Fills what can be derived: the tenant of the actor, no extension. */
29
+ /**
30
+ * Fills what can be derived: the tenant of the actor, no extension. A tenant id outside the
31
+ * grammar of `isTenantId` is refused (`InvalidTenantIdError`), whatever named it.
32
+ */
27
33
  export declare function executionContext(init: ExecutionContextInit): ExecutionContext;
28
34
  //# sourceMappingURL=execution-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context.d.ts","sourceRoot":"","sources":["../../../src/application/execution/execution-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;IACzB,mGAAmG;IACnG,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,+BAA+B,CAAC;CACtD;AAED,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,UAAU,CAAC,GAClF,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC;AAE7D,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAQ7E"}
1
+ {"version":3,"file":"execution-context.d.ts","sourceRoot":"","sources":["../../../src/application/execution/execution-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,oGAAoG;IACpG,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;IACzB,mGAAmG;IACnG,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,+BAA+B,CAAC;CACtD;AAED,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,UAAU,CAAC,GAClF,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAS7E"}
@@ -1,6 +1,11 @@
1
- /** Fills what can be derived: the tenant of the actor, no extension. */
1
+ import { assertTenantId } from '../tenancy/assert-tenant-id.js';
2
+ /**
3
+ * Fills what can be derived: the tenant of the actor, no extension. A tenant id outside the
4
+ * grammar of `isTenantId` is refused (`InvalidTenantIdError`), whatever named it.
5
+ */
2
6
  export function executionContext(init) {
3
- const tenantId = init.tenantId ?? init.actor.tenantId;
7
+ const named = init.tenantId ?? init.actor.tenantId;
8
+ const tenantId = named === undefined ? undefined : assertTenantId(named);
4
9
  return Object.freeze({
5
10
  ...init,
6
11
  ...(tenantId === undefined ? {} : { tenantId }),
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../../../src/application/execution/execution-context.ts"],"names":[],"mappings":"AA6BA,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,IAA0B;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAEtD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,IAAI;QACP,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;QAC/C,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;KACjD,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../../../src/application/execution/execution-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AA+BhE;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA0B;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IACnD,MAAM,QAAQ,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAEzE,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,IAAI;QACP,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;QAC/C,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;KACjD,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"log-fields-of.d.ts","sourceRoot":"","sources":["../../../src/application/execution/log-fields-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAShE"}
1
+ {"version":3,"file":"log-fields-of.d.ts","sourceRoot":"","sources":["../../../src/application/execution/log-fields-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAUhE"}
@@ -6,6 +6,7 @@ export function logFieldsOf(context) {
6
6
  actorId: context.actor.id,
7
7
  ...(context.causationId === undefined ? {} : { causationId: context.causationId }),
8
8
  ...(context.tenantId === undefined ? {} : { tenantId: context.tenantId }),
9
+ ...(context.elevation === undefined ? {} : { elevation: context.elevation.reason }),
9
10
  ...(context.session?.impersonatedBy === undefined ? {} : { impersonatedBy: context.session.impersonatedBy }),
10
11
  };
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"log-fields-of.js","sourceRoot":"","sources":["../../../src/application/execution/log-fields-of.ts"],"names":[],"mappings":"AAGA,iGAAiG;AACjG,MAAM,UAAU,WAAW,CAAC,OAAyB;IACnD,OAAO;QACL,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QACzB,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;QAClF,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzE,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;KAC7G,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"log-fields-of.js","sourceRoot":"","sources":["../../../src/application/execution/log-fields-of.ts"],"names":[],"mappings":"AAGA,iGAAiG;AACjG,MAAM,UAAU,WAAW,CAAC,OAAyB;IACnD,OAAO;QACL,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QACzB,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;QAClF,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzE,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QACnF,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;KAC7G,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Whether a declared media type is in the accepted list, which may hold `type/*`. */
2
+ export declare function acceptsMediaType(accepted: readonly string[], declared: string): boolean;
3
+ //# sourceMappingURL=accepts-media-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accepts-media-type.d.ts","sourceRoot":"","sources":["../../../src/application/files/accepts-media-type.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CASvF"}
@@ -0,0 +1,11 @@
1
+ import { mediaTypeOf } from './media-type-of.js';
2
+ /** Whether a declared media type is in the accepted list, which may hold `type/*`. */
3
+ export function acceptsMediaType(accepted, declared) {
4
+ const essence = mediaTypeOf(declared);
5
+ const [type] = essence.split('/');
6
+ return accepted.some((entry) => {
7
+ const allowed = mediaTypeOf(entry);
8
+ return allowed === essence || allowed === `${type ?? ''}/*`;
9
+ });
10
+ }
11
+ //# sourceMappingURL=accepts-media-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accepts-media-type.js","sourceRoot":"","sources":["../../../src/application/files/accepts-media-type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,sFAAsF;AACtF,MAAM,UAAU,gBAAgB,CAAC,QAA2B,EAAE,QAAgB;IAC5E,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAElC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAEnC,OAAO,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,GAAG,IAAI,IAAI,EAAE,IAAI,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** For a connector: the lifetime of a signed link, refused when it is not a whole number of seconds up to the maximum. */
2
+ export declare function assertExpiry(seconds: number): number;
3
+ //# sourceMappingURL=assert-expiry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-expiry.d.ts","sourceRoot":"","sources":["../../../src/application/files/assert-expiry.ts"],"names":[],"mappings":"AAGA,0HAA0H;AAC1H,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMpD"}
@@ -0,0 +1,10 @@
1
+ import { FileError } from './file-error.js';
2
+ import { MAX_SIGNED_URL_SECONDS } from './max-signed-url-seconds.js';
3
+ /** For a connector: the lifetime of a signed link, refused when it is not a whole number of seconds up to the maximum. */
4
+ export function assertExpiry(seconds) {
5
+ if (!Number.isInteger(seconds) || seconds < 1 || seconds > MAX_SIGNED_URL_SECONDS) {
6
+ throw FileError.invalidExpiry(seconds);
7
+ }
8
+ return seconds;
9
+ }
10
+ //# sourceMappingURL=assert-expiry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-expiry.js","sourceRoot":"","sources":["../../../src/application/files/assert-expiry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,0HAA0H;AAC1H,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,sBAAsB,EAAE,CAAC;QAClF,MAAM,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** For a connector: refuses a key `isFileKey` refuses, before anything is touched. */
2
+ export declare function assertFileKey(key: string): string;
3
+ //# sourceMappingURL=assert-file-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-file-key.d.ts","sourceRoot":"","sources":["../../../src/application/files/assert-file-key.ts"],"names":[],"mappings":"AAGA,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMjD"}
@@ -0,0 +1,10 @@
1
+ import { FileError } from './file-error.js';
2
+ import { isFileKey } from './is-file-key.js';
3
+ /** For a connector: refuses a key `isFileKey` refuses, before anything is touched. */
4
+ export function assertFileKey(key) {
5
+ if (!isFileKey(key)) {
6
+ throw FileError.invalidKey(key);
7
+ }
8
+ return key;
9
+ }
10
+ //# sourceMappingURL=assert-file-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-file-key.js","sourceRoot":"","sources":["../../../src/application/files/assert-file-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,sFAAsF;AACtF,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Refuses a key the storages refuse, and one under `staging/`, which the purge would take for a staged file. */
2
+ export declare function assertFinalKey(key: string): string;
3
+ //# sourceMappingURL=assert-final-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-final-key.d.ts","sourceRoot":"","sources":["../../../src/application/files/assert-final-key.ts"],"names":[],"mappings":"AAIA,iHAAiH;AACjH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMlD"}
@@ -0,0 +1,11 @@
1
+ import { assertFileKey } from './assert-file-key.js';
2
+ import { FileError } from './file-error.js';
3
+ import { STAGING_PREFIX } from './staged-key-of.js';
4
+ /** Refuses a key the storages refuse, and one under `staging/`, which the purge would take for a staged file. */
5
+ export function assertFinalKey(key) {
6
+ if (assertFileKey(key).startsWith(STAGING_PREFIX)) {
7
+ throw FileError.invalidKey(key);
8
+ }
9
+ return key;
10
+ }
11
+ //# sourceMappingURL=assert-final-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-final-key.js","sourceRoot":"","sources":["../../../src/application/files/assert-final-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,iHAAiH;AACjH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAClD,MAAM,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** `attachment`, with the name when there is one, kept to characters that cannot break the header, and its UTF-8 form. */
2
+ export declare function contentDisposition(fileName?: string): string;
3
+ //# sourceMappingURL=content-disposition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-disposition.d.ts","sourceRoot":"","sources":["../../../src/application/files/content-disposition.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAC1H,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ5D"}
@@ -0,0 +1,9 @@
1
+ /** `attachment`, with the name when there is one, kept to characters that cannot break the header, and its UTF-8 form. */
2
+ export function contentDisposition(fileName) {
3
+ if (fileName === undefined) {
4
+ return 'attachment';
5
+ }
6
+ const plain = fileName.replace(/[^A-Za-z0-9._ -]/g, '_');
7
+ return `attachment; filename="${plain}"; filename*=UTF-8''${encodeURIComponent(fileName)}`;
8
+ }
9
+ //# sourceMappingURL=content-disposition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-disposition.js","sourceRoot":"","sources":["../../../src/application/files/content-disposition.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAC1H,MAAM,UAAU,kBAAkB,CAAC,QAAiB;IAClD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IAEzD,OAAO,yBAAyB,KAAK,uBAAuB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC7F,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** What an incoming content must be: one of the accepted media types, the one it declares, verified on its bytes. */
2
+ export interface ContentExpectation {
3
+ readonly mediaType: string;
4
+ readonly accepted: readonly string[];
5
+ }
6
+ //# sourceMappingURL=content-expectation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-expectation.d.ts","sourceRoot":"","sources":["../../../src/application/files/content-expectation.ts"],"names":[],"mappings":"AAAA,qHAAqH;AACrH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=content-expectation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-expectation.js","sourceRoot":"","sources":["../../../src/application/files/content-expectation.ts"],"names":[],"mappings":""}