@cosmicdrift/kumiko-samples 0.367.0 → 0.369.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 (406) hide show
  1. package/package.json +1 -1
  2. package/packages/bundled-features/package.json +16 -2
  3. package/packages/bundled-features/src/audit/handlers/details.query.ts +1 -1
  4. package/packages/bundled-features/src/audit/handlers/list.query.ts +1 -1
  5. package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +5 -5
  6. package/packages/bundled-features/src/auth-email-password/bootstrap.ts +1 -1
  7. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +10 -3
  8. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +10 -3
  9. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  10. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +6 -2
  11. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +1 -1
  12. package/packages/bundled-features/src/auth-email-password/seeding.ts +2 -2
  13. package/packages/bundled-features/src/auth-foundation/feature.ts +43 -34
  14. package/packages/bundled-features/src/auth-foundation/index.ts +1 -0
  15. package/packages/bundled-features/src/auth-mfa/db/queries.ts +5 -2
  16. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +1 -1
  17. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  18. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +2 -2
  19. package/packages/bundled-features/src/auth-mfa/handlers/status.query.ts +1 -1
  20. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  21. package/packages/bundled-features/src/auth-mfa/mfa-code-verifier.ts +1 -1
  22. package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +1 -1
  23. package/packages/bundled-features/src/auth-mfa-user-data/index.ts +19 -10
  24. package/packages/bundled-features/src/billing-foundation/billing-info-query.ts +1 -1
  25. package/packages/bundled-features/src/billing-foundation/feature.ts +138 -135
  26. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +1 -1
  27. package/packages/bundled-features/src/billing-foundation/projection.ts +3 -2
  28. package/packages/bundled-features/src/cap-counter/calendar-cap-usage-reservation.ts +52 -1
  29. package/packages/bundled-features/src/cap-counter/cap-reservation.ts +203 -15
  30. package/packages/bundled-features/src/cap-counter/changes.json +13 -0
  31. package/packages/bundled-features/src/cap-counter/feature.ts +84 -73
  32. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +3 -4
  33. package/packages/bundled-features/src/cap-counter/index.ts +9 -1
  34. package/packages/bundled-features/src/cap-counter/tables.ts +10 -3
  35. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -2
  36. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +6 -2
  37. package/packages/bundled-features/src/cap-overview/handlers/tenant-options.query.ts +1 -1
  38. package/packages/bundled-features/src/channel-email/changes.json +7 -0
  39. package/packages/bundled-features/src/channel-email/email-channel.ts +39 -8
  40. package/packages/bundled-features/src/channel-email/feature.ts +1 -1
  41. package/packages/bundled-features/src/channel-email/index.ts +5 -1
  42. package/packages/bundled-features/src/channel-in-app/handlers/inbox.query.ts +1 -1
  43. package/packages/bundled-features/src/channel-in-app/handlers/mark-all-read.write.ts +1 -1
  44. package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +1 -1
  45. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +1 -1
  46. package/packages/bundled-features/src/channel-in-app/tables.ts +1 -1
  47. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +1 -1
  48. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +1 -1
  49. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +1 -2
  50. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +1 -1
  51. package/packages/bundled-features/src/compliance-profiles/seeding.ts +8 -4
  52. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +26 -17
  53. package/packages/bundled-features/src/config/db/queries/resolver.ts +1 -1
  54. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +2 -2
  55. package/packages/bundled-features/src/config/resolver.ts +1 -1
  56. package/packages/bundled-features/src/config/web/i18n.ts +1 -2
  57. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  58. package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
  59. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +9 -7
  60. package/packages/bundled-features/src/custom-fields/db/queries/field-access.ts +1 -1
  61. package/packages/bundled-features/src/custom-fields/db/queries/projection.ts +1 -1
  62. package/packages/bundled-features/src/custom-fields/db/queries/quota.ts +1 -1
  63. package/packages/bundled-features/src/custom-fields/db/queries/retention.ts +6 -2
  64. package/packages/bundled-features/src/custom-fields/db/queries/user-data-rights.ts +1 -1
  65. package/packages/bundled-features/src/custom-fields/feature.ts +11 -14
  66. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +2 -2
  67. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +2 -2
  68. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +2 -2
  69. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +2 -2
  70. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +4 -4
  71. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  72. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +16 -10
  73. package/packages/bundled-features/src/delivery/address-opt-out.ts +5 -2
  74. package/packages/bundled-features/src/delivery/attempt-log-retention.ts +1 -1
  75. package/packages/bundled-features/src/delivery/changes.json +6 -0
  76. package/packages/bundled-features/src/delivery/channel-context.ts +1 -1
  77. package/packages/bundled-features/src/delivery/db/queries/address-opt-outs.ts +1 -1
  78. package/packages/bundled-features/src/delivery/db/queries/preferences.ts +1 -1
  79. package/packages/bundled-features/src/delivery/delivery-service.ts +16 -6
  80. package/packages/bundled-features/src/delivery/feature.ts +2 -2
  81. package/packages/bundled-features/src/delivery/handlers/log.query.ts +3 -2
  82. package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +1 -1
  83. package/packages/bundled-features/src/delivery/index.ts +8 -1
  84. package/packages/bundled-features/src/delivery/unsubscribe.ts +66 -37
  85. package/packages/bundled-features/src/delivery/upsert-preference.ts +5 -2
  86. package/packages/bundled-features/src/derivatives-sharp/feature.ts +21 -12
  87. package/packages/bundled-features/src/derivatives-sharp/index.ts +1 -1
  88. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +112 -103
  89. package/packages/bundled-features/src/document-ingest-foundation/forget-extract-with-file-ref.ts +3 -3
  90. package/packages/bundled-features/src/document-ingest-foundation/index.ts +4 -1
  91. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  92. package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -5
  93. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  94. package/packages/bundled-features/src/file-derivatives/feature.ts +134 -129
  95. package/packages/bundled-features/src/file-derivatives/handlers/public-variant-by-file-ref.query.ts +1 -1
  96. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  97. package/packages/bundled-features/src/file-foundation/feature.ts +38 -29
  98. package/packages/bundled-features/src/file-foundation/index.ts +1 -0
  99. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +1 -1
  100. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +32 -21
  101. package/packages/bundled-features/src/file-provider-inmemory/index.ts +6 -1
  102. package/packages/bundled-features/src/file-provider-s3/changes.json +10 -1
  103. package/packages/bundled-features/src/file-provider-s3/env-feature.ts +62 -0
  104. package/packages/bundled-features/src/file-provider-s3/feature.ts +107 -73
  105. package/packages/bundled-features/src/file-provider-s3/index.ts +6 -1
  106. package/packages/bundled-features/src/file-provider-s3/lib/index.ts +3 -0
  107. package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/s3-provider.ts +19 -19
  108. package/packages/bundled-features/src/file-provider-s3-env/index.ts +7 -2
  109. package/packages/bundled-features/src/files-provider-s3/index.ts +11 -3
  110. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +1 -1
  111. package/packages/bundled-features/src/files-tenant-data/hooks.ts +1 -2
  112. package/packages/bundled-features/src/folders/feature.ts +8 -3
  113. package/packages/bundled-features/src/folders-user-data/index.ts +27 -18
  114. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
  115. package/packages/bundled-features/src/form-draft/db/queries/draft-count.ts +1 -1
  116. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +3 -2
  117. package/packages/bundled-features/src/form-draft/feature.ts +6 -1
  118. package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +2 -2
  119. package/packages/bundled-features/src/form-draft/index.ts +1 -1
  120. package/packages/bundled-features/src/form-draft/lookup.ts +1 -1
  121. package/packages/bundled-features/src/form-draft-user-data/index.ts +19 -10
  122. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +165 -154
  123. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +1 -2
  124. package/packages/bundled-features/src/inbound-mail-foundation/index.ts +1 -1
  125. package/packages/bundled-features/src/inbound-mail-foundation/oauth-access-token.ts +5 -2
  126. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +3 -2
  127. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +1 -1
  128. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +22 -13
  129. package/packages/bundled-features/src/inbound-provider-imap/index.ts +6 -1
  130. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +20 -12
  131. package/packages/bundled-features/src/inbound-provider-inmemory/index.ts +1 -0
  132. package/packages/bundled-features/src/jobs/db/queries/retention.ts +1 -1
  133. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +1 -1
  134. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +1 -1
  135. package/packages/bundled-features/src/jobs/handlers/list.query.ts +7 -2
  136. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  137. package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +1 -1
  138. package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +1 -1
  139. package/packages/bundled-features/src/jobs/job-run-logger.ts +11 -10
  140. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  141. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  142. package/packages/bundled-features/src/ledger/feature.ts +6 -3
  143. package/packages/bundled-features/src/mail-foundation/feature.ts +66 -46
  144. package/packages/bundled-features/src/mail-foundation/i18n.ts +8 -0
  145. package/packages/bundled-features/src/mail-foundation/index.ts +1 -0
  146. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +31 -17
  147. package/packages/bundled-features/src/mail-transport-inmemory/index.ts +6 -1
  148. package/packages/bundled-features/src/mail-transport-smtp/changes.json +7 -0
  149. package/packages/bundled-features/src/mail-transport-smtp/config-keys.ts +67 -0
  150. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +67 -82
  151. package/packages/bundled-features/src/mail-transport-smtp/i18n.ts +28 -0
  152. package/packages/bundled-features/src/mail-transport-smtp/index.ts +1 -0
  153. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +1 -1
  154. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +1 -2
  155. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +1 -2
  156. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -4
  157. package/packages/bundled-features/src/metrics/compute.ts +1 -1
  158. package/packages/bundled-features/src/metrics/filters.ts +1 -1
  159. package/packages/bundled-features/src/metrics/validate.ts +1 -1
  160. package/packages/bundled-features/src/notes-history/feature.ts +6 -3
  161. package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
  162. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  163. package/packages/bundled-features/src/notes-history-user-data/index.ts +27 -18
  164. package/packages/bundled-features/src/personal-access-tokens/changes.json +6 -0
  165. package/packages/bundled-features/src/personal-access-tokens/feature.ts +17 -2
  166. package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
  167. package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +2 -2
  168. package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
  169. package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
  170. package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -2
  171. package/packages/bundled-features/src/personal-access-tokens/roles.ts +8 -6
  172. package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -0
  173. package/packages/bundled-features/src/readiness/feature.ts +25 -16
  174. package/packages/bundled-features/src/readiness/index.ts +1 -1
  175. package/packages/bundled-features/src/secrets/changes.json +6 -0
  176. package/packages/bundled-features/src/secrets/db/queries/read.ts +1 -1
  177. package/packages/bundled-features/src/secrets/feature.ts +26 -6
  178. package/packages/bundled-features/src/secrets/handlers/delete.write.ts +5 -2
  179. package/packages/bundled-features/src/secrets/handlers/rotate.job.ts +2 -2
  180. package/packages/bundled-features/src/secrets/handlers/set.write.ts +5 -2
  181. package/packages/bundled-features/src/secrets/secrets-context.ts +4 -3
  182. package/packages/bundled-features/src/sessions/db/queries/cleanup.ts +1 -1
  183. package/packages/bundled-features/src/sessions/handlers/detail.query.ts +1 -1
  184. package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -2
  185. package/packages/bundled-features/src/sessions/handlers/mine.query.ts +1 -1
  186. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +1 -1
  187. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +1 -1
  188. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  189. package/packages/bundled-features/src/sessions/session-callbacks.ts +14 -7
  190. package/packages/bundled-features/src/sessions/testing.ts +1 -1
  191. package/packages/bundled-features/src/tags/feature.ts +6 -3
  192. package/packages/bundled-features/src/template-resolver/api.ts +1 -1
  193. package/packages/bundled-features/src/template-resolver/constants.ts +0 -1
  194. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +1 -1
  195. package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +1 -1
  196. package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +1 -2
  197. package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
  198. package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -2
  199. package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +1 -1
  200. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +1 -1
  201. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +1 -1
  202. package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +1 -1
  203. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +1 -1
  204. package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +1 -1
  205. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
  206. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +1 -1
  207. package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +1 -1
  208. package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +1 -1
  209. package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +4 -2
  210. package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +1 -1
  211. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +1 -1
  212. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +1 -1
  213. package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +1 -1
  214. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +1 -1
  215. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +1 -1
  216. package/packages/bundled-features/src/template-resolver/seeding.ts +3 -3
  217. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +1 -1
  218. package/packages/bundled-features/src/template-resolver/template-preview.ts +1 -1
  219. package/packages/bundled-features/src/template-resolver/template-resources.ts +1 -1
  220. package/packages/bundled-features/src/template-resolver/testing.ts +1 -1
  221. package/packages/bundled-features/src/template-resolver-user-data/index.ts +23 -14
  222. package/packages/bundled-features/src/tenant/handlers/active-tenant-ids.query.ts +1 -1
  223. package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -2
  224. package/packages/bundled-features/src/tenant/handlers/cancel-invitation.write.ts +1 -1
  225. package/packages/bundled-features/src/tenant/handlers/invitations.query.ts +1 -1
  226. package/packages/bundled-features/src/tenant/handlers/me.query.ts +1 -1
  227. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
  228. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  229. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  230. package/packages/bundled-features/src/tenant/handlers/remove-member.write.ts +2 -1
  231. package/packages/bundled-features/src/tenant/handlers/resolve-user-ids.query.ts +1 -1
  232. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  233. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
  234. package/packages/bundled-features/src/tenant/handlers/update-member-roles.write.ts +1 -2
  235. package/packages/bundled-features/src/tenant/invited-membership.ts +2 -2
  236. package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -2
  237. package/packages/bundled-features/src/tenant/seeding.ts +12 -12
  238. package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +1 -2
  239. package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts +1 -2
  240. package/packages/bundled-features/src/tenant-lifecycle/lib/revoke-tenant-sessions.ts +1 -1
  241. package/packages/bundled-features/src/tenant-lifecycle/lifecycle-gate.ts +1 -1
  242. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +3 -3
  243. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +10 -5
  244. package/packages/bundled-features/src/tenant-lifecycle/testing.ts +3 -3
  245. package/packages/bundled-features/src/tenant-settings/feature.ts +34 -29
  246. package/packages/bundled-features/src/tier-engine/feature.ts +426 -428
  247. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +2 -3
  248. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +5 -2
  249. package/packages/bundled-features/src/user/changes.json +6 -0
  250. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +1 -1
  251. package/packages/bundled-features/src/user/handlers/create.write.ts +1 -2
  252. package/packages/bundled-features/src/user/handlers/find-for-auth.query.ts +1 -1
  253. package/packages/bundled-features/src/user/handlers/list.query.ts +1 -1
  254. package/packages/bundled-features/src/user/handlers/update-roles.ts +2 -1
  255. package/packages/bundled-features/src/user/index.ts +5 -1
  256. package/packages/bundled-features/src/user/invited-global-roles.ts +2 -2
  257. package/packages/bundled-features/src/user/principal-status.ts +13 -3
  258. package/packages/bundled-features/src/user/resolve-display-names.ts +1 -1
  259. package/packages/bundled-features/src/user/seeding.ts +5 -5
  260. package/packages/bundled-features/src/user-data-rights/audit-download.ts +2 -2
  261. package/packages/bundled-features/src/user-data-rights/changes.json +6 -0
  262. package/packages/bundled-features/src/user-data-rights/db/queries/export-jobs.ts +1 -1
  263. package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +1 -1
  264. package/packages/bundled-features/src/user-data-rights/feature.ts +7 -4
  265. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +1 -1
  266. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +1 -1
  267. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +1 -1
  268. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +1 -1
  269. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +1 -1
  270. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +1 -2
  271. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +3 -3
  272. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +40 -3
  273. package/packages/bundled-features/src/user-data-rights/lib/deny-if-target-outside-admin-tenant.ts +1 -1
  274. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +7 -2
  275. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +7 -3
  276. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +11 -5
  277. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +10 -5
  278. package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +1 -2
  279. package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
  280. package/packages/bundled-features/src/waitlist/lib.ts +5 -2
  281. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +1 -1
  282. package/packages/bundled-features/src/workflow-runner/feature.ts +58 -47
  283. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +1 -1
  284. package/packages/bundled-features/src/workflow-runner/index.ts +1 -1
  285. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +1 -1
  286. package/samples/apps/admin-console/src/run-config.ts +2 -2
  287. package/samples/apps/cap-billing-demo/package.json +3 -0
  288. package/samples/apps/cap-billing-demo/src/feature.ts +2 -2
  289. package/samples/apps/cap-billing-demo/src/run-config.ts +8 -8
  290. package/samples/apps/marketing-demo/src/app/seed.ts +1 -1
  291. package/samples/apps/marketing-demo/src/db/queries/seed-counts.ts +1 -1
  292. package/samples/apps/showcase/package.json +3 -0
  293. package/samples/apps/showcase/src/app/seed-items.ts +1 -1
  294. package/samples/apps/styleguide/src/app/seed.ts +2 -2
  295. package/samples/apps/styleguide/src/features/ai-settings/seed.ts +2 -2
  296. package/samples/apps/ui-walkthrough/scripts/emit-e2e-data.ts +1 -1
  297. package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +1 -1
  298. package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +2 -2
  299. package/samples/apps/ui-walkthrough/src/app/seed-vehicles.ts +1 -1
  300. package/samples/apps/ui-walkthrough/src/app/seed.ts +1 -1
  301. package/samples/apps/ui-walkthrough/src/db/queries/row-counts.ts +1 -1
  302. package/samples/apps/ui-walkthrough/src/db/queries/task-counts.ts +1 -1
  303. package/samples/apps/use-all-bundled/feature-manifest.json +16 -16
  304. package/samples/apps/use-all-bundled/package.json +3 -0
  305. package/samples/apps/use-all-bundled/scripts/check-coverage.ts +2 -2
  306. package/samples/apps/use-all-bundled/src/app/auth-constants.ts +1 -1
  307. package/samples/apps/use-all-bundled/src/app/cap-overview-caps.ts +2 -2
  308. package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +1 -1
  309. package/samples/apps/use-all-bundled/src/app/seed-documents.ts +1 -1
  310. package/samples/apps/use-all-bundled/src/app/seed.ts +11 -5
  311. package/samples/apps/use-all-bundled/src/run-config.ts +55 -56
  312. package/samples/apps/user-data-rights-demo/README.md +2 -2
  313. package/samples/apps/user-data-rights-demo/package.json +3 -0
  314. package/samples/apps/user-data-rights-demo/src/run-config.ts +7 -7
  315. package/samples/apps/workspaces/package.json +3 -0
  316. package/samples/recipes/access-control/package.json +3 -0
  317. package/samples/recipes/anonymous-access/package.json +3 -0
  318. package/samples/recipes/anonymous-access-multitenant/package.json +3 -0
  319. package/samples/recipes/apex-landing/package.json +1 -0
  320. package/samples/recipes/apex-surface-auth/package.json +3 -0
  321. package/samples/recipes/apex-surface-auth/src/feature.ts +2 -2
  322. package/samples/recipes/api-worker-split/package.json +3 -0
  323. package/samples/recipes/api-worker-split/src/feature.ts +1 -2
  324. package/samples/recipes/auth-claims/package.json +3 -0
  325. package/samples/recipes/auth-foundation-providers/src/feature.ts +1 -1
  326. package/samples/recipes/auth-mfa/package.json +3 -0
  327. package/samples/recipes/basic-entity/package.json +3 -0
  328. package/samples/recipes/chat-channels/package.json +3 -0
  329. package/samples/recipes/compliance-profiles-demo/package.json +3 -0
  330. package/samples/recipes/cross-feature-events/package.json +3 -1
  331. package/samples/recipes/cross-feature-events/src/feature.ts +1 -1
  332. package/samples/recipes/crypto-shredding-hr/package.json +3 -0
  333. package/samples/recipes/currencies-global/package.json +3 -0
  334. package/samples/recipes/currencies-per-tenant/package.json +3 -0
  335. package/samples/recipes/custom-fields-basic/package.json +3 -0
  336. package/samples/recipes/custom-handlers/package.json +3 -0
  337. package/samples/recipes/dashboard-stats/package.json +3 -0
  338. package/samples/recipes/delivery-notifications/package.json +3 -0
  339. package/samples/recipes/e2e-generator/package.json +3 -0
  340. package/samples/recipes/embedded/package.json +3 -0
  341. package/samples/recipes/embedded-entity-form/package.json +1 -0
  342. package/samples/recipes/encrypted-tenant-config/README.md +1 -1
  343. package/samples/recipes/encrypted-tenant-config/package.json +3 -0
  344. package/samples/recipes/error-contract/package.json +3 -0
  345. package/samples/recipes/event-sourcing/package.json +3 -1
  346. package/samples/recipes/event-sourcing/src/feature.ts +16 -20
  347. package/samples/recipes/event-sourcing/tsconfig.json +2 -6
  348. package/samples/recipes/feature-toggles/package.json +3 -0
  349. package/samples/recipes/field-access/package.json +3 -0
  350. package/samples/recipes/files-post-processing/package.json +1 -0
  351. package/samples/recipes/golden-path/README.md +30 -0
  352. package/samples/recipes/golden-path/package.json +11 -0
  353. package/samples/recipes/golden-path/src/feature.ts +70 -0
  354. package/samples/recipes/idempotency/package.json +3 -0
  355. package/samples/recipes/inbound-mail-triage/package.json +3 -0
  356. package/samples/recipes/lane-routing/package.json +3 -0
  357. package/samples/recipes/ledger-banking/package.json +3 -0
  358. package/samples/recipes/ledger-invoicing/package.json +3 -0
  359. package/samples/recipes/legal-pages/package.json +3 -0
  360. package/samples/recipes/lifecycle-hooks/package.json +3 -0
  361. package/samples/recipes/managed-config/package.json +3 -0
  362. package/samples/recipes/managed-pages/package.json +3 -0
  363. package/samples/recipes/notes-history-basic/package.json +3 -0
  364. package/samples/recipes/ownership/package.json +3 -0
  365. package/samples/recipes/pdf-audit-export/package.json +1 -0
  366. package/samples/recipes/pipeline-basics/package.json +3 -0
  367. package/samples/recipes/public-share-token/package.json +3 -0
  368. package/samples/recipes/public-share-token/src/feature.ts +1 -1
  369. package/samples/recipes/rate-limiting/package.json +3 -0
  370. package/samples/recipes/realtime-sse/package.json +3 -0
  371. package/samples/recipes/record-detail-layout/package.json +1 -0
  372. package/samples/recipes/reference-data/package.json +3 -0
  373. package/samples/recipes/relations/package.json +3 -0
  374. package/samples/recipes/screens-nav/package.json +3 -0
  375. package/samples/recipes/search/package.json +3 -0
  376. package/samples/recipes/secrets-demo/package.json +3 -0
  377. package/samples/recipes/security-baseline/src/feature.ts +2 -2
  378. package/samples/recipes/session-revocation/README.md +1 -1
  379. package/samples/recipes/session-revocation/package.json +3 -0
  380. package/samples/recipes/session-revocation/src/feature.ts +1 -1
  381. package/samples/recipes/state-machine/package.json +3 -1
  382. package/samples/recipes/state-machine/src/entities/invoice.ts +2 -2
  383. package/samples/recipes/state-machine/src/events.ts +19 -0
  384. package/samples/recipes/state-machine/src/feature.ts +25 -30
  385. package/samples/recipes/state-machine/src/handlers/_helpers.ts +13 -14
  386. package/samples/recipes/state-machine/src/handlers/create.ts +1 -1
  387. package/samples/recipes/state-machine/src/handlers/transitions.ts +129 -122
  388. package/samples/recipes/state-machine/src/reducer.ts +1 -1
  389. package/samples/recipes/state-machine/tsconfig.json +2 -6
  390. package/samples/recipes/tags-basic/package.json +3 -0
  391. package/samples/recipes/tenant-isolation/package.json +3 -0
  392. package/samples/recipes/tenant-settings/package.json +3 -0
  393. package/samples/recipes/tier-admin/package.json +3 -0
  394. package/samples/recipes/timezones/package.json +3 -0
  395. package/samples/recipes/tsconfig.base.json +1 -1
  396. package/samples/recipes/user-data-rights/package.json +3 -0
  397. package/samples/recipes/user-data-rights/src/feature.ts +6 -2
  398. package/samples/recipes/user-profile/package.json +3 -0
  399. package/samples/recipes/user-profile/src/feature.ts +2 -2
  400. package/samples/recipes/webhook-step/package.json +3 -0
  401. package/samples/recipes/wizard-form/package.json +1 -0
  402. package/samples/recipes/workflow-engine/package.json +3 -0
  403. package/samples/recipes/workflow-engine/src/db/queries/suspended-runs.ts +5 -2
  404. package/samples/recipes/writeform-section/package.json +1 -0
  405. package/packages/bundled-features/src/file-provider-s3-env/feature.ts +0 -58
  406. /package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/env-helper.ts +0 -0
