@cosmicdrift/kumiko-bundled-features 0.392.2 → 0.394.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 (380) hide show
  1. package/dist/account-security/feature.d.ts +2 -0
  2. package/dist/account-security/feature.js +3 -1
  3. package/dist/audit/event-classification.js +1 -0
  4. package/dist/auth-email-password/handlers/change-password.write.d.ts +1 -1
  5. package/dist/auth-email-password/handlers/confirm-account-unlock.write.d.ts +1 -1
  6. package/dist/auth-email-password/handlers/invite-accept-with-login.write.d.ts +1 -1
  7. package/dist/auth-email-password/handlers/invite-accept.write.d.ts +1 -1
  8. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  9. package/dist/auth-email-password/handlers/invite-signup-complete.write.d.ts +1 -1
  10. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  11. package/dist/auth-email-password/handlers/logout.write.d.ts +1 -1
  12. package/dist/auth-email-password/handlers/request-account-unlock.write.d.ts +1 -1
  13. package/dist/auth-email-password/handlers/request-email-verification.write.d.ts +1 -1
  14. package/dist/auth-email-password/handlers/request-password-reset.write.d.ts +1 -1
  15. package/dist/auth-email-password/handlers/reset-password.write.d.ts +1 -1
  16. package/dist/auth-email-password/handlers/signup-confirm.write.d.ts +1 -1
  17. package/dist/auth-email-password/handlers/signup-request.write.d.ts +1 -1
  18. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  19. package/dist/auth-email-password/handlers/token-request-handler.d.ts +1 -1
  20. package/dist/auth-email-password/handlers/verify-email.write.d.ts +1 -1
  21. package/dist/auth-email-password/web/auth-client.d.ts +3 -7
  22. package/dist/auth-email-password/web/auth-client.js +3 -24
  23. package/dist/auth-email-password/web/auth-gate.d.ts +2 -4
  24. package/dist/auth-email-password/web/auth-redirect.d.ts +2 -2
  25. package/dist/auth-email-password/web/auth-redirect.js +3 -12
  26. package/dist/auth-email-password/web/index.d.ts +2 -1
  27. package/dist/auth-email-password/web/index.js +1 -0
  28. package/dist/auth-email-password/web/login-failure.d.ts +9 -0
  29. package/dist/auth-email-password/web/login-failure.js +32 -0
  30. package/dist/auth-email-password/web/login-url.d.ts +5 -0
  31. package/dist/auth-email-password/web/login-url.js +13 -0
  32. package/dist/auth-email-password/web/static-login.d.ts +42 -0
  33. package/dist/auth-email-password/web/static-login.js +122 -0
  34. package/dist/auth-mfa/handlers/disable.write.d.ts +1 -1
  35. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.d.ts +1 -1
  36. package/dist/auth-mfa/handlers/enable-confirm.write.d.ts +1 -1
  37. package/dist/auth-mfa/handlers/enable-start-preauth.write.d.ts +1 -1
  38. package/dist/auth-mfa/handlers/enable-start.write.d.ts +1 -1
  39. package/dist/auth-mfa/handlers/regenerate-recovery.write.d.ts +1 -1
  40. package/dist/auth-mfa/handlers/verify.write.d.ts +1 -1
  41. package/dist/auth-mfa/web/mfa-client.js +4 -43
  42. package/dist/billing-foundation/checkout-core.d.ts +2 -1
  43. package/dist/billing-foundation/checkout-core.js +2 -11
  44. package/dist/billing-foundation/events.d.ts +1 -0
  45. package/dist/billing-foundation/events.js +2 -0
  46. package/dist/billing-foundation/feature.js +1 -1
  47. package/dist/billing-foundation/handlers/create-checkout-session.write.js +9 -2
  48. package/dist/billing-foundation/handlers/process-payment-event.write.d.ts +1 -0
  49. package/dist/billing-foundation/handlers/process-payment-event.write.js +2 -0
  50. package/dist/billing-foundation/index.d.ts +1 -1
  51. package/dist/billing-foundation/one-off-checkout-gate.d.ts +9 -0
  52. package/dist/billing-foundation/one-off-checkout-gate.js +30 -0
  53. package/dist/billing-foundation/one-off-customer.d.ts +6 -0
  54. package/dist/billing-foundation/one-off-customer.js +12 -0
  55. package/dist/billing-foundation/plan-catalog.js +1 -0
  56. package/dist/billing-foundation/types.d.ts +25 -0
  57. package/dist/billing-foundation/web/billing-plans-panel.js +1 -0
  58. package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +7 -3
  59. package/dist/billing-foundation/web/plan-switch-recurring.d.ts +16 -0
  60. package/dist/billing-foundation/web/plan-switch-recurring.js +10 -0
  61. package/dist/billing-foundation/webhook-handler.js +1 -0
  62. package/dist/cap-overview/handlers/caps-usage.query.js +3 -3
  63. package/dist/cap-overview/types.d.ts +2 -0
  64. package/dist/channel-in-app/handlers/mark-all-read.write.d.ts +1 -1
  65. package/dist/channel-in-app/handlers/mark-read.write.d.ts +1 -1
  66. package/dist/compliance-profiles/handlers/set-profile.write.d.ts +1 -1
  67. package/dist/compliance-profiles/web/compliance-profile-catalog.js +8 -1
  68. package/dist/config/handlers/reset.write.d.ts +1 -1
  69. package/dist/config/handlers/set.write.d.ts +1 -1
  70. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +1 -1
  71. package/dist/delivery/handlers/resubscribe-address.write.d.ts +1 -1
  72. package/dist/delivery/handlers/resubscribe-user.write.d.ts +1 -1
  73. package/dist/delivery/handlers/set-preference.write.d.ts +1 -1
  74. package/dist/delivery/handlers/unsubscribe-address.write.d.ts +1 -1
  75. package/dist/delivery/handlers/unsubscribe-user.write.d.ts +1 -1
  76. package/dist/feature-toggles/handlers/set.write.d.ts +1 -1
  77. package/dist/file-foundation/read-file-ref-content.d.ts +2 -0
  78. package/dist/file-foundation/read-file-ref-content.js +9 -3
  79. package/dist/form-draft/handlers/discard.write.d.ts +1 -1
  80. package/dist/form-draft/handlers/save.write.d.ts +1 -1
  81. package/dist/inbound-mail-foundation/account-health.d.ts +17 -0
  82. package/dist/inbound-mail-foundation/account-health.js +101 -0
  83. package/dist/inbound-mail-foundation/account-poll-schedule.d.ts +19 -0
  84. package/dist/inbound-mail-foundation/account-poll-schedule.js +44 -0
  85. package/dist/inbound-mail-foundation/account-poll.d.ts +24 -0
  86. package/dist/inbound-mail-foundation/account-poll.js +157 -0
  87. package/dist/inbound-mail-foundation/account-record.d.ts +1 -0
  88. package/dist/inbound-mail-foundation/account-record.js +1 -0
  89. package/dist/inbound-mail-foundation/account-wake.d.ts +3 -0
  90. package/dist/inbound-mail-foundation/account-wake.js +17 -0
  91. package/dist/inbound-mail-foundation/connect-callback-verify.d.ts +10 -0
  92. package/dist/inbound-mail-foundation/connect-callback-verify.js +31 -0
  93. package/dist/inbound-mail-foundation/connect-route-responses.d.ts +13 -0
  94. package/dist/inbound-mail-foundation/connect-route-responses.js +16 -0
  95. package/dist/inbound-mail-foundation/connect-routes.js +52 -33
  96. package/dist/inbound-mail-foundation/constants.d.ts +50 -2
  97. package/dist/inbound-mail-foundation/constants.js +53 -3
  98. package/dist/inbound-mail-foundation/content-refetch.d.ts +14 -0
  99. package/dist/inbound-mail-foundation/content-refetch.js +93 -0
  100. package/dist/inbound-mail-foundation/describe-error.d.ts +1 -0
  101. package/dist/inbound-mail-foundation/describe-error.js +5 -0
  102. package/dist/inbound-mail-foundation/entities.d.ts +26 -0
  103. package/dist/inbound-mail-foundation/entities.js +43 -3
  104. package/dist/inbound-mail-foundation/events.d.ts +97 -0
  105. package/dist/inbound-mail-foundation/events.js +57 -2
  106. package/dist/inbound-mail-foundation/feature.d.ts +5 -2
  107. package/dist/inbound-mail-foundation/feature.js +122 -106
  108. package/dist/inbound-mail-foundation/file-storage-failure.d.ts +8 -0
  109. package/dist/inbound-mail-foundation/file-storage-failure.js +19 -0
  110. package/dist/inbound-mail-foundation/handlers/account-address.d.ts +16 -0
  111. package/dist/inbound-mail-foundation/handlers/account-address.js +51 -0
  112. package/dist/inbound-mail-foundation/handlers/acknowledge-quarantine.write.d.ts +8 -0
  113. package/dist/inbound-mail-foundation/handlers/acknowledge-quarantine.write.js +39 -0
  114. package/dist/inbound-mail-foundation/handlers/attach-message-content.write.d.ts +60 -0
  115. package/dist/inbound-mail-foundation/handlers/attach-message-content.write.js +128 -0
  116. package/dist/inbound-mail-foundation/handlers/connect-account.write.d.ts +3 -2
  117. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +97 -56
  118. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.d.ts +2 -1
  119. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +55 -42
  120. package/dist/inbound-mail-foundation/handlers/ingest-message-prepare.d.ts +26 -0
  121. package/dist/inbound-mail-foundation/handlers/ingest-message-prepare.js +131 -0
  122. package/dist/inbound-mail-foundation/handlers/ingest-message-schema.d.ts +64 -0
  123. package/dist/inbound-mail-foundation/handlers/ingest-message-schema.js +39 -0
  124. package/dist/inbound-mail-foundation/handlers/ingest-message.write.d.ts +74 -21
  125. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +57 -134
  126. package/dist/inbound-mail-foundation/handlers/list-accounts.query.d.ts +2 -1
  127. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +60 -26
  128. package/dist/inbound-mail-foundation/handlers/list-messages.query.d.ts +2 -1
  129. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +43 -29
  130. package/dist/inbound-mail-foundation/handlers/list-quarantine.query.d.ts +3 -0
  131. package/dist/inbound-mail-foundation/handlers/list-quarantine.query.js +75 -0
  132. package/dist/inbound-mail-foundation/handlers/mark-credential-stored.write.d.ts +7 -0
  133. package/dist/inbound-mail-foundation/handlers/mark-credential-stored.write.js +38 -0
  134. package/dist/inbound-mail-foundation/handlers/message-content.d.ts +70 -0
  135. package/dist/inbound-mail-foundation/handlers/message-content.js +137 -0
  136. package/dist/inbound-mail-foundation/handlers/message-content.query.d.ts +19 -0
  137. package/dist/inbound-mail-foundation/handlers/message-content.query.js +59 -0
  138. package/dist/inbound-mail-foundation/handlers/message-detail.query.d.ts +3 -0
  139. package/dist/inbound-mail-foundation/handlers/message-detail.query.js +23 -0
  140. package/dist/inbound-mail-foundation/handlers/reactivate-account.write.d.ts +8 -0
  141. package/dist/inbound-mail-foundation/handlers/reactivate-account.write.js +84 -0
  142. package/dist/inbound-mail-foundation/handlers/retry-quarantined-message.write.d.ts +8 -0
  143. package/dist/inbound-mail-foundation/handlers/retry-quarantined-message.write.js +34 -0
  144. package/dist/inbound-mail-foundation/handlers/scope-visibility.d.ts +10 -2
  145. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +27 -8
  146. package/dist/inbound-mail-foundation/handlers/set-trusted-authserv-id.write.d.ts +13 -0
  147. package/dist/inbound-mail-foundation/handlers/set-trusted-authserv-id.write.js +54 -0
  148. package/dist/inbound-mail-foundation/handlers/thread-rollup.d.ts +24 -0
  149. package/dist/inbound-mail-foundation/handlers/thread-rollup.js +98 -0
  150. package/dist/inbound-mail-foundation/handlers/trusted-authserv-id.d.ts +3 -0
  151. package/dist/inbound-mail-foundation/handlers/trusted-authserv-id.js +3 -0
  152. package/dist/inbound-mail-foundation/handlers/update-account.write.d.ts +13 -3
  153. package/dist/inbound-mail-foundation/handlers/update-account.write.js +62 -46
  154. package/dist/inbound-mail-foundation/i18n.js +72 -2
  155. package/dist/inbound-mail-foundation/inbound-oauth-flow.d.ts +43 -0
  156. package/dist/inbound-mail-foundation/inbound-oauth-flow.js +1 -0
  157. package/dist/inbound-mail-foundation/index.d.ts +19 -6
  158. package/dist/inbound-mail-foundation/index.js +17 -6
  159. package/dist/inbound-mail-foundation/ingest-failures.d.ts +77 -0
  160. package/dist/inbound-mail-foundation/ingest-failures.js +79 -0
  161. package/dist/inbound-mail-foundation/ingest-payload.d.ts +7 -0
  162. package/dist/inbound-mail-foundation/ingest-payload.js +34 -0
  163. package/dist/inbound-mail-foundation/mail-roles.d.ts +21 -0
  164. package/dist/inbound-mail-foundation/mail-roles.js +83 -0
  165. package/dist/inbound-mail-foundation/normalize-inbound-message.d.ts +17 -0
  166. package/dist/inbound-mail-foundation/normalize-inbound-message.js +90 -0
  167. package/dist/inbound-mail-foundation/oauth-access-token.d.ts +3 -1
  168. package/dist/inbound-mail-foundation/oauth-access-token.js +13 -2
  169. package/dist/inbound-mail-foundation/outbound-attachment-access.d.ts +5 -0
  170. package/dist/inbound-mail-foundation/outbound-attachment-access.js +16 -0
  171. package/dist/inbound-mail-foundation/outbound-attachments.d.ts +18 -0
  172. package/dist/inbound-mail-foundation/outbound-attachments.js +77 -0
  173. package/dist/inbound-mail-foundation/outbound-mail.d.ts +15 -1
  174. package/dist/inbound-mail-foundation/outbound-mail.js +4 -0
  175. package/dist/inbound-mail-foundation/probe.js +1 -1
  176. package/dist/inbound-mail-foundation/projection.d.ts +28 -0
  177. package/dist/inbound-mail-foundation/projection.js +25 -3
  178. package/dist/inbound-mail-foundation/provider-errors.d.ts +28 -0
  179. package/dist/inbound-mail-foundation/provider-errors.js +66 -0
  180. package/dist/inbound-mail-foundation/quarantine-entities.d.ts +61 -0
  181. package/dist/inbound-mail-foundation/quarantine-entities.js +47 -0
  182. package/dist/inbound-mail-foundation/quarantine-header-import.d.ts +9 -0
  183. package/dist/inbound-mail-foundation/quarantine-header-import.js +53 -0
  184. package/dist/inbound-mail-foundation/quarantine-retry.d.ts +13 -0
  185. package/dist/inbound-mail-foundation/quarantine-retry.js +97 -0
  186. package/dist/inbound-mail-foundation/quarantine-screens.d.ts +4 -0
  187. package/dist/inbound-mail-foundation/quarantine-screens.js +57 -0
  188. package/dist/inbound-mail-foundation/quarantine.d.ts +13 -0
  189. package/dist/inbound-mail-foundation/quarantine.js +46 -0
  190. package/dist/inbound-mail-foundation/retention-job.d.ts +2 -0
  191. package/dist/inbound-mail-foundation/retention-job.js +62 -0
  192. package/dist/inbound-mail-foundation/retention-sweep.d.ts +4 -0
  193. package/dist/inbound-mail-foundation/retention-sweep.js +35 -8
  194. package/dist/inbound-mail-foundation/screens.d.ts +14 -2
  195. package/dist/inbound-mail-foundation/screens.js +217 -79
  196. package/dist/inbound-mail-foundation/send-from-account.d.ts +11 -1
  197. package/dist/inbound-mail-foundation/send-from-account.js +19 -2
  198. package/dist/inbound-mail-foundation/sender-auth.d.ts +63 -0
  199. package/dist/inbound-mail-foundation/sender-auth.js +198 -0
  200. package/dist/inbound-mail-foundation/supervisor-ingest.d.ts +43 -0
  201. package/dist/inbound-mail-foundation/supervisor-ingest.js +195 -0
  202. package/dist/inbound-mail-foundation/sync-account-now.d.ts +22 -0
  203. package/dist/inbound-mail-foundation/sync-account-now.js +29 -0
  204. package/dist/inbound-mail-foundation/sync-cursor-store.d.ts +9 -0
  205. package/dist/inbound-mail-foundation/sync-cursor-store.js +54 -0
  206. package/dist/inbound-mail-foundation/syncable-accounts.d.ts +16 -0
  207. package/dist/inbound-mail-foundation/syncable-accounts.js +79 -0
  208. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +5 -1
  209. package/dist/inbound-mail-foundation/types.d.ts +61 -62
  210. package/dist/inbound-mail-foundation/types.js +0 -54
  211. package/dist/inbound-mail-foundation/wake-consumer.d.ts +2 -0
  212. package/dist/inbound-mail-foundation/wake-consumer.js +30 -0
  213. package/dist/inbound-mail-foundation/watch-catch-up.d.ts +19 -0
  214. package/dist/inbound-mail-foundation/watch-catch-up.js +33 -0
  215. package/dist/inbound-mail-foundation/watch-lease.d.ts +15 -0
  216. package/dist/inbound-mail-foundation/watch-lease.js +81 -0
  217. package/dist/inbound-mail-foundation/watch-supervisor-types.d.ts +83 -0
  218. package/dist/inbound-mail-foundation/watch-supervisor-types.js +1 -0
  219. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +1 -53
  220. package/dist/inbound-mail-foundation/watch-supervisor.js +123 -290
  221. package/dist/inbound-mail-foundation/web/client-plugin.d.ts +14 -0
  222. package/dist/inbound-mail-foundation/web/client-plugin.js +40 -0
  223. package/dist/inbound-mail-foundation/web/constants.d.ts +5 -0
  224. package/dist/inbound-mail-foundation/web/constants.js +6 -0
  225. package/dist/inbound-mail-foundation/web/index.d.ts +1 -0
  226. package/dist/inbound-mail-foundation/web/index.js +1 -0
  227. package/dist/inbound-provider-imap/connect-mailbox.d.ts +28 -5
  228. package/dist/inbound-provider-imap/connect-mailbox.js +91 -41
  229. package/dist/inbound-provider-imap/connect-my-mailbox.d.ts +13 -0
  230. package/dist/inbound-provider-imap/connect-my-mailbox.js +25 -0
  231. package/dist/inbound-provider-imap/constants.d.ts +12 -1
  232. package/dist/inbound-provider-imap/constants.js +12 -1
  233. package/dist/inbound-provider-imap/credential-document.js +2 -2
  234. package/dist/inbound-provider-imap/download-batch.d.ts +6 -0
  235. package/dist/inbound-provider-imap/download-batch.js +24 -0
  236. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  237. package/dist/inbound-provider-imap/feature.js +49 -32
  238. package/dist/inbound-provider-imap/fetch-content.d.ts +4 -0
  239. package/dist/inbound-provider-imap/fetch-content.js +68 -0
  240. package/dist/inbound-provider-imap/i18n.js +18 -2
  241. package/dist/inbound-provider-imap/imap-client.d.ts +27 -23
  242. package/dist/inbound-provider-imap/imap-client.js +30 -68
  243. package/dist/inbound-provider-imap/index.d.ts +2 -1
  244. package/dist/inbound-provider-imap/index.js +2 -1
  245. package/dist/inbound-provider-imap/mime-content.d.ts +11 -0
  246. package/dist/inbound-provider-imap/mime-content.js +66 -0
  247. package/dist/inbound-provider-imap/parse-message.d.ts +35 -0
  248. package/dist/inbound-provider-imap/parse-message.js +113 -0
  249. package/dist/inbound-provider-imap/reconnect-account.d.ts +17 -0
  250. package/dist/inbound-provider-imap/reconnect-account.js +18 -0
  251. package/dist/inbound-provider-imap/reconnect-mailbox.d.ts +14 -0
  252. package/dist/inbound-provider-imap/reconnect-mailbox.js +71 -0
  253. package/dist/inbound-provider-imap/reconnect-prefill.query.d.ts +3 -0
  254. package/dist/inbound-provider-imap/reconnect-prefill.query.js +34 -0
  255. package/dist/inbound-provider-imap/screens.d.ts +6 -1
  256. package/dist/inbound-provider-imap/screens.js +174 -41
  257. package/dist/inbound-provider-imap/send-mail.d.ts +2 -2
  258. package/dist/inbound-provider-imap/send-mail.js +8 -1
  259. package/dist/inbound-provider-imap/sender-auth-headers.d.ts +3 -0
  260. package/dist/inbound-provider-imap/sender-auth-headers.js +18 -0
  261. package/dist/inbound-provider-inmemory/feature.d.ts +15 -0
  262. package/dist/inbound-provider-inmemory/feature.js +57 -2
  263. package/dist/inbound-provider-inmemory/index.d.ts +1 -1
  264. package/dist/inbound-provider-inmemory/index.js +1 -1
  265. package/dist/jobs/handlers/consumer.write.d.ts +4 -4
  266. package/dist/jobs/handlers/retry.write.d.ts +1 -1
  267. package/dist/jobs/handlers/trigger.write.d.ts +1 -1
  268. package/dist/managed-pages/handlers/set.write.d.ts +1 -1
  269. package/dist/managed-pages/web/i18n.js +1 -0
  270. package/dist/personal-access-tokens/handlers/create.write.d.ts +1 -1
  271. package/dist/personal-access-tokens/handlers/revoke.write.d.ts +1 -1
  272. package/dist/readiness/handlers/run-probes.write.d.ts +1 -1
  273. package/dist/secrets/handlers/delete.write.d.ts +1 -1
  274. package/dist/secrets/handlers/set.write.d.ts +1 -1
  275. package/dist/sessions/handlers/revoke-all-for-user.write.d.ts +1 -1
  276. package/dist/sessions/handlers/revoke-all-others.write.d.ts +1 -1
  277. package/dist/sessions/handlers/revoke.write.d.ts +1 -1
  278. package/dist/subscription-paddle/checkout-config.query.d.ts +3 -0
  279. package/dist/subscription-paddle/checkout-config.query.js +14 -0
  280. package/dist/subscription-paddle/checkout-methods.d.ts +6 -0
  281. package/dist/subscription-paddle/checkout-methods.js +85 -0
  282. package/dist/subscription-paddle/checkout-page.d.ts +19 -0
  283. package/dist/subscription-paddle/checkout-page.js +126 -0
  284. package/dist/subscription-paddle/client.d.ts +24 -0
  285. package/dist/subscription-paddle/client.js +60 -0
  286. package/dist/subscription-paddle/constants.d.ts +16 -0
  287. package/dist/subscription-paddle/constants.js +25 -0
  288. package/dist/subscription-paddle/feature.d.ts +49 -0
  289. package/dist/subscription-paddle/feature.js +192 -0
  290. package/dist/subscription-paddle/index.d.ts +2 -0
  291. package/dist/subscription-paddle/index.js +4 -0
  292. package/dist/subscription-paddle/plan-switch-methods.d.ts +6 -0
  293. package/dist/subscription-paddle/plan-switch-methods.js +114 -0
  294. package/dist/subscription-paddle/price-methods.d.ts +15 -0
  295. package/dist/subscription-paddle/price-methods.js +105 -0
  296. package/dist/subscription-paddle/runtime.d.ts +42 -0
  297. package/dist/subscription-paddle/runtime.js +109 -0
  298. package/dist/subscription-paddle/subscription-state.d.ts +34 -0
  299. package/dist/subscription-paddle/subscription-state.js +48 -0
  300. package/dist/subscription-paddle/tenant-binding.d.ts +8 -0
  301. package/dist/subscription-paddle/tenant-binding.js +26 -0
  302. package/dist/subscription-paddle/verify-webhook.d.ts +4 -0
  303. package/dist/subscription-paddle/verify-webhook.js +55 -0
  304. package/dist/subscription-paddle/webhook-events.d.ts +9 -0
  305. package/dist/subscription-paddle/webhook-events.js +124 -0
  306. package/dist/template-resolver/handlers/collection-item.query.js +2 -2
  307. package/dist/template-resolver/handlers/collection-list.query.js +4 -2
  308. package/dist/template-resolver/handlers/collection-set.write.d.ts +1 -1
  309. package/dist/template-resolver/handlers/collection-shared.d.ts +11 -0
  310. package/dist/template-resolver/handlers/collection-shared.js +16 -0
  311. package/dist/template-resolver/handlers/copy-locale.write.d.ts +1 -1
  312. package/dist/template-resolver/handlers/discard-draft.write.d.ts +2 -2
  313. package/dist/template-resolver/handlers/import-bundle-system.write.d.ts +1 -1
  314. package/dist/template-resolver/handlers/import-bundle.write.d.ts +1 -1
  315. package/dist/template-resolver/handlers/patch-draft.write.d.ts +1 -1
  316. package/dist/template-resolver/handlers/reset-to-system.write.d.ts +1 -1
  317. package/dist/template-resolver/handlers/resource-link-pdf.write.d.ts +1 -1
  318. package/dist/template-resolver/handlers/resource-remove.write.d.ts +1 -1
  319. package/dist/template-resolver/handlers/resource-upload.write.d.ts +1 -1
  320. package/dist/template-resolver/handlers/send-test.write.d.ts +1 -1
  321. package/dist/template-resolver/handlers/set.write.d.ts +1 -1
  322. package/dist/template-resolver/handlers/toggle-status.write.d.ts +4 -4
  323. package/dist/template-resolver/handlers/upsert-system.write.d.ts +1 -1
  324. package/dist/template-resolver/handlers/upsert-tenant.write.d.ts +1 -1
  325. package/dist/template-resolver/web/client-plugin.d.ts +4 -0
  326. package/dist/template-resolver/web/client-plugin.js +134 -52
  327. package/dist/template-resolver/web/i18n.js +1 -1
  328. package/dist/tenant/handlers/add-member.write.d.ts +1 -1
  329. package/dist/tenant/handlers/cancel-invitation.write.d.ts +1 -1
  330. package/dist/tenant/handlers/create.write.d.ts +1 -1
  331. package/dist/tenant/handlers/remove-member.write.d.ts +1 -1
  332. package/dist/tenant/handlers/toggle-enabled.write.d.ts +2 -2
  333. package/dist/tenant/handlers/update-member-roles.write.d.ts +1 -1
  334. package/dist/tenant/handlers/update.write.d.ts +1 -1
  335. package/dist/tenant-handover/handlers/claim.write.d.ts +1 -1
  336. package/dist/tenant-lifecycle/handlers/cancel-destruction.write.d.ts +1 -1
  337. package/dist/tenant-lifecycle/handlers/request-destruction.write.d.ts +1 -1
  338. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +1 -1
  339. package/dist/user/handlers/create.write.d.ts +1 -1
  340. package/dist/user/handlers/update.write.d.ts +1 -1
  341. package/dist/user-data-rights/handlers/cancel-deletion.write.d.ts +1 -1
  342. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.d.ts +1 -1
  343. package/dist/user-data-rights/handlers/lift-restriction.write.d.ts +1 -1
  344. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +1 -1
  345. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +1 -1
  346. package/dist/user-data-rights/handlers/request-export.write.d.ts +1 -1
  347. package/dist/user-data-rights/handlers/restrict-account.write.d.ts +1 -1
  348. package/dist/user-data-rights/handlers/run-forget-cleanup.write.d.ts +1 -1
  349. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +2 -1
  350. package/dist/user-profile/handlers/change-email.write.d.ts +1 -1
  351. package/dist/waitlist/handlers/export-purge.write.d.ts +2 -2
  352. package/dist/waitlist/handlers/invite.write.d.ts +1 -1
  353. package/dist/waitlist/handlers/reject.write.d.ts +1 -1
  354. package/dist/waitlist/handlers/submit.write.d.ts +1 -1
  355. package/package.json +33 -17
  356. package/src/account-security/changes.json +6 -0
  357. package/src/auth-email-password/changes.json +6 -0
  358. package/src/billing-foundation/changes.json +30 -0
  359. package/src/cap-overview/changes.json +6 -0
  360. package/src/files/changes.json +18 -0
  361. package/src/inbound-mail-foundation/changes.json +155 -0
  362. package/src/inbound-provider-imap/changes.json +42 -0
  363. package/src/jobs/changes.json +18 -0
  364. package/src/subscription-paddle/changes.json +15 -0
  365. package/src/template-resolver/changes.json +12 -0
  366. package/dist/subscription-dodo/client.d.ts +0 -17
  367. package/dist/subscription-dodo/client.js +0 -31
  368. package/dist/subscription-dodo/constants.d.ts +0 -12
  369. package/dist/subscription-dodo/constants.js +0 -19
  370. package/dist/subscription-dodo/feature.d.ts +0 -37
  371. package/dist/subscription-dodo/feature.js +0 -144
  372. package/dist/subscription-dodo/index.d.ts +0 -2
  373. package/dist/subscription-dodo/index.js +0 -4
  374. package/dist/subscription-dodo/plugin-methods.d.ts +0 -23
  375. package/dist/subscription-dodo/plugin-methods.js +0 -260
  376. package/dist/subscription-dodo/runtime.d.ts +0 -27
  377. package/dist/subscription-dodo/runtime.js +0 -89
  378. package/dist/subscription-dodo/verify-webhook.d.ts +0 -37
  379. package/dist/subscription-dodo/verify-webhook.js +0 -189
  380. package/src/subscription-dodo/changes.json +0 -14
