@cosmicdrift/kumiko-bundled-features 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 (468) hide show
  1. package/dist/admin-shell/feature.d.ts +3 -0
  2. package/dist/admin-shell/feature.js +6 -1
  3. package/dist/agent-tools/agent-manifest.js +2 -1
  4. package/dist/agent-tools/filter-ops.d.ts +1 -1
  5. package/dist/agent-tools/filter-ops.js +1 -3
  6. package/dist/agent-tools/tool-dispatch.js +2 -1
  7. package/dist/audit/handlers/list.query.js +9 -5
  8. package/dist/auth-email-password/bootstrap.d.ts +8 -5
  9. package/dist/auth-email-password/bootstrap.js +12 -4
  10. package/dist/auth-email-password/email-rate-limits.d.ts +4 -0
  11. package/dist/auth-email-password/email-rate-limits.js +13 -0
  12. package/dist/auth-email-password/email-templates.d.ts +4 -26
  13. package/dist/auth-email-password/email-templates.js +9 -101
  14. package/dist/auth-email-password/feature.js +24 -6
  15. package/dist/auth-email-password/handlers/change-password.write.d.ts +1 -1
  16. package/dist/auth-email-password/handlers/change-password.write.js +6 -2
  17. package/dist/auth-email-password/handlers/confirm-account-unlock.write.d.ts +1 -1
  18. package/dist/auth-email-password/handlers/invite-accept-with-login.write.d.ts +1 -1
  19. package/dist/auth-email-password/handlers/invite-accept.write.d.ts +1 -1
  20. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  21. package/dist/auth-email-password/handlers/invite-create.write.js +4 -4
  22. package/dist/auth-email-password/handlers/invite-signup-complete.write.d.ts +1 -1
  23. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  24. package/dist/auth-email-password/handlers/logout.write.d.ts +1 -1
  25. package/dist/auth-email-password/handlers/logout.write.js +6 -2
  26. package/dist/auth-email-password/handlers/request-account-unlock.write.d.ts +1 -1
  27. package/dist/auth-email-password/handlers/request-account-unlock.write.js +2 -4
  28. package/dist/auth-email-password/handlers/request-email-verification.write.d.ts +1 -1
  29. package/dist/auth-email-password/handlers/request-email-verification.write.js +2 -4
  30. package/dist/auth-email-password/handlers/request-password-reset.write.d.ts +1 -1
  31. package/dist/auth-email-password/handlers/request-password-reset.write.js +2 -4
  32. package/dist/auth-email-password/handlers/reset-password.write.d.ts +1 -1
  33. package/dist/auth-email-password/handlers/signup-confirm.write.d.ts +1 -1
  34. package/dist/auth-email-password/handlers/signup-confirm.write.js +3 -4
  35. package/dist/auth-email-password/handlers/signup-request.write.d.ts +1 -1
  36. package/dist/auth-email-password/handlers/signup-request.write.js +2 -1
  37. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  38. package/dist/auth-email-password/handlers/token-request-handler.d.ts +2 -3
  39. package/dist/auth-email-password/handlers/token-request-handler.js +2 -2
  40. package/dist/auth-email-password/handlers/verify-email.write.d.ts +1 -1
  41. package/dist/auth-email-password/index.d.ts +2 -2
  42. package/dist/auth-email-password/index.js +1 -1
  43. package/dist/auth-email-password/magic-link-mail.d.ts +3 -2
  44. package/dist/auth-email-password/magic-link-mail.js +19 -14
  45. package/dist/auth-email-password/mail-notifications.d.ts +32 -0
  46. package/dist/auth-email-password/mail-notifications.js +116 -0
  47. package/dist/auth-email-password/signup-activation.d.ts +1 -1
  48. package/dist/auth-email-password/signup-activation.js +2 -3
  49. package/dist/auth-email-password/web/auth-gate.js +16 -4
  50. package/dist/auth-foundation/types.js +2 -8
  51. package/dist/auth-mfa/feature.js +4 -4
  52. package/dist/auth-mfa/handlers/disable.write.d.ts +1 -1
  53. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.d.ts +1 -1
  54. package/dist/auth-mfa/handlers/enable-confirm.write.d.ts +1 -1
  55. package/dist/auth-mfa/handlers/enable-start-preauth.write.d.ts +1 -1
  56. package/dist/auth-mfa/handlers/enable-start.write.d.ts +1 -1
  57. package/dist/auth-mfa/handlers/regenerate-recovery.write.d.ts +1 -1
  58. package/dist/auth-mfa/handlers/verify.write.d.ts +1 -1
  59. package/dist/auth-mfa/hmac-token-codec.js +4 -4
  60. package/dist/auth-mfa/mfa-challenge-token.js +3 -3
  61. package/dist/auth-mfa/mfa-preauth-setup-token.js +3 -3
  62. package/dist/auth-mfa/mfa-setup-token.js +8 -8
  63. package/dist/billing-foundation/constants.d.ts +3 -3
  64. package/dist/billing-foundation/constants.js +5 -4
  65. package/dist/billing-foundation/consumer-protection/confirmation-mail.d.ts +32 -14
  66. package/dist/billing-foundation/consumer-protection/confirmation-mail.js +74 -32
  67. package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +3 -0
  68. package/dist/billing-foundation/consumer-protection/consent-gate.js +21 -2
  69. package/dist/billing-foundation/consumer-protection/issue-confirmation.js +3 -3
  70. package/dist/billing-foundation/consumer-protection/mail-notifications.d.ts +8 -0
  71. package/dist/billing-foundation/consumer-protection/mail-notifications.js +95 -0
  72. package/dist/billing-foundation/consumer-protection/register-consent.js +2 -0
  73. package/dist/billing-foundation/consumer-protection/register-termination.js +11 -1
  74. package/dist/billing-foundation/consumer-protection/termination-mail.d.ts +25 -13
  75. package/dist/billing-foundation/consumer-protection/termination-mail.js +11 -23
  76. package/dist/billing-foundation/consumer-protection/termination-notify.js +2 -2
  77. package/dist/billing-foundation/consumer-protection/termination-pages.js +1 -3
  78. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +6 -0
  79. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +34 -0
  80. package/dist/billing-foundation/consumer-protection/termination-record.d.ts +2 -0
  81. package/dist/billing-foundation/consumer-protection/termination-record.js +7 -1
  82. package/dist/billing-foundation/consumer-protection/termination-request.js +31 -21
  83. package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
  84. package/dist/billing-foundation/consumer-protection/termination-texts.js +6 -0
  85. package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +10 -0
  86. package/dist/billing-foundation/consumer-protection/withdrawal-period.js +26 -0
  87. package/dist/billing-foundation/handlers/create-checkout-session.write.js +11 -5
  88. package/dist/billing-foundation/handlers/process-event.write.js +12 -8
  89. package/dist/billing-foundation/handlers/process-payment-event.write.js +1 -1
  90. package/dist/billing-foundation/i18n.js +3 -0
  91. package/dist/billing-foundation/subscription-tier-sync.d.ts +7 -1
  92. package/dist/billing-foundation/subscription-tier-sync.js +16 -9
  93. package/dist/billing-foundation/types.d.ts +7 -2
  94. package/dist/cap-counter/calendar-cap-usage-reservation.js +2 -0
  95. package/dist/cap-counter/enforce-cap.d.ts +18 -1
  96. package/dist/cap-counter/enforce-cap.js +49 -6
  97. package/dist/cap-counter/index.d.ts +1 -1
  98. package/dist/cap-counter/index.js +1 -1
  99. package/dist/cap-counter/with-cap-enforcement.d.ts +2 -0
  100. package/dist/cap-overview/handlers/tenant-caps-list.query.js +2 -1
  101. package/dist/cap-overview/web/cap-usage-cell.js +5 -4
  102. package/dist/channel-email/email-channel.d.ts +2 -2
  103. package/dist/channel-email/email-channel.js +101 -26
  104. package/dist/channel-email/feature.js +3 -3
  105. package/dist/channel-email/index.d.ts +1 -1
  106. package/dist/channel-email/index.js +1 -1
  107. package/dist/channel-email/pii-guard.js +10 -0
  108. package/dist/channel-email/smtp-transport.js +13 -0
  109. package/dist/channel-email/types.d.ts +8 -0
  110. package/dist/channel-in-app/handlers/mark-all-read.write.d.ts +1 -1
  111. package/dist/channel-in-app/handlers/mark-read.write.d.ts +1 -1
  112. package/dist/compliance-profiles/handlers/set-profile.write.d.ts +1 -1
  113. package/dist/config/handlers/reset.write.d.ts +1 -1
  114. package/dist/config/handlers/set.write.d.ts +1 -1
  115. package/dist/config/handlers/set.write.js +3 -4
  116. package/dist/config/resolver.d.ts +1 -0
  117. package/dist/config/resolver.js +11 -14
  118. package/dist/config/write-helpers.d.ts +2 -0
  119. package/dist/config/write-helpers.js +19 -0
  120. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +1 -1
  121. package/dist/crypto-shredding/handlers/forget-subject.write.js +29 -19
  122. package/dist/custom-fields/handlers/update-tenant-field.write.js +0 -1
  123. package/dist/custom-fields/lib/value-schema.js +10 -11
  124. package/dist/custom-fields/wire-user-data-rights.js +7 -6
  125. package/dist/data-retention/index.d.ts +1 -0
  126. package/dist/data-retention/index.js +1 -0
  127. package/dist/data-retention/run-retention-cleanup.js +6 -6
  128. package/dist/delivery/attachment-ref.d.ts +41 -0
  129. package/dist/delivery/attachment-ref.js +78 -0
  130. package/dist/delivery/channel-context.d.ts +8 -4
  131. package/dist/delivery/channel-context.js +94 -2
  132. package/dist/delivery/constants.d.ts +1 -0
  133. package/dist/delivery/constants.js +1 -0
  134. package/dist/delivery/delivery-service.d.ts +4 -1
  135. package/dist/delivery/delivery-service.js +38 -32
  136. package/dist/delivery/feature.js +1 -1
  137. package/dist/delivery/handlers/resubscribe-address.write.d.ts +1 -1
  138. package/dist/delivery/handlers/resubscribe-user.write.d.ts +1 -1
  139. package/dist/delivery/handlers/set-preference.write.d.ts +1 -1
  140. package/dist/delivery/handlers/unsubscribe-address.write.d.ts +1 -1
  141. package/dist/delivery/handlers/unsubscribe-user.write.d.ts +1 -1
  142. package/dist/delivery/index.d.ts +5 -2
  143. package/dist/delivery/index.js +4 -1
  144. package/dist/delivery/jobs.js +66 -14
  145. package/dist/delivery/notify-factory.js +4 -1
  146. package/dist/delivery/testing.d.ts +4 -1
  147. package/dist/delivery/types.d.ts +26 -14
  148. package/dist/delivery/unsubscribe.js +4 -1
  149. package/dist/derivatives-sharp/render.js +1 -18
  150. package/dist/document-ingest-foundation/pages.js +4 -4
  151. package/dist/feature-toggles/handlers/set.write.d.ts +1 -1
  152. package/dist/feature-toggles/toggle-sync-signal.js +4 -4
  153. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  154. package/dist/file-foundation/index.d.ts +1 -0
  155. package/dist/file-foundation/index.js +1 -0
  156. package/dist/file-foundation/read-file-ref-content.d.ts +27 -0
  157. package/dist/file-foundation/read-file-ref-content.js +51 -0
  158. package/dist/files-tenant-data/hooks.js +4 -0
  159. package/dist/folders/web/folder-manager.js +3 -2
  160. package/dist/form-draft/db/queries/cleanup.js +4 -4
  161. package/dist/form-draft/db/queries/draft-count.js +2 -2
  162. package/dist/form-draft/db/queries/owned-file-refs.js +2 -2
  163. package/dist/form-draft/handlers/discard.write.d.ts +1 -1
  164. package/dist/form-draft/handlers/save.write.d.ts +1 -1
  165. package/dist/form-draft/release-file-refs.js +3 -2
  166. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +1 -1
  167. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +6 -6
  168. package/dist/inbound-mail-foundation/handlers/scope-visibility.d.ts +1 -1
  169. package/dist/inbound-mail-foundation/oauth-access-token.js +8 -3
  170. package/dist/inbound-mail-foundation/oauth-state.js +7 -7
  171. package/dist/inbound-mail-foundation/types.js +4 -4
  172. package/dist/inbound-mail-foundation/watch-supervisor.js +24 -13
  173. package/dist/inbound-provider-imap/imap-client.js +4 -3
  174. package/dist/jobs/db/queries/stale-run-sweep.d.ts +1 -1
  175. package/dist/jobs/db/queries/stale-run-sweep.js +12 -5
  176. package/dist/jobs/feature.js +5 -3
  177. package/dist/jobs/handlers/list.query.js +3 -1
  178. package/dist/jobs/handlers/retry.write.d.ts +1 -1
  179. package/dist/jobs/handlers/stale-run-sweep.job.d.ts +1 -1
  180. package/dist/jobs/handlers/stale-run-sweep.job.js +2 -2
  181. package/dist/jobs/handlers/trigger.write.d.ts +1 -1
  182. package/dist/jobs/job-run-logger.js +32 -10
  183. package/dist/jobs/tenant-job-run-table.js +3 -2
  184. package/dist/ledger/entity.js +3 -1
  185. package/dist/ledger/recurring.js +1 -3
  186. package/dist/managed-pages/branding.d.ts +2 -0
  187. package/dist/managed-pages/branding.js +24 -2
  188. package/dist/managed-pages/feature.js +1 -0
  189. package/dist/managed-pages/handlers/set.write.d.ts +1 -1
  190. package/dist/managed-pages/i18n.js +1 -0
  191. package/dist/managed-pages/screens/branding-screen.js +8 -1
  192. package/dist/page-render/branding.d.ts +1 -0
  193. package/dist/page-render/branding.js +1 -0
  194. package/dist/page-render/markdown.js +1 -1
  195. package/dist/personal-access-tokens/feature.js +1 -1
  196. package/dist/personal-access-tokens/handlers/create.write.d.ts +1 -1
  197. package/dist/personal-access-tokens/handlers/list.query.js +2 -1
  198. package/dist/personal-access-tokens/handlers/revoke.write.d.ts +1 -1
  199. package/dist/personal-access-tokens/revoke-for-user.js +2 -1
  200. package/dist/renderer-foundation/api.d.ts +13 -13
  201. package/dist/renderer-foundation/api.js +1 -1
  202. package/dist/renderer-foundation/constants.js +2 -4
  203. package/dist/renderer-foundation/feature.js +7 -7
  204. package/dist/renderer-foundation/index.d.ts +2 -1
  205. package/dist/renderer-foundation/index.js +1 -0
  206. package/dist/renderer-foundation/types.d.ts +94 -32
  207. package/dist/renderer-pdf/feature.js +7 -1
  208. package/dist/renderer-pdf/render-table-pdf.d.ts +27 -33
  209. package/dist/renderer-pdf/render-table-pdf.js +95 -34
  210. package/dist/secrets/feature.js +4 -3
  211. package/dist/secrets/handlers/delete.write.d.ts +1 -1
  212. package/dist/secrets/handlers/set.write.d.ts +1 -1
  213. package/dist/secrets/secrets-context.js +15 -3
  214. package/dist/sessions/db/queries/cleanup.js +2 -2
  215. package/dist/sessions/feature.js +1 -1
  216. package/dist/sessions/handlers/list.query.js +2 -1
  217. package/dist/sessions/handlers/revoke-all-for-user.write.d.ts +1 -1
  218. package/dist/sessions/handlers/revoke-all-others.write.d.ts +1 -1
  219. package/dist/sessions/handlers/revoke.write.d.ts +1 -1
  220. package/dist/shared/attachment-file-name.d.ts +3 -0
  221. package/dist/shared/attachment-file-name.js +35 -0
  222. package/dist/shared/chunked-entity-migration.d.ts +1 -0
  223. package/dist/shared/chunked-entity-migration.js +1 -1
  224. package/dist/shared/index.d.ts +3 -0
  225. package/dist/shared/index.js +3 -0
  226. package/dist/shared/is-tenant-db.js +1 -1
  227. package/dist/shared/mail-template-body.d.ts +7 -0
  228. package/dist/shared/mail-template-body.js +27 -0
  229. package/dist/shared/sharp-input-limits.d.ts +6 -0
  230. package/dist/shared/sharp-input-limits.js +22 -0
  231. package/dist/shared/signup-handover.js +2 -2
  232. package/dist/subscription-stripe/plugin-methods.js +18 -8
  233. package/dist/subscription-stripe/verify-webhook.d.ts +1 -1
  234. package/dist/tags/handlers/assign-tag.write.js +3 -1
  235. package/dist/tags/web/tag-chip.js +2 -0
  236. package/dist/template-resolver/api.d.ts +30 -2
  237. package/dist/template-resolver/api.js +42 -6
  238. package/dist/template-resolver/compile-document-body.d.ts +12 -0
  239. package/dist/template-resolver/compile-document-body.js +205 -0
  240. package/dist/template-resolver/constants.d.ts +13 -4
  241. package/dist/template-resolver/constants.js +32 -10
  242. package/dist/template-resolver/document-sanitizer.d.ts +32 -0
  243. package/dist/template-resolver/document-sanitizer.js +201 -0
  244. package/dist/template-resolver/document-schema.d.ts +21 -0
  245. package/dist/template-resolver/document-schema.js +316 -0
  246. package/dist/template-resolver/feature.d.ts +20 -0
  247. package/dist/template-resolver/feature.js +53 -6
  248. package/dist/template-resolver/handlers/bundle-import.d.ts +20 -0
  249. package/dist/template-resolver/handlers/bundle-import.js +147 -0
  250. package/dist/template-resolver/handlers/collection-set.write.d.ts +1 -1
  251. package/dist/template-resolver/handlers/collection-set.write.js +25 -2
  252. package/dist/template-resolver/handlers/copy-locale.write.d.ts +19 -0
  253. package/dist/template-resolver/handlers/copy-locale.write.js +134 -0
  254. package/dist/template-resolver/handlers/diff-to-system.query.d.ts +22 -0
  255. package/dist/template-resolver/handlers/diff-to-system.query.js +30 -0
  256. package/dist/template-resolver/handlers/discard-draft.write.d.ts +13 -0
  257. package/dist/template-resolver/handlers/discard-draft.write.js +37 -0
  258. package/dist/template-resolver/handlers/export-bundle.query.d.ts +35 -0
  259. package/dist/template-resolver/handlers/export-bundle.query.js +118 -0
  260. package/dist/template-resolver/handlers/find-by-id.query.d.ts +2 -0
  261. package/dist/template-resolver/handlers/find-by-id.query.js +9 -6
  262. package/dist/template-resolver/handlers/import-bundle-system.write.d.ts +39 -0
  263. package/dist/template-resolver/handlers/import-bundle-system.write.js +36 -0
  264. package/dist/template-resolver/handlers/import-bundle.write.d.ts +40 -0
  265. package/dist/template-resolver/handlers/import-bundle.write.js +19 -0
  266. package/dist/template-resolver/handlers/layout-source.query.d.ts +31 -0
  267. package/dist/template-resolver/handlers/layout-source.query.js +87 -0
  268. package/dist/template-resolver/handlers/list.query.d.ts +4 -1
  269. package/dist/template-resolver/handlers/list.query.js +9 -8
  270. package/dist/template-resolver/handlers/override-diff.d.ts +20 -0
  271. package/dist/template-resolver/handlers/override-diff.js +41 -0
  272. package/dist/template-resolver/handlers/overview.query.d.ts +65 -0
  273. package/dist/template-resolver/handlers/overview.query.js +205 -0
  274. package/dist/template-resolver/handlers/preview.query.d.ts +12 -0
  275. package/dist/template-resolver/handlers/preview.query.js +24 -0
  276. package/dist/template-resolver/handlers/reset-to-system.write.d.ts +8 -0
  277. package/dist/template-resolver/handlers/reset-to-system.write.js +50 -0
  278. package/dist/template-resolver/handlers/resource-link-pdf.write.d.ts +8 -0
  279. package/dist/template-resolver/handlers/resource-link-pdf.write.js +32 -0
  280. package/dist/template-resolver/handlers/resource-remove.write.d.ts +9 -0
  281. package/dist/template-resolver/handlers/resource-remove.write.js +44 -0
  282. package/dist/template-resolver/handlers/resource-shared.d.ts +9 -0
  283. package/dist/template-resolver/handlers/resource-shared.js +14 -0
  284. package/dist/template-resolver/handlers/resource-upload.write.d.ts +13 -0
  285. package/dist/template-resolver/handlers/resource-upload.write.js +98 -0
  286. package/dist/template-resolver/handlers/send-test.write.d.ts +13 -0
  287. package/dist/template-resolver/handlers/send-test.write.js +108 -0
  288. package/dist/template-resolver/handlers/set.write.d.ts +5 -2
  289. package/dist/template-resolver/handlers/set.write.js +25 -3
  290. package/dist/template-resolver/handlers/shared.d.ts +9 -5
  291. package/dist/template-resolver/handlers/shared.js +6 -2
  292. package/dist/template-resolver/handlers/template-gates.d.ts +36 -0
  293. package/dist/template-resolver/handlers/template-gates.js +142 -0
  294. package/dist/template-resolver/handlers/template-write.d.ts +45 -0
  295. package/dist/template-resolver/handlers/template-write.js +141 -0
  296. package/dist/template-resolver/handlers/tenant-overrides.query.d.ts +49 -0
  297. package/dist/template-resolver/handlers/tenant-overrides.query.js +112 -0
  298. package/dist/template-resolver/handlers/toggle-status.write.d.ts +27 -2
  299. package/dist/template-resolver/handlers/toggle-status.write.js +47 -15
  300. package/dist/template-resolver/handlers/upsert-system.write.d.ts +5 -8
  301. package/dist/template-resolver/handlers/upsert-system.write.js +14 -59
  302. package/dist/template-resolver/handlers/upsert-tenant.write.d.ts +5 -8
  303. package/dist/template-resolver/handlers/upsert-tenant.write.js +11 -62
  304. package/dist/template-resolver/handlers/usage.query.d.ts +17 -0
  305. package/dist/template-resolver/handlers/usage.query.js +24 -0
  306. package/dist/template-resolver/handlers/validate.query.d.ts +74 -0
  307. package/dist/template-resolver/handlers/validate.query.js +80 -0
  308. package/dist/template-resolver/index.d.ts +19 -1
  309. package/dist/template-resolver/index.js +17 -1
  310. package/dist/template-resolver/layout-appearance.d.ts +10 -0
  311. package/dist/template-resolver/layout-appearance.js +26 -0
  312. package/dist/template-resolver/layout-regions.d.ts +23 -0
  313. package/dist/template-resolver/layout-regions.js +125 -0
  314. package/dist/template-resolver/linked-resources.d.ts +17 -0
  315. package/dist/template-resolver/linked-resources.js +75 -0
  316. package/dist/template-resolver/pdf-constants.d.ts +7 -0
  317. package/dist/template-resolver/pdf-constants.js +8 -0
  318. package/dist/template-resolver/preview-display-html.d.ts +7 -0
  319. package/dist/template-resolver/preview-display-html.js +27 -0
  320. package/dist/template-resolver/print-document.d.ts +1 -0
  321. package/dist/template-resolver/print-document.js +55 -0
  322. package/dist/template-resolver/qualified-names.d.ts +34 -0
  323. package/dist/template-resolver/qualified-names.js +34 -0
  324. package/dist/template-resolver/record-mapping.d.ts +2 -0
  325. package/dist/template-resolver/record-mapping.js +21 -0
  326. package/dist/template-resolver/resource-image.d.ts +15 -0
  327. package/dist/template-resolver/resource-image.js +34 -0
  328. package/dist/template-resolver/seeding.d.ts +14 -1
  329. package/dist/template-resolver/seeding.js +125 -18
  330. package/dist/template-resolver/store-template-resource.d.ts +64 -0
  331. package/dist/template-resolver/store-template-resource.js +264 -0
  332. package/dist/template-resolver/table.d.ts +150 -8
  333. package/dist/template-resolver/table.js +20 -2
  334. package/dist/template-resolver/template-bundle.d.ts +36 -0
  335. package/dist/template-resolver/template-bundle.js +60 -0
  336. package/dist/template-resolver/template-diff.d.ts +7 -0
  337. package/dist/template-resolver/template-diff.js +68 -0
  338. package/dist/template-resolver/template-draft.d.ts +51 -0
  339. package/dist/template-resolver/template-draft.js +72 -0
  340. package/dist/template-resolver/template-meta.d.ts +85 -0
  341. package/dist/template-resolver/template-meta.js +145 -0
  342. package/dist/template-resolver/template-preview.d.ts +103 -0
  343. package/dist/template-resolver/template-preview.js +418 -0
  344. package/dist/template-resolver/template-resources.d.ts +19 -0
  345. package/dist/template-resolver/template-resources.js +73 -0
  346. package/dist/template-resolver/template-usage.d.ts +16 -0
  347. package/dist/template-resolver/template-usage.js +35 -0
  348. package/dist/template-resolver/template-validation.d.ts +22 -0
  349. package/dist/template-resolver/template-validation.js +173 -0
  350. package/dist/template-resolver/testing.js +5 -5
  351. package/dist/template-resolver/user-content-table.d.ts +14 -8
  352. package/dist/template-resolver/web/client-plugin.d.ts +1 -0
  353. package/dist/template-resolver/web/client-plugin.js +12 -7
  354. package/dist/template-resolver/web/document-editor-extensions.d.ts +18 -0
  355. package/dist/template-resolver/web/document-editor-extensions.js +145 -0
  356. package/dist/template-resolver/web/document-editor.d.ts +4 -0
  357. package/dist/template-resolver/web/document-editor.js +17 -0
  358. package/dist/template-resolver/web/document-tiptap-editor.d.ts +3 -0
  359. package/dist/template-resolver/web/document-tiptap-editor.js +492 -0
  360. package/dist/template-resolver/web/document-toolbar-blocks.d.ts +41 -0
  361. package/dist/template-resolver/web/document-toolbar-blocks.js +19 -0
  362. package/dist/template-resolver/web/editor-handle.d.ts +3 -0
  363. package/dist/template-resolver/web/editor-handle.js +24 -0
  364. package/dist/template-resolver/web/i18n.js +91 -0
  365. package/dist/template-resolver/web/index.d.ts +5 -0
  366. package/dist/template-resolver/web/index.js +5 -0
  367. package/dist/template-resolver/web/placeholder-line-editor-lazy.d.ts +4 -0
  368. package/dist/template-resolver/web/placeholder-line-editor-lazy.js +16 -0
  369. package/dist/template-resolver/web/placeholder-line-editor.d.ts +17 -0
  370. package/dist/template-resolver/web/placeholder-line-editor.js +94 -0
  371. package/dist/template-resolver/web/placeholder-text.d.ts +4 -0
  372. package/dist/template-resolver/web/placeholder-text.js +34 -0
  373. package/dist/template-resolver/web/use-stable-by-key.d.ts +1 -0
  374. package/dist/template-resolver/web/use-stable-by-key.js +13 -0
  375. package/dist/tenant/handlers/add-member.write.d.ts +1 -1
  376. package/dist/tenant/handlers/cancel-invitation.write.d.ts +1 -1
  377. package/dist/tenant/handlers/create.write.d.ts +1 -1
  378. package/dist/tenant/handlers/remove-member.write.d.ts +1 -1
  379. package/dist/tenant/handlers/team-list.query.js +3 -2
  380. package/dist/tenant/handlers/toggle-enabled.write.d.ts +2 -2
  381. package/dist/tenant/handlers/update-member-roles.write.d.ts +1 -1
  382. package/dist/tenant/handlers/update.write.d.ts +1 -1
  383. package/dist/tenant/seeding.js +31 -6
  384. package/dist/tenant-handover/handlers/claim.write.d.ts +1 -1
  385. package/dist/tenant-lifecycle/handlers/cancel-destruction.write.d.ts +2 -2
  386. package/dist/tenant-lifecycle/handlers/cancel-destruction.write.js +2 -1
  387. package/dist/tenant-lifecycle/handlers/request-destruction.write.d.ts +1 -1
  388. package/dist/tier-engine/feature.js +9 -3
  389. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +1 -1
  390. package/dist/user/db/queries/stream-tenant-backfill.js +4 -4
  391. package/dist/user/handlers/create.write.d.ts +1 -1
  392. package/dist/user/handlers/detail.query.js +2 -1
  393. package/dist/user/handlers/update.write.d.ts +1 -1
  394. package/dist/user/resolve-display-names.js +5 -9
  395. package/dist/user/seeding.js +20 -1
  396. package/dist/user-data-rights/db/queries/forget-cleanup.d.ts +2 -2
  397. package/dist/user-data-rights/email-templates.d.ts +1 -29
  398. package/dist/user-data-rights/email-templates.js +5 -106
  399. package/dist/user-data-rights/feature.js +53 -35
  400. package/dist/user-data-rights/handlers/cancel-deletion.write.d.ts +2 -2
  401. package/dist/user-data-rights/handlers/cancel-deletion.write.js +2 -1
  402. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.d.ts +1 -1
  403. package/dist/user-data-rights/handlers/lift-restriction.write.d.ts +1 -1
  404. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +1 -1
  405. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +1 -1
  406. package/dist/user-data-rights/handlers/request-deletion.write.js +5 -7
  407. package/dist/user-data-rights/handlers/request-export.write.d.ts +1 -1
  408. package/dist/user-data-rights/handlers/restrict-account.write.d.ts +1 -1
  409. package/dist/user-data-rights/handlers/run-forget-cleanup.write.d.ts +1 -1
  410. package/dist/user-data-rights/lib/default-mailers.d.ts +15 -7
  411. package/dist/user-data-rights/lib/default-mailers.js +100 -48
  412. package/dist/user-data-rights/lib/update-user-lifecycle.js +1 -1
  413. package/dist/user-data-rights/mail-notifications.d.ts +13 -0
  414. package/dist/user-data-rights/mail-notifications.js +118 -0
  415. package/dist/user-data-rights/web/privacy-center-screen.js +2 -1
  416. package/dist/user-profile/handlers/change-email.write.d.ts +1 -1
  417. package/dist/user-profile/web/profile-screen.js +2 -1
  418. package/dist/waitlist/feature.js +10 -0
  419. package/dist/waitlist/handlers/invite.write.d.ts +1 -1
  420. package/dist/waitlist/handlers/reject.write.d.ts +1 -1
  421. package/dist/waitlist/handlers/submit.write.d.ts +1 -1
  422. package/dist/waitlist/handlers/submit.write.js +3 -4
  423. package/dist/waitlist/mail.d.ts +19 -6
  424. package/dist/waitlist/mail.js +50 -14
  425. package/dist/waitlist/options.js +1 -1
  426. package/dist/workflow-runner/event-trigger.js +2 -2
  427. package/dist/workflow-runner/handlers/resume-run.write.js +7 -2
  428. package/package.json +37 -17
  429. package/src/admin-shell/changes.json +6 -0
  430. package/src/audit/changes.json +6 -0
  431. package/src/auth-email-password/changes.json +51 -0
  432. package/src/billing-foundation/changes.json +43 -0
  433. package/src/cap-counter/changes.json +6 -0
  434. package/src/channel-email/changes.json +19 -0
  435. package/src/config/changes.json +6 -0
  436. package/src/crypto-shredding/changes.json +6 -0
  437. package/src/custom-fields/changes.json +6 -0
  438. package/src/data-retention/changes.json +6 -0
  439. package/src/delivery/changes.json +66 -0
  440. package/src/file-foundation/changes.json +6 -0
  441. package/src/files-tenant-data/changes.json +6 -0
  442. package/src/inbound-mail-foundation/changes.json +6 -0
  443. package/src/jobs/changes.json +19 -0
  444. package/src/ledger/changes.json +7 -0
  445. package/src/managed-pages/changes.json +6 -0
  446. package/src/renderer-foundation/changes.json +39 -0
  447. package/src/renderer-pdf/changes.json +12 -0
  448. package/src/secrets/changes.json +6 -0
  449. package/src/shared/changes.json +6 -0
  450. package/src/subscription-stripe/changes.json +6 -0
  451. package/src/template-resolver/changes.json +186 -0
  452. package/src/tier-engine/changes.json +6 -0
  453. package/src/user/changes.json +6 -0
  454. package/src/user-data-rights/changes.json +13 -0
  455. package/src/user-profile/changes.json +1 -1
  456. package/src/waitlist/changes.json +7 -0
  457. package/src/workflow-runner/changes.json +6 -0
  458. package/dist/renderer-simple/feature.d.ts +0 -10
  459. package/dist/renderer-simple/feature.js +0 -42
  460. package/dist/renderer-simple/index.d.ts +0 -3
  461. package/dist/renderer-simple/index.js +0 -2
  462. package/dist/renderer-simple/mail-blocks.d.ts +0 -21
  463. package/dist/renderer-simple/mail-blocks.js +0 -107
  464. package/dist/renderer-simple/resolve-variables.d.ts +0 -7
  465. package/dist/renderer-simple/resolve-variables.js +0 -47
  466. package/dist/renderer-simple/simple-renderer.d.ts +0 -24
  467. package/dist/renderer-simple/simple-renderer.js +0 -200
  468. package/src/renderer-simple/changes.json +0 -27
