@openlup/platform 0.15.0 → 0.17.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 (531) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +633 -6
  3. package/dist/communications/accountingDocumentDelivery.d.ts +35 -0
  4. package/dist/communications/accountingDocumentDelivery.js +33 -0
  5. package/dist/communications/authEmailError.d.ts +5 -0
  6. package/dist/communications/authEmailError.js +8 -0
  7. package/dist/communications/authEmailPorts.d.ts +2 -0
  8. package/dist/communications/authEmailPorts.js +1 -0
  9. package/dist/communications/authSendEmailHook.d.ts +35 -0
  10. package/dist/communications/authSendEmailHook.js +250 -0
  11. package/dist/communications/capturedTransactionalDelivery.d.ts +13 -0
  12. package/dist/communications/capturedTransactionalDelivery.js +14 -0
  13. package/dist/communications/communicationSync.d.ts +11 -0
  14. package/dist/communications/communicationSync.js +79 -0
  15. package/dist/communications/communicationSyncWorker.d.ts +68 -0
  16. package/dist/communications/communicationSyncWorker.js +218 -0
  17. package/dist/communications/consentPolicy.d.ts +19 -0
  18. package/dist/communications/consentPolicy.js +43 -0
  19. package/dist/communications/consentPurposeRegistry.d.ts +4 -0
  20. package/dist/communications/consentPurposeRegistry.js +24 -0
  21. package/dist/communications/contracts/abandonedCart.d.ts +27 -0
  22. package/dist/communications/contracts/abandonedCart.js +25 -0
  23. package/dist/communications/contracts/authEmail.d.ts +62 -0
  24. package/dist/communications/contracts/authEmail.js +1 -0
  25. package/dist/communications/contracts/backInStock.d.ts +28 -0
  26. package/dist/communications/contracts/backInStock.js +28 -0
  27. package/dist/communications/contracts/blocks.d.ts +24 -0
  28. package/dist/communications/contracts/blocks.js +23 -0
  29. package/dist/communications/contracts/checkoutExpired.d.ts +22 -0
  30. package/dist/communications/contracts/checkoutExpired.js +25 -0
  31. package/dist/communications/contracts/checkoutRecovery.d.ts +26 -0
  32. package/dist/communications/contracts/checkoutRecovery.js +37 -0
  33. package/dist/communications/contracts/commerceEmailContent.d.ts +176 -0
  34. package/dist/communications/contracts/commerceEmailContent.js +1 -0
  35. package/dist/communications/contracts/commerceEngagementEmailContent.d.ts +95 -0
  36. package/dist/communications/contracts/commerceEngagementEmailContent.js +1 -0
  37. package/dist/communications/contracts/consent.d.ts +12 -0
  38. package/dist/communications/contracts/consent.js +1 -0
  39. package/dist/communications/contracts/email.d.ts +182 -0
  40. package/dist/communications/contracts/email.js +1 -0
  41. package/dist/communications/contracts/guideCard.d.ts +3 -0
  42. package/dist/communications/contracts/guideCard.js +26 -0
  43. package/dist/communications/contracts/index.d.ts +51 -0
  44. package/dist/communications/contracts/index.js +42 -0
  45. package/dist/communications/contracts/inquiryContent.d.ts +32 -0
  46. package/dist/communications/contracts/inquiryContent.js +33 -0
  47. package/dist/communications/contracts/invoiceDocumentContent.d.ts +26 -0
  48. package/dist/communications/contracts/invoiceDocumentContent.js +36 -0
  49. package/dist/communications/contracts/marketingAutomation.d.ts +52 -0
  50. package/dist/communications/contracts/marketingAutomation.js +1 -0
  51. package/dist/communications/contracts/newsletter.d.ts +63 -0
  52. package/dist/communications/contracts/newsletter.js +1 -0
  53. package/dist/communications/contracts/newsletterWebhook.d.ts +26 -0
  54. package/dist/communications/contracts/newsletterWebhook.js +1 -0
  55. package/dist/communications/contracts/optOutContent.d.ts +11 -0
  56. package/dist/communications/contracts/optOutContent.js +17 -0
  57. package/dist/communications/contracts/orderCanceled.d.ts +25 -0
  58. package/dist/communications/contracts/orderCanceled.js +27 -0
  59. package/dist/communications/contracts/orderDraft.d.ts +46 -0
  60. package/dist/communications/contracts/orderDraft.js +46 -0
  61. package/dist/communications/contracts/orderPaid.d.ts +53 -0
  62. package/dist/communications/contracts/orderPaid.js +71 -0
  63. package/dist/communications/contracts/orderRefunded.d.ts +24 -0
  64. package/dist/communications/contracts/orderRefunded.js +27 -0
  65. package/dist/communications/contracts/paymentFailed.d.ts +24 -0
  66. package/dist/communications/contracts/paymentFailed.js +24 -0
  67. package/dist/communications/contracts/publicIntake.d.ts +49 -0
  68. package/dist/communications/contracts/publicIntake.js +1 -0
  69. package/dist/communications/contracts/render.d.ts +2 -0
  70. package/dist/communications/contracts/render.js +229 -0
  71. package/dist/communications/contracts/reorderReminder.d.ts +24 -0
  72. package/dist/communications/contracts/reorderReminder.js +24 -0
  73. package/dist/communications/contracts/returnEmails.d.ts +25 -0
  74. package/dist/communications/contracts/returnEmails.js +62 -0
  75. package/dist/communications/contracts/reviewEffects.d.ts +26 -0
  76. package/dist/communications/contracts/reviewEffects.js +25 -0
  77. package/dist/communications/contracts/reviewRequest.d.ts +26 -0
  78. package/dist/communications/contracts/reviewRequest.js +24 -0
  79. package/dist/communications/contracts/roleNotificationContent.d.ts +25 -0
  80. package/dist/communications/contracts/roleNotificationContent.js +46 -0
  81. package/dist/communications/contracts/shipmentDelivered.d.ts +23 -0
  82. package/dist/communications/contracts/shipmentDelivered.js +24 -0
  83. package/dist/communications/contracts/shipmentDispatched.d.ts +27 -0
  84. package/dist/communications/contracts/shipmentDispatched.js +35 -0
  85. package/dist/communications/contracts/shipmentException.d.ts +21 -0
  86. package/dist/communications/contracts/shipmentException.js +26 -0
  87. package/dist/communications/contracts/subscriptionActivationActionRequired.d.ts +17 -0
  88. package/dist/communications/contracts/subscriptionActivationActionRequired.js +22 -0
  89. package/dist/communications/contracts/subscriptionAddressChanged.d.ts +19 -0
  90. package/dist/communications/contracts/subscriptionAddressChanged.js +25 -0
  91. package/dist/communications/contracts/subscriptionCancelled.d.ts +19 -0
  92. package/dist/communications/contracts/subscriptionCancelled.js +25 -0
  93. package/dist/communications/contracts/subscriptionCycleSkipped.d.ts +25 -0
  94. package/dist/communications/contracts/subscriptionCycleSkipped.js +40 -0
  95. package/dist/communications/contracts/subscriptionDeliveryRescheduled.d.ts +25 -0
  96. package/dist/communications/contracts/subscriptionDeliveryRescheduled.js +39 -0
  97. package/dist/communications/contracts/subscriptionEmailContent.d.ts +145 -0
  98. package/dist/communications/contracts/subscriptionEmailContent.js +1 -0
  99. package/dist/communications/contracts/subscriptionPackageChanged.d.ts +20 -0
  100. package/dist/communications/contracts/subscriptionPackageChanged.js +26 -0
  101. package/dist/communications/contracts/subscriptionPauseReminder.d.ts +23 -0
  102. package/dist/communications/contracts/subscriptionPauseReminder.js +29 -0
  103. package/dist/communications/contracts/subscriptionPaused.d.ts +21 -0
  104. package/dist/communications/contracts/subscriptionPaused.js +25 -0
  105. package/dist/communications/contracts/subscriptionPaymentExpired.d.ts +34 -0
  106. package/dist/communications/contracts/subscriptionPaymentExpired.js +37 -0
  107. package/dist/communications/contracts/subscriptionPaymentFailed.d.ts +49 -0
  108. package/dist/communications/contracts/subscriptionPaymentFailed.js +56 -0
  109. package/dist/communications/contracts/subscriptionPaymentRecovered.d.ts +19 -0
  110. package/dist/communications/contracts/subscriptionPaymentRecovered.js +22 -0
  111. package/dist/communications/contracts/subscriptionRenewalAtRisk.d.ts +36 -0
  112. package/dist/communications/contracts/subscriptionRenewalAtRisk.js +36 -0
  113. package/dist/communications/contracts/subscriptionRenewalUpcoming.d.ts +49 -0
  114. package/dist/communications/contracts/subscriptionRenewalUpcoming.js +43 -0
  115. package/dist/communications/contracts/subscriptionResumed.d.ts +23 -0
  116. package/dist/communications/contracts/subscriptionResumed.js +25 -0
  117. package/dist/communications/contracts/subscriptionWelcome.d.ts +44 -0
  118. package/dist/communications/contracts/subscriptionWelcome.js +45 -0
  119. package/dist/communications/contracts/subscriptionWinback.d.ts +21 -0
  120. package/dist/communications/contracts/subscriptionWinback.js +28 -0
  121. package/dist/communications/contracts/transactionalDelivery.d.ts +42 -0
  122. package/dist/communications/contracts/transactionalDelivery.js +1 -0
  123. package/dist/communications/contracts/types.d.ts +46 -0
  124. package/dist/communications/contracts/types.js +1 -0
  125. package/dist/communications/contribution.d.ts +10 -0
  126. package/dist/communications/contribution.js +24 -0
  127. package/dist/communications/deliveryReconciliation.d.ts +64 -0
  128. package/dist/communications/deliveryReconciliation.js +60 -0
  129. package/dist/communications/emailEgress.d.ts +38 -0
  130. package/dist/communications/emailEgress.js +100 -0
  131. package/dist/communications/emailHealthAssessment.d.ts +39 -0
  132. package/dist/communications/emailHealthAssessment.js +59 -0
  133. package/dist/communications/emailHealthMetricsPort.d.ts +17 -0
  134. package/dist/communications/emailHealthMetricsPort.js +1 -0
  135. package/dist/communications/emailNotificationControl.d.ts +27 -0
  136. package/dist/communications/emailNotificationControl.js +10 -0
  137. package/dist/communications/emailObservation.d.ts +28 -0
  138. package/dist/communications/emailObservation.js +23 -0
  139. package/dist/communications/emailTransport.d.ts +82 -0
  140. package/dist/communications/emailTransport.js +95 -0
  141. package/dist/communications/errors.d.ts +15 -0
  142. package/dist/communications/errors.js +30 -0
  143. package/dist/communications/index.d.ts +46 -0
  144. package/dist/communications/index.js +38 -0
  145. package/dist/communications/integrationEventSignature.d.ts +15 -0
  146. package/dist/communications/integrationEventSignature.js +37 -0
  147. package/dist/communications/managedTransactionalDeliveryStore.d.ts +12 -0
  148. package/dist/communications/managedTransactionalDeliveryStore.js +49 -0
  149. package/dist/communications/nativeOperations.d.ts +79 -0
  150. package/dist/communications/nativeOperations.js +3 -0
  151. package/dist/communications/newsletterIntegrationContracts.d.ts +130 -0
  152. package/dist/communications/newsletterIntegrationContracts.js +128 -0
  153. package/dist/communications/newsletterWebhookPort.d.ts +11 -0
  154. package/dist/communications/newsletterWebhookPort.js +84 -0
  155. package/dist/communications/newsletterWebhookProcessing.d.ts +17 -0
  156. package/dist/communications/newsletterWebhookProcessing.js +71 -0
  157. package/dist/communications/originPolicy.d.ts +40 -0
  158. package/dist/communications/originPolicy.js +100 -0
  159. package/dist/communications/postgresCommunicationSync.d.ts +79 -0
  160. package/dist/communications/postgresCommunicationSync.js +111 -0
  161. package/dist/communications/postgresConsentEvaluator.d.ts +19 -0
  162. package/dist/communications/postgresConsentEvaluator.js +43 -0
  163. package/dist/communications/postgresDeliveryReconciliation.d.ts +3 -0
  164. package/dist/communications/postgresDeliveryReconciliation.js +113 -0
  165. package/dist/communications/postgresNativeOperations.d.ts +13 -0
  166. package/dist/communications/postgresNativeOperations.js +63 -0
  167. package/dist/communications/postgresNotificationRecipients.d.ts +37 -0
  168. package/dist/communications/postgresNotificationRecipients.js +60 -0
  169. package/dist/communications/postgresTransactionalDeliveryStore.d.ts +7 -0
  170. package/dist/communications/postgresTransactionalDeliveryStore.js +55 -0
  171. package/dist/communications/preferencesToken.d.ts +10 -0
  172. package/dist/communications/preferencesToken.js +40 -0
  173. package/dist/communications/publicPreferenceToken.d.ts +24 -0
  174. package/dist/communications/publicPreferenceToken.js +53 -0
  175. package/dist/communications/shipmentNotifications.d.ts +34 -0
  176. package/dist/communications/shipmentNotifications.js +61 -0
  177. package/dist/communications/sql.d.ts +26 -0
  178. package/dist/communications/sql.js +7 -0
  179. package/dist/communications/standardWebhooks.d.ts +14 -0
  180. package/dist/communications/standardWebhooks.js +73 -0
  181. package/dist/communications/status.d.ts +11 -0
  182. package/dist/communications/status.js +36 -0
  183. package/dist/communications/transactionalDelivery.d.ts +19 -0
  184. package/dist/communications/transactionalDelivery.js +96 -0
  185. package/dist/communications/transactionalDeliveryIdentifier.d.ts +3 -0
  186. package/dist/communications/transactionalDeliveryIdentifier.js +6 -0
  187. package/dist/communications/unsubscribeToken.d.ts +77 -0
  188. package/dist/communications/unsubscribeToken.js +150 -0
  189. package/dist/communications/validation.d.ts +2 -0
  190. package/dist/communications/validation.js +3 -0
  191. package/dist/http/index.d.ts +1 -0
  192. package/dist/http/index.js +1 -0
  193. package/dist/http/webhookSignature.d.ts +42 -0
  194. package/dist/http/webhookSignature.js +86 -0
  195. package/dist/identity/adminAuthBinding.d.ts +28 -0
  196. package/dist/identity/adminAuthBinding.js +66 -0
  197. package/dist/identity/adminAuthorization.d.ts +34 -0
  198. package/dist/identity/adminAuthorization.js +72 -0
  199. package/dist/identity/adminContracts.d.ts +70 -0
  200. package/dist/identity/adminContracts.js +43 -0
  201. package/dist/identity/adminMagicLinkHandler.d.ts +39 -0
  202. package/dist/identity/adminMagicLinkHandler.js +94 -0
  203. package/dist/identity/adminMeHandler.d.ts +15 -0
  204. package/dist/identity/adminMeHandler.js +49 -0
  205. package/dist/identity/adminPreflight.d.ts +16 -0
  206. package/dist/identity/adminPreflight.js +38 -0
  207. package/dist/identity/adminUserActionPorts.d.ts +31 -0
  208. package/dist/identity/adminUserActionPorts.js +51 -0
  209. package/dist/identity/adminUserHandlers.d.ts +38 -0
  210. package/dist/identity/adminUserHandlers.js +140 -0
  211. package/dist/identity/authVerifyUrl.d.ts +6 -0
  212. package/dist/identity/authVerifyUrl.js +54 -0
  213. package/dist/identity/contracts/contracts.d.ts +8 -0
  214. package/dist/identity/contracts/contracts.js +2 -0
  215. package/dist/identity/contracts/emailTrust.d.ts +3 -0
  216. package/dist/identity/contracts/emailTrust.js +4 -0
  217. package/dist/identity/contracts/index.d.ts +8 -0
  218. package/dist/identity/contracts/index.js +8 -0
  219. package/dist/identity/contracts/oidc.d.ts +3 -0
  220. package/dist/identity/contracts/oidc.js +9 -0
  221. package/dist/identity/contracts/operatorAuth.d.ts +35 -0
  222. package/dist/identity/contracts/operatorAuth.js +53 -0
  223. package/dist/identity/contracts/operatorInvitations.d.ts +37 -0
  224. package/dist/identity/contracts/operatorInvitations.js +1 -0
  225. package/dist/identity/contracts/ports.d.ts +22 -0
  226. package/dist/identity/contracts/ports.js +1 -0
  227. package/dist/identity/contracts/privacy.d.ts +62 -0
  228. package/dist/identity/contracts/privacy.js +99 -0
  229. package/dist/identity/contracts/providerList.d.ts +3 -0
  230. package/dist/identity/contracts/providerList.js +11 -0
  231. package/dist/identity/contracts/types.d.ts +16 -0
  232. package/dist/identity/contracts/types.js +4 -0
  233. package/dist/identity/contribution.d.ts +8 -0
  234. package/dist/identity/contribution.js +22 -0
  235. package/dist/identity/customerAuth.d.ts +8 -0
  236. package/dist/identity/customerAuth.js +1 -0
  237. package/dist/identity/customerAuthorization.d.ts +5 -0
  238. package/dist/identity/customerAuthorization.js +22 -0
  239. package/dist/identity/customerContracts.d.ts +42 -0
  240. package/dist/identity/customerContracts.js +43 -0
  241. package/dist/identity/customerIdentityBinding.d.ts +44 -0
  242. package/dist/identity/customerIdentityBinding.js +60 -0
  243. package/dist/identity/customerIdentityVerifier.d.ts +8 -0
  244. package/dist/identity/customerIdentityVerifier.js +101 -0
  245. package/dist/identity/customerMagicLinkHandler.d.ts +38 -0
  246. package/dist/identity/customerMagicLinkHandler.js +115 -0
  247. package/dist/identity/customerMeHandler.d.ts +11 -0
  248. package/dist/identity/customerMeHandler.js +46 -0
  249. package/dist/identity/customerPorts.d.ts +4 -0
  250. package/dist/identity/customerPorts.js +1 -0
  251. package/dist/identity/customerSessionBinding.d.ts +38 -0
  252. package/dist/identity/customerSessionBinding.js +80 -0
  253. package/dist/identity/customerSessionIssuer.d.ts +10 -0
  254. package/dist/identity/customerSessionIssuer.js +57 -0
  255. package/dist/identity/customerVerifyOtpHandler.d.ts +8 -0
  256. package/dist/identity/customerVerifyOtpHandler.js +41 -0
  257. package/dist/identity/directOperatorInvitationStore.d.ts +19 -0
  258. package/dist/identity/directOperatorInvitationStore.js +193 -0
  259. package/dist/identity/emailTrustPolicy.d.ts +14 -0
  260. package/dist/identity/emailTrustPolicy.js +16 -0
  261. package/dist/identity/identityPersonalDataContributor.d.ts +7 -0
  262. package/dist/identity/identityPersonalDataContributor.js +46 -0
  263. package/dist/identity/identityReadiness.d.ts +10 -0
  264. package/dist/identity/identityReadiness.js +25 -0
  265. package/dist/identity/index.d.ts +67 -0
  266. package/dist/identity/index.js +66 -0
  267. package/dist/identity/inviteAdminUserUseCase.d.ts +89 -0
  268. package/dist/identity/inviteAdminUserUseCase.js +75 -0
  269. package/dist/identity/jwtLibrary.d.ts +54 -0
  270. package/dist/identity/jwtLibrary.js +1 -0
  271. package/dist/identity/machineActorWriteFence.d.ts +4 -0
  272. package/dist/identity/machineActorWriteFence.js +13 -0
  273. package/dist/identity/magicLinkPorts.d.ts +28 -0
  274. package/dist/identity/magicLinkPorts.js +1 -0
  275. package/dist/identity/managedAccountLinkStore.d.ts +2 -0
  276. package/dist/identity/managedAccountLinkStore.js +93 -0
  277. package/dist/identity/managedAdminAuthVerifier.d.ts +7 -0
  278. package/dist/identity/managedAdminAuthVerifier.js +27 -0
  279. package/dist/identity/managedAdminUserGateways.d.ts +123 -0
  280. package/dist/identity/managedAdminUserGateways.js +127 -0
  281. package/dist/identity/managedClient.d.ts +90 -0
  282. package/dist/identity/managedClient.js +10 -0
  283. package/dist/identity/managedClientAuthLink.d.ts +3 -0
  284. package/dist/identity/managedClientAuthLink.js +115 -0
  285. package/dist/identity/managedCustomerMe.d.ts +13 -0
  286. package/dist/identity/managedCustomerMe.js +30 -0
  287. package/dist/identity/managedEmailTrustPolicy.d.ts +11 -0
  288. package/dist/identity/managedEmailTrustPolicy.js +105 -0
  289. package/dist/identity/managedIdentityVerifier.d.ts +2 -0
  290. package/dist/identity/managedIdentityVerifier.js +16 -0
  291. package/dist/identity/managedPrivacy.d.ts +4 -0
  292. package/dist/identity/managedPrivacy.js +39 -0
  293. package/dist/identity/messages.d.ts +29 -0
  294. package/dist/identity/messages.js +39 -0
  295. package/dist/identity/oidcIdentityVerifier.d.ts +45 -0
  296. package/dist/identity/oidcIdentityVerifier.js +309 -0
  297. package/dist/identity/oidcPrincipal.d.ts +2 -0
  298. package/dist/identity/oidcPrincipal.js +10 -0
  299. package/dist/identity/operatorAdminAuth.d.ts +6 -0
  300. package/dist/identity/operatorAdminAuth.js +13 -0
  301. package/dist/identity/operatorAuthHandlers.d.ts +18 -0
  302. package/dist/identity/operatorAuthHandlers.js +71 -0
  303. package/dist/identity/operatorIdentityVerifier.d.ts +8 -0
  304. package/dist/identity/operatorIdentityVerifier.js +19 -0
  305. package/dist/identity/operatorInvitationLifecycle.d.ts +7 -0
  306. package/dist/identity/operatorInvitationLifecycle.js +15 -0
  307. package/dist/identity/operatorInvitationPorts.d.ts +31 -0
  308. package/dist/identity/operatorInvitationPorts.js +1 -0
  309. package/dist/identity/operatorPorts.d.ts +37 -0
  310. package/dist/identity/operatorPorts.js +1 -0
  311. package/dist/identity/operatorSession.d.ts +13 -0
  312. package/dist/identity/operatorSession.js +31 -0
  313. package/dist/identity/operatorTokenAdminAuth.d.ts +15 -0
  314. package/dist/identity/operatorTokenAdminAuth.js +50 -0
  315. package/dist/identity/personalDataRegistry.d.ts +4 -0
  316. package/dist/identity/personalDataRegistry.js +11 -0
  317. package/dist/identity/platformAdminAuth.d.ts +15 -0
  318. package/dist/identity/platformAdminAuth.js +1 -0
  319. package/dist/identity/ports.d.ts +127 -0
  320. package/dist/identity/ports.js +38 -0
  321. package/dist/identity/postgresAccountLinkStore.d.ts +7 -0
  322. package/dist/identity/postgresAccountLinkStore.js +52 -0
  323. package/dist/identity/postgresCustomerMe.d.ts +3 -0
  324. package/dist/identity/postgresCustomerMe.js +21 -0
  325. package/dist/identity/postgresCustomerRecovery.d.ts +11 -0
  326. package/dist/identity/postgresCustomerRecovery.js +57 -0
  327. package/dist/identity/postgresOperatorIdentity.d.ts +5 -0
  328. package/dist/identity/postgresOperatorIdentity.js +137 -0
  329. package/dist/identity/postgresPrivacy.d.ts +7 -0
  330. package/dist/identity/postgresPrivacy.js +126 -0
  331. package/dist/identity/privacyHandlers.d.ts +10 -0
  332. package/dist/identity/privacyHandlers.js +35 -0
  333. package/dist/identity/privacyPorts.d.ts +72 -0
  334. package/dist/identity/privacyPorts.js +8 -0
  335. package/dist/identity/privacyUseCases.d.ts +5 -0
  336. package/dist/identity/privacyUseCases.js +55 -0
  337. package/dist/identity/reconcileAccountForPrincipal.d.ts +20 -0
  338. package/dist/identity/reconcileAccountForPrincipal.js +66 -0
  339. package/dist/identity/reconcileAccountHandler.d.ts +11 -0
  340. package/dist/identity/reconcileAccountHandler.js +30 -0
  341. package/dist/identity/removeAdminUserUseCase.d.ts +31 -0
  342. package/dist/identity/removeAdminUserUseCase.js +60 -0
  343. package/dist/identity/response.d.ts +3 -0
  344. package/dist/identity/response.js +2 -0
  345. package/dist/identity/sql.d.ts +44 -0
  346. package/dist/identity/sql.js +10 -0
  347. package/package.json +22 -2
  348. package/release-gates.json +63 -8
  349. package/sql/20260807190000_comms_outbox_rail.sql +329 -0
  350. package/sql/20260810120001_transactional_delivery_receipts.sql +209 -0
  351. package/sql/20260810180001_self_host_actor_auth.sql +40 -0
  352. package/sql/20260810204057_customer_identity_read.sql +31 -0
  353. package/sql/20260813120000_communications_control_plane.sql +568 -0
  354. package/sql/20260814090000_customer_selfservice_recovery.sql +477 -0
  355. package/sql/20260901143000_admin_membership_authority_foundation.sql +234 -0
  356. package/sql/20261018120000_identity_operator_invitations.sql +42 -0
  357. package/sql/20261018180000_identity_operator_challenges.sql +56 -0
  358. package/sql/20261018190000_identity_privacy_erasures.sql +15 -0
  359. package/sql/20261019200000_communications_native_operations.sql +68 -0
  360. package/src/communications/accountingDocumentDelivery.ts +63 -0
  361. package/src/communications/authEmailError.ts +10 -0
  362. package/src/communications/authEmailPorts.ts +2 -0
  363. package/src/communications/authSendEmailHook.ts +310 -0
  364. package/src/communications/capturedTransactionalDelivery.ts +29 -0
  365. package/src/communications/communicationSync.ts +96 -0
  366. package/src/communications/communicationSyncWorker.ts +302 -0
  367. package/src/communications/consentPolicy.ts +82 -0
  368. package/src/communications/consentPurposeRegistry.ts +31 -0
  369. package/src/communications/contracts/abandonedCart.ts +64 -0
  370. package/src/communications/contracts/authEmail.ts +73 -0
  371. package/src/communications/contracts/backInStock.ts +69 -0
  372. package/src/communications/contracts/blocks.ts +47 -0
  373. package/src/communications/contracts/checkoutExpired.ts +62 -0
  374. package/src/communications/contracts/checkoutRecovery.ts +68 -0
  375. package/src/communications/contracts/commerceEmailContent.ts +189 -0
  376. package/src/communications/contracts/commerceEngagementEmailContent.ts +106 -0
  377. package/src/communications/contracts/consent.ts +13 -0
  378. package/src/communications/contracts/email.ts +210 -0
  379. package/src/communications/contracts/guideCard.ts +34 -0
  380. package/src/communications/contracts/index.ts +51 -0
  381. package/src/communications/contracts/inquiryContent.ts +53 -0
  382. package/src/communications/contracts/invoiceDocumentContent.ts +57 -0
  383. package/src/communications/contracts/marketingAutomation.ts +45 -0
  384. package/src/communications/contracts/newsletter.ts +78 -0
  385. package/src/communications/contracts/newsletterWebhook.ts +23 -0
  386. package/src/communications/contracts/optOutContent.ts +23 -0
  387. package/src/communications/contracts/orderCanceled.ts +64 -0
  388. package/src/communications/contracts/orderDraft.ts +112 -0
  389. package/src/communications/contracts/orderPaid.ts +147 -0
  390. package/src/communications/contracts/orderRefunded.ts +63 -0
  391. package/src/communications/contracts/paymentFailed.ts +59 -0
  392. package/src/communications/contracts/publicIntake.ts +53 -0
  393. package/src/communications/contracts/render.ts +271 -0
  394. package/src/communications/contracts/reorderReminder.ts +59 -0
  395. package/src/communications/contracts/returnEmails.ts +113 -0
  396. package/src/communications/contracts/reviewEffects.ts +60 -0
  397. package/src/communications/contracts/reviewRequest.ts +59 -0
  398. package/src/communications/contracts/roleNotificationContent.ts +65 -0
  399. package/src/communications/contracts/shipmentDelivered.ts +59 -0
  400. package/src/communications/contracts/shipmentDispatched.ts +77 -0
  401. package/src/communications/contracts/shipmentException.ts +62 -0
  402. package/src/communications/contracts/subscriptionActivationActionRequired.ts +37 -0
  403. package/src/communications/contracts/subscriptionAddressChanged.ts +56 -0
  404. package/src/communications/contracts/subscriptionCancelled.ts +57 -0
  405. package/src/communications/contracts/subscriptionCycleSkipped.ts +80 -0
  406. package/src/communications/contracts/subscriptionDeliveryRescheduled.ts +79 -0
  407. package/src/communications/contracts/subscriptionEmailContent.ts +163 -0
  408. package/src/communications/contracts/subscriptionPackageChanged.ts +59 -0
  409. package/src/communications/contracts/subscriptionPauseReminder.ts +63 -0
  410. package/src/communications/contracts/subscriptionPaused.ts +58 -0
  411. package/src/communications/contracts/subscriptionPaymentExpired.ts +83 -0
  412. package/src/communications/contracts/subscriptionPaymentFailed.ts +117 -0
  413. package/src/communications/contracts/subscriptionPaymentRecovered.ts +50 -0
  414. package/src/communications/contracts/subscriptionRenewalAtRisk.ts +85 -0
  415. package/src/communications/contracts/subscriptionRenewalUpcoming.ts +103 -0
  416. package/src/communications/contracts/subscriptionResumed.ts +60 -0
  417. package/src/communications/contracts/subscriptionWelcome.ts +102 -0
  418. package/src/communications/contracts/subscriptionWinback.ts +62 -0
  419. package/src/communications/contracts/transactionalDelivery.ts +43 -0
  420. package/src/communications/contracts/types.ts +58 -0
  421. package/src/communications/contribution.ts +33 -0
  422. package/src/communications/deliveryReconciliation.ts +108 -0
  423. package/src/communications/emailEgress.ts +111 -0
  424. package/src/communications/emailHealthAssessment.ts +106 -0
  425. package/src/communications/emailHealthMetricsPort.ts +17 -0
  426. package/src/communications/emailNotificationControl.ts +28 -0
  427. package/src/communications/emailObservation.ts +43 -0
  428. package/src/communications/emailTransport.ts +167 -0
  429. package/src/communications/errors.ts +34 -0
  430. package/src/communications/index.ts +46 -0
  431. package/src/communications/integrationEventSignature.ts +49 -0
  432. package/src/communications/managedTransactionalDeliveryStore.ts +59 -0
  433. package/src/communications/nativeOperations.ts +40 -0
  434. package/src/communications/newsletterIntegrationContracts.ts +154 -0
  435. package/src/communications/newsletterWebhookPort.ts +104 -0
  436. package/src/communications/newsletterWebhookProcessing.ts +102 -0
  437. package/src/communications/originPolicy.ts +151 -0
  438. package/src/communications/postgresCommunicationSync.ts +127 -0
  439. package/src/communications/postgresConsentEvaluator.ts +49 -0
  440. package/src/communications/postgresDeliveryReconciliation.ts +101 -0
  441. package/src/communications/postgresNativeOperations.ts +55 -0
  442. package/src/communications/postgresNotificationRecipients.ts +57 -0
  443. package/src/communications/postgresTransactionalDeliveryStore.ts +79 -0
  444. package/src/communications/preferencesToken.ts +62 -0
  445. package/src/communications/publicPreferenceToken.ts +68 -0
  446. package/src/communications/shipmentNotifications.ts +78 -0
  447. package/src/communications/sql.ts +7 -0
  448. package/src/communications/standardWebhooks.ts +84 -0
  449. package/src/communications/status.ts +51 -0
  450. package/src/communications/transactionalDelivery.ts +114 -0
  451. package/src/communications/transactionalDeliveryIdentifier.ts +9 -0
  452. package/src/communications/unsubscribeToken.ts +186 -0
  453. package/src/communications/validation.ts +3 -0
  454. package/src/http/index.ts +1 -0
  455. package/src/http/webhookSignature.ts +96 -0
  456. package/src/identity/adminAuthBinding.ts +76 -0
  457. package/src/identity/adminAuthorization.ts +106 -0
  458. package/src/identity/adminContracts.ts +52 -0
  459. package/src/identity/adminMagicLinkHandler.ts +132 -0
  460. package/src/identity/adminMeHandler.ts +64 -0
  461. package/src/identity/adminPreflight.ts +46 -0
  462. package/src/identity/adminUserActionPorts.ts +78 -0
  463. package/src/identity/adminUserHandlers.ts +174 -0
  464. package/src/identity/authVerifyUrl.ts +56 -0
  465. package/src/identity/contracts/contracts.ts +15 -0
  466. package/src/identity/contracts/emailTrust.ts +5 -0
  467. package/src/identity/contracts/index.ts +8 -0
  468. package/src/identity/contracts/oidc.ts +10 -0
  469. package/src/identity/contracts/operatorAuth.ts +61 -0
  470. package/src/identity/contracts/operatorInvitations.ts +32 -0
  471. package/src/identity/contracts/ports.ts +25 -0
  472. package/src/identity/contracts/privacy.ts +86 -0
  473. package/src/identity/contracts/providerList.ts +13 -0
  474. package/src/identity/contracts/types.ts +25 -0
  475. package/src/identity/contribution.ts +29 -0
  476. package/src/identity/customerAuth.ts +3 -0
  477. package/src/identity/customerAuthorization.ts +38 -0
  478. package/src/identity/customerContracts.ts +52 -0
  479. package/src/identity/customerIdentityBinding.ts +125 -0
  480. package/src/identity/customerIdentityVerifier.ts +141 -0
  481. package/src/identity/customerMagicLinkHandler.ts +171 -0
  482. package/src/identity/customerMeHandler.ts +64 -0
  483. package/src/identity/customerPorts.ts +2 -0
  484. package/src/identity/customerSessionBinding.ts +114 -0
  485. package/src/identity/customerSessionIssuer.ts +71 -0
  486. package/src/identity/customerVerifyOtpHandler.ts +44 -0
  487. package/src/identity/directOperatorInvitationStore.ts +178 -0
  488. package/src/identity/emailTrustPolicy.ts +16 -0
  489. package/src/identity/identityPersonalDataContributor.ts +48 -0
  490. package/src/identity/identityReadiness.ts +26 -0
  491. package/src/identity/index.ts +69 -0
  492. package/src/identity/inviteAdminUserUseCase.ts +134 -0
  493. package/src/identity/jwtLibrary.ts +24 -0
  494. package/src/identity/machineActorWriteFence.ts +19 -0
  495. package/src/identity/magicLinkPorts.ts +7 -0
  496. package/src/identity/managedAccountLinkStore.ts +105 -0
  497. package/src/identity/managedAdminAuthVerifier.ts +40 -0
  498. package/src/identity/managedAdminUserGateways.ts +164 -0
  499. package/src/identity/managedClient.ts +58 -0
  500. package/src/identity/managedClientAuthLink.ts +120 -0
  501. package/src/identity/managedCustomerMe.ts +52 -0
  502. package/src/identity/managedEmailTrustPolicy.ts +90 -0
  503. package/src/identity/managedIdentityVerifier.ts +20 -0
  504. package/src/identity/managedPrivacy.ts +37 -0
  505. package/src/identity/messages.ts +41 -0
  506. package/src/identity/oidcIdentityVerifier.ts +229 -0
  507. package/src/identity/oidcPrincipal.ts +10 -0
  508. package/src/identity/operatorAdminAuth.ts +14 -0
  509. package/src/identity/operatorAuthHandlers.ts +52 -0
  510. package/src/identity/operatorIdentityVerifier.ts +19 -0
  511. package/src/identity/operatorInvitationLifecycle.ts +14 -0
  512. package/src/identity/operatorInvitationPorts.ts +11 -0
  513. package/src/identity/operatorPorts.ts +11 -0
  514. package/src/identity/operatorSession.ts +30 -0
  515. package/src/identity/operatorTokenAdminAuth.ts +79 -0
  516. package/src/identity/personalDataRegistry.ts +8 -0
  517. package/src/identity/platformAdminAuth.ts +7 -0
  518. package/src/identity/ports.ts +158 -0
  519. package/src/identity/postgresAccountLinkStore.ts +49 -0
  520. package/src/identity/postgresCustomerMe.ts +33 -0
  521. package/src/identity/postgresCustomerRecovery.ts +72 -0
  522. package/src/identity/postgresOperatorIdentity.ts +123 -0
  523. package/src/identity/postgresPrivacy.ts +117 -0
  524. package/src/identity/privacyHandlers.ts +33 -0
  525. package/src/identity/privacyPorts.ts +52 -0
  526. package/src/identity/privacyUseCases.ts +48 -0
  527. package/src/identity/reconcileAccountForPrincipal.ts +99 -0
  528. package/src/identity/reconcileAccountHandler.ts +36 -0
  529. package/src/identity/removeAdminUserUseCase.ts +85 -0
  530. package/src/identity/response.ts +3 -0
  531. package/src/identity/sql.ts +10 -0