@@ -6,4 +6,4 @@ export declare function createRegenerateRecoveryHandler(opts: RegenerateRecovery
6
6
  code: z.ZodString;
7
7
  }, z.core.$strip>, {
8
8
  recoveryCodes: string[];
9
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
9
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -11,4 +11,4 @@ export declare function createMfaVerifyHandler(opts: MfaVerifyOptions): import("
11
11
  }, z.core.$strip>, {
12
12
  kind: string;
13
13
  session: SessionUser;
14
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
14
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -6,7 +6,7 @@
6
6
  // false, error}) because auth-routes.ts uses mintSessionAndRespond() for both
7
7
  // routes.
8
8
  // kumiko-lint-ignore cross-feature-import client-only types, the feature's server barrel has no web/ re-export
9
- import { toLoginResponse, } from "../../auth-email-password/web/index.js";
9
+ import { failureFromErrorField, toLoginResponse, } from "../../auth-email-password/web/index.js";
10
10
  export async function verifyMfaChallenge(challengeToken, code) {
11
11
  const res = await fetch("/api/auth/mfa/verify", {
12
12
  method: "POST",
@@ -25,20 +25,7 @@ export async function verifyMfaChallenge(challengeToken, code) {
25
25
  data: toLoginResponse(body.token, body.user, body.landingPath),
26
26
  };
27
27
  }
28
- const err = body.error;
29
- if (typeof err === "string") {
30
- return { kind: "failure", error: { reason: err } };
31
- }
32
- const reason = err?.details?.reason ?? err?.code ?? "mfa_verify_failed";
33
- const retry = err?.details?.retryAfterSeconds;
34
- return {
35
- kind: "failure",
36
- error: {
37
- reason,
38
- ...(err?.message !== undefined && { message: err.message }),
39
- ...(retry !== undefined && { retryAfterSeconds: retry }),
40
- },
41
- };
28
+ return { kind: "failure", error: failureFromErrorField(body.error, "mfa_verify_failed") };
42
29
  }
43
30
  // Browser side of POST /api/auth/mfa/preauth-enable-start — lets a user
44
31
  // blocked at login by MFA enforcement generate a TOTP secret/QR without a
@@ -71,20 +58,7 @@ export async function startMfaSetupPreauth(preauthSetupToken, accountLabel) {
71
58
  },
72
59
  };
73
60
  }
74
- const err = body.error;
75
- if (typeof err === "string") {
76
- return { kind: "failure", error: { reason: err } };
77
- }
78
- const reason = err?.details?.reason ?? err?.code ?? "setup_failed";
79
- const retry = err?.details?.retryAfterSeconds;
80
- return {
81
- kind: "failure",
82
- error: {
83
- reason,
84
- ...(err?.message !== undefined && { message: err.message }),
85
- ...(retry !== undefined && { retryAfterSeconds: retry }),
86
- },
87
- };
61
+ return { kind: "failure", error: failureFromErrorField(body.error, "setup_failed") };
88
62
  }