@@ -0,0 +1,80 @@
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
+ import { defineQueryHandler, SYSTEM_TENANT_ID, } from "@cosmicdrift/kumiko-framework/engine";
3
+ import * as z from "zod";
4
+ import { imageResourceKeysOf } from "../linked-resources.js";
5
+ import { templateResourcesTable } from "../table.js";
6
+ import { resolveTemplateVariables, systemPlaceholdersFor } from "../template-validation.js";
7
+ import { contentFormatSchema, kindSchema, localeSchema, templateSlugSchema } from "./shared.js";
8
+ import { evaluateTemplateWrite } from "./template-gates.js";
9
+ async function knownResourceKeys(db, where) {
10
+ const rows = await selectMany(db, templateResourcesTable, {
11
+ tenantId: where.tenantId,
12
+ slug: where.slug,
13
+ kind: where.kind,
14
+ scope: where.scope,
15
+ ...(where.locale === undefined ? {} : { locale: where.locale }),
16
+ ...(where.scope === "system" ? { status: "active" } : {}),
17
+ });
18
+ return rows.flatMap((row) => imageResourceKeysOf(row.linkedResources));
19
+ }
20
+ // The dry run of the write pipeline; preview feeds on the evaluation, validate returns the response.
21
+ export async function validateTemplateDraft(ctx, user, payload) {
22
+ const variables = resolveTemplateVariables(ctx.registry, payload.slug, payload.variableSchema);
23
+ const { slug, kind, scope, locale } = payload;
24
+ const known = [
25
+ ...(await knownResourceKeys(ctx.db, {
26
+ tenantId: SYSTEM_TENANT_ID,
27
+ slug,
28
+ kind,
29
+ scope: "system",
30
+ locale,
31
+ })),
32
+ ...(scope === "tenant"
33
+ ? await knownResourceKeys(ctx.db, { tenantId: user.tenantId, slug, kind, scope, locale })
34
+ : []),
35
+ ];
36
+ const evaluation = evaluateTemplateWrite({
37
+ kind,
38
+ scope,
39
+ contentFormat: payload.contentFormat,
40
+ content: payload.content,
41
+ rawMeta: payload.meta,
42
+ variables,
43
+ resourceKeys: known,
44
+ });
45
+ const validation = evaluation.validation;
46
+ const response = {
47
+ canSave: evaluation.ok,
48
+ canPublish: evaluation.ok && evaluation.publishIssues.length === 0,
49
+ issues: evaluation.ok ? [] : [...evaluation.issues],
50
+ publishIssues: evaluation.ok ? [...evaluation.publishIssues] : [],
51
+ used: [...(validation?.used ?? [])],
52
+ unknown: [...(validation?.unknown ?? [])],
53
+ missingRequired: [...(validation?.missingRequired ?? [])],
54
+ warnings: (validation?.unknownResources ?? []).map((key) => ({
55
+ code: "resource_not_uploaded",
56
+ detail: key,
57
+ i18nKey: "templateResolver.warnings.resourceNotUploaded",
58
+ })),
59
+ variables,
60
+ systemPlaceholders: [...systemPlaceholdersFor(kind)].sort(),
61
+ };
62
+ return { response, evaluation };
63
+ }
64
+ export const validateQuery = defineQueryHandler({
65
+ name: "validate",
66
+ schema: z.object({
67
+ slug: templateSlugSchema,
68
+ kind: kindSchema,
69
+ contentFormat: contentFormatSchema,
70
+ content: z.string().max(200_000),
71
+ meta: z.unknown().optional(),
72
+ variableSchema: z.record(z.string(), z.unknown()).default({}),
73
+ /** Narrows the known resource keys to one locale's rows. */
74
+ locale: localeSchema.optional(),
75
+ scope: z.enum(["tenant", "system"]).default("tenant"),
76
+ }),
77
+ access: { roles: ["TenantAdmin", "SystemAdmin"] },
78
+ description: "Dry-runs the write pipeline for a template draft without saving: reports whether it can be saved or published, the sanitizer and placeholder problems, which placeholders it uses, which are unknown, which required variables are missing, and the variables and system placeholders available for the kind; use it to give an editor live feedback.",
79
+ handler: async (query, ctx) => (await validateTemplateDraft(ctx, query.user, query.payload)).response,
80
+ });
@@ -1,6 +1,24 @@
1
1
  export { createTemplateResolverApi, type ResolveRequest, requireTemplateResolver, TemplateNotFoundError, type TemplateResolverApi, type TemplateResource, } from "./api.js";