@@ -0,0 +1,163 @@
1
+ import type { Locale } from "./email.js";
2
+
3
+ type Localized<T> = Readonly<Record<Locale, T>>;
4
+
5
+ export interface SubscriptionBaseCopy {
6
+ subject: string;
7
+ preheader: string;
8
+ heading: string;
9
+ greeting: (firstName: string | null) => string;
10
+ }
11
+
12
+ export interface SubscriptionActionCopy extends SubscriptionBaseCopy {
13
+ intro: string;
14
+ reassurance: string[];
15
+ cta: string;
16
+ outro: string;
17
+ }
18
+
19
+ export interface SubscriptionActivationCopy extends SubscriptionBaseCopy {
20
+ intro: string;
21
+ facts: string[];
22
+ cta: string;
23
+ outro: string;
24
+ }
25
+
26
+ export interface SubscriptionScheduleCopy extends SubscriptionBaseCopy {
27
+ subjectWithoutDates: string;
28
+ intro: string;
29
+ introWithoutDates: string;
30
+ deliveryLabel: string;
31
+ chargeLabel: string;
32
+ dateLine: (window: string, chargeDate: string) => string;
33
+ reassurance: string[];
34
+ cta: string;
35
+ outro: string;
36
+ }
37
+
38
+ export interface SubscriptionPackageChangedCopy extends SubscriptionBaseCopy {
39
+ intro: (actionLabel: string | null) => string;
40
+ reassurance: string[];
41
+ actionLabels: Readonly<Record<string, string>>;
42
+ cta: string;
43
+ outro: string;
44
+ }
45
+
46
+ export interface SubscriptionPauseReminderCopy extends SubscriptionBaseCopy {
47
+ intro: (brandName: string) => string;
48
+ resume: (resumeDate: string) => string;
49
+ reassurance: string[];
50
+ cta: string;
51
+ outro: string;
52
+ }
53
+
54
+ export interface SubscriptionPausedCopy extends SubscriptionBaseCopy {
55
+ intro: string;
56
+ reassurance: (brandName: string) => string[];
57
+ cta: string;
58
+ outro: string;
59
+ }
60
+
61
+ export interface SubscriptionRenewalUpcomingCopy extends SubscriptionBaseCopy {
62
+ intro: (contextName: string | null) => string;
63
+ dateLine: (label: string) => string;
64
+ deliveryLine: (window: string) => string;
65
+ editCutoffLine: (label: string) => string;
66
+ noDateLine: string;
67
+ amountLine: (label: string) => string;
68
+ starterGraduationLine: (units: number, cadenceDays: number, detail?: string | null) => string;
69
+ detailsLabel: string;
70
+ manageLine: string;
71
+ cta: string;
72
+ }
73
+
74
+ export interface SubscriptionResumedCopy extends SubscriptionBaseCopy {
75
+ intro: (contextName: string | null) => string;
76
+ reassurance: (brandName: string) => string[];
77
+ cta: string;
78
+ outro: string;
79
+ }
80
+
81
+ export interface SubscriptionWelcomeCopy extends SubscriptionBaseCopy {
82
+ intro: string;
83
+ cadenceLine: (days: number) => string;
84
+ deliveryLine: (window: string, chargeDate: string) => string;
85
+ editCutoffLine: (label: string) => string;
86
+ fallbackLine: string;
87
+ starterDelivery2Line: (amount: string) => string;
88
+ starterSteadyLine: (units: number, cadenceDays: number, detail?: string | null) => string;
89
+ detailsLabel: string;
90
+ manageLine: string;
91
+ cta: string;
92
+ outro: string;
93
+ }
94
+
95
+ export interface SubscriptionWinbackCopy extends SubscriptionBaseCopy {
96
+ intro: string;
97
+ reasonsLabel?: (brandName: string) => string;
98
+ reasons: string[];
99
+ cta: string;
100
+ outro: string;
101
+ }
102
+
103
+ export interface SubscriptionPaymentExpiredCopy extends SubscriptionBaseCopy {
104
+ preheaderWithCta: string;
105
+ intro: string;
106
+ detail: (amountLabel: string | null) => string[];
107
+ ctaDetail: string;
108
+ cta: string;
109
+ outro: string;
110
+ }
111
+
112
+ export interface SubscriptionPaymentFailedCopy extends SubscriptionBaseCopy {
113
+ intro: string;
114
+ amountLine: (amountLabel: string) => string;
115
+ noAmountLine: string;
116
+ noAmountLineNoRetry: string;
117
+ methodLine: (scheme: string, lastDigits: string) => string;
118
+ reassurance: (attempt: number, dateLabel: string | null) => string;
119
+ noRetryAction: string;
120
+ cta: string;
121
+ outro: string;
122
+ }
123
+
124
+ export interface SubscriptionPaymentRecoveredCopy extends SubscriptionBaseCopy {
125
+ intro: string;
126
+ detail: (amountLabel: string | null) => string[];
127
+ outro: string;
128
+ }
129
+
130
+ export interface SubscriptionRenewalAtRiskCopy extends SubscriptionBaseCopy {
131
+ intro: (renewalDateLabel: string | null) => string;
132
+ consequence: string;
133
+ cta: string;
134
+ outro: string;
135
+ }
136
+
137
+ export interface SubscriptionLifecycleEmailContent {
138
+ activationActionRequired: Localized<SubscriptionActivationCopy>;
139
+ addressChanged: Localized<SubscriptionActionCopy>;
140
+ cancelled: Localized<SubscriptionActionCopy>;
141
+ cycleSkipped: Localized<SubscriptionScheduleCopy & { manageLine: string }>;
142
+ deliveryRescheduled: Localized<SubscriptionScheduleCopy>;
143
+ packageChanged: Localized<SubscriptionPackageChangedCopy>;
144
+ pauseReminder: Localized<SubscriptionPauseReminderCopy>;
145
+ paused: Localized<SubscriptionPausedCopy>;
146
+ renewalUpcoming: Localized<SubscriptionRenewalUpcomingCopy>;
147
+ resumed: Localized<SubscriptionResumedCopy>;
148
+ welcome: Localized<SubscriptionWelcomeCopy>;
149
+ winback: Localized<SubscriptionWinbackCopy>;
150
+ }
151
+
152
+ export interface SubscriptionDunningEmailContent {
153
+ paymentExpired: Localized<SubscriptionPaymentExpiredCopy>;
154
+ paymentFailed: Localized<SubscriptionPaymentFailedCopy>;
155
+ paymentRecovered: Localized<SubscriptionPaymentRecoveredCopy>;
156
+ renewalAtRisk: Localized<SubscriptionRenewalAtRiskCopy>;
157
+ }
158
+
159
+ export interface SubscriptionEmailContent
160
+ extends SubscriptionLifecycleEmailContent,
161
+ SubscriptionDunningEmailContent {
162
+ id: "example" | "deployment-overlay";
163
+ }
@@ -0,0 +1,59 @@
1
+ import type { SubscriptionEmailContent } from "./subscriptionEmailContent.js";
2
+ import type { Locale } from "./email.js";
3
+ import type { SubscriptionPackageChangedCopy } from "./subscriptionEmailContent.js";
4
+ import {
5
+ accentBox,
6
+ button,
7
+ heading,
8
+ paragraph,
9
+ type EmailBlock,
10
+ } from "./blocks.js";
11
+
12
+ export interface SubscriptionPackageChangedEmailVars {
13
+ firstName: string | null;
14
+ action?: string | null;
15
+ /** Absolute CTA URL (manage subscription); null/absent → no button. */
16
+ ctaUrl?: string | null;
17
+ }
18
+
19
+ export interface SubscriptionPackageChangedEmailContent {
20
+ subject: string;
21
+ preheader: string;
22
+ blocks: EmailBlock[];
23
+ }
24
+
25
+ /** Bind host-selected copy and pure helpers without provider or environment access. */
26
+ export function createSubscriptionPackageChangedContentFactory(input: {
27
+ subscriptionEmailContent: Pick<SubscriptionEmailContent, "packageChanged">;
28
+ }) {
29
+ const { subscriptionEmailContent } = input;
30
+
31
+ function subscriptionPackageChangedEmailContent(
32
+ locale: Locale,
33
+ vars: SubscriptionPackageChangedEmailVars,
34
+ signoff: string,
35
+ ): SubscriptionPackageChangedEmailContent {
36
+ const copy: SubscriptionPackageChangedCopy = subscriptionEmailContent.packageChanged[locale];
37
+ const actionLabel = vars.action ? copy.actionLabels[vars.action] ?? null : null;
38
+ const blocks: EmailBlock[] = [
39
+ heading(copy.heading),
40
+ paragraph(copy.greeting(vars.firstName)),
41
+ paragraph(copy.intro(actionLabel)),
42
+ accentBox(copy.reassurance),
43
+ ];
44
+
45
+ if (vars.ctaUrl) {
46
+ blocks.push(button(copy.cta, vars.ctaUrl));
47
+ }
48
+
49
+ blocks.push(paragraph(copy.outro));
50
+ blocks.push(paragraph(signoff));
51
+
52
+ return {
53
+ subject: copy.subject,
54
+ preheader: copy.preheader,
55
+ blocks,
56
+ };
57
+ }
58
+ return { subscriptionPackageChangedEmailContent };
59
+ }
@@ -0,0 +1,63 @@
1
+ import type { SubscriptionEmailContent } from "./subscriptionEmailContent.js";
2
+ import type { Locale } from "./email.js";
3
+ import {
4
+ accentBox,
5
+ button,
6
+ heading,
7
+ paragraph,
8
+ type EmailBlock,
9
+ } from "./blocks.js";
10
+
11
+ export interface SubscriptionPauseReminderEmailVars {
12
+ firstName: string | null;
13
+ /** Consumer-facing brand label injected by the app/composition root. */
14
+ brandName: string;
15
+ /** Pre-formatted resume date, or null when unknown. */
16
+ resumeDateLabel: string | null;
17
+ /** Absolute CTA URL to manage the subscription. */
18
+ ctaUrl: string;
19
+ }
20
+
21
+ export interface SubscriptionPauseReminderEmailContent {
22
+ subject: string;
23
+ preheader: string;
24
+ blocks: EmailBlock[];
25
+ }
26
+
27
+ /** Bind host-selected copy and pure helpers without provider or environment access. */
28
+ export function createSubscriptionPauseReminderContentFactory(input: {
29
+ subscriptionEmailContent: Pick<SubscriptionEmailContent, "pauseReminder">;
30
+ }) {
31
+ const { subscriptionEmailContent } = input;
32
+
33
+ function subscriptionPauseReminderEmailContent(
34
+ locale: Locale,
35
+ vars: SubscriptionPauseReminderEmailVars,
36
+ signoff: string,
37
+ ): SubscriptionPauseReminderEmailContent {
38
+ const copy = subscriptionEmailContent.pauseReminder[locale];
39
+ const resumeDate = vars.resumeDateLabel
40
+ ? locale === "en"
41
+ ? ` on ${vars.resumeDateLabel}`
42
+ : ` ${vars.resumeDateLabel}`
43
+ : "";
44
+
45
+ const blocks: EmailBlock[] = [
46
+ heading(copy.heading),
47
+ paragraph(copy.greeting(vars.firstName)),
48
+ paragraph(copy.intro(vars.brandName)),
49
+ paragraph(copy.resume(resumeDate)),
50
+ accentBox(copy.reassurance),
51
+ button(copy.cta, vars.ctaUrl),
52
+ paragraph(copy.outro),
53
+ paragraph(signoff),
54
+ ];
55
+
56
+ return {
57
+ subject: copy.subject,
58
+ preheader: copy.preheader,
59
+ blocks,
60
+ };
61
+ }
62
+ return { subscriptionPauseReminderEmailContent };
63
+ }
@@ -0,0 +1,58 @@
1
+ import type { SubscriptionEmailContent } from "./subscriptionEmailContent.js";
2
+ import type { Locale } from "./email.js";
3
+ import {
4
+ accentBox,
5
+ button,
6
+ heading,
7
+ paragraph,
8
+ type EmailBlock,
9
+ } from "./blocks.js";
10
+
11
+ export interface SubscriptionPausedEmailVars {
12
+ firstName: string | null;
13
+ /** Consumer-facing brand label injected by the app/composition root. */
14
+ brandName: string;
15
+ /** Absolute CTA URL (manage subscription); null/absent → no button. */
16
+ ctaUrl?: string | null;
17
+ }
18
+
19
+ export interface SubscriptionPausedEmailContent {
20
+ subject: string;
21
+ preheader: string;
22
+ blocks: EmailBlock[];
23
+ }
24
+
25
+ /** Bind host-selected copy and pure helpers without provider or environment access. */
26
+ export function createSubscriptionPausedContentFactory(input: {
27
+ subscriptionEmailContent: Pick<SubscriptionEmailContent, "paused">;
28
+ }) {
29
+ const { subscriptionEmailContent } = input;
30
+
31
+ function subscriptionPausedEmailContent(
32
+ locale: Locale,
33
+ vars: SubscriptionPausedEmailVars,
34
+ signoff: string,
35
+ ): SubscriptionPausedEmailContent {
36
+ const copy = subscriptionEmailContent.paused[locale];
37
+ const blocks: EmailBlock[] = [
38
+ heading(copy.heading),
39
+ paragraph(copy.greeting(vars.firstName)),
40
+ paragraph(copy.intro),
41
+ accentBox(copy.reassurance(vars.brandName)),
42
+ ];
43
+
44
+ if (vars.ctaUrl) {
45
+ blocks.push(button(copy.cta, vars.ctaUrl));
46
+ }
47
+
48
+ blocks.push(paragraph(copy.outro));
49
+ blocks.push(paragraph(signoff));
50
+
51
+ return {
52
+ subject: copy.subject,
53
+ preheader: copy.preheader,
54
+ blocks,
55
+ };
56
+ }
57
+ return { subscriptionPausedEmailContent };
58
+ }
@@ -0,0 +1,83 @@
1
+ import type { SubscriptionEmailContent } from "./subscriptionEmailContent.js";
2
+ import type { PaymentFailureCustomerCause } from "@openlup/core/payment";
3
+ import type { Locale } from "./email.js";
4
+ import {
5
+ accentBox,
6
+ button,
7
+ heading,
8
+ paragraph,
9
+ type EmailBlock,
10
+ } from "./blocks.js";
11
+
12
+ export interface SubscriptionPaymentExpiredEmailVars {
13
+ firstName: string | null;
14
+ /** Formatted gross amount of the unpaid cycle, e.g. "129,99 zł", or null. */
15
+ amountLabel: string | null;
16
+ /**
17
+ * Why the charges were refused, in the payer-facing vocabulary. This template
18
+ * needs it most: "after several attempts" without a reason is the one place
19
+ * the rail asks for trust and offers nothing to trust. Absent or `unknown`
20
+ * renders no cause sentence.
21
+ */
22
+ cause?: PaymentFailureCustomerCause | null;
23
+ /**
24
+ * Recovery-link URL for the case's `resume_subscription` token. When present
25
+ * the template renders the resume CTA; when absent it keeps the support-led
26
+ * wording, because a button with no destination is worse than no button.
27
+ */
28
+ recoveryUrl?: string | null;
29
+ }
30
+
31
+ export interface SubscriptionPaymentExpiredEmailContent {
32
+ subject: string;
33
+ preheader: string;
34
+ blocks: EmailBlock[];
35
+ }
36
+
37
+ /** Bind host-selected copy and pure helpers without provider or environment access. */
38
+ export function createSubscriptionPaymentExpiredContentFactory(input: {
39
+ subscriptionEmailContent: Pick<SubscriptionEmailContent, "paymentExpired">;
40
+ subscriptionPaymentCauseSentence: (locale: Locale, cause: PaymentFailureCustomerCause) => string | null;
41
+ }) {
42
+ const { subscriptionEmailContent, subscriptionPaymentCauseSentence } = input;
43
+
44
+ function subscriptionPaymentExpiredEmailContent(
45
+ locale: Locale,
46
+ vars: SubscriptionPaymentExpiredEmailVars,
47
+ signoff: string,
48
+ ): SubscriptionPaymentExpiredEmailContent {
49
+ const copy = subscriptionEmailContent.paymentExpired[locale];
50
+ const recoveryUrl = vars.recoveryUrl?.trim() ? vars.recoveryUrl.trim() : null;
51
+ const causeSentence = subscriptionPaymentCauseSentence(locale, vars.cause ?? "unknown");
52
+ const detail = [
53
+ // Leads the box for the same reason as in the failed notice: it answers the
54
+ // question the paused subscription raises, before the figures.
55
+ ...(causeSentence ? [causeSentence] : []),
56
+ ...(recoveryUrl
57
+ ? [
58
+ vars.amountLabel ? copy.detail(vars.amountLabel)[0] : copy.detail(null)[0],
59
+ copy.ctaDetail,
60
+ ]
61
+ : copy.detail(vars.amountLabel)),
62
+ ];
63
+
64
+ const blocks: EmailBlock[] = [
65
+ heading(copy.heading),
66
+ paragraph(copy.greeting(vars.firstName)),
67
+ paragraph(copy.intro),
68
+ accentBox(detail),
69
+ ];
70
+
71
+ if (recoveryUrl) blocks.push(button(copy.cta, recoveryUrl));
72
+
73
+ blocks.push(paragraph(copy.outro));
74
+ blocks.push(paragraph(signoff));
75
+
76
+ return {
77
+ subject: copy.subject,
78
+ preheader: recoveryUrl ? copy.preheaderWithCta : copy.preheader,
79
+ blocks,
80
+ };
81
+ }
82
+ return { subscriptionPaymentExpiredEmailContent };
83
+ }
@@ -0,0 +1,117 @@
1
+ import type { SubscriptionEmailContent } from "./subscriptionEmailContent.js";
2
+ import type { PaymentFailureCustomerCause } from "@openlup/core/payment";
3
+ import type { Locale } from "./email.js";
4
+ import {
5
+ accentBox,
6
+ button,
7
+ heading,
8
+ paragraph,
9
+ type EmailBlock,
10
+ } from "./blocks.js";
11
+
12
+ export interface SubscriptionPaymentFailedEmailVars {
13
+ firstName: string | null;
14
+ /** Formatted gross amount that failed, e.g. "129,99 zł", or null when unknown. */
15
+ amountLabel: string | null;
16
+ /** Dunning retry attempt: 1 (gentle), 2 (reminder), 3+ (final retry announced). */
17
+ retryAttempt: number;
18
+ /** Absolute recovery URL (localized); null/absent → no button. */
19
+ recoveryUrl?: string | null;
20
+ /**
21
+ * Pre-formatted calendar day of the scheduled next charge, in the merchant's
22
+ * zone (e.g. "11.08.2026"). The dunning row that selects THIS template always
23
+ * carries a scheduled retry, so in production this is present; null keeps the
24
+ * pre-date sentence rather than printing a placeholder date.
25
+ */
26
+ nextRetryDateLabel?: string | null;
27
+ /** Card scheme as stored on the method's consent snapshot, e.g. "visa". */
28
+ methodScheme?: string | null;
29
+ /** Trailing digits of the stored method, e.g. "4242". */
30
+ methodLastDigits?: string | null;
31
+ /**
32
+ * Why the charge was refused, in the payer-facing vocabulary. Absent or
33
+ * `unknown` renders no cause sentence at all — see `subscriptionPaymentCauseCopy`.
34
+ */
35
+ cause?: PaymentFailureCustomerCause | null;
36
+ /**
37
+ * Whether the ladder scheduled a further charge for this cycle. Absent or
38
+ * `true` is today's rail and today's copy. `false` states that no further
39
+ * attempt is coming and leaves the CTA as the only remedy; any
40
+ * `nextRetryDateLabel` supplied alongside it is ignored rather than printed,
41
+ * because a date is only ever printed as part of a retry promise.
42
+ */
43
+ retryScheduled?: boolean;
44
+ }
45
+
46
+ export interface SubscriptionPaymentFailedEmailContent {
47
+ subject: string;
48
+ preheader: string;
49
+ blocks: EmailBlock[];
50
+ }
51
+
52
+ /** Bind host-selected copy and pure helpers without provider or environment access. */
53
+ export function createSubscriptionPaymentFailedContentFactory(input: {
54
+ subscriptionEmailContent: Pick<SubscriptionEmailContent, "paymentFailed">;
55
+ subscriptionPaymentCauseSentence: (locale: Locale, cause: PaymentFailureCustomerCause) => string | null;
56
+ }) {
57
+ const { subscriptionEmailContent, subscriptionPaymentCauseSentence } = input;
58
+
59
+ function subscriptionPaymentFailedEmailContent(
60
+ locale: Locale,
61
+ vars: SubscriptionPaymentFailedEmailVars,
62
+ signoff: string,
63
+ ): SubscriptionPaymentFailedEmailContent {
64
+ const copy = subscriptionEmailContent.paymentFailed[locale];
65
+ // Method facts are additive and BOTH halves must be present: "karta Visa ••••"
66
+ // with no digits identifies nothing, and bare digits with no scheme is worse.
67
+ // Absent facts drop the sentence rather than render a placeholder.
68
+ const scheme = vars.methodScheme?.trim() || null;
69
+ const lastDigits = vars.methodLastDigits?.trim() || null;
70
+ // The cause leads the box: it is the answer to the question the subject line
71
+ // just raised, and the amount means little until the reader knows why. It is
72
+ // also why it is PREPENDED and never appended — the retry sentence must stay
73
+ // last (see below).
74
+ const causeSentence = subscriptionPaymentCauseSentence(locale, vars.cause ?? "unknown");
75
+ // Only an explicit `false` turns the promises off. Absent means "no producer
76
+ // told us", and the only rail that exists always schedules a retry, so absent
77
+ // must keep rendering today's copy rather than the safer-sounding new copy:
78
+ // telling a customer no attempt is coming when one is would push them to
79
+ // cancel a subscription that was about to recover on its own.
80
+ const retryScheduled = vars.retryScheduled !== false;
81
+ const detail = [
82
+ ...(causeSentence ? [causeSentence] : []),
83
+ vars.amountLabel
84
+ ? copy.amountLine(vars.amountLabel)
85
+ : retryScheduled
86
+ ? copy.noAmountLine
87
+ : copy.noAmountLineNoRetry,
88
+ ...(scheme && lastDigits ? [copy.methodLine(scheme, lastDigits)] : []),
89
+ // Kept LAST in the box on purpose: the retry sentence is the one the
90
+ // characterization pins read off the end of `accentBox.lines`. Its
91
+ // no-retry replacement takes the same position for the same reason.
92
+ retryScheduled
93
+ ? copy.reassurance(vars.retryAttempt, vars.nextRetryDateLabel?.trim() || null)
94
+ : copy.noRetryAction,
95
+ ];
96
+ const blocks: EmailBlock[] = [
97
+ heading(copy.heading),
98
+ paragraph(copy.greeting(vars.firstName)),
99
+ paragraph(copy.intro),
100
+ accentBox(detail),
101
+ ];
102
+
103
+ if (vars.recoveryUrl) {
104
+ blocks.push(button(copy.cta, vars.recoveryUrl));
105
+ }
106
+
107
+ blocks.push(paragraph(copy.outro));
108
+ blocks.push(paragraph(signoff));
109
+
110
+ return {
111
+ subject: copy.subject,
112
+ preheader: copy.preheader,
113
+ blocks,
114
+ };
115
+ }
116
+ return { subscriptionPaymentFailedEmailContent };
117
+ }
@@ -0,0 +1,50 @@
1
+ import type { SubscriptionEmailContent } from "./subscriptionEmailContent.js";
2
+ import type { Locale } from "./email.js";
3
+ import {
4
+ accentBox,
5
+ heading,
6
+ paragraph,
7
+ type EmailBlock,
8
+ } from "./blocks.js";
9
+
10
+ export interface SubscriptionPaymentRecoveredEmailVars {
11
+ firstName: string | null;
12
+ /** Formatted gross amount of the recovered cycle, e.g. "129,99 zł", or null. */
13
+ amountLabel: string | null;
14
+ }
15
+
16
+ export interface SubscriptionPaymentRecoveredEmailContent {
17
+ subject: string;
18
+ preheader: string;
19
+ blocks: EmailBlock[];
20
+ }
21
+
22
+ /** Bind host-selected copy and pure helpers without provider or environment access. */
23
+ export function createSubscriptionPaymentRecoveredContentFactory(input: {
24
+ subscriptionEmailContent: Pick<SubscriptionEmailContent, "paymentRecovered">;
25
+ }) {
26
+ const { subscriptionEmailContent } = input;
27
+
28
+ function subscriptionPaymentRecoveredEmailContent(
29
+ locale: Locale,
30
+ vars: SubscriptionPaymentRecoveredEmailVars,
31
+ signoff: string,
32
+ ): SubscriptionPaymentRecoveredEmailContent {
33
+ const copy = subscriptionEmailContent.paymentRecovered[locale];
34
+ const blocks: EmailBlock[] = [
35
+ heading(copy.heading),
36
+ paragraph(copy.greeting(vars.firstName)),
37
+ paragraph(copy.intro),
38
+ accentBox(copy.detail(vars.amountLabel)),
39
+ paragraph(copy.outro),
40
+ paragraph(signoff),
41
+ ];
42
+
43
+ return {
44
+ subject: copy.subject,
45
+ preheader: copy.preheader,
46
+ blocks,
47
+ };
48
+ }
49
+ return { subscriptionPaymentRecoveredEmailContent };
50
+ }
@@ -0,0 +1,85 @@
1
+ import type { SubscriptionEmailContent } from "./subscriptionEmailContent.js";
2
+ import type { PaymentFailureCustomerCause } from "@openlup/core/payment";
3
+ import type { Locale } from "./email.js";
4
+ import {
5
+ accentBox,
6
+ button,
7
+ heading,
8
+ paragraph,
9
+ type EmailBlock,
10
+ } from "./blocks.js";
11
+
12
+ /**
13
+ * Which of the two unchargeable states produced this notice.
14
+ *
15
+ * ⛔ THESE TWO TOKENS ARE LEDGER IDENTITY, NOT COPY KEYS. The producer's dedupe
16
+ * key AND its two-send cap are one string, `<subscriptionId>:<cause>:<day>`, and
17
+ * the cap is read back by matching this token as a LIKE prefix. Renaming either
18
+ * value — including "aligning" it with the shared cause vocabulary below —
19
+ * silently resets every cap ever recorded, because the new prefix matches
20
+ * nothing. The mapping to the shared vocabulary therefore happens at RENDER
21
+ * time, here, and never in the producer.
22
+ */
23
+ export type SubscriptionRenewalAtRiskCause = "mandate" | "missing";
24
+
25
+ export interface SubscriptionRenewalAtRiskEmailVars {
26
+ firstName: string | null;
27
+ /** Calendar day of the scheduled renewal in the merchant zone, or null. */
28
+ renewalDateLabel: string | null;
29
+ cause: SubscriptionRenewalAtRiskCause;
30
+ /** Account payments deep link; the same one the activation-gap email uses. */
31
+ ctaUrl: string;
32
+ }
33
+
34
+ export interface SubscriptionRenewalAtRiskEmailContent {
35
+ subject: string;
36
+ preheader: string;
37
+ blocks: EmailBlock[];
38
+ }
39
+
40
+ /** Bind host-selected copy and pure helpers without provider or environment access. */
41
+ export function createSubscriptionRenewalAtRiskContentFactory(input: {
42
+ subscriptionEmailContent: Pick<SubscriptionEmailContent, "renewalAtRisk">;
43
+ subscriptionPaymentCauseSentence: (locale: Locale, cause: PaymentFailureCustomerCause) => string | null;
44
+ }) {
45
+ const { subscriptionEmailContent, subscriptionPaymentCauseSentence } = input;
46
+
47
+ /** Render-time only. See the ⛔ above before touching either side of this map. */
48
+ const SHARED_CAUSE: Record<SubscriptionRenewalAtRiskCause, PaymentFailureCustomerCause> = {
49
+ mandate: "method_cannot_recur",
50
+ missing: "method_missing",
51
+ };
52
+
53
+ /**
54
+ * Both of this rail's causes state something about the stored method, so both
55
+ * have a shared sentence and neither can be `unknown`. The non-null assertion is
56
+ * carried by the `SHARED_CAUSE` map's exhaustive typing, not by an assumption.
57
+ */
58
+ function causeSentence(locale: Locale, cause: SubscriptionRenewalAtRiskCause): string {
59
+ return subscriptionPaymentCauseSentence(locale, SHARED_CAUSE[cause]) ?? "";
60
+ }
61
+
62
+ function subscriptionRenewalAtRiskEmailContent(
63
+ locale: Locale,
64
+ vars: SubscriptionRenewalAtRiskEmailVars,
65
+ signoff: string,
66
+ ): SubscriptionRenewalAtRiskEmailContent {
67
+ const copy = subscriptionEmailContent.renewalAtRisk[locale];
68
+ const blocks: EmailBlock[] = [
69
+ heading(copy.heading),
70
+ paragraph(copy.greeting(vars.firstName)),
71
+ paragraph(copy.intro(vars.renewalDateLabel)),
72
+ accentBox([causeSentence(locale, vars.cause), copy.consequence]),
73
+ button(copy.cta, vars.ctaUrl),
74
+ paragraph(copy.outro),
75
+ paragraph(signoff),
76
+ ];
77
+
78
+ return {
79
+ subject: copy.subject,
80
+ preheader: copy.preheader,
81
+ blocks,
82
+ };
83
+ }
84
+ return { subscriptionRenewalAtRiskEmailContent };
85
+ }