89
63
  // Browser side of POST /api/auth/mfa/preauth-confirm — completes both the
90
64
  // enrollment started by startMfaSetupPreauth and the login
@@ -110,18 +84,5 @@ export async function confirmMfaSetupPreauth(setupToken, code) {
110
84
  data: toLoginResponse(body.token, body.user, body.landingPath),
111
85
  };
112
86
  }
113
- const err = body.error;
114
- if (typeof err === "string") {
115
- return { kind: "failure", error: { reason: err } };
116
- }
117
- const reason = err?.details?.reason ?? err?.code ?? "mfa_setup_confirm_failed";
118
- const retry = err?.details?.retryAfterSeconds;
119
- return {
120
- kind: "failure",
121
- error: {
122
- reason,
123
- ...(err?.message !== undefined && { message: err.message }),
124
- ...(retry !== undefined && { retryAfterSeconds: retry }),
125
- },
126
- };
87
+ return { kind: "failure", error: failureFromErrorField(body.error, "mfa_setup_confirm_failed") };
127
88
  }
@@ -1,7 +1,7 @@
1
1
  /// <reference types="temporal-polyfill/global" preserve="true" />
2
2
  import type { HandlerContext } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { getSubscriptionForTenant } from "./get-subscription-for-tenant.ts";
