@cosmicdrift/kumiko-bundled-features 0.366.0 → 0.368.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 (365) hide show
  1. package/dist/audit/handlers/details.query.js +1 -1
  2. package/dist/audit/handlers/list.query.js +1 -1
  3. package/dist/audit/run-escape-hatch-retention.js +1 -1
  4. package/dist/auth-email-password/bootstrap.js +1 -1
  5. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +6 -3
  6. package/dist/auth-email-password/handlers/invite-accept.write.js +6 -3
  7. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  8. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +6 -3
  9. package/dist/auth-email-password/handlers/signup-confirm.write.js +1 -1
  10. package/dist/auth-email-password/seeding.js +2 -2
  11. package/dist/auth-foundation/feature.d.ts +4 -0
  12. package/dist/auth-foundation/feature.js +37 -33
  13. package/dist/auth-foundation/index.d.ts +1 -1
  14. package/dist/auth-foundation/index.js +1 -1
  15. package/dist/auth-mfa/db/queries.js +1 -2
  16. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +1 -1
  17. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  18. package/dist/auth-mfa/handlers/reencrypt.job.js +2 -3
  19. package/dist/auth-mfa/handlers/status.query.js +1 -1
  20. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  21. package/dist/auth-mfa/mfa-code-verifier.js +1 -1
  22. package/dist/auth-mfa/mfa-status-checker.js +1 -1
  23. package/dist/auth-mfa-user-data/index.d.ts +4 -0
  24. package/dist/auth-mfa-user-data/index.js +13 -9
  25. package/dist/billing-foundation/billing-info-query.js +1 -1
  26. package/dist/billing-foundation/feature.d.ts +1 -0
  27. package/dist/billing-foundation/feature.js +5 -6
  28. package/dist/billing-foundation/handlers/create-portal-session.write.js +1 -1
  29. package/dist/billing-foundation/projection.js +1 -2
  30. package/dist/cap-counter/calendar-cap-usage-reservation.d.ts +7 -0
  31. package/dist/cap-counter/calendar-cap-usage-reservation.js +28 -2
  32. package/dist/cap-counter/cap-reservation.d.ts +16 -0
  33. package/dist/cap-counter/cap-reservation.js +144 -14
  34. package/dist/cap-counter/feature.d.ts +4 -0
  35. package/dist/cap-counter/feature.js +74 -68
  36. package/dist/cap-counter/handlers/increment-rolling.write.js +3 -4
  37. package/dist/cap-counter/index.d.ts +3 -2
  38. package/dist/cap-counter/index.js +3 -2
  39. package/dist/cap-counter/tables.js +10 -3
  40. package/dist/cap-overview/handlers/caps-usage.query.js +1 -2
  41. package/dist/cap-overview/handlers/tenant-caps-list.query.js +1 -2
  42. package/dist/cap-overview/handlers/tenant-options.query.js +1 -1
  43. package/dist/channel-email/email-channel.d.ts +5 -1
  44. package/dist/channel-email/email-channel.js +8 -2
  45. package/dist/channel-email/feature.js +1 -1
  46. package/dist/channel-in-app/handlers/inbox.query.js +1 -1
  47. package/dist/channel-in-app/handlers/mark-all-read.write.js +1 -1
  48. package/dist/channel-in-app/handlers/mark-read.write.js +1 -1
  49. package/dist/channel-in-app/handlers/unread-count.query.js +1 -1
  50. package/dist/channel-in-app/tables.js +1 -2
  51. package/dist/compliance-profiles/handlers/for-tenant.query.js +1 -1
  52. package/dist/compliance-profiles/handlers/needs-profile.query.js +1 -1
  53. package/dist/compliance-profiles/handlers/set-profile.write.js +1 -2
  54. package/dist/compliance-profiles/resolve-for-tenant.js +1 -1
  55. package/dist/compliance-profiles/seeding.js +3 -5
  56. package/dist/compliance-profiles-ops/index.d.ts +8 -0
  57. package/dist/compliance-profiles-ops/index.js +19 -15
  58. package/dist/config/db/queries/resolver.js +1 -1
  59. package/dist/config/handlers/reencrypt.job.js +2 -2
  60. package/dist/config/resolver.js +1 -1
  61. package/dist/config/write-helpers.js +1 -1
  62. package/dist/crypto-shredding/handlers/forget-subject.write.js +6 -3
  63. package/dist/custom-fields/db/queries/field-access.js +1 -1
  64. package/dist/custom-fields/db/queries/projection.js +1 -1
  65. package/dist/custom-fields/db/queries/quota.js +1 -1
  66. package/dist/custom-fields/db/queries/retention.js +1 -2
  67. package/dist/custom-fields/db/queries/user-data-rights.js +1 -1
  68. package/dist/custom-fields/feature.d.ts +20 -2
  69. package/dist/custom-fields/feature.js +9 -13
  70. package/dist/custom-fields/handlers/clear-custom-field.write.js +2 -2
  71. package/dist/custom-fields/handlers/delete-system-field.write.js +2 -2
  72. package/dist/custom-fields/handlers/delete-tenant-field.write.js +2 -2
  73. package/dist/custom-fields/handlers/set-custom-field.write.js +2 -2
  74. package/dist/custom-fields/wire-for-entity.js +4 -4
  75. package/dist/data-retention/resolve-for-tenant.js +1 -1
  76. package/dist/data-retention/run-retention-cleanup.js +17 -13
  77. package/dist/delivery/address-opt-out.js +1 -2
  78. package/dist/delivery/attempt-log-retention.js +1 -1
  79. package/dist/delivery/channel-context.js +2 -1
  80. package/dist/delivery/db/queries/address-opt-outs.js +1 -1
  81. package/dist/delivery/db/queries/preferences.js +1 -1
  82. package/dist/delivery/delivery-service.d.ts +2 -0
  83. package/dist/delivery/delivery-service.js +46 -11
  84. package/dist/delivery/feature.js +2 -2
  85. package/dist/delivery/handlers/log.query.js +2 -3
  86. package/dist/delivery/handlers/preferences.query.js +1 -1
  87. package/dist/delivery/handlers/unsubscribe-address.write.d.ts +6 -0
  88. package/dist/delivery/handlers/unsubscribe-address.write.js +8 -5
  89. package/dist/delivery/index.d.ts +3 -0
  90. package/dist/delivery/index.js +2 -0
  91. package/dist/delivery/testing.d.ts +2 -0
  92. package/dist/delivery/types.d.ts +2 -1
  93. package/dist/delivery/unsubscribe-link.d.ts +25 -0
  94. package/dist/delivery/unsubscribe-link.js +40 -0
  95. package/dist/delivery/unsubscribe-page-strings.d.ts +11 -0
  96. package/dist/delivery/unsubscribe-page-strings.js +15 -0
  97. package/dist/delivery/unsubscribe.d.ts +3 -0
  98. package/dist/delivery/unsubscribe.js +65 -29
  99. package/dist/delivery/upsert-preference.js +1 -2
  100. package/dist/derivatives-sharp/feature.d.ts +4 -0
  101. package/dist/derivatives-sharp/feature.js +15 -11
  102. package/dist/derivatives-sharp/index.d.ts +1 -1
  103. package/dist/derivatives-sharp/index.js +1 -1
  104. package/dist/document-ingest-foundation/feature.d.ts +7 -0
  105. package/dist/document-ingest-foundation/feature.js +94 -90
  106. package/dist/document-ingest-foundation/forget-extract-with-file-ref.js +3 -3
  107. package/dist/document-ingest-foundation/index.d.ts +1 -1
  108. package/dist/document-ingest-foundation/index.js +1 -1
  109. package/dist/feature-toggles/global-feature-state-table.js +1 -2
  110. package/dist/feature-toggles/handlers/set.write.js +3 -5
  111. package/dist/feature-toggles/toggle-runtime.js +1 -1
  112. package/dist/file-derivatives/feature.d.ts +1 -0
  113. package/dist/file-derivatives/feature.js +2 -1
  114. package/dist/file-derivatives/handlers/public-variant-by-file-ref.query.js +1 -1
  115. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  116. package/dist/file-foundation/feature.d.ts +6 -0
  117. package/dist/file-foundation/feature.js +29 -25
  118. package/dist/file-foundation/index.d.ts +1 -1
  119. package/dist/file-foundation/index.js +1 -1
  120. package/dist/file-foundation/read-file-ref-content.js +1 -1
  121. package/dist/file-provider-inmemory/feature.d.ts +4 -0
  122. package/dist/file-provider-inmemory/feature.js +24 -20
  123. package/dist/file-provider-inmemory/index.d.ts +1 -1
  124. package/dist/file-provider-inmemory/index.js +1 -1
  125. package/dist/file-provider-s3/env-feature.d.ts +3 -0
  126. package/dist/file-provider-s3/env-feature.js +46 -0
  127. package/dist/file-provider-s3/feature.d.ts +26 -0
  128. package/dist/file-provider-s3/feature.js +84 -72
  129. package/dist/file-provider-s3/index.d.ts +1 -1
  130. package/dist/file-provider-s3/index.js +1 -1
  131. package/dist/file-provider-s3/lib/index.d.ts +3 -0
  132. package/dist/file-provider-s3/lib/index.js +2 -0
  133. package/dist/{files-provider-s3 → file-provider-s3/lib}/s3-provider.js +19 -19
  134. package/dist/file-provider-s3-env/index.d.ts +8 -1
  135. package/dist/file-provider-s3-env/index.js +7 -2
  136. package/dist/files-provider-s3/index.d.ts +5 -3
  137. package/dist/files-provider-s3/index.js +5 -2
  138. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +1 -1
  139. package/dist/files-tenant-data/hooks.js +1 -2
  140. package/dist/folders/feature.d.ts +6 -2
  141. package/dist/folders/feature.js +4 -2
  142. package/dist/folders-user-data/index.d.ts +4 -0
  143. package/dist/folders-user-data/index.js +21 -17
  144. package/dist/form-draft/db/queries/cleanup.js +1 -1
  145. package/dist/form-draft/db/queries/draft-count.js +1 -1
  146. package/dist/form-draft/db/queries/owned-file-refs.js +1 -2
  147. package/dist/form-draft/feature.d.ts +4 -0
  148. package/dist/form-draft/feature.js +5 -1
  149. package/dist/form-draft/handlers/cleanup.job.js +2 -2
  150. package/dist/form-draft/index.d.ts +1 -1
  151. package/dist/form-draft/index.js +1 -1
  152. package/dist/form-draft/lookup.js +1 -1
  153. package/dist/form-draft-user-data/index.d.ts +4 -0
  154. package/dist/form-draft-user-data/index.js +13 -9
  155. package/dist/inbound-mail-foundation/feature.d.ts +4 -0
  156. package/dist/inbound-mail-foundation/feature.js +151 -147
  157. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +1 -2
  158. package/dist/inbound-mail-foundation/index.d.ts +1 -1
  159. package/dist/inbound-mail-foundation/index.js +1 -1
  160. package/dist/inbound-mail-foundation/oauth-access-token.js +1 -2
  161. package/dist/inbound-mail-foundation/projection.js +1 -2
  162. package/dist/inbound-mail-foundation/watch-supervisor.js +1 -1
  163. package/dist/inbound-provider-imap/feature.d.ts +4 -0
  164. package/dist/inbound-provider-imap/feature.js +16 -12
  165. package/dist/inbound-provider-imap/index.d.ts +1 -1
  166. package/dist/inbound-provider-imap/index.js +1 -1
  167. package/dist/inbound-provider-inmemory/feature.d.ts +4 -0
  168. package/dist/inbound-provider-inmemory/feature.js +14 -10
  169. package/dist/inbound-provider-inmemory/index.d.ts +1 -1
  170. package/dist/inbound-provider-inmemory/index.js +1 -1
  171. package/dist/jobs/db/queries/retention.js +1 -1
  172. package/dist/jobs/db/queries/stale-run-sweep.js +1 -1
  173. package/dist/jobs/handlers/detail.query.js +1 -1
  174. package/dist/jobs/handlers/list.query.js +1 -2
  175. package/dist/jobs/handlers/retry.write.js +1 -1
  176. package/dist/jobs/handlers/tenant-failures.query.js +1 -1
  177. package/dist/jobs/handlers/tenant-runs.query.js +1 -1
  178. package/dist/jobs/job-run-logger.js +1 -2
  179. package/dist/jobs/tenant-job-failure-table.js +1 -2
  180. package/dist/jobs/tenant-job-run-table.js +1 -2
  181. package/dist/ledger/feature.d.ts +6 -2
  182. package/dist/ledger/feature.js +4 -2
  183. package/dist/mail-foundation/feature.d.ts +23 -1
  184. package/dist/mail-foundation/feature.js +76 -49
  185. package/dist/mail-foundation/index.d.ts +1 -1
  186. package/dist/mail-foundation/index.js +1 -1
  187. package/dist/mail-transport-inmemory/feature.d.ts +4 -0
  188. package/dist/mail-transport-inmemory/feature.js +20 -16
  189. package/dist/mail-transport-inmemory/index.d.ts +1 -1
  190. package/dist/mail-transport-inmemory/index.js +1 -1
  191. package/dist/mail-transport-smtp/feature.d.ts +16 -0
  192. package/dist/mail-transport-smtp/feature.js +85 -79
  193. package/dist/mail-transport-smtp/index.d.ts +1 -1
  194. package/dist/mail-transport-smtp/index.js +1 -1
  195. package/dist/managed-pages/handlers/by-slug.query.js +1 -1
  196. package/dist/managed-pages/handlers/by-tenant-published.query.js +1 -2
  197. package/dist/managed-pages/handlers/set.write.js +1 -2
  198. package/dist/managed-pages/seeding.js +3 -5
  199. package/dist/metrics/compute.d.ts +1 -1
  200. package/dist/metrics/filters.d.ts +1 -1
  201. package/dist/metrics/filters.js +1 -1
  202. package/dist/metrics/validate.js +1 -1
  203. package/dist/notes-history/feature.d.ts +7 -2
  204. package/dist/notes-history/feature.js +4 -2
  205. package/dist/notes-history/handlers/add-note.write.js +1 -1
  206. package/dist/notes-history-user-data/hooks.js +1 -1
  207. package/dist/notes-history-user-data/index.d.ts +4 -0
  208. package/dist/notes-history-user-data/index.js +21 -17
  209. package/dist/personal-access-tokens/feature.d.ts +4 -1
  210. package/dist/personal-access-tokens/feature.js +10 -2
  211. package/dist/personal-access-tokens/handlers/create.write.js +1 -1
  212. package/dist/personal-access-tokens/handlers/list.query.js +2 -2
  213. package/dist/personal-access-tokens/handlers/revoke.write.js +1 -1
  214. package/dist/personal-access-tokens/resolver.js +1 -1
  215. package/dist/personal-access-tokens/revoke-for-user.js +1 -1
  216. package/dist/personal-access-tokens/roles.js +3 -5
  217. package/dist/personal-access-tokens/screens.js +2 -0
  218. package/dist/readiness/feature.d.ts +8 -0
  219. package/dist/readiness/feature.js +18 -14
  220. package/dist/readiness/index.d.ts +1 -1
  221. package/dist/readiness/index.js +1 -1
  222. package/dist/secrets/db/queries/read.js +1 -1
  223. package/dist/secrets/feature.d.ts +3 -0
  224. package/dist/secrets/feature.js +3 -2
  225. package/dist/secrets/handlers/rotate.job.js +2 -3
  226. package/dist/secrets/secrets-context.js +3 -4
  227. package/dist/sessions/db/queries/cleanup.js +1 -1
  228. package/dist/sessions/handlers/detail.query.js +1 -1
  229. package/dist/sessions/handlers/list.query.js +2 -2
  230. package/dist/sessions/handlers/mine.query.js +1 -1
  231. package/dist/sessions/handlers/revoke-all-for-user.write.js +1 -1
  232. package/dist/sessions/handlers/revoke-all-others.write.js +1 -1
  233. package/dist/sessions/handlers/revoke.write.js +1 -1
  234. package/dist/sessions/session-callbacks.js +4 -6
  235. package/dist/sessions/testing.d.ts +1 -1
  236. package/dist/tags/feature.d.ts +6 -2
  237. package/dist/tags/feature.js +4 -2
  238. package/dist/template-resolver/api.js +1 -1
  239. package/dist/template-resolver/compile-document-body.js +47 -11
  240. package/dist/template-resolver/document-sanitizer.d.ts +2 -0
  241. package/dist/template-resolver/document-sanitizer.js +16 -1
  242. package/dist/template-resolver/document-schema.d.ts +2 -0
  243. package/dist/template-resolver/document-schema.js +31 -0
  244. package/dist/template-resolver/handlers/bundle-import.js +4 -3
  245. package/dist/template-resolver/handlers/by-slug.query.js +1 -1
  246. package/dist/template-resolver/handlers/by-tenant.query.js +1 -2
  247. package/dist/template-resolver/handlers/collection-item.query.js +1 -1
  248. package/dist/template-resolver/handlers/collection-list.query.js +1 -2
  249. package/dist/template-resolver/handlers/collection-set.write.js +1 -1
  250. package/dist/template-resolver/handlers/copy-locale.write.js +4 -3
  251. package/dist/template-resolver/handlers/diff-to-system.query.js +1 -1
  252. package/dist/template-resolver/handlers/export-bundle.query.js +1 -1
  253. package/dist/template-resolver/handlers/find-by-id.query.js +6 -2
  254. package/dist/template-resolver/handlers/layout-source.query.js +1 -1
  255. package/dist/template-resolver/handlers/list.query.js +4 -2
  256. package/dist/template-resolver/handlers/overview.query.js +5 -3
  257. package/dist/template-resolver/handlers/reset-to-system.write.js +1 -1
  258. package/dist/template-resolver/handlers/resource-remove.write.js +1 -1
  259. package/dist/template-resolver/handlers/set.write.js +1 -1
  260. package/dist/template-resolver/handlers/template-write.d.ts +2 -1
  261. package/dist/template-resolver/handlers/template-write.js +13 -2
  262. package/dist/template-resolver/handlers/tenant-overrides.query.js +1 -1
  263. package/dist/template-resolver/handlers/toggle-status.write.js +1 -1
  264. package/dist/template-resolver/handlers/usage.query.js +1 -1
  265. package/dist/template-resolver/handlers/validate.query.js +1 -1
  266. package/dist/template-resolver/index.d.ts +3 -2
  267. package/dist/template-resolver/index.js +3 -2
  268. package/dist/template-resolver/qualified-names.d.ts +1 -0
  269. package/dist/template-resolver/qualified-names.js +1 -0
  270. package/dist/template-resolver/seeding.d.ts +4 -0
  271. package/dist/template-resolver/seeding.js +43 -9
  272. package/dist/template-resolver/store-template-resource.js +1 -1
  273. package/dist/template-resolver/template-preview.js +3 -1
  274. package/dist/template-resolver/template-resources.js +1 -1
  275. package/dist/template-resolver/template-system-only.d.ts +8 -0
  276. package/dist/template-resolver/template-system-only.js +11 -0
  277. package/dist/template-resolver/template-validation.js +42 -28
  278. package/dist/template-resolver/testing.js +1 -1
  279. package/dist/template-resolver/web/i18n.js +1 -0
  280. package/dist/template-resolver-user-data/index.d.ts +4 -0
  281. package/dist/template-resolver-user-data/index.js +17 -13
  282. package/dist/tenant/handlers/active-tenant-ids.query.js +1 -1
  283. package/dist/tenant/handlers/add-member.write.js +1 -2
  284. package/dist/tenant/handlers/cancel-invitation.write.js +1 -1
  285. package/dist/tenant/handlers/invitations.query.js +1 -1
  286. package/dist/tenant/handlers/me.query.js +1 -1
  287. package/dist/tenant/handlers/member-directory.query.js +1 -1
  288. package/dist/tenant/handlers/members.query.js +1 -1
  289. package/dist/tenant/handlers/memberships.query.js +1 -1
  290. package/dist/tenant/handlers/remove-member.write.js +1 -2
  291. package/dist/tenant/handlers/resolve-user-ids.query.js +1 -1
  292. package/dist/tenant/handlers/team-list.query.js +1 -1
  293. package/dist/tenant/handlers/tenant-directory.query.js +1 -1
  294. package/dist/tenant/handlers/update-member-roles.write.js +1 -2
  295. package/dist/tenant/invited-membership.js +2 -3
  296. package/dist/tenant/last-tenant-admin.js +1 -2
  297. package/dist/tenant/seeding.js +12 -6
  298. package/dist/tenant-lifecycle/handlers/cancel-destruction.write.js +1 -2
  299. package/dist/tenant-lifecycle/handlers/request-destruction.write.js +1 -2
  300. package/dist/tenant-lifecycle/lib/revoke-tenant-sessions.js +1 -1
  301. package/dist/tenant-lifecycle/lifecycle-gate.js +1 -1
  302. package/dist/tenant-lifecycle/run-tenant-destroy.js +3 -5
  303. package/dist/tenant-lifecycle/stages.js +10 -6
  304. package/dist/tenant-lifecycle/testing.d.ts +1 -1
  305. package/dist/tenant-lifecycle/testing.js +2 -2
  306. package/dist/tenant-settings/feature.d.ts +1 -0
  307. package/dist/tenant-settings/feature.js +2 -1
  308. package/dist/tier-engine/feature.d.ts +1 -8
  309. package/dist/tier-engine/feature.js +71 -78
  310. package/dist/tier-engine/handlers/get-tenant-tier.query.js +2 -3
  311. package/dist/tier-engine/handlers/set-tenant-tier.write.js +1 -2
  312. package/dist/user/db/queries/stream-tenant-backfill.js +1 -1
  313. package/dist/user/handlers/create.write.js +1 -2
  314. package/dist/user/handlers/find-for-auth.query.js +1 -1
  315. package/dist/user/handlers/list.query.js +1 -1
  316. package/dist/user/handlers/update-roles.js +1 -2
  317. package/dist/user/index.d.ts +1 -1
  318. package/dist/user/index.js +1 -1
  319. package/dist/user/invited-global-roles.js +2 -3
  320. package/dist/user/principal-status.d.ts +4 -0
  321. package/dist/user/principal-status.js +9 -3
  322. package/dist/user/resolve-display-names.js +1 -1
  323. package/dist/user/seeding.js +5 -6
  324. package/dist/user-data-rights/audit-download.js +2 -2
  325. package/dist/user-data-rights/db/queries/export-jobs.js +1 -1
  326. package/dist/user-data-rights/db/queries/forget-cleanup.js +1 -1
  327. package/dist/user-data-rights/handlers/download-by-job.query.js +1 -1
  328. package/dist/user-data-rights/handlers/download-by-token.query.js +1 -1
  329. package/dist/user-data-rights/handlers/export-status.query.js +1 -1
  330. package/dist/user-data-rights/handlers/list-download-attempts.query.js +1 -1
  331. package/dist/user-data-rights/handlers/my-audit-log.query.js +1 -1
  332. package/dist/user-data-rights/handlers/request-export.write.js +1 -2
  333. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +3 -3
  334. package/dist/user-data-rights/lib/deny-if-target-outside-admin-tenant.d.ts +1 -1
  335. package/dist/user-data-rights/lib/deny-if-target-outside-admin-tenant.js +1 -1
  336. package/dist/user-data-rights/lib/update-user-lifecycle.d.ts +1 -0
  337. package/dist/user-data-rights/lib/update-user-lifecycle.js +3 -3
  338. package/dist/user-data-rights/run-export-jobs.js +2 -3
  339. package/dist/user-data-rights/run-forget-cleanup.js +9 -5
  340. package/dist/user-data-rights/run-user-export.js +9 -5
  341. package/dist/waitlist/handlers/invite.write.js +1 -2
  342. package/dist/waitlist/handlers/reject.write.js +1 -1
  343. package/dist/waitlist/lib.js +1 -2
  344. package/dist/workflow-runner/event-subscriber.js +1 -1
  345. package/dist/workflow-runner/feature.d.ts +4 -0
  346. package/dist/workflow-runner/feature.js +44 -40
  347. package/dist/workflow-runner/handlers/resume-run.write.js +1 -1
  348. package/dist/workflow-runner/index.d.ts +1 -1
  349. package/dist/workflow-runner/index.js +1 -1
  350. package/dist/workflow-runner/pending-projection.js +1 -1
  351. package/package.json +28 -11
  352. package/src/cap-counter/changes.json +13 -0
  353. package/src/channel-email/changes.json +6 -0
  354. package/src/crypto-shredding/changes.json +6 -0
  355. package/src/delivery/changes.json +12 -0
  356. package/src/file-provider-s3/changes.json +10 -1
  357. package/src/personal-access-tokens/changes.json +6 -0
  358. package/src/template-resolver/changes.json +25 -0
  359. package/src/user/changes.json +6 -0
  360. package/src/user-data-rights/changes.json +6 -0
  361. package/dist/file-provider-s3-env/feature.d.ts +0 -3
  362. package/dist/file-provider-s3-env/feature.js +0 -46
  363. /package/dist/{files-provider-s3 → file-provider-s3/lib}/env-helper.d.ts +0 -0
  364. /package/dist/{files-provider-s3 → file-provider-s3/lib}/env-helper.js +0 -0
  365. /package/dist/{files-provider-s3 → file-provider-s3/lib}/s3-provider.d.ts +0 -0