2
- export { CONTENT_FORMATS, type ContentFormat, FALLBACK_LOCALE, NON_RENDER_KINDS, type NonRenderKind, RENDER_KINDS, type RenderKind, SYSTEM_TENANT_ID, TEMPLATE_KINDS, TEMPLATE_SCOPES, TEMPLATE_STATUSES, TEXT_BLOCK_KIND, type TemplateKind, type TemplateScope, type TemplateStatus, UPSERT_KINDS, type UpsertKind, } from "./constants.js";
2
+ export { type CompileDocumentBodyOptions, collectDocumentResourceKeys, compileDocumentBodyToHandlebars, toResourceDataUri, } from "./compile-document-body.js";
3
+ export { CONTENT_FORMATS, type ContentFormat, DEFAULT_MAIL_LAYOUT_SLUG, DOCUMENT_HTML_KINDS, type DocumentHtmlKind, FALLBACK_LOCALE, NON_RENDER_KINDS, type NonRenderKind, PDF_DEFAULT_MARGIN_MM, PDF_FOOTER_MARGIN_MM, PDF_HEADER_MARGIN_MM, PDF_ORIENTATIONS, PDF_PAGE_FORMATS, type PdfOrientation, type PdfPageFormat, RENDER_KINDS, type RenderKind, SYSTEM_TENANT_ID, TEMPLATE_KINDS, TEMPLATE_SCOPES, TEMPLATE_STATUSES, TEXT_BLOCK_KIND, type TemplateKind, type TemplateScope, type TemplateStatus, UPSERT_KINDS, type UpsertKind, } from "./constants.js";
4
+ export { type DocumentViolation, type DocumentViolationCode, documentViolationsToFieldIssues, type SanitizeBodyResult, type SanitizeHtmlResult, sanitizeDocumentHtml, sanitizeTemplateBody, } from "./document-sanitizer.js";
5
+ export { DOCUMENT_NODE_NAMES, DOCUMENT_TEXT_ALIGNMENTS, DocumentButton, DocumentDivider, DocumentLink, DocumentPageBreak, DocumentResource, DocumentTable, DocumentTableCell, DocumentTableHeader, DocumentTableRow, DocumentTextAlign, type DocumentTextAlignment, DocumentVariable, documentExtensions, isAllowedDocumentLinkHref, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "./document-schema.js";
3
6
  export { createTemplateResolverFeature } from "./feature.js";
7
+ export type { LayoutSourceResponse, LayoutSourceRow } from "./handlers/layout-source.query.js";
8
+ export type { OverviewKindGroup, OverviewOrigin, OverviewResponse, OverviewRow, OverviewUsage, } from "./handlers/overview.query.js";
9
+ export { localeSchema } from "./handlers/shared.js";
10
+ export { isHexColor, type MailLayoutAppearance, mailLayoutAppearance, } from "./layout-appearance.js";
11
+ export { type LayoutRegions, readLayoutRegions, type SanitizeLayoutResult, sanitizeLayoutHtml, } from "./layout-regions.js";
12
+ export { fileAttachmentsOf, imageLinksOf, type LinkedResourceEntry, parseLinkedResourceEntries, pdfAttachmentLinksOf, type TemplatePdfAttachmentLink, templatePdfAttachmentLinkSchema, } from "./linked-resources.js";
13
+ export { prepareDocumentForPrint } from "./print-document.js";
4
14
  export { TEMPLATE_RESOLVER_FEATURE, TemplateResolverErrors, TemplateResolverHandlers, TemplateResolverQueries, } from "./qualified-names.js";
15
+ export { mapRecordToVariables } from "./record-mapping.js";
16
+ export { readTemplateResourceMaxBytes, type StoredTemplateResource, storeTemplateResource, } from "./store-template-resource.js";
5
17
  export { type TemplateResourceRow, templateResourceEntity, templateResourcesTable, } from "./table.js";
18
+ export { type TemplateBundle, templateBundleSchema } from "./template-bundle.js";
19
+ export { isMailTemplateMeta, type LayoutTemplateMeta, MAIL_CATEGORIES, type MailCategory, type MailLayoutMeta, type MailTemplateMeta, type PdfTemplateMeta, parseTemplateMeta, pdfAttachmentFileNamePatternSchema, readMailLayoutMeta, readPdfTemplateMeta, type TemplateMeta, type TemplateMetaIssue, type TemplateMetaResult, templateSlugSchema, } from "./template-meta.js";
20
+ export { type DocumentDraftOutcome, evaluateDocumentDraft } from "./template-preview.js";
21
+ export { readTemplateResource, type TemplateResourceFile } from "./template-resources.js";
22
+ export { collectTemplateUsage, type TemplateUsageEntry } from "./template-usage.js";
23
+ export { hasPlaceholderProblems, resolveTemplateVariables, SYSTEM_PLACEHOLDERS, systemPlaceholdersFor, type TemplateValidation, validateTemplatePlaceholders, } from "./template-validation.js";
6
24
  export { type UserContentEntryRow, userContentEntriesTable, userContentEntryEntity, } from "./user-content-table.js";
@@ -1,6 +1,22 @@
1
1
  export { createTemplateResolverApi, requireTemplateResolver, TemplateNotFoundError, } from "./api.js";
2
- export { CONTENT_FORMATS, FALLBACK_LOCALE, NON_RENDER_KINDS, RENDER_KINDS, SYSTEM_TENANT_ID, TEMPLATE_KINDS, TEMPLATE_SCOPES, TEMPLATE_STATUSES, TEXT_BLOCK_KIND, UPSERT_KINDS, } from "./constants.js";
2
+ export { collectDocumentResourceKeys, compileDocumentBodyToHandlebars, toResourceDataUri, } from "./compile-document-body.js";
3
+ export { CONTENT_FORMATS, DEFAULT_MAIL_LAYOUT_SLUG, DOCUMENT_HTML_KINDS, FALLBACK_LOCALE, NON_RENDER_KINDS, PDF_DEFAULT_MARGIN_MM, PDF_FOOTER_MARGIN_MM, PDF_HEADER_MARGIN_MM, PDF_ORIENTATIONS, PDF_PAGE_FORMATS, RENDER_KINDS, SYSTEM_TENANT_ID, TEMPLATE_KINDS, TEMPLATE_SCOPES, TEMPLATE_STATUSES, TEXT_BLOCK_KIND, UPSERT_KINDS, } from "./constants.js";
4
+ export { documentViolationsToFieldIssues, sanitizeDocumentHtml, sanitizeTemplateBody, } from "./document-sanitizer.js";
5
+ export { DOCUMENT_NODE_NAMES, DOCUMENT_TEXT_ALIGNMENTS, DocumentButton, DocumentDivider, DocumentLink, DocumentPageBreak, DocumentResource, DocumentTable, DocumentTableCell, DocumentTableHeader, DocumentTableRow, DocumentTextAlign, DocumentVariable, documentExtensions, isAllowedDocumentLinkHref, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "./document-schema.js";
3
6
  export { createTemplateResolverFeature } from "./feature.js";
7
+ export { localeSchema } from "./handlers/shared.js";
8
+ export { isHexColor, mailLayoutAppearance, } from "./layout-appearance.js";
9
+ export { readLayoutRegions, sanitizeLayoutHtml, } from "./layout-regions.js";
10
+ export { fileAttachmentsOf, imageLinksOf, parseLinkedResourceEntries, pdfAttachmentLinksOf, templatePdfAttachmentLinkSchema, } from "./linked-resources.js";
11
+ export { prepareDocumentForPrint } from "./print-document.js";
4
12
  export { TEMPLATE_RESOLVER_FEATURE, TemplateResolverErrors, TemplateResolverHandlers, TemplateResolverQueries, } from "./qualified-names.js";
13
+ export { mapRecordToVariables } from "./record-mapping.js";
14
+ export { readTemplateResourceMaxBytes, storeTemplateResource, } from "./store-template-resource.js";
5
15
  export { templateResourceEntity, templateResourcesTable, } from "./table.js";
16
+ export { templateBundleSchema } from "./template-bundle.js";
17
+ export { isMailTemplateMeta, MAIL_CATEGORIES, parseTemplateMeta, pdfAttachmentFileNamePatternSchema, readMailLayoutMeta, readPdfTemplateMeta, templateSlugSchema, } from "./template-meta.js";
18
+ export { evaluateDocumentDraft } from "./template-preview.js";
19
+ export { readTemplateResource } from "./template-resources.js";
20
+ export { collectTemplateUsage } from "./template-usage.js";
21
+ export { hasPlaceholderProblems, resolveTemplateVariables, SYSTEM_PLACEHOLDERS, systemPlaceholdersFor, validateTemplatePlaceholders, } from "./template-validation.js";
6
22
  export { userContentEntriesTable, userContentEntryEntity, } from "./user-content-table.js";
@@ -0,0 +1,10 @@
1
+ import { type MailLayoutMeta } from "./template-meta.js";
2
+ export type MailLayoutAppearance = {
3
+ readonly width: number;
4
+ readonly fontFamily: string;
5
+ readonly outerBackground: string;
6
+ readonly accentLine: boolean;
7
+ readonly buttonStyle: string;
8
+ };
9
+ export declare function isHexColor(value: string): boolean;
10
+ export declare function mailLayoutAppearance(meta: MailLayoutMeta | unknown): MailLayoutAppearance;
@@ -0,0 +1,26 @@
1
+ import { HEX_COLOR_PATTERN } from "./constants.js";
2
+ import { readMailLayoutMeta } from "./template-meta.js";
3
+ const FONT_FAMILIES = {
4
+ sans: "Arial, Helvetica, sans-serif",
5
+ serif: "Georgia, 'Times New Roman', serif",
6
+ };
7
+ const BUTTON_COLOR = "#1f5468";
8
+ const BUTTON_BASE = "display:inline-block;padding:10px 20px;font-weight:600;text-decoration:none";
9
+ const BUTTON_STYLES = {
10
+ "filled-rounded": `${BUTTON_BASE};border-radius:6px;background-color:${BUTTON_COLOR};color:#ffffff`,
11
+ "filled-square": `${BUTTON_BASE};background-color:${BUTTON_COLOR};color:#ffffff`,
12
+ outline: `${BUTTON_BASE};border:2px solid ${BUTTON_COLOR};border-radius:6px;color:${BUTTON_COLOR}`,
13
+ };
14
+ export function isHexColor(value) {
15
+ return HEX_COLOR_PATTERN.test(value);
16
+ }
17
+ export function mailLayoutAppearance(meta) {
18
+ const parsed = readMailLayoutMeta(meta);
19
+ return {
20
+ width: parsed.width ?? 600,
21
+ fontFamily: FONT_FAMILIES[parsed.font ?? "sans"],
22
+ outerBackground: parsed.outerBackground ?? "#f5f5f5",
23
+ accentLine: (parsed.accentLine ?? "none") === "branding",
24
+ buttonStyle: BUTTON_STYLES[parsed.buttonStyle ?? "filled-rounded"],
25
+ };
26
+ }
@@ -0,0 +1,23 @@
1
+ import type { ContentFormat } from "./constants.js";
2
+ import { type DocumentViolation, type SanitizeBodyResult } from "./document-sanitizer.js";
3
+ export type LayoutRegions = {
4
+ readonly header: string;
5
+ readonly signature: string;
6
+ readonly footer: string;
7
+ };
8
+ export type SanitizeLayoutResult = {
9
+ readonly ok: true;
10
+ readonly html: string;
11
+ } | {
12
+ readonly ok: false;
13
+ readonly violations: readonly DocumentViolation[];
14
+ };
15
+ export declare function sanitizeLayoutHtml(html: string): SanitizeLayoutResult;
16
+ export declare function readLayoutRegions(html: string): LayoutRegions;
17
+ export type TemplateWriteScope = "system" | "tenant";
18
+ export declare function sanitizeTemplateWriteBody(input: {
19
+ readonly kind: string;
20
+ readonly scope: TemplateWriteScope;
21
+ readonly contentFormat: ContentFormat;
22
+ readonly content: string | null;
23
+ }): SanitizeBodyResult;
@@ -0,0 +1,125 @@
1
+ // Server-only (happy-dom). A structured layout is the editable frame around a
2
+ // mail or PDF body: header, signature and footer regions plus one empty
3
+ // content slot. Everything else is rejected so a layout can never carry markup
4
+ // the renderer did not plan for.
5
+ import { sanitizeDocumentHtml, sanitizeTemplateBody, violation, withParsedDocument, } from "./document-sanitizer.js";
6
+ const REGION_ATTRIBUTES = ["data-header", "data-content", "data-signature", "data-footer"];
7
+ const MAIL_LAYOUT_CONTENT_SLOT = /\{\{\{\s*content\s*\}\}\}/g;
8
+ const ELEMENT_NODE = 1;
9
+ const TEXT_NODE = 3;
10
+ function regionAttributeOf(element) {
11
+ if (element.tagName.toLowerCase() !== "div")
12
+ return null;
13
+ const present = REGION_ATTRIBUTES.filter((name) => element.hasAttribute(name));
14
+ return present.length === 1 ? (present[0] ?? null) : null;
15
+ }
16
+ function parseRegions(html) {
17
+ return withParsedDocument(html, (body) => {
18
+ const innerHtml = {};
19
+ const violations = [];
20
+ let contentIsEmpty = true;
21
+ const invalid = (detail, message) => violations.push(violation("layout_invalid_structure", detail, message));
22
+ for (const node of Array.from(body.childNodes)) {
23
+ if (node.nodeType === ELEMENT_NODE)
24
+ continue;
25
+ if (node.nodeType !== TEXT_NODE || (node.textContent ?? "").trim() !== "") {
26
+ invalid("text", "Text and comments outside the layout regions are not allowed");
27
+ }
28
+ }
29
+ for (const element of Array.from(body.children)) {
30
+ const region = regionAttributeOf(element);
31
+ if (region === null) {
32
+ invalid(element.tagName.toLowerCase(), "Only <div data-header>, <div data-content>, <div data-signature> and <div data-footer> are allowed at the top level");
33
+ continue;
34
+ }
35
+ if (innerHtml[region] !== undefined) {
36
+ invalid(region, `Layout region ${region} may appear only once`);
37
+ continue;
38
+ }
39
+ innerHtml[region] = element.innerHTML;
40
+ if (region === "data-content") {
41
+ contentIsEmpty = element.children.length === 0 && (element.textContent ?? "").trim() === "";
42
+ }
43
+ }
44
+ return { innerHtml, contentIsEmpty, violations };
45
+ });
46
+ }
47
+ export function sanitizeLayoutHtml(html) {
48
+ const parsed = parseRegions(html);
49
+ const violations = [...parsed.violations];
50
+ if (parsed.innerHtml["data-content"] === undefined) {
51
+ violations.push(violation("layout_missing_content_slot", "data-content", "A layout needs exactly one empty <div data-content></div> where the body is placed"));
52
+ }
53
+ else if (!parsed.contentIsEmpty) {
54
+ violations.push(violation("layout_invalid_structure", "data-content", "The data-content region must be empty"));
55
+ }
56
+ const cleanedHtml = {};
57
+ for (const name of ["data-header", "data-signature", "data-footer"]) {
58
+ const inner = parsed.innerHtml[name];
59
+ if (inner === undefined || inner.trim() === "")
60
+ continue;
61
+ const result = sanitizeDocumentHtml(inner);
62
+ if (result.ok)
63
+ cleanedHtml[name] = result.html;
64
+ else
65
+ violations.push(...result.violations);
66
+ }
67
+ if (violations.length > 0)
68
+ return { ok: false, violations };
69
+ const part = (name) => {
70
+ const regionHtml = cleanedHtml[name];
71
+ return regionHtml === undefined ? "" : `<div ${name}>${regionHtml}</div>`;
72
+ };
73
+ return {
74
+ ok: true,
75
+ html: [
76
+ part("data-header"),
77
+ "<div data-content></div>",
78
+ part("data-signature"),
79
+ part("data-footer"),
80
+ ].join(""),
81
+ };
82
+ }
83
+ export function readLayoutRegions(html) {
84
+ const { innerHtml } = parseRegions(html);
85
+ return {
86
+ header: innerHtml["data-header"] ?? "",
87
+ signature: innerHtml["data-signature"] ?? "",
88
+ footer: innerHtml["data-footer"] ?? "",
89
+ };
90
+ }
91
+ function rejected(violationItem) {
92
+ return { ok: false, violations: [violationItem] };
93
+ }
94
+ function sanitizeMailLayout(scope, contentFormat, content) {
95
+ if (contentFormat === "html")
96
+ return fromLayoutResult(sanitizeLayoutHtml(content));
97
+ if (contentFormat !== "mjml") {
98
+ return rejected(violation("layout_requires_mjml_format", contentFormat, `Templates of kind mail-layout require contentFormat mjml or html, got "${contentFormat}"`));
99
+ }
100
+ if (scope !== "system") {
101
+ return rejected(violation("layout_source_system_only", "mjml", "Only system layouts may use mjml source; tenant layouts use the structured html format"));
102
+ }
103
+ if ((content.match(MAIL_LAYOUT_CONTENT_SLOT) ?? []).length !== 1) {
104
+ return rejected(violation("layout_missing_content_slot", "{{{content}}}", "A mjml layout must contain {{{content}}} exactly once"));
105
+ }
106
+ return { ok: true, content };
107
+ }
108
+ function fromLayoutResult(result) {
109
+ return result.ok ? { ok: true, content: result.html } : result;
110
+ }
111
+ // One entry for every write path: layout kinds follow the scope-dependent
112
+ // layout rules, everything else the plain document sanitizer.
113
+ export function sanitizeTemplateWriteBody(input) {
114
+ const { kind, scope, contentFormat, content } = input;
115
+ if (kind === "mail-layout" && content !== null) {
116
+ return sanitizeMailLayout(scope, contentFormat, content);
117
+ }
118
+ if (kind === "pdf-layout" && content !== null) {
119
+ if (contentFormat !== "html") {
120
+ return rejected(violation("document_requires_html_format", contentFormat, `Templates of kind pdf-layout require contentFormat html, got "${contentFormat}"`));
121
+ }
122
+ return fromLayoutResult(sanitizeLayoutHtml(content));
123
+ }
124
+ return sanitizeTemplateBody({ kind, contentFormat, content });
125
+ }
@@ -0,0 +1,17 @@
1
+ import * as z from "zod";
2
+ import type { FileAttachmentRef } from "../renderer-foundation/index.js";
3
+ export declare const templatePdfAttachmentLinkSchema: z.ZodObject<{
4
+ kind: z.ZodLiteral<"rendered-pdf">;
5
+ templateSlug: z.ZodString;
6
+ fileName: z.ZodString;
7
+ }, z.core.$strict>;
8
+ export type TemplatePdfAttachmentLink = z.infer<typeof templatePdfAttachmentLinkSchema>;
9
+ export type LinkedResourceEntry = string | FileAttachmentRef | TemplatePdfAttachmentLink;
10
+ export declare function isFileAttachmentEntry(entry: LinkedResourceEntry): entry is FileAttachmentRef;
11
+ export declare function isPdfAttachmentLink(entry: LinkedResourceEntry): entry is TemplatePdfAttachmentLink;
12
+ export declare function parseLinkedResourceEntries(raw: string | null): Record<string, LinkedResourceEntry>;
13
+ export declare function imageLinksOf(entries: Readonly<Record<string, LinkedResourceEntry>>): Record<string, string>;
14
+ export declare function fileAttachmentsOf(entries: Readonly<Record<string, LinkedResourceEntry>>): FileAttachmentRef[];
15
+ export declare function pdfAttachmentLinksOf(entries: Readonly<Record<string, LinkedResourceEntry>>): TemplatePdfAttachmentLink[];
16
+ export declare function attachmentEntriesOf(entries: Readonly<Record<string, LinkedResourceEntry>>): [string, FileAttachmentRef | TemplatePdfAttachmentLink][];
17
+ export declare function imageResourceKeysOf(raw: string | null): string[];
@@ -0,0 +1,75 @@
1
+ import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
2
+ import * as z from "zod";
3
+ import { pdfAttachmentFileNamePatternSchema, templateSlugSchema } from "./template-meta.js";
4
+ export const templatePdfAttachmentLinkSchema = z
5
+ .object({
6
+ kind: z.literal("rendered-pdf"),
7
+ templateSlug: templateSlugSchema,
8
+ fileName: pdfAttachmentFileNamePatternSchema,
9
+ })
10
+ .strict();
11
+ export function isFileAttachmentEntry(entry) {
12
+ return typeof entry !== "string" && entry.kind === "file";
13
+ }
14
+ export function isPdfAttachmentLink(entry) {
15
+ return typeof entry !== "string" && entry.kind === "rendered-pdf";
16
+ }
17
+ function toLinkedResourceEntry(raw) {
18
+ if (typeof raw === "string")
19
+ return raw;
20
+ if (!isPlainObject(raw))
21
+ return null;
22
+ if (raw["kind"] === "rendered-pdf") {
23
+ const link = templatePdfAttachmentLinkSchema.safeParse(raw);
24
+ return link.success ? link.data : null;
25
+ }
26
+ const { fileRefId, fileName } = raw;
27
+ if (raw["kind"] !== "file" || typeof fileRefId !== "string" || typeof fileName !== "string") {
28
+ return null;
29
+ }
30
+ return { kind: "file", fileRefId, fileName };
31
+ }
32
+ export function parseLinkedResourceEntries(raw) {
33
+ if (!raw)
34
+ return {};
35
+ let parsed;
36
+ try {
37
+ parsed = JSON.parse(raw);
38
+ }
39
+ catch {
40
+ return {};
41
+ }
42
+ if (!isPlainObject(parsed))
43
+ return {};
44
+ const entries = {};
45
+ for (const [key, value] of Object.entries(parsed)) {
46
+ const entry = toLinkedResourceEntry(value);
47
+ if (entry !== null)
48
+ entries[key] = entry;
49
+ }
50
+ return entries;
51
+ }
52
+ export function imageLinksOf(entries) {
53
+ const images = {};
54
+ for (const [key, entry] of Object.entries(entries)) {
55
+ if (typeof entry === "string")
56
+ images[key] = entry;
57
+ }
58
+ return images;
59
+ }
60
+ export function fileAttachmentsOf(entries) {
61
+ return Object.entries(entries)
62
+ .sort(([a], [b]) => a.localeCompare(b))
63
+ .flatMap(([, entry]) => (isFileAttachmentEntry(entry) ? [entry] : []));
64
+ }
65
+ export function pdfAttachmentLinksOf(entries) {
66
+ return Object.entries(entries)
67
+ .sort(([a], [b]) => a.localeCompare(b))
68
+ .flatMap(([, entry]) => (isPdfAttachmentLink(entry) ? [entry] : []));
69
+ }
70
+ export function attachmentEntriesOf(entries) {
71
+ return Object.entries(entries).flatMap(([key, entry]) => typeof entry === "string" ? [] : [[key, entry]]);
72
+ }
73
+ export function imageResourceKeysOf(raw) {
74
+ return Object.keys(imageLinksOf(parseLinkedResourceEntries(raw)));
75
+ }
@@ -0,0 +1,7 @@
1
+ export declare const PDF_PAGE_FORMATS: readonly ["A4", "Letter"];
2
+ export type PdfPageFormat = (typeof PDF_PAGE_FORMATS)[number];
3
+ export declare const PDF_ORIENTATIONS: readonly ["portrait", "landscape"];
4
+ export type PdfOrientation = (typeof PDF_ORIENTATIONS)[number];
5
+ export declare const PDF_DEFAULT_MARGIN_MM = 15;
6
+ export declare const PDF_HEADER_MARGIN_MM = 30;
7
+ export declare const PDF_FOOTER_MARGIN_MM = 20;
@@ -0,0 +1,8 @@
1
+ // @runtime client
2
+ // No imports: web/ re-exports these, and constants.ts pulls in the framework engine.
3
+ export const PDF_PAGE_FORMATS = ["A4", "Letter"];
4
+ export const PDF_ORIENTATIONS = ["portrait", "landscape"];
5
+ // Page margins in mm; the header/footer values apply when the layout contributes that region and the template sets no margin itself.
6
+ export const PDF_DEFAULT_MARGIN_MM = 15;
7
+ export const PDF_HEADER_MARGIN_MM = 30;
8
+ export const PDF_FOOTER_MARGIN_MM = 20;
@@ -0,0 +1,7 @@
1
+ import type { InlineAttachmentRef } from "../renderer-foundation/index.js";
2
+ export declare const PREVIEW_IMAGE_BUDGET_BYTES: number;
3
+ export type PreviewAttachmentReader = (ref: InlineAttachmentRef) => Promise<{
4
+ readonly content: Uint8Array;
5
+ readonly contentType: string;
6
+ } | null>;
7
+ export declare function buildDisplayHtml(html: string, inline: readonly InlineAttachmentRef[], readAttachment: PreviewAttachmentReader): Promise<string>;
@@ -0,0 +1,27 @@
1
+ export const PREVIEW_IMAGE_BUDGET_BYTES = 5 * 1024 * 1024;
2
+ const DISPLAYABLE_IMAGE_TYPES = new Set([
3
+ "image/png",
4
+ "image/jpeg",
5
+ "image/gif",
6
+ "image/webp",
7
+ ]);
8
+ // The preview shows images the mail client would resolve by Content-ID; a browser cannot, so each
9
+ // resolved image becomes a data URI. `html` itself stays untouched because the send path needs the cids.
10
+ export async function buildDisplayHtml(html, inline, readAttachment) {
11
+ let displayHtml = html;
12
+ let usedBytes = 0;
13
+ for (const ref of inline) {
14
+ const needle = `src="cid:${ref.cid}"`;
15
+ if (!displayHtml.includes(needle))
16
+ continue;
17
+ const found = await readAttachment(ref);
18
+ if (found === null || !DISPLAYABLE_IMAGE_TYPES.has(found.contentType))
19
+ continue;
20
+ if (usedBytes + found.content.length > PREVIEW_IMAGE_BUDGET_BYTES)
21
+ continue;
22
+ usedBytes += found.content.length;
23
+ const dataUri = `src="data:${found.contentType};base64,${Buffer.from(found.content).toString("base64")}"`;
24
+ displayHtml = displayHtml.replaceAll(needle, () => dataUri);
25
+ }
26
+ return displayHtml;
27
+ }
@@ -0,0 +1 @@
1
+ export declare function prepareDocumentForPrint(html: string): string;
@@ -0,0 +1,55 @@
1
+ // Server-only (happy-dom). Prepares a rendered document body for the browser
2
+ // that prints it: repeating table headers become real <thead> rows, and
3
+ // everything that would make the browser fetch something external is removed.
4
+ import { withParsedDocument } from "./document-sanitizer.js";
5
+ const REPEAT_HEADER_ATTRIBUTE = "data-repeat-header";
6
+ const FETCHING_ELEMENTS = "script, link, iframe, object, embed, video, audio, source, meta, base, style";
7
+ const FETCHING_ATTRIBUTES = ["src", "srcset", "poster", "background", "data"];
8
+ // Anchors only navigate; on svg image/use/feImage an href fetches.
9
+ const HREF_ATTRIBUTES = ["href", "xlink:href"];
10
+ const EXTERNAL_STYLE_REFERENCE = /url\(|@import/i;
11
+ function isEmbeddedValue(value) {
12
+ return value.trim().toLowerCase().startsWith("data:");
13
+ }
14
+ function moveRepeatHeadersIntoThead(table) {
15
+ const rows = Array.from(table.querySelectorAll("tr")).filter((row) => row.closest("table") === table);
16
+ const leading = [];
17
+ for (const row of rows) {
18
+ if (!row.hasAttribute(REPEAT_HEADER_ATTRIBUTE))
19
+ break;
20
+ leading.push(row);
21
+ }
22
+ // skip: a table without leading repeat-header rows keeps its structure as written
23
+ if (leading.length === 0)
24
+ return;
25
+ const thead = table.ownerDocument.createElement("thead");
26
+ for (const row of leading) {
27
+ row.removeAttribute(REPEAT_HEADER_ATTRIBUTE);
28
+ thead.appendChild(row);
29
+ }
30
+ table.insertBefore(thead, table.firstChild);
31
+ }
32
+ export function prepareDocumentForPrint(html) {
33
+ return withParsedDocument(html, (body) => {
34
+ for (const table of Array.from(body.querySelectorAll("table"))) {
35
+ moveRepeatHeadersIntoThead(table);
36
+ }
37
+ for (const element of Array.from(body.querySelectorAll(FETCHING_ELEMENTS)))
38
+ element.remove();
39
+ for (const element of Array.from(body.querySelectorAll("*"))) {
40
+ for (const name of FETCHING_ATTRIBUTES) {
41
+ const value = element.getAttribute(name);
42
+ if (value !== null && !isEmbeddedValue(value))
43
+ element.removeAttribute(name);
44
+ }
45
+ if (element.tagName.toLowerCase() !== "a") {
46
+ for (const name of HREF_ATTRIBUTES)
47
+ element.removeAttribute(name);
48
+ }
49
+ const style = element.getAttribute("style");
50
+ if (style !== null && EXTERNAL_STYLE_REFERENCE.test(style))
51
+ element.removeAttribute("style");
52
+ }
53
+ return body.innerHTML;
54
+ });
55
+ }
@@ -4,11 +4,31 @@ export declare const TemplateResolverHandlers: {
4
4
  readonly upsertTenant: "template-resolver:write:upsert-tenant";
5
5
  readonly publish: "template-resolver:write:publish";
6
6
  readonly archive: "template-resolver:write:archive";
7
+ readonly publishSystem: "template-resolver:write:publish-system";
8
+ readonly archiveSystem: "template-resolver:write:archive-system";
9
+ readonly discardDraft: "template-resolver:write:discard-draft";
10
+ readonly discardDraftSystem: "template-resolver:write:discard-draft-system";
11
+ readonly resetToSystem: "template-resolver:write:reset-to-system";
7
12
  readonly set: "template-resolver:write:set";
13
+ readonly importBundle: "template-resolver:write:import-bundle";
14
+ readonly importBundleSystem: "template-resolver:write:import-bundle-system";
15
+ readonly copyLocale: "template-resolver:write:copy-locale";
16
+ readonly resourceUpload: "template-resolver:write:resource-upload";
17
+ readonly resourceRemove: "template-resolver:write:resource-remove";
18
+ readonly resourceLinkPdf: "template-resolver:write:resource-link-pdf";
19
+ readonly sendTest: "template-resolver:write:send-test";
8
20
  };
9
21
  export declare const TemplateResolverQueries: {
10
22
  readonly findById: "template-resolver:query:find-by-id";
11
23
  readonly list: "template-resolver:query:list";
24
+ readonly usage: "template-resolver:query:usage";
25
+ readonly overview: "template-resolver:query:overview";
26
+ readonly layoutSource: "template-resolver:query:layout-source";
27
+ readonly tenantOverrides: "template-resolver:query:tenant-overrides";
28
+ readonly diffToSystem: "template-resolver:query:diff-to-system";
29
+ readonly validate: "template-resolver:query:validate";
30
+ readonly preview: "template-resolver:query:preview";
31
+ readonly exportBundle: "template-resolver:query:export-bundle";
12
32
  readonly bySlug: "template-resolver:query:by-slug";
13
33
  readonly byTenant: "template-resolver:query:by-tenant";
14
34
  };
@@ -19,6 +39,20 @@ export declare const TemplateResolverErrors: {
19
39
  readonly invalidSlug: "invalid_slug";
20
40
  readonly invalidLocale: "invalid_locale";
21
41
  readonly systemAdminRequired: "system_admin_required";
42
+ readonly noDraft: "no_draft";
22
43
  readonly alreadyActive: "template_already_active";
23
44
  readonly alreadyArchived: "template_already_archived";
45
+ readonly targetExists: "target_exists";
46
+ readonly systemResourcesNeedSystemTenant: "system_resources_need_system_tenant";
47
+ readonly bundleLocalesDiffer: "bundle_locales_differ";
48
+ readonly resourceTooLarge: "template_resource_too_large";
49
+ readonly resourceUnsupportedImage: "template_resource_unsupported_image";
50
+ readonly attachmentUnsupportedType: "template_attachment_unsupported_type";
51
+ readonly attachmentLimit: "template_attachment_limit";
52
+ readonly attachmentInvalid: "template_attachment_invalid";
53
+ readonly attachmentPdfTemplateMissing: "template_attachment_pdf_template_missing";
54
+ readonly previewRenderFailed: "template_preview_render_failed";
55
+ readonly testMailNoChannel: "template_test_mail_no_channel";
56
+ readonly testMailNoAddress: "template_test_mail_no_address";
57
+ readonly testMailFailed: "template_test_mail_failed";
24
58
  };
@@ -6,11 +6,31 @@ export const TemplateResolverHandlers = {
6
6
  upsertTenant: "template-resolver:write:upsert-tenant",
7
7
  publish: "template-resolver:write:publish",
8
8
  archive: "template-resolver:write:archive",
9
+ publishSystem: "template-resolver:write:publish-system",
10
+ archiveSystem: "template-resolver:write:archive-system",
11
+ discardDraft: "template-resolver:write:discard-draft",
12
+ discardDraftSystem: "template-resolver:write:discard-draft-system",
13
+ resetToSystem: "template-resolver:write:reset-to-system",
9
14
  set: "template-resolver:write:set",
15
+ importBundle: "template-resolver:write:import-bundle",
16
+ importBundleSystem: "template-resolver:write:import-bundle-system",
17
+ copyLocale: "template-resolver:write:copy-locale",
18
+ resourceUpload: "template-resolver:write:resource-upload",
19
+ resourceRemove: "template-resolver:write:resource-remove",
20
+ resourceLinkPdf: "template-resolver:write:resource-link-pdf",
21
+ sendTest: "template-resolver:write:send-test",
10
22
  };
11
23
  export const TemplateResolverQueries = {
12
24
  findById: "template-resolver:query:find-by-id",
13
25
  list: "template-resolver:query:list",
26
+ usage: "template-resolver:query:usage",
27
+ overview: "template-resolver:query:overview",
28
+ layoutSource: "template-resolver:query:layout-source",
29
+ tenantOverrides: "template-resolver:query:tenant-overrides",
30
+ diffToSystem: "template-resolver:query:diff-to-system",
31
+ validate: "template-resolver:query:validate",
32
+ preview: "template-resolver:query:preview",
33
+ exportBundle: "template-resolver:query:export-bundle",
14
34
  // Public pair — anonymous-reachable, kind pinned to text-block.
15
35
  bySlug: "template-resolver:query:by-slug",
16
36
  byTenant: "template-resolver:query:by-tenant",
@@ -30,6 +50,20 @@ export const TemplateResolverErrors = {
30
50
  invalidSlug: "invalid_slug",
31
51
  invalidLocale: "invalid_locale",
32
52
  systemAdminRequired: "system_admin_required",
53
+ noDraft: "no_draft",
33
54
  alreadyActive: "template_already_active",
34
55
  alreadyArchived: "template_already_archived",
56
+ targetExists: "target_exists",
57
+ systemResourcesNeedSystemTenant: "system_resources_need_system_tenant",
58
+ bundleLocalesDiffer: "bundle_locales_differ",
59
+ resourceTooLarge: "template_resource_too_large",
60
+ resourceUnsupportedImage: "template_resource_unsupported_image",
61
+ attachmentUnsupportedType: "template_attachment_unsupported_type",
62
+ attachmentLimit: "template_attachment_limit",
63
+ attachmentInvalid: "template_attachment_invalid",
64
+ attachmentPdfTemplateMissing: "template_attachment_pdf_template_missing",
65
+ previewRenderFailed: "template_preview_render_failed",
66
+ testMailNoChannel: "template_test_mail_no_channel",
67
+ testMailNoAddress: "template_test_mail_no_address",
68
+ testMailFailed: "template_test_mail_failed",
35
69
  };
@@ -0,0 +1,2 @@
1
+ import type { NotificationRecordMapping } from "@cosmicdrift/kumiko-framework/engine";
2
+ export declare function mapRecordToVariables(mapping: NotificationRecordMapping, row: Readonly<Record<string, unknown>>): Record<string, unknown>;