4
- import type { BillingPlanCatalog, SubscriptionProviderPlugin } from "./types.ts";
4
+ import type { BillingFoundationOptions, BillingPlanCatalog, SubscriptionProviderPlugin } from "./types.ts";
5
5
  /** Narrows a `readonly string[]` to the non-empty tuple shape `z.enum`
6
6
  * needs. Callers only reach this with a catalog's `plans` — the feature
7
7
  * factory already rejected an empty `plans` array at mount time, so the
@@ -75,6 +75,7 @@ export type OpenCheckoutOptions = {
75
75
  readonly baseUrl?: string;
76
76
  readonly catalog?: BillingPlanCatalog;
77
77
  readonly now: () => Temporal.Instant;
78
+ readonly authorizeOneOffCheckout?: BillingFoundationOptions["authorizeOneOffCheckout"];
78
79
  /** The caller already ran `assertBillingEnabled` under its own handler name
79
80
  * (before a costly provider lookup), so the gate is not repeated here. */
80
81
  readonly billingEnabledChecked?: boolean;
@@ -5,6 +5,7 @@
5
5
  // checkout into a plan-aware one. Internal — not re-exported from index.ts.
6
6
  import { ConflictError, FeatureDisabledError, UnconfiguredError, UnprocessableError, } from "@cosmicdrift/kumiko-framework/errors";