@@ -54,151 +54,155 @@ import { updateAccountHandler } from "./handlers/update-account.write.js";
54
54
  import { applyInboundMessageReceived, applyMailAccountConnected, applyMailAccountDisconnected, applyMailAccountUpdated, applyMailThreadUpdated, inboundMessagesProjectionTable, mailAccountsProjectionTable, mailThreadsProjectionTable, } from "./projection.js";
55
55
  import { runInboundMailRetention } from "./retention-sweep.js";
56
56
  import { INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON, inboundMessageTenantDestroyHook, mailAccountTenantDestroyHook, mailThreadTenantDestroyHook, } from "./tenant-destroy-hook.js";
57
- export const inboundMailFoundationFeature = defineFeature(INBOUND_MAIL_FOUNDATION_FEATURE, (r) => {
58
- r.describe("Plugin host for inbound e-mail (inbox federation) — provider plugins (inbound-provider-imap, later M365 Graph / Gmail REST) register at the `inboundMailProvider` extension point with verify/fetch and optional oauth/watch (live push). The foundation owns three event-sourced streams (mail-account lifecycle, inbound-message with exactly-once ingest via deterministic aggregate ids, mail-thread rollup) and their projections `read_mail_accounts`/`read_inbound_messages`/`read_mail_threads`; PII fields are envelope-encrypted per tenant subject key before every append (crypto-shredding on tenant destroy). Wire `createInboundMailConnectRoutes` (OAuth connect + anonymous callback outside /api) and `createInboundMailSupervisor` (IDLE watch with backoff + reconciliation poll) in bin/server.ts. Consume `inbound-mail-foundation:event:inbound-message-received` from app features to attach business processes.");
59
- r.uiHints({
60
- displayLabel: "Inbound Mail · Foundation",
61
- category: "notifications",
62
- recommended: false,
63
- });
64
- // EXT_TENANT_DATA-Hook braucht den tenant-lifecycle-Host.
65
- r.requires({ features: ["tenant-lifecycle"] });
66
- // 5 fine-grained domain-events (Payload-Schemas: events.ts).
67
- // piiFields: "none" — address/subject/snippet are already ciphertext under the tenant subject key before append (see events.ts).
68
- // "displayName" stays plaintext (often the mailbox owner's real name for
69
- // personal accounts); encrypting it would break the entity-projection read
70
- // path that carries it as `personal: false`.
71
- r.defineEvent(MAIL_ACCOUNT_CONNECTED_EVENT_SHORT, mailAccountEventPayloadSchema, {
72
- piiFields: "none",
73
- });
74
- r.defineEvent(MAIL_ACCOUNT_UPDATED_EVENT_SHORT, mailAccountEventPayloadSchema, {
75
- piiFields: "none",
76
- });
77
- r.defineEvent(MAIL_ACCOUNT_DISCONNECTED_EVENT_SHORT, mailAccountEventPayloadSchema, {
78
- piiFields: "none",
79
- });
80
- r.defineEvent(INBOUND_MESSAGE_RECEIVED_EVENT_SHORT, inboundMessageEventPayloadSchema, {
81
- piiFields: "none",
82
- });
83
- r.defineEvent(MAIL_THREAD_UPDATED_EVENT_SHORT, mailThreadEventPayloadSchema, {
84
- piiFields: "none",
85
- });
86
- // Inline projections — apply in derselben TX wie der Append.
87
- r.projection({
88
- name: "mail-account",
89
- source: MAIL_ACCOUNT_AGGREGATE_TYPE,
90
- table: mailAccountsProjectionTable,
91
- entity: mailAccountEntity,
92
- apply: {
93
- [MAIL_ACCOUNT_CONNECTED_EVENT_QN]: applyMailAccountConnected,
94
- [MAIL_ACCOUNT_UPDATED_EVENT_QN]: applyMailAccountUpdated,
95
- [MAIL_ACCOUNT_DISCONNECTED_EVENT_QN]: applyMailAccountDisconnected,
96
- },
97
- });
98
- r.projection({
99
- name: "inbound-message",
100
- source: INBOUND_MESSAGE_AGGREGATE_TYPE,
101
- table: inboundMessagesProjectionTable,
102
- entity: inboundMessageEntity,
103
- apply: {
104
- [INBOUND_MESSAGE_RECEIVED_EVENT_QN]: applyInboundMessageReceived,
105
- },
106
- });
107
- r.projection({
108
- name: "mail-thread",
109
- source: MAIL_THREAD_AGGREGATE_TYPE,
110
- table: mailThreadsProjectionTable,
111
- entity: mailThreadEntity,
112
- apply: {
113
- [MAIL_THREAD_UPDATED_EVENT_QN]: applyMailThreadUpdated,
114
- },
115
- });
116
- // Plugin extension-point — Provider registrieren sich via
117
- // r.useExtension("inboundMailProvider", "<key>", plugin).
118
- r.extendsRegistrar(INBOUND_MAIL_PROVIDER_EXTENSION, {
119
- onRegister: () => {
120
- // No side-effects at register-time — Lookup läuft zur Laufzeit
121
- // über resolveInboundProviderForKey/-Account.
122
- },
123
- });
124
- // Sync-Maschinerie: hochfrequenter Tick-State, bewusst NICHT
125
- // event-sourced — r.storeTable hält die Migration-DDL, nimmt die
126
- // Tabellen aber aus dem Projection-Rebuild (#494/#498-Klasse).
127
- r.storeTable(syncCursorTable, {
128
- reason: "read_side.mail_sync_cursors_direct_write",
129
- });
130
- r.storeTable(seenMessageTable, {
131
- reason: "read_side.mail_seen_messages_direct_write",
132
- });
133
- // Write-Handler:
134
- // - ingest-message: programmatic (Supervisor/Poll, SystemAdmin)
135
- // - connect/update/disconnect-account: Lifecycle
136
- r.writeHandler(ingestMessageHandler);
137
- r.writeHandler(connectAccountHandler);
138
- r.writeHandler(updateAccountHandler);
139
- r.writeHandler(disconnectAccountHandler);
140
- // List-Queries (PII-decrypted, scope-gefiltert).
141
- r.queryHandler(listAccountsQuery);
142
- r.queryHandler(listMessagesQuery);
143
- // Entity-genaue GDPR-Destroy-Hooks — der gdpr-storage-Boot-Validator
144
- // prueft die EXT_TENANT_DATA-Registrierung pro tenant-subject-Entity.
145
- r.useExtension(EXT_TENANT_DATA, "mail-account", {
146
- destroy: mailAccountTenantDestroyHook,
147
- escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
148
- });
149
- r.useExtension(EXT_TENANT_DATA, "inbound-message", {
150
- destroy: inboundMessageTenantDestroyHook,
151
- escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
152
- });
153
- r.useExtension(EXT_TENANT_DATA, "mail-thread", {
154
- destroy: mailThreadTenantDestroyHook,
155
- escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
156
- });
157
- // Data-Retention (#957) — perTenant fan-out (one run per tenant, like
158
- // data-retention:retention-cleanup): runInboundMailRetention's raw query
159
- // helpers need the unfiltered runner, so the handler declares escapeHatch
160
- // and reaches for ctx.db.unsafeRaw(). Without this cron, read_inbound_messages
161
- // + the bodies grow unbounded (GDPR Art. 5).
162
- const INBOUND_MAIL_RETENTION_REASON = "inbound-mail retention runs raw deletes; every statement filters by this run's tenantId";
163
- r.job({
164
- name: "inbound-mail-retention",
165
- trigger: { cron: "0 3 * * *" },
166
- perTenant: true,
167
- concurrency: "skip",
168
- escapeHatch: { reason: INBOUND_MAIL_RETENTION_REASON },
169
- handler: async (_payload, ctx) => {
170
- if (!ctx.registry) {
171
- throw new Error("inbound-mail-retention: ctx.registry required (JobContext incomplete)");
172
- }
173
- const tenantId = ctx.systemUser?.tenantId ?? ctx._tenantId;
174
- if (tenantId === undefined) {
175
- // skip: cron fired without a perTenant fan-out tenant — nothing scoped
176
- return;
177
- }
178
- const T = (await import("@cosmicdrift/kumiko-framework/time")).getTemporal();
179
- const retentionDb = ctx.db.unsafeRaw(); // @cast-boundary db-operator — jobs never run inside a DbTx
180
- // Body-Objekte liegen in file-foundation. Provider lazy + memoized —
181
- // heute schreibt der Ingest kein bodyRef (storeBody-Hook ungebunden),
182
- // der Provider wird also nie gebaut. Sobald storeBody wired ist, raeumt
183
- // die Retention die Bodies mit ab.
184
- let providerPromise = null;
185
- const deleteBodyObject = async (bodyRef) => {
186
- if (!providerPromise) {
187
- providerPromise = createFileProviderForTenant({ config: ctx.config, registry: ctx.registry }, tenantId);
57
+ export function createInboundMailFoundationFeature() {
58
+ return defineFeature(INBOUND_MAIL_FOUNDATION_FEATURE, (r) => {
59
+ r.describe("Plugin host for inbound e-mail (inbox federation) — provider plugins (inbound-provider-imap, later M365 Graph / Gmail REST) register at the `inboundMailProvider` extension point with verify/fetch and optional oauth/watch (live push). The foundation owns three event-sourced streams (mail-account lifecycle, inbound-message with exactly-once ingest via deterministic aggregate ids, mail-thread rollup) and their projections `read_mail_accounts`/`read_inbound_messages`/`read_mail_threads`; PII fields are envelope-encrypted per tenant subject key before every append (crypto-shredding on tenant destroy). Wire `createInboundMailConnectRoutes` (OAuth connect + anonymous callback outside /api) and `createInboundMailSupervisor` (IDLE watch with backoff + reconciliation poll) in bin/server.ts. Consume `inbound-mail-foundation:event:inbound-message-received` from app features to attach business processes.");
60
+ r.uiHints({
61
+ displayLabel: "Inbound Mail · Foundation",
62
+ category: "notifications",
63
+ recommended: false,
64
+ });
65
+ // EXT_TENANT_DATA-Hook braucht den tenant-lifecycle-Host.
66
+ r.requires({ features: ["tenant-lifecycle"] });
67
+ // 5 fine-grained domain-events (Payload-Schemas: events.ts).
68
+ // piiFields: "none" — address/subject/snippet are already ciphertext under the tenant subject key before append (see events.ts).
69
+ // "displayName" stays plaintext (often the mailbox owner's real name for
70
+ // personal accounts); encrypting it would break the entity-projection read
71
+ // path that carries it as `personal: false`.
72
+ r.defineEvent(MAIL_ACCOUNT_CONNECTED_EVENT_SHORT, mailAccountEventPayloadSchema, {
73
+ piiFields: "none",
74
+ });
75
+ r.defineEvent(MAIL_ACCOUNT_UPDATED_EVENT_SHORT, mailAccountEventPayloadSchema, {
76
+ piiFields: "none",
77
+ });
78
+ r.defineEvent(MAIL_ACCOUNT_DISCONNECTED_EVENT_SHORT, mailAccountEventPayloadSchema, {
79
+ piiFields: "none",
80
+ });
81
+ r.defineEvent(INBOUND_MESSAGE_RECEIVED_EVENT_SHORT, inboundMessageEventPayloadSchema, {
82
+ piiFields: "none",
83
+ });
84
+ r.defineEvent(MAIL_THREAD_UPDATED_EVENT_SHORT, mailThreadEventPayloadSchema, {
85
+ piiFields: "none",
86
+ });
87
+ // Inline projections — apply in derselben TX wie der Append.
88
+ r.projection({
89
+ name: "mail-account",
90
+ source: MAIL_ACCOUNT_AGGREGATE_TYPE,
91
+ table: mailAccountsProjectionTable,
92
+ entity: mailAccountEntity,
93
+ apply: {
94
+ [MAIL_ACCOUNT_CONNECTED_EVENT_QN]: applyMailAccountConnected,
95
+ [MAIL_ACCOUNT_UPDATED_EVENT_QN]: applyMailAccountUpdated,
96
+ [MAIL_ACCOUNT_DISCONNECTED_EVENT_QN]: applyMailAccountDisconnected,
97
+ },
98
+ });
99
+ r.projection({
100
+ name: "inbound-message",
101
+ source: INBOUND_MESSAGE_AGGREGATE_TYPE,
102
+ table: inboundMessagesProjectionTable,
103
+ entity: inboundMessageEntity,
104
+ apply: {
105
+ [INBOUND_MESSAGE_RECEIVED_EVENT_QN]: applyInboundMessageReceived,
106
+ },
107
+ });
108
+ r.projection({
109
+ name: "mail-thread",
110
+ source: MAIL_THREAD_AGGREGATE_TYPE,
111
+ table: mailThreadsProjectionTable,
112
+ entity: mailThreadEntity,
113
+ apply: {
114
+ [MAIL_THREAD_UPDATED_EVENT_QN]: applyMailThreadUpdated,
115
+ },
116
+ });
117
+ // Plugin extension point — providers register via
118
+ // r.useExtension("inboundMailProvider", "<key>", plugin).
119
+ r.extendsRegistrar(INBOUND_MAIL_PROVIDER_EXTENSION, {
120
+ onRegister: () => {
121
+ // No side-effects at register-time — lookup happens at runtime
122
+ // via resolveInboundProviderForKey/-Account.
123
+ },
124
+ });
125
+ // Sync machinery: high-frequency tick state, deliberately NOT
126
+ // event-sourced — r.storeTable keeps the migration DDL but excludes the
127
+ // tables from the projection rebuild (#494/#498 class).
128
+ r.storeTable(syncCursorTable, {
129
+ reason: "read_side.mail_sync_cursors_direct_write",
130
+ });
131
+ r.storeTable(seenMessageTable, {
132
+ reason: "read_side.mail_seen_messages_direct_write",
133
+ });
134
+ // Write-Handler:
135
+ // - ingest-message: programmatic (Supervisor/Poll, SystemAdmin)
136
+ // - connect/update/disconnect-account: Lifecycle
137
+ r.writeHandler(ingestMessageHandler);
138
+ r.writeHandler(connectAccountHandler);
139
+ r.writeHandler(updateAccountHandler);
140
+ r.writeHandler(disconnectAccountHandler);
141
+ // List-Queries (PII-decrypted, scope-gefiltert).
142
+ r.queryHandler(listAccountsQuery);
143
+ r.queryHandler(listMessagesQuery);
144
+ // Entity-genaue GDPR-Destroy-Hooks — der gdpr-storage-Boot-Validator
145
+ // prueft die EXT_TENANT_DATA-Registrierung pro tenant-subject-Entity.
146
+ r.useExtension(EXT_TENANT_DATA, "mail-account", {
147
+ destroy: mailAccountTenantDestroyHook,
148
+ escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
149
+ });
150
+ r.useExtension(EXT_TENANT_DATA, "inbound-message", {
151
+ destroy: inboundMessageTenantDestroyHook,
152
+ escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
153
+ });
154
+ r.useExtension(EXT_TENANT_DATA, "mail-thread", {
155
+ destroy: mailThreadTenantDestroyHook,
156
+ escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
157
+ });
158
+ // Data-Retention (#957) — perTenant fan-out (one run per tenant, like
159
+ // data-retention:retention-cleanup): runInboundMailRetention's raw query
160
+ // helpers need the unfiltered runner, so the handler declares escapeHatch
161
+ // and reaches for ctx.db.unsafeRaw(). Without this cron, read_inbound_messages
162
+ // + the bodies grow unbounded (GDPR Art. 5).
163
+ const INBOUND_MAIL_RETENTION_REASON = "inbound-mail retention runs raw deletes; every statement filters by this run's tenantId";
164
+ r.job({
165
+ name: "inbound-mail-retention",
166
+ trigger: { cron: "0 3 * * *" },
167
+ perTenant: true,
168
+ concurrency: "skip",
169
+ escapeHatch: { reason: INBOUND_MAIL_RETENTION_REASON },
170
+ handler: async (_payload, ctx) => {
171
+ if (!ctx.registry) {
172
+ throw new Error("inbound-mail-retention: ctx.registry required (JobContext incomplete)");
188
173
  }
189
- const provider = await providerPromise;
190
- await provider.delete(bodyRef);
191
- };
192
- const report = await runInboundMailRetention({
193
- db: retentionDb,
194
- tenantId,
195
- now: T.Now.instant(),
196
- deleteBodyObject,
197
- });
198
- if (report.bodyObjectErrors > 0) {
199
- // biome-ignore lint/suspicious/noConsole: operator-visibility for failed body deletes
200
- console.warn(`[inbound-mail-foundation:inbound-mail-retention] tenant=${tenantId} bodyObjectErrors=${report.bodyObjectErrors}`);
201
- }
202
- },
203
- });
204
- });
174
+ const tenantId = ctx.systemUser?.tenantId ?? ctx._tenantId;
175
+ if (tenantId === undefined) {
176
+ // skip: cron fired without a perTenant fan-out tenant — nothing scoped
177
+ return;
178
+ }
179
+ const T = (await import("@cosmicdrift/kumiko-framework/time")).getTemporal();
180
+ const retentionDb = ctx.db.unsafeRaw(); // @cast-boundary db-operator — jobs never run inside a DbTx
181
+ // Body-Objekte liegen in file-foundation. Provider lazy + memoized —
182
+ // heute schreibt der Ingest kein bodyRef (storeBody-Hook ungebunden),
183
+ // der Provider wird also nie gebaut. Sobald storeBody wired ist, raeumt
184
+ // die Retention die Bodies mit ab.
185
+ let providerPromise = null;
186
+ const deleteBodyObject = async (bodyRef) => {
187
+ if (!providerPromise) {
188
+ providerPromise = createFileProviderForTenant({ config: ctx.config, registry: ctx.registry }, tenantId);
189
+ }
190
+ const provider = await providerPromise;
191
+ await provider.delete(bodyRef);
192
+ };
193
+ const report = await runInboundMailRetention({
194
+ db: retentionDb,
195
+ tenantId,
196
+ now: T.Now.instant(),
197
+ deleteBodyObject,
198
+ });
199
+ if (report.bodyObjectErrors > 0) {
200
+ // biome-ignore lint/suspicious/noConsole: operator-visibility for failed body deletes
201
+ console.warn(`[inbound-mail-foundation:inbound-mail-retention] tenant=${tenantId} bodyObjectErrors=${report.bodyObjectErrors}`);
202
+ }
203
+ },
204
+ });
205
+ }, { dedupeOptions: {} });
206
+ }
207
+ /** @deprecated Use createInboundMailFoundationFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
208
+ export const inboundMailFoundationFeature = createInboundMailFoundationFeature();
@@ -19,9 +19,8 @@
19
19
  //
20
20
  // SystemAdmin-only: Aufrufer ist der Watch/Sync-Supervisor bzw. der
21
21
  // Poll-Cron mit programmatic SystemUser — nie ein Tenant-Request.
22
- import { countWhere } from "@cosmicdrift/kumiko-framework/bun-db";
23
22
  import { configuredPiiSubjectKms, encryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
24
- import { acquireNamespacedAdvisoryLock } from "@cosmicdrift/kumiko-framework/db";
23
+ import { acquireNamespacedAdvisoryLock, countWhere } from "@cosmicdrift/kumiko-framework/db";
25
24
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
26
25
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
27
26
  import * as z from "zod";
@@ -3,7 +3,7 @@ export { createInboundMailConnectRoutes, type InboundMailConnectRoutesOptions, }
3
3
  export { INBOUND_MAIL_FOUNDATION_FEATURE, INBOUND_MAIL_PROVIDER_EXTENSION, type InboundMailAccountStatus, InboundMailAccountStatuses, type InboundMailAuthMethod, InboundMailAuthMethods, InboundMailFoundationHandlers, InboundMailFoundationQueries, inboundCredentialSecretKey, } from "./constants.js";
4
4
  export { INBOUND_MESSAGE_PII_FIELDS, inboundMessageEntity, MAIL_ACCOUNT_PII_FIELDS, MAIL_THREAD_PII_FIELDS, mailAccountEntity, mailThreadEntity, seenMessageEntity, seenMessageTable, syncCursorEntity, syncCursorTable, } from "./entities.js";
5
5
  export { INBOUND_MESSAGE_AGGREGATE_TYPE, INBOUND_MESSAGE_RECEIVED_EVENT_QN, INBOUND_MESSAGE_RECEIVED_EVENT_SHORT, type InboundMessageEventHeaders, type InboundMessageEventPayload, inboundMessageEventPayloadSchema, MAIL_ACCOUNT_AGGREGATE_TYPE, MAIL_ACCOUNT_CONNECTED_EVENT_QN, MAIL_ACCOUNT_CONNECTED_EVENT_SHORT, MAIL_ACCOUNT_DISCONNECTED_EVENT_QN, MAIL_ACCOUNT_DISCONNECTED_EVENT_SHORT, MAIL_ACCOUNT_UPDATED_EVENT_QN, MAIL_ACCOUNT_UPDATED_EVENT_SHORT, MAIL_THREAD_AGGREGATE_TYPE, MAIL_THREAD_UPDATED_EVENT_QN, MAIL_THREAD_UPDATED_EVENT_SHORT, type MailAccountEventHeaders, type MailAccountEventPayload, type MailThreadEventPayload, mailAccountEventPayloadSchema, mailThreadEventPayloadSchema, } from "./events.js";
6
- export { inboundMailFoundationFeature } from "./feature.js";
6
+ export { createInboundMailFoundationFeature, inboundMailFoundationFeature } from "./feature.js";
7
7
  export { createOAuthAccessTokenManager, inboundRefreshTokenSecretOptions, type OAuthAccessTokenManager, type OAuthAccessTokenManagerDeps, usesFoundationManagedOAuth, } from "./oauth-access-token.js";
8
8
  export { type OAuthStatePayload, signOAuthState, type VerifyOAuthStateResult, verifyOAuthState, } from "./oauth-state.js";
9
9
  export { inboundMessagesProjectionTable, mailAccountsProjectionTable, mailThreadsProjectionTable, } from "./projection.js";
@@ -4,7 +4,7 @@ export { createInboundMailConnectRoutes, } from "./connect-routes.js";
4
4
  export { INBOUND_MAIL_FOUNDATION_FEATURE, INBOUND_MAIL_PROVIDER_EXTENSION, InboundMailAccountStatuses, InboundMailAuthMethods, InboundMailFoundationHandlers, InboundMailFoundationQueries, inboundCredentialSecretKey, } from "./constants.js";
5
5
  export { INBOUND_MESSAGE_PII_FIELDS, inboundMessageEntity, MAIL_ACCOUNT_PII_FIELDS, MAIL_THREAD_PII_FIELDS, mailAccountEntity, mailThreadEntity, seenMessageEntity, seenMessageTable, syncCursorEntity, syncCursorTable, } from "./entities.js";
6
6
  export { INBOUND_MESSAGE_AGGREGATE_TYPE, INBOUND_MESSAGE_RECEIVED_EVENT_QN, INBOUND_MESSAGE_RECEIVED_EVENT_SHORT, inboundMessageEventPayloadSchema, MAIL_ACCOUNT_AGGREGATE_TYPE, MAIL_ACCOUNT_CONNECTED_EVENT_QN, MAIL_ACCOUNT_CONNECTED_EVENT_SHORT, MAIL_ACCOUNT_DISCONNECTED_EVENT_QN, MAIL_ACCOUNT_DISCONNECTED_EVENT_SHORT, MAIL_ACCOUNT_UPDATED_EVENT_QN, MAIL_ACCOUNT_UPDATED_EVENT_SHORT, MAIL_THREAD_AGGREGATE_TYPE, MAIL_THREAD_UPDATED_EVENT_QN, MAIL_THREAD_UPDATED_EVENT_SHORT, mailAccountEventPayloadSchema, mailThreadEventPayloadSchema, } from "./events.js";
7
- export { inboundMailFoundationFeature } from "./feature.js";
7
+ export { createInboundMailFoundationFeature, inboundMailFoundationFeature } from "./feature.js";
8
8
  export { createOAuthAccessTokenManager, inboundRefreshTokenSecretOptions, usesFoundationManagedOAuth, } from "./oauth-access-token.js";
9
9
  export { signOAuthState, verifyOAuthState, } from "./oauth-state.js";
10
10
  export { inboundMessagesProjectionTable, mailAccountsProjectionTable, mailThreadsProjectionTable, } from "./projection.js";
@@ -15,8 +15,7 @@
15
15
  // The refresh token is re-read inside the lock via `secrets.get` without an
16
16
  // audit context. SecretsContext does not cache values (only unwrapped DEKs),
17
17
  // so the read always reflects the latest committed write.
18
- import { transaction } from "@cosmicdrift/kumiko-framework/bun-db";
19
- import { acquireNamespacedAdvisoryLock } from "@cosmicdrift/kumiko-framework/db";
18
+ import { acquireNamespacedAdvisoryLock, transaction, } from "@cosmicdrift/kumiko-framework/db";
20
19
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
21
20
  import { InboundMailAuthMethods, inboundCredentialSecretKey } from "./constants.js";
22
21
  import { InboundAuthError, } from "./types.js";
@@ -16,8 +16,7 @@
16
16
  // kommen bereits als Ciphertext an — encrypted VOR dem append im
17
17
  // write-handler. Die applies kopieren nur durch; decrypted wird erst
18
18
  // in den list-queries.
19
- import { insertOnConflictDoNothing, requireEntityTableMeta, upsertOnConflict, } from "@cosmicdrift/kumiko-framework/bun-db";
20
- import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
19
+ import { buildEntityTable, insertOnConflictDoNothing, requireEntityTableMeta, upsertOnConflict, } from "@cosmicdrift/kumiko-framework/db";
21
20
  import { defineApply } from "@cosmicdrift/kumiko-framework/engine";
22
21
  import { inboundMessageEntity, mailAccountEntity, mailThreadEntity } from "./entities.js";
23
22
  // Drizzle-table-instances aus den entity-shapes — geteilt zwischen
@@ -43,8 +43,8 @@
43
43
  // as the watcher state lives, including across reconnect backoff, not
44
44
  // only while the connection is open. Losing the claim (Redis outage, TTL
45
45
  // exceeded) tears down the local watcher instead of racing a new holder.
46
- import { fetchOne, insertOne, selectMany, updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
47
46
  import { configuredPiiSubjectKms, decryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
47
+ import { fetchOne, insertOne, selectMany, updateMany } from "@cosmicdrift/kumiko-framework/db";
48
48
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
49
49
  import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
50
50
  import { InboundMailAccountStatuses, InboundMailFoundationHandlers } from "./constants.js";
@@ -4,6 +4,10 @@ export { setImapMailHostLookup } from "./imap-client.js";
4
4
  /** Exportiert für den Live-Test (imap-live.integration.test.ts) —
5
5
  * Apps nutzen das Feature, nie das Plugin direkt. */
6
6
  export declare const imapInboundMailPlugin: InboundMailProviderPlugin;
7
+ export declare function createInboundProviderImapFeature(): import("@cosmicdrift/kumiko-types/feature").FeatureDefinition & {
8
+ readonly exports: void;
9
+ };
10
+ /** @deprecated Use createInboundProviderImapFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
7
11
  export declare const inboundProviderImapFeature: import("@cosmicdrift/kumiko-types/feature").FeatureDefinition & {
8
12
  readonly exports: void;
9
13
  };
@@ -217,15 +217,19 @@ export const imapInboundMailPlugin = {
217
217
  // Formular (connect-account + Secret-Write); XOAUTH2-Token-Flows
218
218
  // gehören den OAuth-Providern (M365/Gmail).
219
219
  };
220
- export const inboundProviderImapFeature = defineFeature(FEATURE_NAME, (r) => {
221
- r.describe('Registers the `"imap"` provider for `inbound-mail-foundation` using imapflow — password/app-password auth covers classic IMAP hosts without any OAuth (plus an XOAUTH2 fallback consuming an access token from the secret slot). Incremental sync via a UIDVALIDITY:lastUid cursor (UIDVALIDITY change triggers a cursor-invalid full resync), initial backfill bounded by the foundation backfill window, and live push via IMAP IDLE for the watch supervisor. Store the per-account connection JSON (host/port/secure/user/password) in the account credential secret slot before the first sync.');
222
- r.uiHints({
223
- displayLabel: "Inbound Mail · IMAP",
224
- category: "notifications",
225
- recommended: false,
226
- });
227
- r.requires({ features: ["inbound-mail-foundation"] });
228
- r.requires({ features: ["secrets"] });
229
- r.envSchema(mailAllowedPrivateHostsEnvSchema);
230
- r.useExtension(INBOUND_MAIL_PROVIDER_EXTENSION, IMAP_PROVIDER_KEY, imapInboundMailPlugin);
231
- });
220
+ export function createInboundProviderImapFeature() {
221
+ return defineFeature(FEATURE_NAME, (r) => {
222
+ r.describe('Registers the `"imap"` provider for `inbound-mail-foundation` using imapflow — password/app-password auth covers classic IMAP hosts without any OAuth (plus an XOAUTH2 fallback consuming an access token from the secret slot). Incremental sync via a UIDVALIDITY:lastUid cursor (UIDVALIDITY change triggers a cursor-invalid full resync), initial backfill bounded by the foundation backfill window, and live push via IMAP IDLE for the watch supervisor. Store the per-account connection JSON (host/port/secure/user/password) in the account credential secret slot before the first sync.');
223
+ r.uiHints({
224
+ displayLabel: "Inbound Mail · IMAP",
225
+ category: "notifications",
226
+ recommended: false,
227
+ });
228
+ r.requires({ features: ["inbound-mail-foundation"] });
229
+ r.requires({ features: ["secrets"] });
230
+ r.envSchema(mailAllowedPrivateHostsEnvSchema);
231
+ r.useExtension(INBOUND_MAIL_PROVIDER_EXTENSION, IMAP_PROVIDER_KEY, imapInboundMailPlugin);
232
+ }, { dedupeOptions: {} });
233
+ }
234
+ /** @deprecated Use createInboundProviderImapFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
235
+ export const inboundProviderImapFeature = createInboundProviderImapFeature();
@@ -1,3 +1,3 @@
1
1
  export { type ImapCredentialDocument, imapCredentialDocumentSchema, type ParseCredentialResult, parseImapCredentialDocument, } from "./credential-document.js";
2
- export { IMAP_PROVIDER_KEY, inboundProviderImapFeature, setImapMailHostLookup } from "./feature.js";
2
+ export { createInboundProviderImapFeature, IMAP_PROVIDER_KEY, inboundProviderImapFeature, setImapMailHostLookup, } from "./feature.js";
3
3
  export { assertUidValidity, buildProviderMessageId, type ImapCursor, mapImapError, normalizeReferences, parseImapCursor, } from "./imap-client.js";
@@ -1,4 +1,4 @@
1
1
  // Public API of the inbound-provider-imap bundled-feature.
2
2
  export { imapCredentialDocumentSchema, parseImapCredentialDocument, } from "./credential-document.js";
3
- export { IMAP_PROVIDER_KEY, inboundProviderImapFeature, setImapMailHostLookup } from "./feature.js";
3
+ export { createInboundProviderImapFeature, IMAP_PROVIDER_KEY, inboundProviderImapFeature, setImapMailHostLookup, } from "./feature.js";
4
4
  export { assertUidValidity, buildProviderMessageId, mapImapError, normalizeReferences, parseImapCursor, } from "./imap-client.js";
@@ -18,6 +18,10 @@ export declare function isWatching(accountId: string): boolean;
18
18
  * nie zwischen Tests teilen). */
19
19
  export declare function resetInboundInMemory(): void;
20
20
  export declare const inMemoryInboundMailPlugin: InboundMailProviderPlugin;
21
+ export declare function createInboundProviderInMemoryFeature(): import("@cosmicdrift/kumiko-types/feature").FeatureDefinition & {
22
+ readonly exports: void;
23
+ };
24
+ /** @deprecated Use createInboundProviderInMemoryFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
21
25
  export declare const inboundProviderInMemoryFeature: import("@cosmicdrift/kumiko-types/feature").FeatureDefinition & {
22
26
  readonly exports: void;
23
27
  };
@@ -103,13 +103,17 @@ export const inMemoryInboundMailPlugin = {
103
103
  // =============================================================================
104
104
  // Feature-definition
105
105
  // =============================================================================
106
- export const inboundProviderInMemoryFeature = defineFeature(FEATURE_NAME, (r) => {
107
- r.describe('Registers a scriptable in-process `"inmemory"` provider for `inbound-mail-foundation`. Seed messages with `seedInboundMessage(accountId, msg)` — an active watch pushes them immediately (IDLE simulation) and the cursor-based `fetch` re-delivers them on the reconciliation path, exercising the foundation dedup guarantee. Error injection via `failNextFetchWith`/`failNextVerifyWith`/`emitWatchError`; reset state with `resetInboundInMemory()`. For tests, demos and sample apps — not for production.');
108
- r.uiHints({
109
- displayLabel: "Inbound Mail · In-Memory Provider",
110
- category: "notifications",
111
- recommended: false,
112
- });
113
- r.requires({ features: ["inbound-mail-foundation"] });
114
- r.useExtension("inboundMailProvider", INMEMORY_PROVIDER_KEY, inMemoryInboundMailPlugin);
115
- });
106
+ export function createInboundProviderInMemoryFeature() {
107
+ return defineFeature(FEATURE_NAME, (r) => {
108
+ r.describe('Registers a scriptable in-process `"inmemory"` provider for `inbound-mail-foundation`. Seed messages with `seedInboundMessage(accountId, msg)` — an active watch pushes them immediately (IDLE simulation) and the cursor-based `fetch` re-delivers them on the reconciliation path, exercising the foundation dedup guarantee. Error injection via `failNextFetchWith`/`failNextVerifyWith`/`emitWatchError`; reset state with `resetInboundInMemory()`. For tests, demos and sample apps — not for production.');
109
+ r.uiHints({
110
+ displayLabel: "Inbound Mail · In-Memory Provider",
111
+ category: "notifications",
112
+ recommended: false,
113
+ });
114
+ r.requires({ features: ["inbound-mail-foundation"] });
115
+ r.useExtension("inboundMailProvider", INMEMORY_PROVIDER_KEY, inMemoryInboundMailPlugin);
116
+ }, { dedupeOptions: {} });
117
+ }
118
+ /** @deprecated Use createInboundProviderInMemoryFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
119
+ export const inboundProviderInMemoryFeature = createInboundProviderInMemoryFeature();
@@ -1 +1 @@
1
- export { emitWatchError, failNextFetchWith, failNextVerifyWith, INMEMORY_PROVIDER_KEY, inboundProviderInMemoryFeature, isWatching, resetInboundInMemory, seedInboundMessage, } from "./feature.js";
1
+ export { createInboundProviderInMemoryFeature, emitWatchError, failNextFetchWith, failNextVerifyWith, INMEMORY_PROVIDER_KEY, inboundProviderInMemoryFeature, isWatching, resetInboundInMemory, seedInboundMessage, } from "./feature.js";
@@ -1,2 +1,2 @@
1
1
  // Public API of the inbound-provider-inmemory bundled-feature.
2
- export { emitWatchError, failNextFetchWith, failNextVerifyWith, INMEMORY_PROVIDER_KEY, inboundProviderInMemoryFeature, isWatching, resetInboundInMemory, seedInboundMessage, } from "./feature.js";
2
+ export { createInboundProviderInMemoryFeature, emitWatchError, failNextFetchWith, failNextVerifyWith, INMEMORY_PROVIDER_KEY, inboundProviderInMemoryFeature, isWatching, resetInboundInMemory, seedInboundMessage, } from "./feature.js";
@@ -9,7 +9,7 @@
9
9
  //
10
10
  // deleteManyBatched (typed query API, no raw SQL in this file) chunks each
11
11
  // delete so a large backlog doesn't hold one lock for the whole sweep.
12
- import { deleteManyBatched } from "@cosmicdrift/kumiko-framework/bun-db";
12
+ import { deleteManyBatched } from "@cosmicdrift/kumiko-framework/db";
13
13
  import { jobRunLogsTable, jobRunsTable } from "../../job-run-table.js";
14
14
  import { tenantJobFailuresTable } from "../../tenant-job-failure-table.js";
15
15
  import { tenantJobRunsTable } from "../../tenant-job-run-table.js";
@@ -11,7 +11,7 @@
11
11
  // schema/migration change, no web filter-dropdown/status-enum update, and
12
12
  // the run becomes retriable via the existing jobs:write:retry gate
13
13
  // (retry.write.ts only allows retry from "failed").
14
- import { deleteManyBatched, selectMany, updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
14
+ import { deleteManyBatched, selectMany, updateMany } from "@cosmicdrift/kumiko-framework/db";
15
15
  import { mapWithConcurrency } from "../../../shared/index.js";
16
16
  import { DEFAULT_JOB_RUN_RETENTION_DAYS } from "../../handlers/retention-cleanup.job.js";
17
17
  import { encryptFailureError } from "../../job-run-logger.js";
@@ -1,4 +1,4 @@
1
- import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
@@ -1,5 +1,4 @@
1
- import { countWhere, selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { decodeCursor, encodeCursor } from "@cosmicdrift/kumiko-framework/db";
1
+ import { countWhere, decodeCursor, encodeCursor, selectMany, } from "@cosmicdrift/kumiko-framework/db";
3
2
  import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
4
3
  import { InternalError, ValidationError } from "@cosmicdrift/kumiko-framework/errors";
5
4
  import * as z from "zod";
@@ -1,5 +1,5 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import { isPiiCiphertext, PII_ERASED_SENTINEL } from "@cosmicdrift/kumiko-framework/crypto";
2
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
3
3
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import { InternalError, NotFoundError, UnprocessableError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
5
5
  import { parseJsonOrThrow } from "@cosmicdrift/kumiko-framework/utils";
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { access, defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { serializeJobSubject } from "@cosmicdrift/kumiko-framework/jobs";
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { access, defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { serializeJobSubject } from "@cosmicdrift/kumiko-framework/jobs";
@@ -1,6 +1,5 @@
1
- import { deleteMany, fetchOne, insertMany, insertOnConflictDoNothing, insertOne, transaction, updateMany, upsertOnConflict, } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import { configuredPiiSubjectKms, encryptPiiValueForSubject, KeyErasedError, PII_ERASED_SENTINEL, } from "@cosmicdrift/kumiko-framework/crypto";
3
- import { acquireNamespacedAdvisoryLock } from "@cosmicdrift/kumiko-framework/db";
2
+ import { acquireNamespacedAdvisoryLock, deleteMany, fetchOne, insertMany, insertOnConflictDoNothing, insertOne, transaction, updateMany, upsertOnConflict, } from "@cosmicdrift/kumiko-framework/db";
4
3
  import { SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
5
4
  import { createFallbackLogger } from "@cosmicdrift/kumiko-framework/logging";
6
5
  import { generateId } from "@cosmicdrift/kumiko-framework/utils";
@@ -1,5 +1,4 @@
1
- import { requireEntityTableMeta } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { index, instant, table as pgTable, serial, sql, text, uniqueIndex, uuid, } from "@cosmicdrift/kumiko-framework/db";
1
+ import { index, instant, table as pgTable, requireEntityTableMeta, serial, sql, text, uniqueIndex, uuid, } from "@cosmicdrift/kumiko-framework/db";
3
2
  // The tenant's own view of a failed job (fw#3079). Direct-write store like
4
3
  // store_job_runs: job-run-logger.ts writes it from the BullMQ callbacks,
5
4
  // outside any dispatcher transaction.
@@ -1,5 +1,4 @@
1
- import { requireEntityTableMeta } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { index, instant, table as pgTable, serial, sql, text, uniqueIndex, uuid, } from "@cosmicdrift/kumiko-framework/db";
1
+ import { index, instant, table as pgTable, requireEntityTableMeta, serial, sql, text, uniqueIndex, uuid, } from "@cosmicdrift/kumiko-framework/db";
3
2
  // The tenant's own view of a job's run state (fw#3616). Direct-write store
4
3
  // like store_job_runs, written by job-run-logger.ts from the runner callbacks.
5
4
  //