@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
@@ -8,15 +8,15 @@
8
8
  //
9
9
  // Default ifExists="skip". The actor is `createSystemUser(SYSTEM_TENANT_ID)`,
10
10
  // deliberately not TestUsers (prod seeds are not test utilities).
11
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
12
- import { createTenantDb, deleteMany, } from "@cosmicdrift/kumiko-framework/db";
11
+ import { createTenantDb, deleteMany, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
13
12
  import { createSystemUser, SYSTEM_TENANT_ID, } from "@cosmicdrift/kumiko-framework/engine";
14
13
  import { getStreamVersion, getUnscopedStreamMaxVersionForSeed, } from "@cosmicdrift/kumiko-framework/event-store";
15
14
  import { runEventStoreSeed } from "@cosmicdrift/kumiko-framework/seeding";
15
+ import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
16
16
  import { TEXT_BLOCK_KIND } from "./constants.js";
17
17
  import { executor } from "./handlers/shared.js";
18
18
  import { evaluateTemplateWrite } from "./handlers/template-gates.js";
19
- import { TEMPLATE_RESOLVER_FEATURE } from "./qualified-names.js";
19
+ import { TEMPLATE_RESOLVER_FEATURE, TemplateResolverHandlers } from "./qualified-names.js";
20
20
  import { templateResourcesTable } from "./table.js";
21
21
  import { activeStampChanges, servedStampChanges } from "./template-draft.js";
22
22
  import { templateSlugSchema } from "./template-meta.js";
@@ -43,7 +43,7 @@ async function resolveExistingForEventStoreSeed(db, tdb, existingRow, tenantId)
43
43
  export async function seedSystemTemplate(db, opts) {
44
44
  const tenantId = SYSTEM_TENANT_ID;
45
45
  const by = opts.by ?? createSystemUser(tenantId);
46
- const tdb = createTenantDb(db, tenantId, "system");
46
+ const tdb = createTenantDb({ db, tenantId, mode: "system" });
47
47
  const label = `seedSystemTemplate ${opts.slug}/${opts.kind}/${opts.locale}`;
48
48
  const slug = templateSlugSchema.safeParse(opts.slug);
49
49
  if (!slug.success)
@@ -154,12 +154,12 @@ export async function seedSystemTemplate(db, opts) {
154
154
  update: (row) => applyUpdate(row, existingRow),
155
155
  });
156
156
  }