7
7
  import { getSubscriptionForTenant } from "./get-subscription-for-tenant.js";
8
+ import { assertOneOffAuthorized, assertOneOffPriceAllowed } from "./one-off-checkout-gate.js";
8
9
  import { BILLING_FOUNDATION_FEATURE, isSubscriptionBlockingCheckout, SUBSCRIPTION_PROVIDER_EXTENSION, } from "./web/constants.js";
9
10
  /** Narrows a `readonly string[]` to the non-empty tuple shape `z.enum`
10
11
  * needs. Callers only reach this with a catalog's `plans` — the feature
@@ -208,17 +209,6 @@ function assertSubscriptionPriceAllowed(plugin, catalog, input) {
208
209
  });
209
210
  }
210
211
  }
211
- // Missing/empty oneOffPriceIds rejects every payment checkout: same
212
- // "no gate configured yet = closed" default as the priceToTier gate.
213
- function assertOneOffPriceAllowed(plugin, input) {
214
- const oneOffPriceIds = plugin.oneOffPriceIds ?? [];
215
- if (!oneOffPriceIds.includes(input.priceId)) {
216
- throw new UnprocessableError("unknown_price", {
217
- i18nKey: "billing-foundation.errors.unknownPrice",
218
- message: `subscription-foundation: priceId "${input.priceId}" is not in provider "${input.providerName}"'s oneOffPriceIds`,
219
- });
220
- }
221
- }
222
212
  function canCreateCheckoutSession(plugin) {
223
213
  return plugin.createCheckoutSession !== undefined;
224
214
  }
@@ -251,6 +241,7 @@ export async function assertCheckoutAllowed(ctx, options, input) {
251
241
  }
252
242
  else {
253
243
  assertOneOffPriceAllowed(plugin, input);
244
+ await assertOneOffAuthorized(ctx, options.authorizeOneOffCheckout, input);
254
245
  }
255
246
  // Rejects a foreign tenant's provider-customer id — otherwise the checkout
256
247
  // would attach to that customer's stored payment methods and invoices.
@@ -39,6 +39,7 @@ export declare const paymentEventPayloadSchema: z.ZodObject<{
39
39
  providerName: z.ZodString;
40
40
  providerCustomerId: z.ZodString;
41
41
  priceId: z.ZodString;
42
+ quantity: z.ZodOptional<z.ZodNumber>;
42
43
  consentId: z.ZodOptional<z.ZodString>;
43
44
  }, z.core.$strip>;
44
45
  export type PaymentEventPayload = z.infer<typeof paymentEventPayloadSchema>;
@@ -79,6 +79,8 @@ export const paymentEventPayloadSchema = z.object({
79
79
  // subscriptionEventPayloadSchema's same rationale.
80
80
  providerCustomerId: z.string().min(1).max(1000),
81
81
  priceId: z.string().min(1).max(200),
82
+ // Optional so payloads stored before quantity existed still parse; absent = 1.
83
+ quantity: z.number().int().positive().optional(),
82
84
  consentId: z.string().min(1).max(100).optional(),
83
85
  });
84
86
  // =============================================================================
@@ -90,7 +90,7 @@ export function createBillingFoundationFeature(options = {}) {
90
90
  }),
91
91
  };
92
92
  return defineFeature(BILLING_FOUNDATION_FEATURE, (r) => {
93
- r.describe("Plugin host for subscription billing. Manages the `read_subscriptions` projection table and exposes 5 domain events (subscription created/updated/canceled, invoice paid/failed) appended by the foundation's own `billing-foundation:write:process-event` write-handler after provider plugins verify and normalize each webhook. Also manages a separate `read_payments` projection table (one row per one-off-payment) fed by its own `payment-received` event and `billing-foundation:write:process-payment-event` write-handler. Also ships `billing-foundation:write:create-checkout-session` and `billing-foundation:write:create-portal-session` write-handlers, a `billing-foundation:query:subscription:list` query handler, and a `createSubscriptionWebhookRoute` factory for the `/api/subscription/webhook/:providerName` extraRoute. `createBillingFoundationFeature({ baseUrl, catalog })` additionally derives a `billing-foundation:query:billing-plans` query, `start-plan-checkout`/`switch-plan` write-handlers, a `plan-switch-preview` query and a dormant billing-plans dashboard screen/panel from the catalog. Several providers can be mounted at once: new checkouts are offered by every enabled provider (enabled means keys set and billingLive on, or simply mounted for plugins without `isBillingEnabled`), the customer picks one in the plan panel and `start-plan-checkout` takes a `providerName`. An existing subscription stays with the provider that stored it, so the plan list and every switch follow that provider. A plan switch is either hosted (`createPlanSwitchSession` answers a url) or in-app (`previewPlanSwitch` shows the proration, `applyPlanSwitch` runs after the customer confirms; `switch-plan` then answers `{ applied: true }` and records the consent). `consumerProtection.providerTexts` overrides the checkout note and the VAT note per provider. Also ships `billing-foundation:write:sync-subscription` (pulls a provider plugin's live subscription state via `retrieveSubscription` and appends drift as a `subscription.updated` event, which catches changes made on the provider's own dashboard that never reached us as a webhook) and the `sync-subscriptions` job (manual-trigger + runOnBoot, perTenant) that dispatches it. Low-level building block: use `subscription-stripe`, `subscription-mollie` or `subscription-dodo` unless you are writing a new payment provider.");
93
+ r.describe("Plugin host for subscription billing. Manages the `read_subscriptions` projection table and exposes 5 domain events (subscription created/updated/canceled, invoice paid/failed) appended by the foundation's own `billing-foundation:write:process-event` write-handler after provider plugins verify and normalize each webhook. Also manages a separate `read_payments` projection table (one row per one-off-payment) fed by its own `payment-received` event and `billing-foundation:write:process-payment-event` write-handler. Also ships `billing-foundation:write:create-checkout-session` and `billing-foundation:write:create-portal-session` write-handlers, a `billing-foundation:query:subscription:list` query handler, and a `createSubscriptionWebhookRoute` factory for the `/api/subscription/webhook/:providerName` extraRoute. `createBillingFoundationFeature({ baseUrl, catalog })` additionally derives a `billing-foundation:query:billing-plans` query, `start-plan-checkout`/`switch-plan` write-handlers, a `plan-switch-preview` query and a dormant billing-plans dashboard screen/panel from the catalog. Several providers can be mounted at once: new checkouts are offered by every enabled provider (enabled means keys set and billingLive on, or simply mounted for plugins without `isBillingEnabled`), the customer picks one in the plan panel and `start-plan-checkout` takes a `providerName`. An existing subscription stays with the provider that stored it, so the plan list and every switch follow that provider. A plan switch is either hosted (`createPlanSwitchSession` answers a url) or in-app (`previewPlanSwitch` shows the proration, `applyPlanSwitch` runs after the customer confirms; `switch-plan` then answers `{ applied: true }` and records the consent). `consumerProtection.providerTexts` overrides the checkout note and the VAT note per provider. Also ships `billing-foundation:write:sync-subscription` (pulls a provider plugin's live subscription state via `retrieveSubscription` and appends drift as a `subscription.updated` event, which catches changes made on the provider's own dashboard that never reached us as a webhook) and the `sync-subscriptions` job (manual-trigger + runOnBoot, perTenant) that dispatches it. Low-level building block: use `subscription-stripe`, `subscription-mollie` or `subscription-paddle` unless you are writing a new payment provider.");
94
94
  r.uiHints({
95
95
  displayLabel: "Billing · Foundation",
96
96
  category: "billing",
@@ -25,6 +25,7 @@ import { InternalError, UnprocessableError } from "@cosmicdrift/kumiko-framework
25
25
  import * as z from "zod";
26
26
  import { assertCheckoutAllowed, openCheckout, startProviderCheckout, } from "../checkout-core.js";
27
27
  import { assertValidOrderItem, consentCheckoutFields, consentPayloadSchema, prepareConsent, recordConsent, } from "../consumer-protection/consent-gate.js";
28
+ import { withOwnProviderCustomer } from "../one-off-customer.js";
28
29
  const createCheckoutSessionSchema = z.object({
29
30
  /** Welcher Provider — entityName eines registrierten subscription-
30
31
  * Plugins ("stripe" / "paypal" / ...). */
