@cosmicdrift/kumiko-samples 0.362.0 → 0.364.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 (321) hide show
  1. package/package.json +1 -1
  2. package/packages/bundled-features/package.json +23 -6
  3. package/packages/bundled-features/src/admin-shell/changes.json +6 -0
  4. package/packages/bundled-features/src/admin-shell/feature.ts +8 -1
  5. package/packages/bundled-features/src/agent-tools/agent-manifest.ts +3 -4
  6. package/packages/bundled-features/src/agent-tools/filter-ops.ts +1 -3
  7. package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -3
  8. package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +2 -1
  9. package/packages/bundled-features/src/audit/changes.json +6 -0
  10. package/packages/bundled-features/src/audit/handlers/list.query.ts +10 -5
  11. package/packages/bundled-features/src/auth-email-password/bootstrap.ts +29 -8
  12. package/packages/bundled-features/src/auth-email-password/changes.json +51 -0
  13. package/packages/bundled-features/src/auth-email-password/email-rate-limits.ts +16 -0
  14. package/packages/bundled-features/src/auth-email-password/email-templates.ts +12 -138
  15. package/packages/bundled-features/src/auth-email-password/feature.ts +30 -9
  16. package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +6 -2
  17. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +4 -5
  18. package/packages/bundled-features/src/auth-email-password/handlers/logout.write.ts +7 -2
  19. package/packages/bundled-features/src/auth-email-password/handlers/request-account-unlock.write.ts +2 -5
  20. package/packages/bundled-features/src/auth-email-password/handlers/request-email-verification.write.ts +2 -5
  21. package/packages/bundled-features/src/auth-email-password/handlers/request-password-reset.write.ts +2 -5
  22. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +3 -4
  23. package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +2 -1
  24. package/packages/bundled-features/src/auth-email-password/handlers/token-request-handler.ts +5 -13
  25. package/packages/bundled-features/src/auth-email-password/index.ts +2 -17
  26. package/packages/bundled-features/src/auth-email-password/magic-link-mail.ts +30 -22
  27. package/packages/bundled-features/src/auth-email-password/mail-notifications.ts +158 -0
  28. package/packages/bundled-features/src/auth-email-password/signup-activation.ts +2 -3
  29. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +24 -5
  30. package/packages/bundled-features/src/auth-foundation/types.ts +8 -18
  31. package/packages/bundled-features/src/auth-mfa/feature.ts +8 -10
  32. package/packages/bundled-features/src/auth-mfa/hmac-token-codec.ts +4 -4
  33. package/packages/bundled-features/src/auth-mfa/mfa-challenge-token.ts +3 -3
  34. package/packages/bundled-features/src/auth-mfa/mfa-preauth-setup-token.ts +3 -3
  35. package/packages/bundled-features/src/auth-mfa/mfa-setup-token.ts +8 -8
  36. package/packages/bundled-features/src/billing-foundation/changes.json +43 -0
  37. package/packages/bundled-features/src/billing-foundation/constants.ts +5 -4
  38. package/packages/bundled-features/src/billing-foundation/consumer-protection/confirmation-mail.ts +90 -44
  39. package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-gate.ts +22 -1
  40. package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +3 -3
  41. package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +118 -0
  42. package/packages/bundled-features/src/billing-foundation/consumer-protection/register-consent.ts +2 -0
  43. package/packages/bundled-features/src/billing-foundation/consumer-protection/register-termination.ts +11 -1
  44. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-mail.ts +39 -33
  45. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-notify.ts +2 -2
  46. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-pages.ts +1 -4
  47. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-receipt-limit.ts +41 -0
  48. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +10 -1
  49. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +36 -20
  50. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +9 -0
  51. package/packages/bundled-features/src/billing-foundation/consumer-protection/withdrawal-period.ts +35 -0
  52. package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +2 -2
  53. package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +11 -3
  54. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +4 -9
  55. package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +1 -1
  56. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +12 -6
  57. package/packages/bundled-features/src/billing-foundation/handlers/process-payment-event.write.ts +1 -1
  58. package/packages/bundled-features/src/billing-foundation/i18n.ts +3 -0
  59. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +20 -11
  60. package/packages/bundled-features/src/billing-foundation/types.ts +7 -2
  61. package/packages/bundled-features/src/cap-counter/calendar-cap-usage-reservation.ts +2 -0
  62. package/packages/bundled-features/src/cap-counter/changes.json +6 -0
  63. package/packages/bundled-features/src/cap-counter/enforce-cap.ts +75 -5
  64. package/packages/bundled-features/src/cap-counter/index.ts +1 -0
  65. package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -0
  66. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +2 -1
  67. package/packages/bundled-features/src/cap-overview/web/cap-usage-cell.tsx +6 -4
  68. package/packages/bundled-features/src/channel-email/changes.json +19 -0
  69. package/packages/bundled-features/src/channel-email/email-channel.ts +135 -29
  70. package/packages/bundled-features/src/channel-email/feature.ts +6 -3
  71. package/packages/bundled-features/src/channel-email/index.ts +7 -1
  72. package/packages/bundled-features/src/channel-email/pii-guard.ts +13 -0
  73. package/packages/bundled-features/src/channel-email/smtp-transport.ts +15 -1
  74. package/packages/bundled-features/src/channel-email/types.ts +23 -0
  75. package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +2 -2
  76. package/packages/bundled-features/src/config/changes.json +6 -0
  77. package/packages/bundled-features/src/config/handlers/set.write.ts +3 -7
  78. package/packages/bundled-features/src/config/resolver.ts +15 -12
  79. package/packages/bundled-features/src/config/write-helpers.ts +23 -0
  80. package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
  81. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +48 -27
  82. package/packages/bundled-features/src/custom-fields/changes.json +6 -0
  83. package/packages/bundled-features/src/custom-fields/db/queries/user-data-rights.ts +2 -2
  84. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +0 -1
  85. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -11
  86. package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +7 -6
  87. package/packages/bundled-features/src/data-retention/changes.json +6 -0
  88. package/packages/bundled-features/src/data-retention/index.ts +1 -0
  89. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +8 -6
  90. package/packages/bundled-features/src/delivery/attachment-ref.ts +105 -0
  91. package/packages/bundled-features/src/delivery/changes.json +66 -0
  92. package/packages/bundled-features/src/delivery/channel-context.ts +152 -4
  93. package/packages/bundled-features/src/delivery/constants.ts +2 -0
  94. package/packages/bundled-features/src/delivery/delivery-service.ts +104 -26
  95. package/packages/bundled-features/src/delivery/feature.ts +1 -1
  96. package/packages/bundled-features/src/delivery/index.ts +19 -2
  97. package/packages/bundled-features/src/delivery/jobs.ts +97 -17
  98. package/packages/bundled-features/src/delivery/notify-factory.ts +14 -9
  99. package/packages/bundled-features/src/delivery/testing.ts +9 -1
  100. package/packages/bundled-features/src/delivery/types.ts +34 -18
  101. package/packages/bundled-features/src/delivery/unsubscribe.ts +5 -2
  102. package/packages/bundled-features/src/derivatives-sharp/render.ts +1 -22
  103. package/packages/bundled-features/src/document-ingest-foundation/pages.ts +6 -3
  104. package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +4 -4
  105. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  106. package/packages/bundled-features/src/file-foundation/changes.json +6 -0
  107. package/packages/bundled-features/src/file-foundation/index.ts +7 -0
  108. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +89 -0
  109. package/packages/bundled-features/src/files-tenant-data/changes.json +6 -0
  110. package/packages/bundled-features/src/files-tenant-data/hooks.ts +4 -0
  111. package/packages/bundled-features/src/folders/web/folder-manager.tsx +5 -2
  112. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +11 -11
  113. package/packages/bundled-features/src/form-draft/db/queries/draft-count.ts +2 -2
  114. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +2 -2
  115. package/packages/bundled-features/src/form-draft/release-file-refs.ts +3 -2
  116. package/packages/bundled-features/src/inbound-mail-foundation/changes.json +6 -0
  117. package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +1 -1
  118. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +6 -6
  119. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +1 -1
  120. package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +1 -1
  121. package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +2 -2
  122. package/packages/bundled-features/src/inbound-mail-foundation/oauth-access-token.ts +13 -8
  123. package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +7 -7
  124. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +2 -6
  125. package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +5 -13
  126. package/packages/bundled-features/src/inbound-mail-foundation/types.ts +4 -6
  127. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +42 -25
  128. package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +4 -3
  129. package/packages/bundled-features/src/jobs/changes.json +19 -0
  130. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +12 -4
  131. package/packages/bundled-features/src/jobs/feature.ts +7 -4
  132. package/packages/bundled-features/src/jobs/handlers/catalog.query.ts +1 -1
  133. package/packages/bundled-features/src/jobs/handlers/list.query.ts +3 -1
  134. package/packages/bundled-features/src/jobs/handlers/stale-run-sweep.job.ts +5 -2
  135. package/packages/bundled-features/src/jobs/job-run-logger.ts +52 -17
  136. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +7 -2
  137. package/packages/bundled-features/src/ledger/changes.json +7 -0
  138. package/packages/bundled-features/src/ledger/entity.ts +3 -1
  139. package/packages/bundled-features/src/ledger/recurring.ts +1 -3
  140. package/packages/bundled-features/src/managed-pages/branding.ts +33 -9
  141. package/packages/bundled-features/src/managed-pages/changes.json +6 -0
  142. package/packages/bundled-features/src/managed-pages/feature.ts +1 -0
  143. package/packages/bundled-features/src/managed-pages/i18n.ts +1 -0
  144. package/packages/bundled-features/src/managed-pages/screens/branding-screen.ts +8 -0
  145. package/packages/bundled-features/src/page-render/branding.ts +3 -0
  146. package/packages/bundled-features/src/page-render/markdown.ts +1 -1
  147. package/packages/bundled-features/src/personal-access-tokens/feature.ts +2 -4
  148. package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +2 -1
  149. package/packages/bundled-features/src/personal-access-tokens/index.ts +1 -1
  150. package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -1
  151. package/packages/bundled-features/src/renderer-foundation/README.md +11 -10
  152. package/packages/bundled-features/src/renderer-foundation/api.ts +14 -14
  153. package/packages/bundled-features/src/renderer-foundation/changes.json +39 -0
  154. package/packages/bundled-features/src/renderer-foundation/constants.ts +6 -8
  155. package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
  156. package/packages/bundled-features/src/renderer-foundation/index.ts +13 -2
  157. package/packages/bundled-features/src/renderer-foundation/types.ts +134 -35
  158. package/packages/bundled-features/src/renderer-pdf/changes.json +12 -0
  159. package/packages/bundled-features/src/renderer-pdf/feature.ts +7 -1
  160. package/packages/bundled-features/src/renderer-pdf/render-table-pdf.ts +162 -82
  161. package/packages/bundled-features/src/secrets/changes.json +6 -0
  162. package/packages/bundled-features/src/secrets/feature.ts +4 -3
  163. package/packages/bundled-features/src/secrets/secrets-context.ts +23 -3
  164. package/packages/bundled-features/src/sessions/db/queries/cleanup.ts +2 -2
  165. package/packages/bundled-features/src/sessions/feature.ts +2 -4
  166. package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -1
  167. package/packages/bundled-features/src/shared/attachment-file-name.ts +39 -0
  168. package/packages/bundled-features/src/shared/changes.json +6 -0
  169. package/packages/bundled-features/src/shared/chunked-entity-migration.ts +4 -1
  170. package/packages/bundled-features/src/shared/index.ts +6 -0
  171. package/packages/bundled-features/src/shared/is-tenant-db.ts +1 -1
  172. package/packages/bundled-features/src/shared/mail-template-body.ts +42 -0
  173. package/packages/bundled-features/src/shared/sharp-input-limits.ts +26 -0
  174. package/packages/bundled-features/src/shared/signup-handover.ts +4 -4
  175. package/packages/bundled-features/src/subscription-stripe/changes.json +6 -0
  176. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +19 -11
  177. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +3 -1
  178. package/packages/bundled-features/src/tags/handlers/assign-tag.write.ts +5 -1
  179. package/packages/bundled-features/src/tags/web/tag-chip.tsx +2 -1
  180. package/packages/bundled-features/src/template-resolver/README.md +66 -8
  181. package/packages/bundled-features/src/template-resolver/api.ts +85 -9
  182. package/packages/bundled-features/src/template-resolver/changes.json +186 -0
  183. package/packages/bundled-features/src/template-resolver/compile-document-body.ts +278 -0
  184. package/packages/bundled-features/src/template-resolver/constants.ts +49 -11
  185. package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +335 -0
  186. package/packages/bundled-features/src/template-resolver/document-schema.ts +345 -0
  187. package/packages/bundled-features/src/template-resolver/feature.ts +59 -6
  188. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +188 -0
  189. package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +30 -2
  190. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +160 -0
  191. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +33 -0
  192. package/packages/bundled-features/src/template-resolver/handlers/discard-draft.write.ts +52 -0
  193. package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +138 -0
  194. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +9 -6
  195. package/packages/bundled-features/src/template-resolver/handlers/import-bundle-system.write.ts +42 -0
  196. package/packages/bundled-features/src/template-resolver/handlers/import-bundle.write.ts +22 -0
  197. package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +151 -0
  198. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +19 -18
  199. package/packages/bundled-features/src/template-resolver/handlers/override-diff.ts +49 -0
  200. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +323 -0
  201. package/packages/bundled-features/src/template-resolver/handlers/preview.query.ts +25 -0
  202. package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +58 -0
  203. package/packages/bundled-features/src/template-resolver/handlers/resource-link-pdf.write.ts +34 -0
  204. package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +50 -0
  205. package/packages/bundled-features/src/template-resolver/handlers/resource-shared.ts +24 -0
  206. package/packages/bundled-features/src/template-resolver/handlers/resource-upload.write.ts +135 -0
  207. package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +135 -0
  208. package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +32 -3
  209. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +7 -2
  210. package/packages/bundled-features/src/template-resolver/handlers/template-gates.ts +196 -0
  211. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +233 -0
  212. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +137 -0
  213. package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +91 -17
  214. package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +19 -71
  215. package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +16 -77
  216. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +31 -0
  217. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +116 -0
  218. package/packages/bundled-features/src/template-resolver/index.ts +111 -0
  219. package/packages/bundled-features/src/template-resolver/layout-appearance.ts +40 -0
  220. package/packages/bundled-features/src/template-resolver/layout-regions.ts +206 -0
  221. package/packages/bundled-features/src/template-resolver/linked-resources.ts +102 -0
  222. package/packages/bundled-features/src/template-resolver/pdf-constants.ts +12 -0
  223. package/packages/bundled-features/src/template-resolver/preview-display-html.ts +36 -0
  224. package/packages/bundled-features/src/template-resolver/print-document.ts +58 -0
  225. package/packages/bundled-features/src/template-resolver/qualified-names.ts +34 -0
  226. package/packages/bundled-features/src/template-resolver/record-mapping.ts +26 -0
  227. package/packages/bundled-features/src/template-resolver/resource-image.ts +47 -0
  228. package/packages/bundled-features/src/template-resolver/seeding.ts +171 -20
  229. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +416 -0
  230. package/packages/bundled-features/src/template-resolver/table.ts +27 -1
  231. package/packages/bundled-features/src/template-resolver/template-bundle.ts +79 -0
  232. package/packages/bundled-features/src/template-resolver/template-diff.ts +78 -0
  233. package/packages/bundled-features/src/template-resolver/template-draft.ts +106 -0
  234. package/packages/bundled-features/src/template-resolver/template-meta.ts +192 -0
  235. package/packages/bundled-features/src/template-resolver/template-preview.ts +676 -0
  236. package/packages/bundled-features/src/template-resolver/template-resources.ts +114 -0
  237. package/packages/bundled-features/src/template-resolver/template-usage.ts +68 -0
  238. package/packages/bundled-features/src/template-resolver/template-validation.ts +230 -0
  239. package/packages/bundled-features/src/template-resolver/testing.ts +5 -5
  240. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +20 -13
  241. package/packages/bundled-features/src/template-resolver/web/document-editor-extensions.ts +215 -0
  242. package/packages/bundled-features/src/template-resolver/web/document-editor.tsx +37 -0
  243. package/packages/bundled-features/src/template-resolver/web/document-tiptap-editor.tsx +1065 -0
  244. package/packages/bundled-features/src/template-resolver/web/document-toolbar-blocks.ts +72 -0
  245. package/packages/bundled-features/src/template-resolver/web/editor-handle.ts +26 -0
  246. package/packages/bundled-features/src/template-resolver/web/i18n.ts +121 -0
  247. package/packages/bundled-features/src/template-resolver/web/index.ts +26 -0
  248. package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor-lazy.tsx +36 -0
  249. package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor.tsx +176 -0
  250. package/packages/bundled-features/src/template-resolver/web/placeholder-text.ts +37 -0
  251. package/packages/bundled-features/src/template-resolver/web/use-stable-by-key.ts +14 -0
  252. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +3 -2
  253. package/packages/bundled-features/src/tenant/seeding.ts +41 -7
  254. package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
  255. package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +2 -1
  256. package/packages/bundled-features/src/tier-engine/changes.json +6 -0
  257. package/packages/bundled-features/src/tier-engine/feature.ts +11 -3
  258. package/packages/bundled-features/src/user/changes.json +6 -0
  259. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +4 -4
  260. package/packages/bundled-features/src/user/handlers/detail.query.ts +3 -5
  261. package/packages/bundled-features/src/user/resolve-display-names.ts +8 -15
  262. package/packages/bundled-features/src/user/roles-input-schema.ts +2 -2
  263. package/packages/bundled-features/src/user/seeding.ts +19 -5
  264. package/packages/bundled-features/src/user-data-rights/changes.json +13 -0
  265. package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +2 -2
  266. package/packages/bundled-features/src/user-data-rights/email-templates.ts +5 -149
  267. package/packages/bundled-features/src/user-data-rights/feature.ts +72 -35
  268. package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +2 -1
  269. package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +5 -11
  270. package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +134 -53
  271. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +2 -2
  272. package/packages/bundled-features/src/user-data-rights/mail-notifications.ts +157 -0
  273. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +1 -1
  274. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +2 -1
  275. package/packages/bundled-features/src/user-profile/changes.json +1 -1
  276. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +2 -1
  277. package/packages/bundled-features/src/waitlist/changes.json +7 -0
  278. package/packages/bundled-features/src/waitlist/feature.ts +17 -0
  279. package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +4 -5
  280. package/packages/bundled-features/src/waitlist/mail.ts +69 -18
  281. package/packages/bundled-features/src/waitlist/options.ts +1 -1
  282. package/packages/bundled-features/src/workflow-runner/changes.json +6 -0
  283. package/packages/bundled-features/src/workflow-runner/event-trigger.ts +3 -3
  284. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +7 -1
  285. package/samples/apps/ui-walkthrough/package.json +11 -0
  286. package/samples/apps/ui-walkthrough/playwright.config.ts +40 -7
  287. package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +9 -0
  288. package/samples/apps/ui-walkthrough/src/app/client.tsx +6 -0
  289. package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +239 -0
  290. package/samples/apps/ui-walkthrough/src/app/server.ts +5 -1
  291. package/samples/apps/ui-walkthrough/src/app/shell.tsx +12 -1
  292. package/samples/apps/ui-walkthrough/src/app/template-seed-data.ts +570 -0
  293. package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +72 -0
  294. package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +18 -0
  295. package/samples/apps/ui-walkthrough/src/features/billing/index.ts +2 -0
  296. package/samples/apps/ui-walkthrough/src/features/billing/web/index.ts +7 -0
  297. package/samples/apps/ui-walkthrough/src/run-config.ts +41 -1
  298. package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-features.ts +0 -2
  299. package/samples/apps/use-all-bundled/feature-manifest.json +118 -21
  300. package/samples/apps/use-all-bundled/kumiko/migrations/0045_template-resource-meta.rebuild.json +4 -0
  301. package/samples/apps/use-all-bundled/kumiko/migrations/0046_pdf-rendered.rebuild.json +4 -0
  302. package/samples/apps/use-all-bundled/package.json +2 -0
  303. package/samples/apps/use-all-bundled/playwright.config.ts +38 -3
  304. package/samples/apps/use-all-bundled/schema/generate.ts +13 -3
  305. package/samples/apps/use-all-bundled/schema/schema.generated.ts +3 -0
  306. package/samples/apps/use-all-bundled/scripts/check-coverage.ts +3 -0
  307. package/samples/apps/use-all-bundled/src/app/auth-constants.ts +3 -0
  308. package/samples/apps/use-all-bundled/src/app/client.tsx +4 -0
  309. package/samples/apps/use-all-bundled/src/app/seed-documents.ts +128 -0
  310. package/samples/apps/use-all-bundled/src/app/seed.ts +4 -0
  311. package/samples/apps/use-all-bundled/src/run-config.ts +11 -11
  312. package/samples/recipes/delivery-notifications/README.md +26 -25
  313. package/samples/recipes/delivery-notifications/package.json +2 -1
  314. package/samples/recipes/delivery-notifications/src/feature.ts +64 -58
  315. package/samples/recipes/seed-migration/README.md +1 -1
  316. package/packages/bundled-features/src/renderer-simple/changes.json +0 -27
  317. package/packages/bundled-features/src/renderer-simple/feature.ts +0 -66
  318. package/packages/bundled-features/src/renderer-simple/index.ts +0 -8
  319. package/packages/bundled-features/src/renderer-simple/mail-blocks.ts +0 -138
  320. package/packages/bundled-features/src/renderer-simple/resolve-variables.ts +0 -57
  321. package/packages/bundled-features/src/renderer-simple/simple-renderer.ts +0 -304