@@ -37,36 +37,45 @@ export {
37
37
 
38
38
  const FEATURE_NAME = "file-foundation";
39
39
 
40
- export const fileFoundationFeature = defineFeature(FEATURE_NAME, (r) => {
41
- r.describe(
42
- "Defines the `fileProvider` extension point and a per-tenant `provider` config key that selects which registered storage plugin to use at runtime. Call `createFileProviderForTenant(ctx, tenantId)` to get a `FileStorageProvider` — use this feature together with at least one `file-provider-*` feature; the `files` feature builds on top of it for tracked `FileRef` entities with GDPR hooks.",
43
- );
44
- r.uiHints({
45
- displayLabel: "File Provider Foundation",
46
- category: "storage",
47
- recommended: false,
48
- });
49
- r.requires({ features: ["config"] });
40
+ export function createFileFoundationFeature() {
41
+ return defineFeature(
42
+ FEATURE_NAME,
43
+ (r) => {
44
+ r.describe(
45
+ "Defines the `fileProvider` extension point and a per-tenant `provider` config key that selects which registered storage plugin to use at runtime. Call `createFileProviderForTenant(ctx, tenantId)` to get a `FileStorageProvider` — use this feature together with at least one `file-provider-*` feature; the `files` feature builds on top of it for tracked `FileRef` entities with GDPR hooks.",
46
+ );
47
+ r.uiHints({
48
+ displayLabel: "File Provider Foundation",
49
+ category: "storage",
50
+ recommended: false,
51
+ });
52
+ r.requires({ features: ["config"] });
50
53
 
51
- r.extendsRegistrar(EXT_FILE_PROVIDER, {
52
- onRegister: () => {
53
- // No side-effects at register-time — registry stores the usage,
54
- // factory looks it up at request-time.
55
- },
56
- });
54
+ r.extendsRegistrar(EXT_FILE_PROVIDER, {
55
+ onRegister: () => {
56
+ // No side-effects at register-time — registry stores the usage,
57
+ // factory looks it up at request-time.
58
+ },
59
+ });
57
60
 
58
- const providerConfigKey = r.config(
59
- "provider",
60
- createTenantConfig("text", {
61
- default: "",
62
- env: FILE_STORAGE_PROVIDER_ENV,
63
- write: access.roles("TenantAdmin", "SystemAdmin"),
64
- read: access.roles("TenantAdmin", "SystemAdmin", "User"),
65
- }),
61
+ const providerConfigKey = r.config(
62
+ "provider",
63
+ createTenantConfig("text", {
64
+ default: "",
65
+ env: FILE_STORAGE_PROVIDER_ENV,
66
+ write: access.roles("TenantAdmin", "SystemAdmin"),
67
+ read: access.roles("TenantAdmin", "SystemAdmin", "User"),
68
+ }),
69
+ );
70
+ // Readiness gating: provider-plugins' required keys/secrets count only
71
+ // while their plugin is the one this key selects.
72
+ r.extensionSelector(EXT_FILE_PROVIDER, providerConfigKey);
73
+
74
+ return { providerConfigKey };
75
+ },
76
+ { dedupeOptions: {} },
66
77
  );
67
- // Readiness gating: provider-plugins' required keys/secrets count only
68
- // while their plugin is the one this key selects.
69
- r.extensionSelector(EXT_FILE_PROVIDER, providerConfigKey);
78
+ }
70
79
 
71
- return { providerConfigKey };
72
- });
80
+ /** @deprecated Use createFileFoundationFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
81
+ export const fileFoundationFeature = createFileFoundationFeature();
@@ -1,6 +1,7 @@
1
1
  // Public API of the file-foundation bundled-feature.
2
2
 
3
3
  export {
4
+ createFileFoundationFeature,
4
5
  createFileProviderForTenant,
5
6
  type FileProviderContext,
6
7
  type FileProviderPlugin,
@@ -1,5 +1,5 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
2
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
3
3
  import { isUuid, type TenantId } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import {
5
5
  createFileContext,
@@ -58,27 +58,38 @@ export function clearStorage(tenantId: string): void {
58
58
  // =============================================================================
59
59
  // Feature-definition
60
60
  // =============================================================================
61
+ export function createFileProviderInMemoryFeature() {
62
+ return defineFeature(
63
+ FEATURE_NAME,
64
+ (r) => {
65
+ r.describe(
66
+ 'Registers an in-process `"inmemory"` provider for `file-foundation` that stores file bytes per tenant in a module-level Map. Use `listKeys(tenantId)` and `clearStorage(tenantId)` in demo apps and tests; not for production (data is lost on restart and grows without bound).',
67
+ );
68
+ r.uiHints({
69
+ displayLabel: "File Provider · In-Memory",
70
+ category: "storage",
71
+ recommended: false,
72
+ });
73
+ // Kein requires auf "config" oder "secrets" — der
74
+ // In-Memory-Provider hat keine Config + kein Secret. Nur die
75
+ // file-foundation muss da sein (Plugin-extension-point).
76
+ r.requires({ features: ["file-foundation"] });
61
77
 
62
- export const fileProviderInMemoryFeature = defineFeature(FEATURE_NAME, (r) => {
63
- r.describe(
64
- 'Registers an in-process `"inmemory"` provider for `file-foundation` that stores file bytes per tenant in a module-level Map. Use `listKeys(tenantId)` and `clearStorage(tenantId)` in demo apps and tests; not for production (data is lost on restart and grows without bound).',
78
+ const plugin: FileProviderPlugin = {
79
+ build: async (
80
+ _ctx: FileProviderContext,
81
+ tenantId: string,
82
+ ): Promise<FileStorageProvider> => {
83
+ // Returns the per-tenant storage. Identity-stable across calls so
84
+ // accumulated state is kept.
85
+ return getOrCreateProviderForTenant(tenantId);
86
+ }, // @wrapper-known semantic-alias
87
+ };
88
+ r.useExtension("fileProvider", "inmemory", plugin);
89
+ },
90
+ { dedupeOptions: {} },
65
91
  );
66
- r.uiHints({
67
- displayLabel: "File Provider · In-Memory",
68
- category: "storage",
69
- recommended: false,
70
- });
71
- // Kein requires auf "config" oder "secrets" — der
72
- // In-Memory-Provider hat keine Config + kein Secret. Nur die
73
- // file-foundation muss da sein (Plugin-extension-point).
74
- r.requires({ features: ["file-foundation"] });
92
+ }
75
93
 
76
- const plugin: FileProviderPlugin = {
77
- build: async (_ctx: FileProviderContext, tenantId: string): Promise<FileStorageProvider> => {
78
- // Returnt den per-tenant Storage. Identitätsstabil zwischen calls
79
- // damit accumulated state erhalten bleibt.
80
- return getOrCreateProviderForTenant(tenantId);
81
- }, // @wrapper-known semantic-alias
82
- };
83
- r.useExtension("fileProvider", "inmemory", plugin);
84
- });
94
+ /** @deprecated Use createFileProviderInMemoryFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
95
+ export const fileProviderInMemoryFeature = createFileProviderInMemoryFeature();
@@ -1,3 +1,8 @@
1
1
  // Public API of the file-provider-inmemory bundled-feature.
2
2
 
3
- export { clearStorage, fileProviderInMemoryFeature, listKeys } from "./feature.js";
3
+ export {
4
+ clearStorage,
5
+ createFileProviderInMemoryFeature,
6
+ fileProviderInMemoryFeature,
7
+ listKeys,
8
+ } from "./feature.js";
@@ -1 +1,10 @@
1
- []
1
+ [
2
+ {
3
+ "version": "0.368.0",
4
+ "type": "breaking",
5
+ "title": "The S3 file providers merge into createFileProviderS3Feature({ fromEnv })",
6
+ "detail": "createFileProviderS3Feature() mounts the per-tenant config provider as before. createFileProviderS3Feature({ fromEnv: true }) mounts the env-configured provider (feature name, provider key \"s3-env\" and requires unchanged). The S3 client helpers (createS3Provider, createS3ProviderFromEnv, parseS3EnvConfig, resolveForcePathStyle, S3ProviderConfig) move to the new subpath @cosmicdrift/kumiko-bundled-features/file-provider-s3/lib.\n\nThe subpaths file-provider-s3-env and files-provider-s3 keep working as deprecated re-exports and are removed in the first release after 2026-10-29.\n\nold -> new:\n fileProviderS3EnvFeature from .../file-provider-s3-env -> createFileProviderS3Feature({ fromEnv: true }) from .../file-provider-s3\n fileProviderS3Feature -> createFileProviderS3Feature()\n @cosmicdrift/kumiko-bundled-features/files-provider-s3 -> @cosmicdrift/kumiko-bundled-features/file-provider-s3/lib",
7
+ "migration": "Run `bun kumiko-upgrade --apply`. It rewrites the imports and the env feature mount, and reports `typeof fileProviderS3EnvFeature` and re-exports of it with file and line.",
8
+ "codemod": "scripts/codemod/s3-imports.ts"
9
+ }
10
+ ]
@@ -0,0 +1,62 @@
1
+ // file-provider-s3-env — S3 file provider configured entirely from
2
+ // process.env. ONE shared bucket for ALL tenants: wire it by setting the
3
+ // `S3_*` env vars + mounting — no per-tenant admin seeding and no
4
+ // `secrets`-feature dependency.
5
+ //
6
+ // **vs the default file-provider-s3:** the config-based `"s3"` provider owns per-tenant
7
+ // config keys + an encrypted `s3.secretAccessKey` secret (per-tenant
8
+ // buckets, admin-seeded). This `"s3-env"` provider reads one credential set
9
+ // from env and serves every tenant from one bucket — the
10
+ // Hetzner-Object-Storage / single-bucket deploy case. Tenant isolation
11
+ // still holds: file keys carry the tenant (export ZIPs:
12
+ // `exports/<tenantId>/<jobId>.zip`) or are globally-unique UUIDs (fileRefs).
13
+ //
14
+ // **Pattern-Vorbild:** mirrors file-provider-inmemory (zero admin seeding,
15
+ // only the file-foundation plugin-point required).
16
+ //
17
+ // **Env vars** (read by createS3ProviderFromEnv, prefix `S3_`):
18
+ // required — S3_BUCKET, S3_REGION, S3_ACCESS_KEY, S3_SECRET_KEY
19
+ // optional — S3_ENDPOINT (S3-compat stores incl. Hetzner Object Storage),
20
+ // S3_FORCE_PATH_STYLE
21
+ // Missing required vars throw on the FIRST file op (inside the export cron).
22
+ // The user-data-rights boot guard surfaces that at boot instead.
23
+
24
+ import type {
25
+ FileProviderContext,
26
+ FileProviderPlugin,
27
+ } from "@cosmicdrift/kumiko-bundled-features/file-foundation";
28
+ import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
29
+ import type { FileStorageProvider } from "@cosmicdrift/kumiko-framework/files";
30
+ import { createS3ProviderFromEnv } from "./lib/env-helper.js";
31
+
32
+ const FEATURE_NAME = "file-provider-s3-env";
33
+
34
+ export function createFileProviderS3EnvFeature() {
35
+ return defineFeature(
36
+ FEATURE_NAME,
37
+ (r) => {
38
+ r.describe(
39
+ 'Registers an `"s3-env"` provider for `file-foundation` that reads one S3 credential set from `process.env` (`S3_BUCKET`/`S3_REGION`/`S3_ACCESS_KEY`/`S3_SECRET_KEY`, optional `S3_ENDPOINT`/`S3_FORCE_PATH_STYLE`) and serves every tenant from one shared bucket — no per-tenant config or secret seeding. Use this for single-bucket S3-compatible deploys (e.g. Hetzner Object Storage); use `file-provider-s3` instead when each tenant needs its own bucket/credentials.',
40
+ );
41
+ r.uiHints({
42
+ displayLabel: "File Provider · S3 (env)",
43
+ category: "storage",
44
+ recommended: false,
45
+ });
46
+ // No requires on "config" or "secrets" — credentials come from
47
+ // env, not the per-tenant config + secrets store. Only the file-foundation
48
+ // plugin-extension-point must be mounted.
49
+ r.requires({ features: ["file-foundation"] });
50
+
51
+ const plugin: FileProviderPlugin = {
52
+ // tenantId ignored: one shared bucket serves all tenants (isolation via
53
+ // tenant-prefixed / UUID keys). Built fresh per call like file-provider-s3;
54
+ // the S3 client opens no connection at construction.
55
+ build: async (_ctx: FileProviderContext, _tenantId: string): Promise<FileStorageProvider> =>
56
+ createS3ProviderFromEnv(), // @wrapper-known semantic-alias
57
+ };
58
+ r.useExtension("fileProvider", "s3-env", plugin);
59
+ },
60
+ { dedupeOptions: {} },
61
+ );
62
+ }
@@ -11,7 +11,7 @@
11
11
  // { build })`. file-foundation's Factory findet den Plugin via
12
12
  // registry.
13
13
  // 3. build(ctx, tenantId) liest config + secret, ruft `createS3Provider`
14
- // aus files-provider-s3 auf. Der EINZIGE Cross-Feature-Import
14
+ // aus ./lib auf. Der EINZIGE Cross-Feature-Import
15
15
  // des Plugins — bewusst lokal gehalten.
16
16
  //
17
17
  // **Pattern-Vorbild:** mirrors mail-transport-smtp.
@@ -22,7 +22,6 @@ import type {
22
22
  FileProviderContext,
23
23
  FileProviderPlugin,
24
24
  } from "@cosmicdrift/kumiko-bundled-features/file-foundation";
25
- import { createS3Provider } from "@cosmicdrift/kumiko-bundled-features/files-provider-s3";
26
25
  import {
27
26
  requireDefined,
28
27
  requireNonEmpty,
@@ -31,85 +30,120 @@ import {
31
30
  import { requireSecretsContext } from "@cosmicdrift/kumiko-bundled-features/secrets";
32
31
  import { access, createTenantConfig, defineFeature } from "@cosmicdrift/kumiko-framework/engine";
33
32
  import type { FileStorageProvider } from "@cosmicdrift/kumiko-framework/files";
33
+ import { createFileProviderS3EnvFeature } from "./env-feature.js";
34
+ import { createS3Provider } from "./lib/s3-provider.js";
34
35
 
35
36
  const FEATURE_NAME = "file-provider-s3";
36
37
 
37
38
  // =============================================================================
38
39
  // Feature-definition
39
40
  // =============================================================================
41
+ function createTenantConfigFileProviderS3Feature() {
42
+ return defineFeature(
43
+ FEATURE_NAME,
44
+ (r) => {
45
+ r.describe(
46
+ 'Registers itself as the `"s3"` provider for `file-foundation` and owns the per-tenant config keys (`bucket`, `region`, `endpoint`, `forcePathStyle`, `accessKeyId`) and the encrypted `s3.secretAccessKey` secret. Compatible with any S3-compatible object store (AWS S3, Hetzner Object Storage); set credentials via the admin UI or a seed handler before the first file operation.',
47
+ );
48
+ r.uiHints({
49
+ displayLabel: "File Provider · S3",
50
+ category: "storage",
51
+ recommended: false,
52
+ });
53
+ r.requires({ features: ["config"] });
54
+ r.requires({ features: ["secrets"] });
55
+ r.requires({ features: ["file-foundation"] });
40
56
 
41
- export const fileProviderS3Feature = defineFeature(FEATURE_NAME, (r) => {
42
- r.describe(
43
- 'Registers itself as the `"s3"` provider for `file-foundation` and owns the per-tenant config keys (`bucket`, `region`, `endpoint`, `forcePathStyle`, `accessKeyId`) and the encrypted `s3.secretAccessKey` secret. Compatible with any S3-compatible object store (AWS S3, Hetzner Object Storage); set credentials via the admin UI or a seed handler before the first file operation.',
44
- );
45
- r.uiHints({
46
- displayLabel: "File Provider · S3",
47
- category: "storage",
48
- recommended: false,
49
- });
50
- r.requires({ features: ["config"] });
51
- r.requires({ features: ["secrets"] });
52
- r.requires({ features: ["file-foundation"] });
53
-
54
- const secretAccessKey = r.secret("s3.secretAccessKey", {
55
- label: { en: "S3 secret access key" },
56
- hint: {
57
- en: "Private half of the S3 key pair. Hetzner calls it 'Secret Key', AWS calls it 'Secret Access Key'.",
58
- },
59
- redact: (plaintext) => {
60
- if (plaintext.length < 8) return "•".repeat(plaintext.length);
61
- return `${plaintext.slice(0, 4)}...${plaintext.slice(-4)}`;
62
- },
63
- scope: "tenant",
64
- // required: true ↔ the missing-secret throw in readSecretAccessKey — keep in sync.
65
- required: true,
66
- });
67
-
68
- // required: true ↔ the requireNonEmpty calls in buildS3Provider — keep in sync.
69
- const configKeys = r.config({
70
- keys: {
71
- bucket: createTenantConfig("text", {
72
- required: true,
73
- default: "",
74
- write: access.roles("TenantAdmin", "SystemAdmin"),
75
- read: access.roles("TenantAdmin", "SystemAdmin"),
76
- }),
77
- region: createTenantConfig("text", {
78
- required: true,
79
- default: "",
80
- write: access.roles("TenantAdmin", "SystemAdmin"),
81
- read: access.roles("TenantAdmin", "SystemAdmin"),
82
- }),
83
- endpoint: createTenantConfig("text", {
84
- default: "",
85
- write: access.roles("TenantAdmin", "SystemAdmin"),
86
- read: access.roles("TenantAdmin", "SystemAdmin"),
87
- }),
88
- forcePathStyle: createTenantConfig("boolean", {
89
- default: false,
90
- write: access.roles("TenantAdmin", "SystemAdmin"),
91
- }),
92
- accessKeyId: createTenantConfig("text", {
57
+ const secretAccessKey = r.secret("s3.secretAccessKey", {
58
+ label: { en: "S3 secret access key" },
59
+ hint: {
60
+ en: "Private half of the S3 key pair. Hetzner calls it 'Secret Key', AWS calls it 'Secret Access Key'.",
61
+ },
62
+ redact: (plaintext) => {
63
+ if (plaintext.length < 8) return "•".repeat(plaintext.length);
64
+ return `${plaintext.slice(0, 4)}...${plaintext.slice(-4)}`;
65
+ },
66
+ scope: "tenant",
67
+ // required: true ↔ the missing-secret throw in readSecretAccessKey — keep in sync.
93
68
  required: true,
94
- default: "",
95
- write: access.roles("TenantAdmin", "SystemAdmin"),
96
- read: access.roles("TenantAdmin", "SystemAdmin"),
97
- }),
69
+ });
70
+
71
+ // required: true ↔ the requireNonEmpty calls in buildS3Provider — keep in sync.
72
+ const configKeys = r.config({
73
+ keys: {
74
+ bucket: createTenantConfig("text", {
75
+ required: true,
76
+ default: "",
77
+ write: access.roles("TenantAdmin", "SystemAdmin"),
78
+ read: access.roles("TenantAdmin", "SystemAdmin"),
79
+ }),
80
+ region: createTenantConfig("text", {
81
+ required: true,
82
+ default: "",
83
+ write: access.roles("TenantAdmin", "SystemAdmin"),
84
+ read: access.roles("TenantAdmin", "SystemAdmin"),
85
+ }),
86
+ endpoint: createTenantConfig("text", {
87
+ default: "",
88
+ write: access.roles("TenantAdmin", "SystemAdmin"),
89
+ read: access.roles("TenantAdmin", "SystemAdmin"),
90
+ }),
91
+ forcePathStyle: createTenantConfig("boolean", {
92
+ default: false,
93
+ write: access.roles("TenantAdmin", "SystemAdmin"),
94
+ }),
95
+ accessKeyId: createTenantConfig("text", {
96
+ required: true,
97
+ default: "",
98
+ write: access.roles("TenantAdmin", "SystemAdmin"),
99
+ read: access.roles("TenantAdmin", "SystemAdmin"),
100
+ }),
101
+ },
102
+ });
103
+
104
+ // Plugin-Registration. entityName "s3" ist was tenants in
105
+ // file-foundation's `provider` config-key setzen.
106
+ const plugin: FileProviderPlugin = {
107
+ build: async (ctx: FileProviderContext, tenantId: string) => buildS3Provider(ctx, tenantId), // @wrapper-known semantic-alias
108
+ };
109
+ r.useExtension("fileProvider", "s3", plugin);
110
+
111
+ return { configKeys, secretAccessKey };
98
112
  },
99
- });
113
+ { dedupeOptions: {} },
114
+ );
115
+ }
116
+
117
+ export type FileProviderS3FeatureOptions = {
118
+ /** Read one shared credential set from the `S3_*` env vars (provider key "s3-env", feature name "file-provider-s3-env") instead of per-tenant config and secret. */
119
+ readonly fromEnv?: boolean;
120
+ };
121
+
122
+ export function createFileProviderS3Feature(options: {
123
+ readonly fromEnv: true;
124
+ }): ReturnType<typeof createFileProviderS3EnvFeature>;
125
+ export function createFileProviderS3Feature(options?: {
126
+ readonly fromEnv?: false;
127
+ }): ReturnType<typeof createTenantConfigFileProviderS3Feature>;
128
+ export function createFileProviderS3Feature(
129
+ options: FileProviderS3FeatureOptions,
130
+ ):
131
+ | ReturnType<typeof createFileProviderS3EnvFeature>
132
+ | ReturnType<typeof createTenantConfigFileProviderS3Feature>;
133
+ export function createFileProviderS3Feature(options: FileProviderS3FeatureOptions = {}) {
134
+ return options.fromEnv === true
135
+ ? createFileProviderS3EnvFeature()
136
+ : createTenantConfigFileProviderS3Feature();
137
+ }
100
138
 
101
- // Plugin-Registration. entityName "s3" ist was tenants in
102
- // file-foundation's `provider` config-key setzen.
103
- const plugin: FileProviderPlugin = {
104
- build: async (ctx: FileProviderContext, tenantId: string) => buildS3Provider(ctx, tenantId), // @wrapper-known semantic-alias
105
- };
106
- r.useExtension("fileProvider", "s3", plugin);
139
+ /** @deprecated Use createFileProviderS3Feature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
140
+ export const fileProviderS3Feature = createFileProviderS3Feature();
107
141
 
108
- return { configKeys, secretAccessKey };
109
- });
142
+ // Typed config/secret handles are identical across instances, so one module-level instance serves them.
143
+ const tenantConfigFeature = createTenantConfigFileProviderS3Feature();
110
144
 
111
145
  /** Typed handle for the S3 secret-access-key. */
112
- export const S3_SECRET_ACCESS_KEY = fileProviderS3Feature.exports.secretAccessKey;
146
+ export const S3_SECRET_ACCESS_KEY = tenantConfigFeature.exports.secretAccessKey;
113
147
 
114
148
  // =============================================================================
115
149
  // Internal: build the FileStorageProvider from tenant config + secret
@@ -128,30 +162,30 @@ async function buildS3Provider(
128
162
 
129
163
  const FILE_HINT = "Set via tenant-admin UI or seed-handler before reading or writing files.";
130
164
  const bucket = requireNonEmpty(
131
- await ctxConfig(fileProviderS3Feature.exports.configKeys.bucket),
165
+ await ctxConfig(tenantConfigFeature.exports.configKeys.bucket),
132
166
  FEATURE_NAME,
133
167
  "bucket",
134
168
  FILE_HINT,
135
169
  );
136
170
  const region = requireNonEmpty(
137
- await ctxConfig(fileProviderS3Feature.exports.configKeys.region),
171
+ await ctxConfig(tenantConfigFeature.exports.configKeys.region),
138
172
  FEATURE_NAME,
139
173
  "region",
140
174
  FILE_HINT,
141
175
  );
142
176
  const endpointRaw = requireDefined(
143
- await ctxConfig(fileProviderS3Feature.exports.configKeys.endpoint),
177
+ await ctxConfig(tenantConfigFeature.exports.configKeys.endpoint),
144
178
  FEATURE_NAME,
145
179
  "endpoint",
146
180
  ) as string; // @cast-boundary engine-payload
147
181
  const endpoint = endpointRaw.length > 0 ? endpointRaw : undefined;
148
182
  const forcePathStyle = requireDefined(
149
- await ctxConfig(fileProviderS3Feature.exports.configKeys.forcePathStyle),
183
+ await ctxConfig(tenantConfigFeature.exports.configKeys.forcePathStyle),
150
184
  FEATURE_NAME,
151
185
  "forcePathStyle",
152
186
  ) as boolean; // @cast-boundary engine-payload
153
187
  const accessKeyId = requireNonEmpty(
154
- await ctxConfig(fileProviderS3Feature.exports.configKeys.accessKeyId),
188
+ await ctxConfig(tenantConfigFeature.exports.configKeys.accessKeyId),
155
189
  FEATURE_NAME,
156
190
  "accessKeyId",
157
191
  FILE_HINT,
@@ -1,3 +1,8 @@
1
1
  // Public API of the file-provider-s3 bundled-feature.
2
2
 
3
- export { fileProviderS3Feature, S3_SECRET_ACCESS_KEY } from "./feature.js";
3
+ export {
4
+ createFileProviderS3Feature,
5
+ type FileProviderS3FeatureOptions,
6
+ fileProviderS3Feature,
7
+ S3_SECRET_ACCESS_KEY,
8
+ } from "./feature.js";
@@ -0,0 +1,3 @@
1
+ export { createS3ProviderFromEnv, parseS3EnvConfig } from "./env-helper.js";
2
+ export type { S3ProviderConfig } from "./s3-provider.js";
3
+ export { createS3Provider, resolveForcePathStyle } from "./s3-provider.js";
@@ -8,12 +8,12 @@ import {
8
8
  // Operator-Pflicht-Setup (Multipart-Upload-Cleanup)
9
9
  // =============================================================================
10
10
  //
11
- // `writeStream` nutzt Bun's S3-Writer fuer echtes multipart-streaming. S3
12
- // created dabei eine Multipart-Upload-Session mit einer Upload-ID; bei
13
- // normaler Completion wird sie geschlossen. Wird der Export-Worker mid-write
14
- // gecancelt (Pod-Restart, K8s-OOM-Kill, Process-Signal), bleibt die Session
15
- // in S3 OFFEN und berechnet Storage-Kosten fuer die bereits hochgeladenen
16
- // Parts — bis sie via Lifecycle-Rule abgebrochen werden.
11
+ // `writeStream` uses Bun's S3 writer for real multipart streaming. S3
12
+ // creates a multipart-upload session with an upload ID for it; on normal
13
+ // completion the session is closed. If the export worker is cancelled
14
+ // mid-write (pod restart, K8s OOM kill, process signal), the session stays
15
+ // OPEN in S3 and bills storage for the parts already uploaded — until a
16
+ // lifecycle rule aborts it.
17
17
  //
18
18
  // **Pflicht-Operator-Setup auf jedem Bucket:**
19
19
  //
@@ -26,9 +26,9 @@ import {
26
26
  // }]
27
27
  // }
28
28
  //
29
- // AWS-CLI: `aws s3api put-bucket-lifecycle-configuration --bucket <name>
30
- // --lifecycle-configuration file://lifecycle.json`. Hetzner Object Storage
31
- // + R2 + Minio supporten dieselbe Syntax.
29
+ // AWS CLI: `aws s3api put-bucket-lifecycle-configuration --bucket <name>
30
+ // --lifecycle-configuration file://lifecycle.json`. Hetzner Object Storage,
31
+ // R2 and Minio support the same syntax.
32
32
  //
33
33
  // =============================================================================
34
34
  // Operator-Pflicht-Setup (IAM: list permission)
@@ -117,11 +117,11 @@ export function createS3Provider(config: S3ProviderConfig): FileStorageProvider
117
117
 
118
118
  async writeStream(key, source, options): Promise<void> {
119
119
  assertSafeStorageKey(key);
120
- // Echtes multipart-streaming via Bun's S3-Writer — partSize steuert die
121
- // Part-Boundary intern (AWS/R2 verlangen non-final Parts >= 5 MiB,
122
- // sonst EntityTooSmall beim CompleteMultipartUpload). Manuelles flush()
123
- // hier wuerde genau diese Garantie brechen, sobald die Source-Chunks
124
- // nicht auf partSize aufgehen.
120
+ // Real multipart streaming via Bun's S3 writer — partSize controls the
121
+ // part boundary internally (AWS/R2 require non-final parts >= 5 MiB,
122
+ // otherwise EntityTooSmall on CompleteMultipartUpload). A manual flush()
123
+ // here would break exactly that guarantee as soon as the source chunks
124
+ // do not line up with partSize.
125
125
  const writer = client.file(key).writer({
126
126
  ...(options?.mimeType !== undefined && { type: options.mimeType }),
127
127
  retry: 3,
@@ -129,8 +129,8 @@ export function createS3Provider(config: S3ProviderConfig): FileStorageProvider
129
129
  partSize: STREAM_PART_SIZE,
130
130
  });
131
131
  for await (const chunk of source) {
132
- // Await applies Backpressure und bounded die in-flight Queue auf
133
- // queueSize, statt unbegrenzt zu puffern.
132
+ // Await applies backpressure and bounds the in-flight queue to
133
+ // queueSize instead of buffering without limit.
134
134
  await writer.write(chunk);
135
135
  }
136
136
  await writer.end();
@@ -143,9 +143,9 @@ export function createS3Provider(config: S3ProviderConfig): FileStorageProvider
143
143
 
144
144
  readStream(key): AsyncIterable<Uint8Array> {
145
145
  assertSafeStorageKey(key);
146
- // Lazy: erst beim ersten chunk-pull wird der GET-Request abgesetzt.
147
- // Existiert der Key nicht, faellt der Error genau dort (nicht beim
148
- // readStream-Aufruf) — gleiches Lazy-Verhalten wie inmemory + local.
146
+ // Lazy: the GET request is only sent on the first chunk pull. If the key
147
+ // does not exist, the error surfaces right there (not on the readStream
148
+ // call) — same lazy behavior as inmemory + local.
149
149
  return {
150
150
  async *[Symbol.asyncIterator]() {
151
151
  for await (const chunk of client.file(key).stream()) {
@@ -1,3 +1,8 @@
1
- // Public API of the file-provider-s3-env bundled-feature.
1
+ import { createFileProviderS3Feature } from "../file-provider-s3/index.js";
2
2
 
3
- export { fileProviderS3EnvFeature } from "./feature.js";
3
+ /**
4
+ * @deprecated Use createFileProviderS3Feature({ fromEnv: true }) from
5
+ * `@cosmicdrift/kumiko-bundled-features/file-provider-s3`. Run `bun kumiko-upgrade --apply`.
6
+ * Removed in the first release after 2026-10-29.
7
+ */
8
+ export const fileProviderS3EnvFeature = createFileProviderS3Feature({ fromEnv: true });
@@ -1,3 +1,11 @@
1
- export { createS3ProviderFromEnv, parseS3EnvConfig } from "./env-helper.js";
2
- export type { S3ProviderConfig } from "./s3-provider.js";
3
- export { createS3Provider, resolveForcePathStyle } from "./s3-provider.js";
1
+ /**
2
+ * @deprecated Moved to `@cosmicdrift/kumiko-bundled-features/file-provider-s3/lib`. Run `bun kumiko-upgrade --apply`
3
+ * to rewrite imports. Removed in the first release after 2026-10-29.
4
+ */
5
+ export {
6
+ createS3Provider,
7
+ createS3ProviderFromEnv,
8
+ parseS3EnvConfig,
9
+ resolveForcePathStyle,
10
+ type S3ProviderConfig,
11
+ } from "../file-provider-s3/lib/index.js";
@@ -18,8 +18,8 @@
18
18
  // candidates into a flat queue so the shared deadline/circuit-breaker/signal
19
19
  // handling still applies per-key.
20
20
 
21
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
22
21
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
22
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
23
23
  import { parseDerivativeKey } from "@cosmicdrift/kumiko-framework/derivatives";
24
24
  import type { JobContext, TenantId } from "@cosmicdrift/kumiko-framework/engine";
25
25
  import {
@@ -46,8 +46,7 @@
46
46
  // its original. Batched: one existence query per chunk of listed keys,
47
47
  // not one query per key.
48
48
 
49
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
50
- import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
49
+ import { createEventStoreExecutor, selectMany } from "@cosmicdrift/kumiko-framework/db";
51
50
  import {
52
51
  createSystemUser,
53
52
  parseTenantId,