157
- // Seeds one system row per bundle locale. Bundled resources need a file
158
- // provider and the system tenant's file space, which a boot seed does not
159
- // have, so those go through the import-bundle-system write instead.
157
+ // Seeds one system row per bundle locale. Bundled resources need a file provider and
158
+ // the system tenant's file space, so those bundles are written through the
159
+ // import-bundle-system handler on the seed dispatcher instead of directly.
160
160
  export async function seedSystemTemplateBundle(db, bundle, opts = {}) {
161
161
  if (Object.keys(bundle.resources).length > 0) {
162
- throw new Error(`seedSystemTemplateBundle ${bundle.slug}/${bundle.kind}: bundles with resources cannot be seeded; use the import-bundle-system write`);
162
+ return seedSystemTemplateBundleWithResources(db, bundle, opts);
163
163
  }
164
164
  const ids = {};
165
165
  for (const [locale, entry] of Object.entries(bundle.locales)) {
@@ -178,6 +178,40 @@ export async function seedSystemTemplateBundle(db, bundle, opts = {}) {
178
178
  }
179
179
  return { ids };
180
180
  }
181
+ async function seedSystemTemplateBundleWithResources(db, bundle, opts) {
182
+ const label = `seedSystemTemplateBundle ${bundle.slug}/${bundle.kind}`;
183
+ const { dispatcher } = opts;
184
+ if (!dispatcher) {
185
+ throw new Error(`${label}: bundles with resources need a file provider; pass opts.dispatcher (the dispatcher of the seed deps) so the files are stored through the import-bundle-system write`);
186
+ }
187
+ if ((opts.ifExists ?? "skip") === "skip") {
188
+ const existingIds = {};
189
+ for (const locale of Object.keys(bundle.locales)) {
190
+ const row = await fetchOne(db, templateResourcesTable, {
191
+ tenantId: SYSTEM_TENANT_ID,
192
+ slug: bundle.slug,
193
+ kind: bundle.kind,
194
+ locale,
195
+ });
196
+ if (row)
197
+ existingIds[locale] = String(row.id);
198
+ }
199
+ if (Object.keys(existingIds).length === Object.keys(bundle.locales).length) {
200
+ return { ids: existingIds };
201
+ }
202
+ }
203
+ const result = await dispatcher.write(TemplateResolverHandlers.importBundleSystem, { bundle }, opts.by ?? createSystemUser(SYSTEM_TENANT_ID, ["SystemAdmin"]));
204
+ if (!result.isSuccess) {
205
+ throw new Error(`${label} failed: ${result.error.code}: ${result.error.message}`);
206
+ }
207
+ return { ids: importedIds(result.data) };
208
+ }
209
+ function importedIds(data) {
210
+ const ids = isPlainObject(data) ? data["ids"] : undefined;
211
+ if (!isPlainObject(ids))
212
+ throw new Error("seedSystemTemplateBundle: import returned no ids");
213
+ return Object.fromEntries(Object.entries(ids).map(([locale, id]) => [locale, String(id)]));
214
+ }
181
215
  export function hasNotificationTemplates(registry) {
182
216
  return Array.from(registry.getAllNotifications().values()).some((notification) => notification.template !== undefined);
183
217
  }
@@ -215,7 +249,7 @@ export async function seedNotificationTemplates(db, registry) {
215
249
  // without the access check. Default ifExists="skip".
216
250
  export async function seedTextBlock(db, opts) {
217
251
  const by = opts.by ?? createSystemUser(opts.tenantId);
218
- const tdb = createTenantDb(db, opts.tenantId, "system");
252
+ const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
219
253
  const existingRow = await fetchOne(db, templateResourcesTable, {
220
254
  tenantId: opts.tenantId,
221
255
  slug: opts.slug,
@@ -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 { NotFoundError, UnprocessableError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
3
3
  import { createFileRefFromUploadedBytes, uploadFileBytesBeforeTransaction, } from "@cosmicdrift/kumiko-framework/files";
4
4
  import { fileContextForTenant } from "../file-foundation/index.js";
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { NotFoundError, UnprocessableError, ValidationError, } from "@cosmicdrift/kumiko-framework/errors";
3
3
  import { fileRefsTable } from "@cosmicdrift/kumiko-framework/files";
4
4
  import { escapeHtml } from "@cosmicdrift/kumiko-headless";
@@ -33,6 +33,8 @@ function sampleScalar(name, def) {
33
33
  return 0;
34
34
  case "date":
35
35
  return SAMPLE_DATE;
36
+ case "percent":
37
+ return 0;
36
38
  }
37
39
  }
38
40
  function sampleRow(item, given = {}) {
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { NotFoundError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
3
3
  import { fileRefsTable } from "@cosmicdrift/kumiko-framework/files";
4
4
  import { requireForTenant } from "../shared/index.js";
@@ -0,0 +1,8 @@
1
+ import type { Registry } from "@cosmicdrift/kumiko-framework/engine";
2
+ export declare function isSystemOnlyTemplate(registry: Registry, slug: string, kind: string): boolean;
3
+ export declare function isSystemOnlyTemplateHiddenFrom(user: {
4
+ readonly roles: readonly string[];
5
+ }, registry: Registry, row: {
6
+ readonly slug: string;
7
+ readonly kind: string;
8
+ }): boolean;
@@ -0,0 +1,11 @@
1
+ import { isSystemAdmin } from "./template-draft.js";
2
+ const NOTIFICATION_TEMPLATE_KIND = "mail";
3
+ // A notification registered with systemOnly keeps its mail template as the system default:
4
+ // tenants neither list nor override it, and overrides stored before the flag are ignored.
5
+ export function isSystemOnlyTemplate(registry, slug, kind) {
6
+ return (kind === NOTIFICATION_TEMPLATE_KIND &&
7
+ registry.getAllNotifications().get(slug)?.systemOnly === true);
8
+ }
9
+ export function isSystemOnlyTemplateHiddenFrom(user, registry, row) {
10
+ return !isSystemAdmin(user) && isSystemOnlyTemplate(registry, row.slug, row.kind);
11
+ }
@@ -1,6 +1,6 @@
1
1
  import * as z from "zod";
2
- import { withParsedDocument } from "./document-sanitizer.js";
3
- import { isDocumentPlaceholderHref, isDocumentReferenceName } from "./document-schema.js";
2
+ import { conditionScopeElement, withParsedDocument } from "./document-sanitizer.js";
3
+ import { DOCUMENT_CONDITION_ATTRIBUTE, isDocumentPlaceholderHref, isDocumentReferenceName, } from "./document-schema.js";
4
4
  export const SYSTEM_PLACEHOLDERS = new Set([
5
5
  "tenantName",
6
6
  "signature",
@@ -34,6 +34,7 @@ const scalarVariableSchema = z.discriminatedUnion("type", [
34
34
  .optional(),
35
35
  }),
36
36
  z.object({ ...variableCommon, type: z.literal("date"), example: textLikeExample }),
37
+ z.object({ ...variableCommon, type: z.literal("percent"), example: z.number().optional() }),
37
38
  ]);
38
39
  const variableDefSchema = z.union([
39
40
  scalarVariableSchema,
@@ -99,34 +100,47 @@ const NAME_ATTRIBUTE_BY_TAG = {
99
100
  span: "data-variable",
100
101
  div: "data-steps",
101
102
  };
102
- function scanBodyPlaceholders(body, scope) {
103
- withParsedDocument(body, (root) => {
104
- for (const element of Array.from(root.querySelectorAll("tr[data-each]"))) {
105
- const listName = element.getAttribute("data-each") ?? "";
106
- const def = Object.hasOwn(scope.variables, listName) ? scope.variables[listName] : undefined;
107
- if (def?.type === "list")
108
- scope.used.add(listName);
109
- else
110
- scope.unknown.add(listName);
103
+ function scanRepeatRows(root, scope) {
104
+ for (const element of Array.from(root.querySelectorAll("tr[data-each]"))) {
105
+ const listName = element.getAttribute("data-each") ?? "";
106
+ const def = Object.hasOwn(scope.variables, listName) ? scope.variables[listName] : undefined;
107
+ if (def?.type === "list")
108
+ scope.used.add(listName);
109
+ else
110
+ scope.unknown.add(listName);
111
+ }
112
+ }
113
+ function scanConditions(root, scope) {
114
+ for (const element of Array.from(root.querySelectorAll(`[${DOCUMENT_CONDITION_ATTRIBUTE}]`))) {
115
+ const itemFields = listItemFields(scope.variables, enclosingEachName(conditionScopeElement(element)));
116
+ recordName(element.getAttribute(DOCUMENT_CONDITION_ATTRIBUTE) ?? "", itemFields, scope);
117
+ }
118
+ }
119
+ function scanReferences(root, scope) {
120
+ for (const element of Array.from(root.querySelectorAll("span[data-variable], div[data-steps], a[href], img[data-resource]"))) {
121
+ const itemFields = listItemFields(scope.variables, enclosingEachName(element));
122
+ const tag = element.tagName.toLowerCase();
123
+ const nameAttribute = NAME_ATTRIBUTE_BY_TAG[tag];
124
+ if (nameAttribute !== undefined) {
125
+ recordName(element.getAttribute(nameAttribute) ?? "", itemFields, scope);
126
+ }
127
+ else if (tag === "a") {
128
+ const href = element.getAttribute("href") ?? "";
129
+ if (isDocumentPlaceholderHref(href))
130
+ recordName(href.slice(2, -2), itemFields, scope);
111
131
  }
112
- for (const element of Array.from(root.querySelectorAll("span[data-variable], div[data-steps], a[href], img[data-resource]"))) {
113
- const itemFields = listItemFields(scope.variables, enclosingEachName(element));
114
- const tag = element.tagName.toLowerCase();
115
- const nameAttribute = NAME_ATTRIBUTE_BY_TAG[tag];
116
- if (nameAttribute !== undefined) {
117
- recordName(element.getAttribute(nameAttribute) ?? "", itemFields, scope);
118
- }
119
- else if (tag === "a") {
120
- const href = element.getAttribute("href") ?? "";
121
- if (isDocumentPlaceholderHref(href))
122
- recordName(href.slice(2, -2), itemFields, scope);
123
- }
124
- else {
125
- const key = element.getAttribute("data-resource") ?? "";
126
- if (!scope.resourceKeys.has(key))
127
- scope.unknownResources.add(key);
128
- }
132
+ else {
133
+ const key = element.getAttribute("data-resource") ?? "";
134
+ if (!scope.resourceKeys.has(key))
135
+ scope.unknownResources.add(key);
129
136
  }
137
+ }
138
+ }
139
+ function scanBodyPlaceholders(body, scope) {
140
+ withParsedDocument(body, (root) => {
141
+ scanRepeatRows(root, scope);
142
+ scanConditions(root, scope);
143
+ scanReferences(root, scope);
130
144
  });
131
145
  }
132
146
  const HANDLEBARS_EXPRESSION = /\{\{([^{}]*)\}\}/g;
@@ -1,7 +1,7 @@
1
1
  // Test-only helpers for template-resolver consumers. Import via
2
2
  // `@cosmicdrift/kumiko-bundled-features/template-resolver/testing`.
3
3
  // No bun:test here — callers register cases with their own test runner.
4
- import { seedRow } from "@cosmicdrift/kumiko-framework/testing";
4
+ import { seedRow } from "@cosmicdrift/kumiko-testing/helpers";
5
5
  import { TemplateNotFoundError } from "./api.js";
6
6
  import { FALLBACK_LOCALE, SYSTEM_TENANT_ID, } from "./constants.js";
7
7
  import { templateResourcesTable } from "./table.js";
@@ -76,6 +76,7 @@ export const defaultTranslations = {
76
76
  "templateResolver.errors.collection.kindNotAllowed": "“{detail}” templates are written through their own editor, not through a collection.",
77
77
  "templateResolver.errors.noSystemTemplate": "There is no active system template to reset to.",
78
78
  "templateResolver.errors.noDraft": "There is no draft to discard.",
79
+ "templateResolver.errors.systemOnlyTemplate": "Only the platform maintains this template; it cannot be overridden per tenant.",
79
80
  "templateResolver.errors.template.invalidMeta": "The template settings are invalid.",
80
81
  "templateResolver.errors.template.meta.subject.required": "The subject is missing.",
81
82
  "templateResolver.errors.template.meta.subject.invalid": "The subject is invalid (at most 200 characters, no line breaks).",
@@ -1,3 +1,7 @@
1
+ export declare function createTemplateResolverUserDataFeature(): import("@cosmicdrift/kumiko-types/feature").FeatureDefinition & {
2
+ readonly exports: void;
3
+ };
4
+ /** @deprecated Use createTemplateResolverUserDataFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
1
5
  export declare const templateResolverUserDataFeature: import("@cosmicdrift/kumiko-types/feature").FeatureDefinition & {
2
6
  readonly exports: void;
3
7
  };
@@ -6,16 +6,20 @@
6
6
  // notes-history-user-data.
7
7
  import { defineFeature, EXT_USER_DATA } from "@cosmicdrift/kumiko-framework/engine";
8
8
  import { userContentDeleteHook, userContentExportHook } from "./hooks.js";
9
- export const templateResolverUserDataFeature = defineFeature("template-resolver-user-data", (r) => {
10
- r.describe("GDPR (Art. 20 export / Art. 17 erasure) coverage for the `template-resolver` feature's `user-content-entry` entity — the per-user half of the content store (mail signatures, personal reply snippets). Mounts the EXT_USER_DATA export hook so a user's own entries land in the export bundle; the delete hook is a deliberate no-op because `content` is annotated `userOwned`, so erasure runs via crypto-shredding (destroying the owner's subject key) rather than a physical delete, which would not survive an event replay. Mount this whenever `createTemplateResolverFeature` declares a collection with `ownership: \"user\"` — the boot guard otherwise refuses the entity. Requires `user-data-rights`, optionalRequires `template-resolver`.");
11
- // user-data-rights is the hard dependency (EXT_USER_DATA host).
12
- // template-resolver is optional for the same reason as in
13
- // notes-history-user-data: a toggleable mount would otherwise trip the
14
- // "effectively disabled" boot warning even though the entity is there.
15
- r.requires({ features: ["user-data-rights"] });
16
- r.optionalRequires("template-resolver");
17
- r.useExtension(EXT_USER_DATA, "user-content-entry", {
18
- export: userContentExportHook,
19
- delete: userContentDeleteHook,
20
- });
21
- });
9
+ export function createTemplateResolverUserDataFeature() {
10
+ return defineFeature("template-resolver-user-data", (r) => {
11
+ r.describe("GDPR (Art. 20 export / Art. 17 erasure) coverage for the `template-resolver` feature's `user-content-entry` entity — the per-user half of the content store (mail signatures, personal reply snippets). Mounts the EXT_USER_DATA export hook so a user's own entries land in the export bundle; the delete hook is a deliberate no-op because `content` is annotated `userOwned`, so erasure runs via crypto-shredding (destroying the owner's subject key) rather than a physical delete, which would not survive an event replay. Mount this whenever `createTemplateResolverFeature` declares a collection with `ownership: \"user\"` — the boot guard otherwise refuses the entity. Requires `user-data-rights`, optionalRequires `template-resolver`.");
12
+ // user-data-rights is the hard dependency (EXT_USER_DATA host).
13
+ // template-resolver is optional for the same reason as in
14
+ // notes-history-user-data: a toggleable mount would otherwise trip the
15
+ // "effectively disabled" boot warning even though the entity is there.
16
+ r.requires({ features: ["user-data-rights"] });
17
+ r.optionalRequires("template-resolver");
18
+ r.useExtension(EXT_USER_DATA, "user-content-entry", {
19
+ export: userContentExportHook,
20
+ delete: userContentDeleteHook,
21
+ });
22
+ }, { dedupeOptions: {} });
23
+ }
24
+ /** @deprecated Use createTemplateResolverUserDataFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
25
+ export const templateResolverUserDataFeature = createTemplateResolverUserDataFeature();
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineQueryHandler, SYSTEM_ROLE, } 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 { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
1
+ import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
3
2
  import { defineWriteHandler, SYSTEM_ROLE, SYSTEM_USER_ID, } from "@cosmicdrift/kumiko-framework/engine";
4
3
  import { AccessDeniedError, ConflictError, InternalError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
5
4
  import * as z from "zod";
@@ -9,7 +9,7 @@
9
9
  // Idempotent: cancelling an already-cancelled / accepted / expired
10
10
  // invitation = no-op + 200. Cancelling a non-existent invitation
11
11
  // = invitation_not_found.
12
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
12
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
13
13
  import { access, defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
14
14
  import { InternalError, NotFoundError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
15
15
  import * as z from "zod";
@@ -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 * as z from "zod";
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } 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,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { access, definePagedQueryHandler, MAX_LIST_LIMIT, } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
@@ -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 { parseRoles } 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 { defineQueryHandler, SYSTEM_ROLE } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
@@ -1,5 +1,4 @@
1
- import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { createEventStoreExecutor, } from "@cosmicdrift/kumiko-framework/db";
1
+ import { createEventStoreExecutor, fetchOne, selectMany, } from "@cosmicdrift/kumiko-framework/db";
3
2
  import { createSystemUser, defineWriteHandler, parseTenantId, withResponseData, } from "@cosmicdrift/kumiko-framework/engine";
4
3
  import { InternalError, NotFoundError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
5
4
  import { parseRoles } 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 { defineQueryHandler, SYSTEM_ROLE } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import * as z from "zod";
@@ -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, definePagedQueryHandler, MAX_LIST_LIMIT, } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
@@ -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 { access, definePagedQueryHandler, MAX_LIST_LIMIT, } 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 { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
1
+ import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
3
2
  import { access, assignableAppRolesOf, createSystemUser, defineWriteHandler, findForbiddenRoleAssignment, mayOverrideTenant, mergeAssignedRoles, parseTenantId, SYSTEM_ROLE, withResponseData, } from "@cosmicdrift/kumiko-framework/engine";
4
3
  import { InternalError, NotFoundError, ValidationError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
5
4
  import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
@@ -1,5 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { createEventStoreExecutor, createTenantDb, } from "@cosmicdrift/kumiko-framework/db";
1
+ import { createEventStoreExecutor, createTenantDb, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
3
2
  import { createSystemUser } from "@cosmicdrift/kumiko-framework/engine";
4
3
  import { ConflictError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
5
4
  import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
@@ -44,7 +43,7 @@ export async function grantInvitedMembershipRole(db, options) {
44
43
  if (currentRoles.includes(options.role))
45
44
  return grantedMembership(true, currentRoles);
46
45
  const roles = [...currentRoles, options.role];
47
- const updateResult = await membershipExecutor.update({ id: existing.id, version: existing.version, changes: { roles: JSON.stringify(roles) } }, createSystemUser(options.tenantId), createTenantDb(db, options.tenantId, "system"));
46
+ const updateResult = await membershipExecutor.update({ id: existing.id, version: existing.version, changes: { roles: JSON.stringify(roles) } }, createSystemUser(options.tenantId), createTenantDb({ db, tenantId: options.tenantId, mode: "system" }));
48
47
  if (!updateResult.isSuccess)
49
48
  return updateResult;
50
49
  return grantedMembership(true, roles);
@@ -1,5 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { acquireNamespacedAdvisoryLock } from "@cosmicdrift/kumiko-framework/db";
1
+ import { acquireNamespacedAdvisoryLock, selectMany } from "@cosmicdrift/kumiko-framework/db";
3
2
  import { ConflictError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
4
3
  import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
5
4
  import { TenantErrors } from "./constants.js";
@@ -27,12 +27,11 @@
27
27
  // Idempotent (add-only): calling twice for the same (userId, tenantId) is
28
28
  // a no-op on the second call. Memberships have no update-semantic — to
29
29
  // change roles, write a new event via the regular handler path.
30
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
31
- import { createEventStoreExecutor, createTenantDb, } from "@cosmicdrift/kumiko-framework/db";
30
+ import { createEventStoreExecutor, createTenantDb, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
32
31
  import { createSystemUser, HookPhases, } from "@cosmicdrift/kumiko-framework/engine";
33
32
  import { getUnscopedAggregateStreamMaxVersion } from "@cosmicdrift/kumiko-framework/event-store";
34
33
  import { createDeferringNotify, createLifecycleHooks, } from "@cosmicdrift/kumiko-framework/pipeline";
35
- import { TestUsers } from "@cosmicdrift/kumiko-framework/stack";
34
+ import { TestUsers } from "@cosmicdrift/kumiko-framework/seeding";
36
35
  import { assertAssignableMembershipRoles } from "./membership-roles.js";
37
36
  import { tenantMembershipEntity, tenantMembershipsTable } from "./membership-table.js";
38
37
  import { tenantEntity, tenantTable } from "./schema/tenant.js";
@@ -87,7 +86,14 @@ function scopeSeedHookContext(context, targetTenantId, runner,
87
86
  // The afterCommit sink is snapshotted when it flushes, so a hook scheduled from inside an
88
87
  // afterCommit-phase hook would be dropped: that phase must notify inline.
89
88
  notifyTiming) {
90
- const db = createTenantDb(runner, targetTenantId, "system", context.tracer, context.meter, context.signal);
89
+ const db = createTenantDb({
90
+ db: runner,
91
+ tenantId: targetTenantId,
92
+ mode: "system",
93
+ tracer: context.tracer,
94
+ meter: context.meter,
95
+ signal: context.signal,
96
+ });
91
97
  // HandlerContext carries `user`; AppContext only `systemUser`. Prefer the
92
98
  // live handler user when present so notify/hasFeature keep a real SessionUser.
93
99
  const handlerUser = context.user;
@@ -160,7 +166,7 @@ export async function seedTenant(db, options, hooks) {
160
166
  // tenant-scoped ist, braucht der Wrap-Layer für die runtime-API zu
161
167
  // existieren. by.tenantId reicht — keine Override-Semantik wie bei
162
168
  // seedTenantMembership nötig.
163
- const tdb = createTenantDb(db, by.tenantId, "system");
169
+ const tdb = createTenantDb({ db, tenantId: by.tenantId, mode: "system" });
164
170
  const existing = await fetchOne(db, tenantTable, { id: options.id });
165
171
  if (existing)
166
172
  return { id: options.id };
@@ -211,7 +217,7 @@ hooks) {
211
217
  const by = options.by ?? createSystemUser(options.tenantId);
212
218
  // System-scoped TenantDb: payload.tenantId may differ from an explicit
213
219
  // `by` override; stream tenant still follows `by` via streamTenantFor.
214
- const tdb = createTenantDb(db, options.tenantId, "system");
220
+ const tdb = createTenantDb({ db, tenantId: options.tenantId, mode: "system" });
215
221
  // Idempotency: duplicate seeds are common across beforeEach-resets where
216
222
  // only certain tables get truncated. A plain executor.create would trip
217
223
  // the (user_id, tenant_id) unique index; the fixture call-site would then
@@ -1,5 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
- import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
1
+ import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
3
2
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
4
3
  import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
5
4
  import * as z from "zod";
@@ -1,6 +1,5 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import { addDurationSpec } from "@cosmicdrift/kumiko-framework/compliance";
3
- import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
2
+ import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
4
3
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
5
4
  import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
6
5
  import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
@@ -1,4 +1,4 @@
1
- import { updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { updateMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
3
3
  import { userSessionTable } from "../../sessions/index.js";
4
4
  /** Revoke all live sessions scoped to a tenant (destruction-request gate). */
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { tenantTable } from "../tenant/index.js";
3
3
  // Every authenticated + anonymous request consults this (via auth-middleware's
4
4
  // resolveTenantLifecycleStatus) — a per-request DB round-trip otherwise.
@@ -1,6 +1,4 @@
1
- /// <reference types="temporal-polyfill/global" preserve="true" />
2
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
3
- import { createEventStoreExecutor, createTenantDb, WritePurposes, } from "@cosmicdrift/kumiko-framework/db";
1
+ import { createEventStoreExecutor, createTenantDb, selectMany, WritePurposes, } from "@cosmicdrift/kumiko-framework/db";
4
2
  import { createSystemUser, } from "@cosmicdrift/kumiko-framework/engine";
5
3
  import { append, loadAggregate, VersionConflictError, } from "@cosmicdrift/kumiko-framework/event-store";
6
4
  import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
@@ -91,7 +89,7 @@ async function appendTenantStageEventIdempotent(db, tenantId, type, payload, exp
91
89
  }
92
90
  async function markTenantDestroyFailed(db, tenantId) {
93
91
  const user = createSystemUser(tenantId);
94
- const scopedDb = createTenantDb(db, tenantId, "system");
92
+ const scopedDb = createTenantDb({ db, tenantId, mode: "system" });
95
93
  await tenantCrud.update({
96
94
  id: tenantId,
97
95
  changes: { status: "destroyFailed" },
@@ -234,7 +232,7 @@ export async function runTenantDestructionSweep(args) {
234
232
  const events = await loadAggregate(args.db, tenantId, tenantId);
235
233
  const version = lastEventVersion(events);
236
234
  const user = createSystemUser(tenantId);
237
- const scopedDb = createTenantDb(args.db, tenantId, "system");
235
+ const scopedDb = createTenantDb({ db: args.db, tenantId, mode: "system" });
238
236
  // Version-guarded (no skipOptimisticLock): a concurrent cancel-destruction
239
237
  // between the `due` select above and this write also appends to the same
240
238
  // tenant stream, so an unguarded overwrite here would silently revert the
@@ -1,6 +1,5 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import { configuredPiiSubjectKms, subjectIdToKey, } from "@cosmicdrift/kumiko-framework/crypto";
3
- import { createEventStoreExecutor, createTenantDb, WritePurposes, } from "@cosmicdrift/kumiko-framework/db";
2
+ import { createEventStoreExecutor, createTenantDb, selectMany, WritePurposes, } from "@cosmicdrift/kumiko-framework/db";
4
3
  import { createSystemUser, EXT_EXTERNAL_RESOURCE, EXT_INFRA_RESOURCE, EXT_SEARCH_ADAPTER, EXT_STORAGE_PROVIDER, EXT_TENANT_DATA, extensionUsageEscapeHatchReason, isTenantDataExtensionHooks, isTenantResourceExtensionHooks, } from "@cosmicdrift/kumiko-framework/engine";
5
4
  import { createFallbackLogger } from "@cosmicdrift/kumiko-framework/logging";
6
5
  import { createEscapeHatchReporter, UNATTRIBUTED_ACTOR, } from "@cosmicdrift/kumiko-framework/pipeline";
@@ -56,9 +55,14 @@ async function runTenantDataHooks(ctx) {
56
55
  log: ctx.escapeHatchAuditLog ?? createFallbackLogger("tenant-lifecycle"),
57
56
  });
58
57
  const hookCtx = {
59
- db: createTenantDb(ctx.db, ctx.tenantId, "tenant", undefined, undefined, undefined, {
60
- unsafeRaw: reason !== undefined ? { reason } : undefined,
61
- report,
58
+ db: createTenantDb({
59
+ db: ctx.db,
60
+ tenantId: ctx.tenantId,
61
+ mode: "tenant",
62
+ grants: {
63
+ unsafeRaw: reason !== undefined ? { reason } : undefined,
64
+ report,
65
+ },
62
66
  }),
63
67
  registry: ctx.registry,
64
68
  tenantId: ctx.tenantId,
@@ -106,7 +110,7 @@ async function purgeTenantCache(ctx) {
106
110
  async function tombstoneTenantRow(ctx) {
107
111
  const now = getTemporal().Now.instant();
108
112
  const user = createSystemUser(ctx.tenantId);
109
- const db = createTenantDb(ctx.db, ctx.tenantId, "system");
113
+ const db = createTenantDb({ db: ctx.db, tenantId: ctx.tenantId, mode: "system" });
110
114
  // Per-row forget() through the executor, not a bulk deleteMany: memberships
111
115
  // are an ES-managed projection (add/remove/update-roles all go through
112
116
  // tenantMembershipCrud), so a store table write here is eventless — a future
@@ -1,7 +1,7 @@
1
1
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
2
2
  import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import type { SearchAdapter } from "@cosmicdrift/kumiko-framework/search";
4
- import type { TestStack } from "@cosmicdrift/kumiko-framework/stack";
4
+ import type { TestStack } from "@cosmicdrift/kumiko-testing/stack";
5
5
  import { runTenantDestructionSweep } from "./run-tenant-destroy.js";
6
6
  export declare function seedDestroyingTenant(db: DbConnection, tenantId: TenantId): Promise<void>;
7
7
  export declare function driveDestructionToCompletion(stack: TestStack, db: DbConnection, tenantId: TenantId, searchAdapter?: SearchAdapter): Promise<string>;
@@ -1,7 +1,7 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { append, loadAggregate } from "@cosmicdrift/kumiko-framework/event-store";
3
- import { updateRows } from "@cosmicdrift/kumiko-framework/testing";
4
3
  import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
4
+ import { updateRows } from "@cosmicdrift/kumiko-testing/helpers";
5
5
  import { tenantTable } from "../tenant/index.js";
6
6
  import { TENANT_AGGREGATE_TYPE, TENANT_DESTRUCTION_STARTED_EVENT_QN } from "./constants.js";
7
7
  import { runTenantDestructionSweep } from "./run-tenant-destroy.js";
@@ -2,4 +2,5 @@ import { type FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import { type TenantSettingsKeyOptions } from "./config.js";
3
3
  export type TenantSettingsFeatureOptions = TenantSettingsKeyOptions;
4
4
  export declare function createTenantSettingsFeature(opts?: TenantSettingsFeatureOptions): FeatureDefinition;
5
+ /** @deprecated Use createTenantSettingsFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
5
6
  export declare const tenantSettingsFeature: FeatureDefinition;