@@ -1,57 +0,0 @@
1
- import type { RendererContext, RenderRequest } from "../renderer-foundation/index.js";
2
- import {
3
- createTemplateResolverApi,
4
- FALLBACK_LOCALE,
5
- TemplateNotFoundError,
6
- } from "../template-resolver/index.js";
7
-
8
- type NotificationRequest = Extract<RenderRequest, { kind: "notification" }>;
9
-
10
- /** Merge template-resolver content (plain JSON EmailTemplateData) with runtime variables. */
11
- export async function resolveNotificationVariables(
12
- req: NotificationRequest,
13
- ctx: RendererContext,
14
- ): Promise<Readonly<Record<string, unknown>>> {
15
- const variables = req.payload.variables ?? {};
16
- const slug = req.payload.template?.trim();
17
- if (!slug || req.payload.content || !ctx.db || !ctx.registry.features.has("template-resolver")) {
18
- return variables;
19
- }
20
-
21
- try {
22
- const api = createTemplateResolverApi(ctx.db);
23
- const locale = req.payload.locale ?? FALLBACK_LOCALE;
24
- const resolved = await api.resolveTemplate({
25
- tenantId: ctx.tenantId,
26
- slug,
27
- kind: "notification",
28
- locale,
29
- });
30
- if (resolved.contentFormat === "plain") {
31
- const base = parsePlainTemplateContent(resolved.content);
32
- return { ...base, ...variables };
33
- }
34
- // body always wins from the resolved template for rendered formats — a runtime
35
- // "variables.body" override would clobber the actual rendered content.
36
- return { ...variables, body: resolved.content };
37
- } catch (err) {
38
- if (err instanceof TemplateNotFoundError) {
39
- return variables;
40
- }
41
- throw err;
42
- }
43
- }
44
-
45
- function parsePlainTemplateContent(content: string): Record<string, unknown> {
46
- const trimmed = content.trim();
47
- if (!trimmed) return {};
48
- try {
49
- const parsed: unknown = JSON.parse(trimmed);
50
- if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
51
- return parsed as Record<string, unknown>;
52
- }
53
- } catch {
54
- // ponytail: non-JSON plain content becomes a single body section downstream
55
- }
56
- return { body: content };
57
- }
@@ -1,304 +0,0 @@
1
- import { escapeHtml, escapeHtmlAttr } from "@cosmicdrift/kumiko-headless";
2
- import type { NotificationRenderer } from "../delivery/index.js";
3
- import { renderSafeMarkdown } from "../page-render/index.js";
4
- import {
5
- badgeText,
6
- chipsText,
7
- type MailBadge,
8
- type MailChip,
9
- type MailStage,
10
- parseBadge,
11
- renderBadge,
12
- renderChips,
13
- renderStages,
14
- stagesText,
15
- } from "./mail-blocks.js";
16
-
17
- export type MailBranding = {
18
- /** Shown as text when there is no logo, and as the logo alt text. */
19
- readonly productName?: string;
20
- /** Hex color (#rgb, #rrggbb, #rrggbbaa); used for buttons and the header accent. */
21
- readonly primaryColor?: string;
22
- /** Absolute http(s) URL; anything else is dropped. Mutually exclusive with `logoPath`. */
23
- readonly logoUrl?: string;
24
- /** Absolute path on `baseUrl` (e.g. "/logo.png"); use PNG/JPEG, mail clients block SVG. */
25
- readonly logoPath?: string;
26
- /** Absolute http(s) origin that `logoPath` is resolved against; same base as `auth.mail.baseUrl`. */
27
- readonly baseUrl?: string;
28
- /** Locale tried after the exact and language-part match when a localized field has no entry. */
29
- readonly defaultLocale?: string;
30
- readonly footerText?: LocalizedText;
31
- /** Absolute http(s) URLs only; string URLs that are not are dropped, localized ones fail at boot. */
32
- readonly footerLinks?: readonly {
33
- readonly label: LocalizedText;
34
- readonly url: LocalizedText;
35
- }[];
36
- };
37
-
38
- export type LocalizedText = string | Readonly<Record<string, string>>;
39
-
40
- const DEFAULT_PRIMARY_COLOR = "#2563eb";
41
- const HEX_COLOR_PATTERN = /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
42
-
43
- function isHttpUrl(value: string): boolean {
44
- try {
45
- const { protocol } = new URL(value);
46
- return protocol === "http:" || protocol === "https:";
47
- } catch {
48
- return false;
49
- }
50
- }
51
-
52
- function languagePart(locale: string): string {
53
- return locale.split("-")[0] ?? locale;
54
- }
55
-
56
- function pickByLocale(
57
- entries: Readonly<Record<string, string>>,
58
- locale: string,
59
- ): string | undefined {
60
- // Own keys only: a locale like "constructor" must not hit Object.prototype.
61
- const ownEntry = (key: string): string | undefined =>
62
- Object.hasOwn(entries, key) ? entries[key] : undefined;
63
- return ownEntry(locale) ?? ownEntry(languagePart(locale));
64
- }
65
-
66
- function resolveLocalized(
67
- value: LocalizedText | undefined,
68
- locale: string | undefined,
69
- defaultLocale: string | undefined,
70
- ): string | undefined {
71
- if (value === undefined || typeof value === "string") return value;
72
- return (
73
- (locale !== undefined ? pickByLocale(value, locale) : undefined) ??
74
- (defaultLocale !== undefined ? pickByLocale(value, defaultLocale) : undefined) ??
75
- Object.values(value)[0]
76
- );
77
- }
78
-
79
- function assertLocalizedUrlsAreHttp(branding: MailBranding): void {
80
- for (const link of branding.footerLinks ?? []) {
81
- if (typeof link.url === "string") continue;
82
- for (const [locale, url] of Object.entries(link.url)) {
83
- if (!isHttpUrl(url)) {
84
- throw new Error(
85
- `createSimpleRenderer: footerLinks url for locale "${locale}" must be an absolute http(s) URL`,
86
- );
87
- }
88
- }
89
- }
90
- }
91
-
92
- function resolveLogoUrl(branding: MailBranding | undefined): string | undefined {
93
- if (!branding) return undefined;
94
- const { logoUrl, logoPath, baseUrl } = branding;
95
- if (logoPath === undefined) {
96
- return logoUrl && isHttpUrl(logoUrl) ? logoUrl : undefined;
97
- }
98
- if (logoUrl !== undefined) {
99
- throw new Error("createSimpleRenderer: logoPath and logoUrl are mutually exclusive");
100
- }
101
- if (baseUrl === undefined || !isHttpUrl(baseUrl)) {
102
- throw new Error("createSimpleRenderer: logoPath requires an absolute http(s) baseUrl");
103
- }
104
- if (!/^\/(?![/\\])/.test(logoPath) || logoPath.includes("\\")) {
105
- throw new Error('createSimpleRenderer: logoPath must start with a single "/"');
106
- }
107
- const resolved = new URL(logoPath, baseUrl);
108
- if (resolved.origin !== new URL(baseUrl).origin) {
109
- throw new Error("createSimpleRenderer: logoPath must stay on the baseUrl origin");
110
- }
111
- return resolved.href;
112
- }
113
-
114
- function resolvePrimaryColor(branding: MailBranding | undefined): string {
115
- const color = branding?.primaryColor;
116
- return color && HEX_COLOR_PATTERN.test(color) ? color : DEFAULT_PRIMARY_COLOR;
117
- }
118
-
119
- function renderBrandingHeader(
120
- branding: MailBranding | undefined,
121
- primaryColor: string,
122
- logoUrl: string | undefined,
123
- ): string {
124
- if (!branding) return "";
125
- if (!logoUrl && !branding.productName) return "";
126
- const logo = logoUrl
127
- ? `<img src="${escapeHtmlAttr(logoUrl)}" alt="${escapeHtmlAttr(branding.productName ?? "")}" style="display:block;max-height:40px;max-width:200px;border:0" />`
128
- : `<span style="font-size:18px;font-weight:700;color:${escapeHtmlAttr(primaryColor)}">${escapeHtml(branding.productName ?? "")}</span>`;
129
- return `<div style="margin:0 0 24px;padding:0 0 16px;border-bottom:3px solid ${escapeHtmlAttr(primaryColor)}">${logo}</div>`;
130
- }
131
-
132
- type ResolvedBrandingFooter = {
133
- readonly footerText: string | undefined;
134
- readonly links: readonly { readonly label: string; readonly url: string }[];
135
- };
136
-
137
- function resolveBrandingFooter(
138
- branding: MailBranding,
139
- locale: string | undefined,
140
- ): ResolvedBrandingFooter {
141
- const pick = (value: LocalizedText | undefined): string | undefined =>
142
- resolveLocalized(value, locale, branding.defaultLocale);
143
- const links = (branding.footerLinks ?? []).flatMap((link) => {
144
- const url = pick(link.url);
145
- if (url === undefined || !isHttpUrl(url)) return [];
146
- return [{ label: pick(link.label) ?? "", url }];
147
- });
148
- return { footerText: pick(branding.footerText), links };
149
- }
150
-
151
- function renderBrandingFooter(
152
- branding: MailBranding | undefined,
153
- locale: string | undefined,
154
- ): string {
155
- if (!branding) return "";
156
- const { footerText, links: resolvedLinks } = resolveBrandingFooter(branding, locale);
157
- const links = resolvedLinks.map(
158
- (link) =>
159
- `<a href="${escapeHtmlAttr(link.url)}" style="color:#999">${escapeHtml(link.label)}</a>`,
160
- );
161
- const footerPartsHtml = [footerText ? escapeHtml(footerText) : "", links.join(" · ")].filter(
162
- (part) => part !== "",
163
- );
164
- if (footerPartsHtml.length === 0) return "";
165
- const footerHtml = footerPartsHtml.join("<br />");
166
- return `<p style="margin:16px 0 0;color:#999;font-size:12px">${footerHtml}</p>`;
167
- }
168
-
169
- function brandingFooterLines(
170
- branding: MailBranding | undefined,
171
- locale: string | undefined,
172
- ): readonly string[] {
173
- if (!branding) return [];
174
- const { footerText, links } = resolveBrandingFooter(branding, locale);
175
- return [
176
- ...(footerText ? [footerText] : []),
177
- ...links.map((link) => (link.label ? `${link.label}: ${link.url}` : link.url)),
178
- ];
179
- }
180
-
181
- type Section =
182
- | { readonly text: string }
183
- | { readonly heading: string }
184
- | { readonly markdown: string }
185
- | { readonly button: { readonly label: string; readonly url: string } }
186
- | { readonly stages: readonly MailStage[] }
187
- | { readonly chips: readonly MailChip[] };
188
-
189
- type EmailTemplateData = {
190
- // Preferred: structured email data
191
- readonly badge?: MailBadge;
192
- readonly header?: string;
193
- readonly sections?: readonly Section[];
194
- readonly footer?: string;
195
- // Fallback: plain title + body (used when no structured template is defined)
196
- readonly title?: string;
197
- readonly body?: string;
198
- };
199
-
200
- function templateContent(variables: Readonly<Record<string, unknown>>): {
201
- readonly badge: MailBadge | undefined;
202
- readonly header: string | undefined;
203
- readonly sections: readonly Section[] | undefined;
204
- readonly footer: string | undefined;
205
- } {
206
- const data = variables as EmailTemplateData; // @cast-boundary render-helper
207
- // Without structured fields, title + body become the header and a single text section.
208
- return {
209
- badge: parseBadge(data.badge),
210
- header: data.header ?? data.title,
211
- sections: data.sections ?? (data.body ? [{ text: data.body }] : undefined),
212
- footer: data.footer,
213
- };
214
- }
215
-
216
- // Markdown stays as written: its source is already readable plain text.
217
- function sectionText(section: Section): string {
218
- if ("text" in section) return section.text;
219
- if ("heading" in section) return section.heading;
220
- if ("markdown" in section) return section.markdown;
221
- if ("button" in section) return `${section.button.label}: ${section.button.url}`;
222
- if ("stages" in section) return stagesText(section.stages);
223
- if ("chips" in section) return chipsText(section.chips);
224
- return "";
225
- }
226
-
227
- function renderSection(section: Section, primaryColor: string): string {
228
- if ("text" in section) {
229
- return `<p style="margin:0 0 16px;color:#333;font-size:14px;line-height:1.5">${escapeHtml(section.text)}</p>`;
230
- }
231
- if ("heading" in section) {
232
- return `<h2 style="margin:24px 0 12px;color:#111;font-size:16px;font-weight:600">${escapeHtml(section.heading)}</h2>`;
233
- }
234
- if ("markdown" in section) {
235
- const markdownHtml = renderSafeMarkdown(section.markdown);
236
- return `<div style="color:#333;font-size:14px;line-height:1.5">${markdownHtml}</div>`;
237
- }
238
- if ("button" in section) {
239
- return `<p style="margin:0 0 16px"><a href="${escapeHtml(section.button.url)}" style="display:inline-block;padding:10px 24px;background:${escapeHtmlAttr(primaryColor)};color:#fff;text-decoration:none;border-radius:4px;font-size:14px">${escapeHtml(section.button.label)}</a></p>`;
240
- }
241
- if ("stages" in section) return renderStages(section.stages, primaryColor);
242
- if ("chips" in section) return renderChips(section.chips);
243
- return "";
244
- }
245
-
246
- // Simple Renderer: turns structured email template data into HTML with inline CSS.
247
- // No external dependencies, no template engine — just string concatenation.
248
- export function createSimpleRenderer(branding?: MailBranding): NotificationRenderer {
249
- const primaryColor = resolvePrimaryColor(branding);
250
- const logoUrl = resolveLogoUrl(branding);
251
- if (branding) assertLocalizedUrlsAreHttp(branding);
252
- return {
253
- name: "simple",
254
-
255
- async render(input) {
256
- const { badge, header, sections, footer } = templateContent(input.variables);
257
-
258
- const parts: string[] = [];
259
- parts.push('<!DOCTYPE html><html><body style="margin:0;padding:0;font-family:sans-serif">');
260
- parts.push('<div style="max-width:600px;margin:0 auto;padding:24px">');
261
- parts.push(renderBrandingHeader(branding, primaryColor, logoUrl));
262
-
263
- if (badge) parts.push(renderBadge(badge));
264
-
265
- if (header) {
266
- parts.push(
267
- `<h1 style="margin:0 0 24px;color:#111;font-size:20px;font-weight:600">${escapeHtml(header)}</h1>`,
268
- );
269
- }
270
-
271
- if (sections) {
272
- for (const section of sections) {
273
- parts.push(renderSection(section, primaryColor));
274
- }
275
- }
276
-
277
- if (footer) {
278
- parts.push(
279
- `<p style="margin:24px 0 0;color:#999;font-size:12px;border-top:1px solid #eee;padding-top:16px">${escapeHtml(footer)}</p>`,
280
- );
281
- }
282
-
283
- parts.push(renderBrandingFooter(branding, input.locale));
284
- parts.push("</div></body></html>");
285
- return parts.join("");
286
- },
287
-
288
- async renderText(input) {
289
- const { badge, header, sections, footer } = templateContent(input.variables);
290
- const brandingFooter = brandingFooterLines(branding, input.locale).join("\n");
291
- return [
292
- badge ? badgeText(badge) : undefined,
293
- header,
294
- ...(sections ?? []).map(sectionText),
295
- footer,
296
- brandingFooter,
297
- ]
298
- .filter((block): block is string => block !== undefined && block !== "")
299
- .join("\n\n");
300
- },
301
- };
302
- }
303
-
304
- export const simpleRenderer: NotificationRenderer = createSimpleRenderer();