@@ -58,8 +59,13 @@ export function createCheckoutSessionHandler(options) {
58
59
  handler: async (event, ctx) => {
59
60
  // @cast-boundary engine-payload — dispatcher-zod-validated payload
60
61
  const payload = event.payload;
61
- const openOptions = { baseUrl: options.baseUrl, catalog: options.catalog, now: options.now };
62
- const checkoutInput = {
62
+ const openOptions = {
63
+ baseUrl: options.baseUrl,
64
+ catalog: options.catalog,
65
+ now: options.now,
66
+ authorizeOneOffCheckout: options.authorizeOneOffCheckout,
67
+ };
68
+ const requestedInput = {
63
69
  providerName: payload.providerName,
64
70
  priceId: payload.priceId,
65
71
  successUrl: payload.successUrl,
@@ -67,6 +73,7 @@ export function createCheckoutSessionHandler(options) {
67
73
  ...(payload.providerCustomerId && { providerCustomerId: payload.providerCustomerId }),
68
74
  ...(payload.mode && { mode: payload.mode }),
69
75
  };
76
+ const checkoutInput = await withOwnProviderCustomer(ctx, requestedInput);
70
77
  if (!consumerProtection) {
71
78
  const result = await openCheckout(ctx, openOptions, checkoutInput);
72
79
  return {
@@ -6,6 +6,7 @@ export declare const processPaymentEventSchema: z.ZodObject<{
6
6
  providerCheckoutId: z.ZodOptional<z.ZodString>;
7
7
  providerCustomerId: z.ZodString;
8
8
  priceId: z.ZodString;
9
+ quantity: z.ZodOptional<z.ZodNumber>;
9
10
  consentId: z.ZodOptional<z.ZodString>;
10
11
  }, z.core.$strip>;
11
12
  export declare const processPaymentEventHandler: WriteHandlerDef;
@@ -20,6 +20,7 @@ export const processPaymentEventSchema = z.object({
20
20
  providerCheckoutId: z.string().min(1).max(200).optional(),
21
21
  providerCustomerId: z.string().min(1).max(200),
22
22
  priceId: z.string().min(1).max(200),
23
+ quantity: z.number().int().positive().optional(),
23
24
  consentId: z.string().min(1).max(100).optional(),
24
25
  });
25
26
  // SystemAdmin-only: this handler is called exclusively by the programmatic
@@ -72,6 +73,7 @@ export const processPaymentEventHandler = {
72
73
  providerName: payload.providerName,
73
74
  providerCustomerId: encryptedFields.providerCustomerId,
74
75
  priceId: payload.priceId,
76
+ ...(payload.quantity !== undefined && { quantity: payload.quantity }),
75
77
  ...(payload.consentId !== undefined && { consentId: payload.consentId }),
76
78
  };
77
79
  const headers = {
@@ -10,7 +10,7 @@ export { getSubscriptionForTenant, type SubscriptionView } from "./get-subscript
10
10
  export { paymentsProjectionTable, subscriptionsProjectionTable } from "./projection.ts";
11
11
  export { billingPlansPanel, createBillingPlansScreen } from "./screens.ts";
12
12
  export { createSubscriptionTierSync, effectiveTierFromSubscription, SUBSCRIPTION_WEBHOOK_PATH, type SubscriptionTierSyncDeps, type TierSyncResult, } from "./subscription-tier-sync.ts";
13
- export { type BillingFoundationOptions, type BillingPlanBenefit, type BillingPlanCatalog, type BillingPlanContactCard, type BillingPlanPrice, type BillingPlansResult, type BillingPlanView, type BillingProviderView, type ConsumerProtectionOptions, KNOWN_RECURRING_INTERVALS, type LegalLinkSet, type PaymentEvent, type PlanSwitchPreview, type ProviderPrice, type ProviderSubscriptionSnapshot, type RecurringInterval, type SubscriptionEvent, type SubscriptionProviderPlugin, } from "./types.ts";
13
+ export { type BillingFoundationOptions, type BillingPlanBenefit, type BillingPlanCatalog, type BillingPlanContactCard, type BillingPlanPrice, type BillingPlansResult, type BillingPlanView, type BillingProviderView, type ConsumerProtectionOptions, KNOWN_RECURRING_INTERVALS, type LegalLinkSet, type OneOffCheckoutRequest, type OneOffCheckoutVerdict, type PaymentEvent, type PlanSwitchPreview, type ProviderPrice, type ProviderSubscriptionSnapshot, type RecurringInterval, type SubscriptionEvent, type SubscriptionProviderPlugin, } from "./types.ts";
14
14
  export { BILLING_FOUNDATION_FEATURE, BILLING_PLANS_PANEL_COMPONENT, BILLING_PLANS_SCREEN_ID, type BillingEventKind, BillingEventKinds, type BillingPlanAction, BillingPlanActions, DEFAULT_PURCHASE_ROLES, isSwitchableSubscriptionStatus, isTerminalSubscriptionStatus, parseProviderConsentId, SUBSCRIPTION_PROVIDER_EXTENSION, type SubscriptionCancelTiming, SubscriptionCancelTimings, type SubscriptionEventType, SubscriptionEventTypes, SubscriptionFoundationHandlers, SubscriptionFoundationQueries, type SubscriptionStatus, SubscriptionStatuses, } from "./web/constants.ts";
15
15
  export { CONSENT_LOCALES, type ConsentLocale, resolveConsentLocale, } from "./web/consumer-protection/consent-locale.ts";
16
16
  export { createSubscriptionWebhookRoute, type SubscriptionWebhookRouteOptions, } from "./webhook-handler.ts";
@@ -0,0 +1,9 @@
1
+ import type { HandlerContext } from "@cosmicdrift/kumiko-framework/engine";
2
+ import type { BillingFoundationOptions, SubscriptionProviderPlugin } from "./types.ts";
3
+ type OneOffCheckoutInput = {
4
+ readonly providerName: string;
5
+ readonly priceId: string;
6
+ };
7
+ export declare function assertOneOffPriceAllowed(plugin: SubscriptionProviderPlugin, input: OneOffCheckoutInput): void;
8
+ export declare function assertOneOffAuthorized(ctx: HandlerContext, authorize: BillingFoundationOptions["authorizeOneOffCheckout"], input: OneOffCheckoutInput): Promise<void>;
9
+ export {};
@@ -0,0 +1,30 @@
1
+ // Gates for mode:"payment" checkouts, run before any provider call.
2
+ import { UnprocessableError } from "@cosmicdrift/kumiko-framework/errors";
3
+ // Missing/empty oneOffPriceIds rejects every payment checkout: same
4
+ // "no gate configured yet = closed" default as the priceToTier gate.
5
+ export function assertOneOffPriceAllowed(plugin, input) {
6
+ const oneOffPriceIds = plugin.oneOffPriceIds ?? [];
7
+ if (!oneOffPriceIds.includes(input.priceId)) {
8
+ throw new UnprocessableError("unknown_price", {
9
+ i18nKey: "billing-foundation.errors.unknownPrice",
10
+ message: `subscription-foundation: priceId "${input.priceId}" is not in provider "${input.providerName}"'s oneOffPriceIds`,
11
+ });
12
+ }
13
+ }
14
+ // The app's own gate (for example a tier check): without it every price in
15
+ // oneOffPriceIds is open to any TenantAdmin.
16
+ export async function assertOneOffAuthorized(ctx, authorize, input) {
17
+ const verdict = authorize
18
+ ? await authorize(ctx, {
19
+ tenantId: ctx.user.tenantId,
20
+ providerName: input.providerName,
21
+ priceId: input.priceId,
22
+ })
23
+ : { allowed: true };
24
+ if (!verdict.allowed) {
25
+ throw new UnprocessableError(verdict.reason, {
26
+ i18nKey: verdict.i18nKey,
27
+ message: `billing-foundation: authorizeOneOffCheckout rejected the one-off checkout (${verdict.reason})`,
28
+ });
29
+ }
30
+ }
@@ -0,0 +1,6 @@
1
+ import type { HandlerContext } from "@cosmicdrift/kumiko-framework/engine";
2
+ import type { OpenCheckoutInput } from "./checkout-core.ts";
3
+ /** A one-off checkout without an explicit customer reuses the provider customer of the
4
+ * tenant's own subscription at the same provider, so the buyer is not asked again and
5
+ * does not become a second customer. The foreign-customer guard still runs afterwards. */
6
+ export declare function withOwnProviderCustomer(ctx: HandlerContext, input: OpenCheckoutInput): Promise<OpenCheckoutInput>;
@@ -0,0 +1,12 @@
1
+ import { getSubscriptionForTenant } from "./get-subscription-for-tenant.js";
2
+ /** A one-off checkout without an explicit customer reuses the provider customer of the
3
+ * tenant's own subscription at the same provider, so the buyer is not asked again and
4
+ * does not become a second customer. The foreign-customer guard still runs afterwards. */
5
+ export async function withOwnProviderCustomer(ctx, input) {
6
+ if (input.mode !== "payment" || input.providerCustomerId)
7
+ return input;
8
+ const own = await getSubscriptionForTenant(ctx, ctx.user.tenantId);
9
+ return own && own.providerName === input.providerName && own.providerCustomerId
10
+ ? { ...input, providerCustomerId: own.providerCustomerId }
11
+ : input;
12
+ }
@@ -169,5 +169,6 @@ export function toBillingPlansResult(catalog, base, views) {
169
169
  plans: views.plans,
170
170
  ...(views.inAppSwitch && { inAppPlanSwitch: true }),
171
171
  ...(catalog.contact !== undefined && { contact: catalog.contact }),
172
+ ...(catalog.priceNoteKey !== undefined && { priceNoteKey: catalog.priceNoteKey }),
172
173
  };
173
174
  }
@@ -73,6 +73,8 @@ export type PaymentEvent = {
73
73
  readonly providerCustomerId: string;
74
74
  /** Provider's own price/plan-ID of the purchased item. */
75
75
  readonly priceId: string;
76
+ /** Number of units bought; absent = 1. */
77
+ readonly quantity?: number;
76
78
  };
77
79
  export type SubscriptionProviderPlugin = {
78
80
  /** Human-readable provider name for the plan panel's provider switch. */
@@ -270,6 +272,10 @@ export type PlanSwitchPreview = {
270
272
  readonly currency: string;
271
273
  /** Credit for the unused time on the old plan, smallest currency unit. */
272
274
  readonly credit: number;
275
+ /** Recurring price per period as charged by the provider, smallest unit, tax included. */
276
+ readonly recurringAmount?: number;
277
+ /** Tax part of `recurringAmount`; null when the provider reports none. */
278
+ readonly recurringTax?: number | null;
273
279
  readonly effectiveAt: string;
274
280
  };
275
281
  export type ProviderSubscriptionSnapshot = {
@@ -332,6 +338,8 @@ export type BillingPlanCatalog<TTier extends string = string> = {
332
338
  readonly providerName?: string;
333
339
  /** Rendered as the last card, no price, visible to `viewRoles` regardless of `purchaseRoles`. */
334
340
  readonly contact?: BillingPlanContactCard;
341
+ /** App i18n key for a small note under every card's price, e.g. "plus VAT" when catalog prices are net. */
342
+ readonly priceNoteKey?: string;
335
343
  };
336
344
  export type LegalLinkSet = {
337
345
  readonly terms: string;
@@ -375,6 +383,18 @@ export type ConsumerProtectionOptions = {
375
383
  * one set per consent locale (`de` and `en` required). */
376
384
  readonly legalLinks: LegalLinkSet | Readonly<Record<ConsentLocale, LegalLinkSet>>;
377
385
  };
386
+ export type OneOffCheckoutRequest = {
387
+ readonly tenantId: TenantId;
388
+ readonly providerName: string;
389
+ readonly priceId: string;
390
+ };
391
+ export type OneOffCheckoutVerdict = {
392
+ readonly allowed: true;
393
+ } | {
394
+ readonly allowed: false;
395
+ readonly reason: string;
396
+ readonly i18nKey: string;
397
+ };
378
398
  export type BillingFoundationOptions<TTier extends string = string> = {
379
399
  /** Absolute http(s) URL. Its origin is the only redirect origin
380
400
  * create-checkout-session/create-portal-session (when set) and the plan
@@ -384,6 +404,9 @@ export type BillingFoundationOptions<TTier extends string = string> = {
384
404
  * NOT via `new URL(path, baseUrl)` (which would drop the prefix). */
385
405
  readonly baseUrl?: string;
386
406
  readonly catalog?: BillingPlanCatalog<TTier>;
407
+ /** Runs before every one-off (mode "payment") checkout, after the oneOffPriceIds gate and
408
+ * before any provider call; a rejection becomes an UnprocessableError with `reason` as code. */
409
+ readonly authorizeOneOffCheckout?: (ctx: HandlerContext, request: OneOffCheckoutRequest) => Promise<OneOffCheckoutVerdict>;
387
410
  /** Enables the consent gate on checkout; requires `baseUrl`. */
388
411
  readonly consumerProtection?: ConsumerProtectionOptions;
389
412
  /** Injectable clock for the stale-incomplete-subscription check
@@ -446,6 +469,8 @@ export type BillingPlansResult = {
446
469
  readonly inAppPlanSwitch?: true;
447
470
  /** Present only when `catalog.contact` is configured. */
448
471
  readonly contact?: BillingPlanContactCard;
472
+ /** Present only when `catalog.priceNoteKey` is configured. */
473
+ readonly priceNoteKey?: string;
449
474
  /** Present only when `consumerProtection` is configured. */
450
475
  readonly consumerProtection?: {
451
476
  readonly consentTexts: Readonly<Record<"de" | "en", {
@@ -166,6 +166,7 @@ export function BillingPlansPanel(_props) {
166
166
  : {
167
167
  amount: formatMoney(shownPrice.unitAmount, shownPrice.currency, locale),
168
168
  ...(fromPrice !== undefined && { prefix: t("billing-foundation.plans.priceFrom") }),
169
+ ...(result.priceNoteKey !== undefined && { note: t(result.priceNoteKey) }),
169
170
  ...(key !== undefined && {
170
171
  period: t(key, {
171
172
  count: new Intl.NumberFormat(locale).format(shownPrice.intervalCount ?? 1),
@@ -6,6 +6,7 @@ import { CONSENT_TEXT_OUTDATED_CODE, } from "./checkout-consent-dialog.js";
6
6
  import { SubscriptionFoundationHandlers, SubscriptionFoundationQueries } from "./constants.js";
7
7
  import { resolveConsentLocale } from "./consumer-protection/consent-locale.js";
8
8
  import { intervalKey } from "./plan-price.js";
9
+ import { recurringAmountsOf } from "./plan-switch-recurring.js";
9
10
  // kumiko-lint-ignore no-custom-primitives Uses usePrimitives().Modal internally, name is a billing domain action, not a primitive reimplementation
10
11
  export function PlanSwitchConfirmDialog({ open, onOpenChange, tier, fromPlanName, toPlanName, consumerProtection, onApplied, onConsentTextOutdated, }) {
11
12
  const t = useTranslation();
@@ -48,11 +49,14 @@ export function PlanSwitchConfirmDialog({ open, onOpenChange, tier, fromPlanName
48
49
  const reply = previewQuery.data;
49
50
  const money = (amount, currency) => formatMoney(amount, currency, locale);
50
51
  const recurringKey = reply === null ? undefined : intervalKey(reply.target);
51
- const recurringPrice = reply === null
52
+ const recurring = reply === null ? null : recurringAmountsOf(reply);
53
+ const recurringPrice = reply === null || recurring === null
52
54
  ? ""
53
- : `${money(reply.target.unitAmount, reply.target.currency)}${recurringKey === undefined
55
+ : `${money(recurring.amount, recurring.currency)}${recurringKey === undefined
54
56
  ? ""
55
- : ` ${t(recurringKey, { count: new Intl.NumberFormat(locale).format(reply.target.intervalCount ?? 1) })}`}`;
57
+ : ` ${t(recurringKey, { count: new Intl.NumberFormat(locale).format(reply.target.intervalCount ?? 1) })}`}${recurring.tax === null
58
+ ? ""
59
+ : ` (${t("billing-foundation.planSwitch.includesTax", { tax: money(recurring.tax, recurring.currency) })})`}`;
56
60
  return (_jsx(Modal, { open: open, onOpenChange: onOpenChange, title: t("billing-foundation.planSwitch.title"), testId: "plan-switch-confirm-dialog", children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(Text, { children: t("billing-foundation.planSwitch.summary", { from: fromPlanName, to: toPlanName }) }), previewQuery.error !== null && (_jsx(Banner, { variant: "error", testId: "plan-switch-preview-error", children: t(previewQuery.error.i18nKey, previewQuery.error.i18nParams) })), previewQuery.loading && reply === null && (_jsx(Banner, { variant: "loading", testId: "plan-switch-preview-loading", children: t("kumiko.widget.loading") })), reply !== null && (_jsxs("div", { className: "flex flex-col gap-1", "data-testid": "plan-switch-summary", children: [_jsxs(Text, { children: [t("billing-foundation.planSwitch.dueNow", {
57
61
  amount: money(reply.preview.amountDueNow, reply.preview.currency),
58
62
  }), reply.preview.tax !== null &&
@@ -0,0 +1,16 @@
1
+ import type { PlanSwitchPreview } from "../types.ts";
2
+ type RecurringSource = {
3
+ readonly preview: PlanSwitchPreview;
4
+ readonly target: {
5
+ readonly unitAmount: number;
6
+ readonly currency: string;
7
+ };
8
+ };
9
+ export type RecurringAmounts = {
10
+ readonly amount: number;
11
+ readonly currency: string;
12
+ readonly tax: number | null;
13
+ };
14
+ /** The provider's gross recurring price when it reports one, else the catalog's unit amount. */
15
+ export declare function recurringAmountsOf({ preview, target }: RecurringSource): RecurringAmounts;
16
+ export {};
@@ -0,0 +1,10 @@
1
+ /** The provider's gross recurring price when it reports one, else the catalog's unit amount. */
2
+ export function recurringAmountsOf({ preview, target }) {
3
+ return preview.recurringAmount === undefined
4
+ ? { amount: target.unitAmount, currency: target.currency, tax: null }
5
+ : {
6
+ amount: preview.recurringAmount,
7
+ currency: preview.currency,
8
+ tax: preview.recurringTax ?? null,
9
+ };
10
+ }
@@ -61,6 +61,7 @@ export function createSubscriptionWebhookRoute(options = {}) {
61
61
  providerName: parsed.providerName,
62
62
  providerCustomerId: parsed.providerCustomerId,
63
63
  priceId: parsed.priceId,
64
+ ...(parsed.quantity !== undefined && { quantity: parsed.quantity }),
64
65
  ...(parsed.consentId !== undefined && { consentId: parsed.consentId }),
65
66
  ...(parsed.providerCheckoutId !== undefined && {
66
67
  providerCheckoutId: parsed.providerCheckoutId,
@@ -54,7 +54,7 @@ export function createCapsUsageQuery(caps, usageRoles) {
54
54
  const config = override === undefined ? ctx.config : ctx.tenants.config?.(targetTenantId);
55
55
  const rows = await Promise.all(caps.map(async (cap) => {
56
56
  const used = await cap.usage(db, targetTenantId);
57
- const limit = await cap.limit(tier, { config });
57
+ const limit = cap.showLimit === false ? null : await cap.limit(tier, { config });
58
58
  const base = {
59
59
  id: cap.id,
60
60
  label: cap.label,
@@ -63,8 +63,8 @@ export function createCapsUsageQuery(caps, usageRoles) {
63
63
  ...(cap.icon !== undefined && { icon: cap.icon }),
64
64
  ...(cap.accentColor !== undefined && { accentColor: cap.accentColor }),
65
65
  };
66
- if (used === null) {
67
- return { ...base, used: null, fraction: 0, tone: "default", percent: null };
66
+ if (used === null || cap.showLimit === false) {
67
+ return { ...base, used, fraction: 0, tone: "default", percent: null };
68
68
  }
69
69
  const fraction = computeFraction(used, limit);
70
70
  return {
@@ -10,6 +10,8 @@ export type CapSpec = {
10
10
  readonly usage: (db: TenantDb, tenantId: TenantId) => Promise<number | null>;
11
11
  readonly usageBatch?: (db: TenantDb, tenantIds: readonly TenantId[]) => Promise<Map<TenantId, number | null>>;
12
12
  readonly unit?: CapUnit;
13
+ /** `false` shows the counter only: the limit is not sent to the client; enforcement stays with cap-counter. Default true. */
14
+ readonly showLimit?: boolean;
13
15
  /** Icon chip on the dashboard cards. Optional — omitted renders the card
14
16
  * without an icon, same as before this field existed. */
15
17
  readonly icon?: CapIconKey;
@@ -1,4 +1,4 @@
1
1
  import * as z from "zod";
2
2
  export declare const markAllReadWrite: import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"markAllRead", z.ZodObject<{}, z.core.$strip>, {
3
3
  marked: number;
4
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
4
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -3,4 +3,4 @@ export declare const markReadWrite: import("@cosmicdrift/kumiko-types/define-han
3
3
  id: z.ZodNumber;
4
4
  }, z.core.$strip>, {
5
5
  id: number | undefined;
6
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
6
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -10,4 +10,4 @@ export declare const setProfileWrite: import("@cosmicdrift/kumiko-types/define-h
10
10
  }, z.core.$strip>, {
11
11
  profileKey: "de-hr-dsgvo-hgb" | "eu-dsgvo" | "swiss-dsg";
12
12
  isNew: boolean;
13
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
13
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -5,6 +5,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  // this is reference material for the tenant admin.
6
6
  import { usePrimitives, useQuery, useTranslation, } from "@cosmicdrift/kumiko-renderer";
7
7
  import { ComplianceProfileQueries } from "./constants.js";
8
+ // The select options above carry locale translations; the catalog reuses them so both
9
+ // name a profile alike. A profile without an option key keeps its source label.
10
+ function profileLabel(profile, t) {
11
+ const optionKey = `compliance-profiles:entity:__action-form__:field:profileKey:option:${profile.key}`;
12
+ const translated = t(optionKey);
13
+ return translated === optionKey ? profile.label : translated;
14
+ }
8
15
  export function ComplianceProfileCatalog(_props) {
9
16
  const { Banner, Text } = usePrimitives();
10
17
  const t = useTranslation();
@@ -15,5 +22,5 @@ export function ComplianceProfileCatalog(_props) {
15
22
  if (query.error) {
16
23
  return (_jsx(Banner, { variant: "error", testId: "compliance-profile-catalog-error", children: _jsx(Text, { children: t(query.error.i18nKey, query.error.i18nParams) }) }));
17
24
  }
18
- return (_jsx("ul", { className: "flex flex-col gap-2 text-sm", "data-testid": "compliance-profile-catalog", children: (query.data?.profiles ?? []).map((profile) => (_jsxs("li", { "data-profile-key": profile.key, children: [_jsx("strong", { children: profile.label }), " \u2014 ", profile.region, " \u2014 ", profile.authorityContact] }, profile.key))) }));
25
+ return (_jsx("ul", { className: "flex flex-col gap-2 text-sm", "data-testid": "compliance-profile-catalog", children: (query.data?.profiles ?? []).map((profile) => (_jsxs("li", { "data-profile-key": profile.key, children: [_jsx("strong", { children: profileLabel(profile, t) }), " \u2014 ", profile.region, " \u2014", " ", profile.authorityContact] }, profile.key))) }));
19
26
  }
@@ -9,4 +9,4 @@ export declare const resetWrite: import("@cosmicdrift/kumiko-types/define-handle
9
9
  }, z.core.$strip>, {
10
10
  key: string;
11
11
  scope: import("@cosmicdrift/kumiko-types/config-scope").ConfigScope;
12
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
12
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -11,4 +11,4 @@ export declare const setWrite: import("@cosmicdrift/kumiko-types/define-handler"
11
11
  key: string;
12
12
  value: string | number | boolean;
13
13
  scope: import("@cosmicdrift/kumiko-types/config-scope").ConfigScope;
14
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
14
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -48,4 +48,4 @@ export declare const forgetSubjectWrite: import("@cosmicdrift/kumiko-types/defin
48
48
  reason: z.ZodString;
49
49
  }, z.core.$strip>, {
50
50
  subjectKey: string;
51
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
51
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -6,4 +6,4 @@ export declare const resubscribeAddressWrite: import("@cosmicdrift/kumiko-types/
6
6
  }, z.core.$strip>, {
7
7
  notificationType: string;
8
8
  channel: string;
9
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
9
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -6,4 +6,4 @@ export declare const resubscribeUserWrite: import("@cosmicdrift/kumiko-types/def
6
6
  }, z.core.$strip>, {
7
7
  notificationType: string;
8
8
  channel: string;
9
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
9
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -7,4 +7,4 @@ export declare const setPreferenceWrite: import("@cosmicdrift/kumiko-types/defin
7
7
  notificationType: string;
8
8
  channel: string;
9
9
  enabled: boolean;
10
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
10
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -12,4 +12,4 @@ export declare const unsubscribeAddressWrite: import("@cosmicdrift/kumiko-types/
12
12
  }, z.core.$strip>, {
13
13
  notificationType: string;
14
14
  channel: string;
15
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
15
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -6,4 +6,4 @@ export declare const unsubscribeUserWrite: import("@cosmicdrift/kumiko-types/def
6
6
  }, z.core.$strip>, {
7
7
  notificationType: string;
8
8
  channel: string;
9
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
9
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -7,4 +7,4 @@ export declare function createSetWriteHandler(getRuntime: (() => GlobalFeatureTo
7
7
  featureName: string;
8
8
  enabled: boolean;
9
9
  previousEnabled: boolean | null;
10
- }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
10
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined, undefined>;
@@ -5,6 +5,8 @@ export type FileRefContent = {
5
5
  readonly contentType: string;
6
6
  readonly tenantId: string;
7
7
  readonly size: number;
8
+ /** As stored: personal data that may be PII ciphertext. Decrypt before showing or sending it. */
9
+ readonly fileName: string;
8
10
  };
9
11
  export declare function fileContextForTenant(ctx: {
10
12
  readonly services: {