@aglyn/tenant-data-admin 1.0.0-beta.143

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 (374) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/jest.integration.config.d.ts +39 -0
  4. package/jest.integration.setup.d.ts +17 -0
  5. package/package.json +51 -0
  6. package/src/index.d.ts +17 -0
  7. package/src/index.js +18 -0
  8. package/src/index.js.map +1 -0
  9. package/src/lib/render-cache.d.ts +184 -0
  10. package/src/lib/render-cache.js +198 -0
  11. package/src/lib/render-cache.js.map +1 -0
  12. package/src/lib/server/account-addresses.d.ts +160 -0
  13. package/src/lib/server/account-addresses.js +311 -0
  14. package/src/lib/server/account-addresses.js.map +1 -0
  15. package/src/lib/server/account-emails.d.ts +219 -0
  16. package/src/lib/server/account-emails.js +640 -0
  17. package/src/lib/server/account-emails.js.map +1 -0
  18. package/src/lib/server/admin-audit.d.ts +180 -0
  19. package/src/lib/server/admin-audit.js +233 -0
  20. package/src/lib/server/admin-audit.js.map +1 -0
  21. package/src/lib/server/analytics-retention.d.ts +63 -0
  22. package/src/lib/server/analytics-retention.js +66 -0
  23. package/src/lib/server/analytics-retention.js.map +1 -0
  24. package/src/lib/server/api-http.d.ts +159 -0
  25. package/src/lib/server/api-http.js +230 -0
  26. package/src/lib/server/api-http.js.map +1 -0
  27. package/src/lib/server/api-keys.d.ts +117 -0
  28. package/src/lib/server/api-keys.js +298 -0
  29. package/src/lib/server/api-keys.js.map +1 -0
  30. package/src/lib/server/auth-handoff.d.ts +165 -0
  31. package/src/lib/server/auth-handoff.js +482 -0
  32. package/src/lib/server/auth-handoff.js.map +1 -0
  33. package/src/lib/server/auth-pools.d.ts +246 -0
  34. package/src/lib/server/auth-pools.js +551 -0
  35. package/src/lib/server/auth-pools.js.map +1 -0
  36. package/src/lib/server/billing-addons.d.ts +171 -0
  37. package/src/lib/server/billing-addons.js +277 -0
  38. package/src/lib/server/billing-addons.js.map +1 -0
  39. package/src/lib/server/campaign-attribution-store.d.ts +55 -0
  40. package/src/lib/server/campaign-attribution-store.js +95 -0
  41. package/src/lib/server/campaign-attribution-store.js.map +1 -0
  42. package/src/lib/server/campaign-conversion-attribution.d.ts +205 -0
  43. package/src/lib/server/campaign-conversion-attribution.js +279 -0
  44. package/src/lib/server/campaign-conversion-attribution.js.map +1 -0
  45. package/src/lib/server/client-error-report.d.ts +301 -0
  46. package/src/lib/server/client-error-report.js +755 -0
  47. package/src/lib/server/client-error-report.js.map +1 -0
  48. package/src/lib/server/connect-account-status.d.ts +74 -0
  49. package/src/lib/server/connect-account-status.js +94 -0
  50. package/src/lib/server/connect-account-status.js.map +1 -0
  51. package/src/lib/server/connect-payout-failure.d.ts +103 -0
  52. package/src/lib/server/connect-payout-failure.js +127 -0
  53. package/src/lib/server/connect-payout-failure.js.map +1 -0
  54. package/src/lib/server/console-api-rate-limit.d.ts +81 -0
  55. package/src/lib/server/console-api-rate-limit.js +111 -0
  56. package/src/lib/server/console-api-rate-limit.js.map +1 -0
  57. package/src/lib/server/console-domains.d.ts +326 -0
  58. package/src/lib/server/console-domains.js +779 -0
  59. package/src/lib/server/console-domains.js.map +1 -0
  60. package/src/lib/server/consume-once.d.ts +91 -0
  61. package/src/lib/server/consume-once.js +96 -0
  62. package/src/lib/server/consume-once.js.map +1 -0
  63. package/src/lib/server/contact-company-link.d.ts +85 -0
  64. package/src/lib/server/contact-company-link.js +105 -0
  65. package/src/lib/server/contact-company-link.js.map +1 -0
  66. package/src/lib/server/contact-email-engagement.d.ts +32 -0
  67. package/src/lib/server/contact-email-engagement.js +145 -0
  68. package/src/lib/server/contact-email-engagement.js.map +1 -0
  69. package/src/lib/server/contact-email-index.d.ts +56 -0
  70. package/src/lib/server/contact-email-index.js +158 -0
  71. package/src/lib/server/contact-email-index.js.map +1 -0
  72. package/src/lib/server/contact-lifecycle-floor.d.ts +89 -0
  73. package/src/lib/server/contact-lifecycle-floor.js +88 -0
  74. package/src/lib/server/contact-lifecycle-floor.js.map +1 -0
  75. package/src/lib/server/contact-merge.d.ts +55 -0
  76. package/src/lib/server/contact-merge.js +279 -0
  77. package/src/lib/server/contact-merge.js.map +1 -0
  78. package/src/lib/server/contact-suppression.d.ts +153 -0
  79. package/src/lib/server/contact-suppression.js +259 -0
  80. package/src/lib/server/contact-suppression.js.map +1 -0
  81. package/src/lib/server/crm-booking-activity.d.ts +86 -0
  82. package/src/lib/server/crm-booking-activity.js +251 -0
  83. package/src/lib/server/crm-booking-activity.js.map +1 -0
  84. package/src/lib/server/crm-email-activity.d.ts +112 -0
  85. package/src/lib/server/crm-email-activity.js +143 -0
  86. package/src/lib/server/crm-email-activity.js.map +1 -0
  87. package/src/lib/server/crm-inbound-email.d.ts +145 -0
  88. package/src/lib/server/crm-inbound-email.js +287 -0
  89. package/src/lib/server/crm-inbound-email.js.map +1 -0
  90. package/src/lib/server/crm-next-activity.d.ts +74 -0
  91. package/src/lib/server/crm-next-activity.js +194 -0
  92. package/src/lib/server/crm-next-activity.js.map +1 -0
  93. package/src/lib/server/crm-records.d.ts +144 -0
  94. package/src/lib/server/crm-records.js +218 -0
  95. package/src/lib/server/crm-records.js.map +1 -0
  96. package/src/lib/server/csp-aggregate.d.ts +62 -0
  97. package/src/lib/server/csp-aggregate.js +276 -0
  98. package/src/lib/server/csp-aggregate.js.map +1 -0
  99. package/src/lib/server/data-storage-gate.d.ts +66 -0
  100. package/src/lib/server/data-storage-gate.js +48 -0
  101. package/src/lib/server/data-storage-gate.js.map +1 -0
  102. package/src/lib/server/dataset-live-pages.d.ts +179 -0
  103. package/src/lib/server/dataset-live-pages.js +421 -0
  104. package/src/lib/server/dataset-live-pages.js.map +1 -0
  105. package/src/lib/server/dns-probe.d.ts +53 -0
  106. package/src/lib/server/dns-probe.js +184 -0
  107. package/src/lib/server/dns-probe.js.map +1 -0
  108. package/src/lib/server/document-id.d.ts +29 -0
  109. package/src/lib/server/document-id.js +100 -0
  110. package/src/lib/server/document-id.js.map +1 -0
  111. package/src/lib/server/domain-provider-vercel.d.ts +33 -0
  112. package/src/lib/server/domain-provider-vercel.js +298 -0
  113. package/src/lib/server/domain-provider-vercel.js.map +1 -0
  114. package/src/lib/server/domain-provider-webhook.d.ts +73 -0
  115. package/src/lib/server/domain-provider-webhook.js +223 -0
  116. package/src/lib/server/domain-provider-webhook.js.map +1 -0
  117. package/src/lib/server/domain-provider-wildcard.d.ts +54 -0
  118. package/src/lib/server/domain-provider-wildcard.js +163 -0
  119. package/src/lib/server/domain-provider-wildcard.js.map +1 -0
  120. package/src/lib/server/domain-provider.d.ts +197 -0
  121. package/src/lib/server/domain-provider.js +221 -0
  122. package/src/lib/server/domain-provider.js.map +1 -0
  123. package/src/lib/server/duplicate-activity.d.ts +54 -0
  124. package/src/lib/server/duplicate-activity.js +67 -0
  125. package/src/lib/server/duplicate-activity.js.map +1 -0
  126. package/src/lib/server/duplicate-resource.d.ts +55 -0
  127. package/src/lib/server/duplicate-resource.js +474 -0
  128. package/src/lib/server/duplicate-resource.js.map +1 -0
  129. package/src/lib/server/dynamic-list-materialize.d.ts +153 -0
  130. package/src/lib/server/dynamic-list-materialize.js +581 -0
  131. package/src/lib/server/dynamic-list-materialize.js.map +1 -0
  132. package/src/lib/server/edit-access-authz.d.ts +56 -0
  133. package/src/lib/server/edit-access-authz.js +107 -0
  134. package/src/lib/server/edit-access-authz.js.map +1 -0
  135. package/src/lib/server/edit-access-token.d.ts +72 -0
  136. package/src/lib/server/edit-access-token.js +116 -0
  137. package/src/lib/server/edit-access-token.js.map +1 -0
  138. package/src/lib/server/edit-hint-token.d.ts +83 -0
  139. package/src/lib/server/edit-hint-token.js +119 -0
  140. package/src/lib/server/edit-hint-token.js.map +1 -0
  141. package/src/lib/server/email-delivery-log.d.ts +509 -0
  142. package/src/lib/server/email-delivery-log.js +1043 -0
  143. package/src/lib/server/email-delivery-log.js.map +1 -0
  144. package/src/lib/server/email-flow-gate.d.ts +80 -0
  145. package/src/lib/server/email-flow-gate.js +153 -0
  146. package/src/lib/server/email-flow-gate.js.map +1 -0
  147. package/src/lib/server/email-marketing-gate.d.ts +333 -0
  148. package/src/lib/server/email-marketing-gate.js +639 -0
  149. package/src/lib/server/email-marketing-gate.js.map +1 -0
  150. package/src/lib/server/email-metering.d.ts +293 -0
  151. package/src/lib/server/email-metering.js +359 -0
  152. package/src/lib/server/email-metering.js.map +1 -0
  153. package/src/lib/server/email-revenue-attribution.d.ts +185 -0
  154. package/src/lib/server/email-revenue-attribution.js +300 -0
  155. package/src/lib/server/email-revenue-attribution.js.map +1 -0
  156. package/src/lib/server/email-send-rate.d.ts +232 -0
  157. package/src/lib/server/email-send-rate.js +417 -0
  158. package/src/lib/server/email-send-rate.js.map +1 -0
  159. package/src/lib/server/email-sender-reputation.d.ts +317 -0
  160. package/src/lib/server/email-sender-reputation.js +464 -0
  161. package/src/lib/server/email-sender-reputation.js.map +1 -0
  162. package/src/lib/server/email-suppression.d.ts +490 -0
  163. package/src/lib/server/email-suppression.js +648 -0
  164. package/src/lib/server/email-suppression.js.map +1 -0
  165. package/src/lib/server/email-topic-confirmation.d.ts +150 -0
  166. package/src/lib/server/email-topic-confirmation.js +272 -0
  167. package/src/lib/server/email-topic-confirmation.js.map +1 -0
  168. package/src/lib/server/email-unsubscribe-link.d.ts +174 -0
  169. package/src/lib/server/email-unsubscribe-link.js +236 -0
  170. package/src/lib/server/email-unsubscribe-link.js.map +1 -0
  171. package/src/lib/server/erase-person.d.ts +116 -0
  172. package/src/lib/server/erase-person.js +272 -0
  173. package/src/lib/server/erase-person.js.map +1 -0
  174. package/src/lib/server/erase.d.ts +458 -0
  175. package/src/lib/server/erase.js +1506 -0
  176. package/src/lib/server/erase.js.map +1 -0
  177. package/src/lib/server/firebase-admin.d.ts +71 -0
  178. package/src/lib/server/firebase-admin.js +343 -0
  179. package/src/lib/server/firebase-admin.js.map +1 -0
  180. package/src/lib/server/form-dataset-binding-token.d.ts +35 -0
  181. package/src/lib/server/form-dataset-binding-token.js +107 -0
  182. package/src/lib/server/form-dataset-binding-token.js.map +1 -0
  183. package/src/lib/server/free-workspace-cap.d.ts +201 -0
  184. package/src/lib/server/free-workspace-cap.js +404 -0
  185. package/src/lib/server/free-workspace-cap.js.map +1 -0
  186. package/src/lib/server/ga4-measurement-protocol.d.ts +256 -0
  187. package/src/lib/server/ga4-measurement-protocol.js +558 -0
  188. package/src/lib/server/ga4-measurement-protocol.js.map +1 -0
  189. package/src/lib/server/host-email-tokens.d.ts +47 -0
  190. package/src/lib/server/host-email-tokens.js +72 -0
  191. package/src/lib/server/host-email-tokens.js.map +1 -0
  192. package/src/lib/server/host-memberships.d.ts +54 -0
  193. package/src/lib/server/host-memberships.js +194 -0
  194. package/src/lib/server/host-memberships.js.map +1 -0
  195. package/src/lib/server/host-sending-domain.d.ts +292 -0
  196. package/src/lib/server/host-sending-domain.js +451 -0
  197. package/src/lib/server/host-sending-domain.js.map +1 -0
  198. package/src/lib/server/host-visitor-records.d.ts +150 -0
  199. package/src/lib/server/host-visitor-records.js +262 -0
  200. package/src/lib/server/host-visitor-records.js.map +1 -0
  201. package/src/lib/server/id-token-refusal.d.ts +28 -0
  202. package/src/lib/server/id-token-refusal.js +111 -0
  203. package/src/lib/server/id-token-refusal.js.map +1 -0
  204. package/src/lib/server/legal-acceptance.d.ts +214 -0
  205. package/src/lib/server/legal-acceptance.js +305 -0
  206. package/src/lib/server/legal-acceptance.js.map +1 -0
  207. package/src/lib/server/list-members.d.ts +211 -0
  208. package/src/lib/server/list-members.js +176 -0
  209. package/src/lib/server/list-members.js.map +1 -0
  210. package/src/lib/server/live-page-usage.d.ts +202 -0
  211. package/src/lib/server/live-page-usage.js +300 -0
  212. package/src/lib/server/live-page-usage.js.map +1 -0
  213. package/src/lib/server/lockdown.d.ts +313 -0
  214. package/src/lib/server/lockdown.js +643 -0
  215. package/src/lib/server/lockdown.js.map +1 -0
  216. package/src/lib/server/media-cdn-rate-limit.d.ts +188 -0
  217. package/src/lib/server/media-cdn-rate-limit.js +204 -0
  218. package/src/lib/server/media-cdn-rate-limit.js.map +1 -0
  219. package/src/lib/server/media-delivery.d.ts +267 -0
  220. package/src/lib/server/media-delivery.js +485 -0
  221. package/src/lib/server/media-delivery.js.map +1 -0
  222. package/src/lib/server/media-download-tokens.d.ts +161 -0
  223. package/src/lib/server/media-download-tokens.js +386 -0
  224. package/src/lib/server/media-download-tokens.js.map +1 -0
  225. package/src/lib/server/media-quarantine.d.ts +127 -0
  226. package/src/lib/server/media-quarantine.js +170 -0
  227. package/src/lib/server/media-quarantine.js.map +1 -0
  228. package/src/lib/server/media-signing.d.ts +126 -0
  229. package/src/lib/server/media-signing.js +159 -0
  230. package/src/lib/server/media-signing.js.map +1 -0
  231. package/src/lib/server/media-storage-path.d.ts +96 -0
  232. package/src/lib/server/media-storage-path.js +111 -0
  233. package/src/lib/server/media-storage-path.js.map +1 -0
  234. package/src/lib/server/media-strong-digest.d.ts +85 -0
  235. package/src/lib/server/media-strong-digest.js +190 -0
  236. package/src/lib/server/media-strong-digest.js.map +1 -0
  237. package/src/lib/server/media-tombstone.d.ts +276 -0
  238. package/src/lib/server/media-tombstone.js +421 -0
  239. package/src/lib/server/media-tombstone.js.map +1 -0
  240. package/src/lib/server/media-variants.d.ts +309 -0
  241. package/src/lib/server/media-variants.js +428 -0
  242. package/src/lib/server/media-variants.js.map +1 -0
  243. package/src/lib/server/member-email-aliases.d.ts +180 -0
  244. package/src/lib/server/member-email-aliases.js +420 -0
  245. package/src/lib/server/member-email-aliases.js.map +1 -0
  246. package/src/lib/server/member-photo.d.ts +88 -0
  247. package/src/lib/server/member-photo.js +185 -0
  248. package/src/lib/server/member-photo.js.map +1 -0
  249. package/src/lib/server/membership-recover-throttle.d.ts +211 -0
  250. package/src/lib/server/membership-recover-throttle.js +231 -0
  251. package/src/lib/server/membership-recover-throttle.js.map +1 -0
  252. package/src/lib/server/notifications.d.ts +55 -0
  253. package/src/lib/server/notifications.js +134 -0
  254. package/src/lib/server/notifications.js.map +1 -0
  255. package/src/lib/server/org-billing.d.ts +97 -0
  256. package/src/lib/server/org-billing.js +236 -0
  257. package/src/lib/server/org-billing.js.map +1 -0
  258. package/src/lib/server/organizations.d.ts +837 -0
  259. package/src/lib/server/organizations.js +1814 -0
  260. package/src/lib/server/organizations.js.map +1 -0
  261. package/src/lib/server/password-reset-throttle.d.ts +84 -0
  262. package/src/lib/server/password-reset-throttle.js +102 -0
  263. package/src/lib/server/password-reset-throttle.js.map +1 -0
  264. package/src/lib/server/personal-data-export.d.ts +241 -0
  265. package/src/lib/server/personal-data-export.js +858 -0
  266. package/src/lib/server/personal-data-export.js.map +1 -0
  267. package/src/lib/server/platform-domain-names.d.ts +62 -0
  268. package/src/lib/server/platform-domain-names.js +197 -0
  269. package/src/lib/server/platform-domain-names.js.map +1 -0
  270. package/src/lib/server/platform-marketing-consent.d.ts +133 -0
  271. package/src/lib/server/platform-marketing-consent.js +209 -0
  272. package/src/lib/server/platform-marketing-consent.js.map +1 -0
  273. package/src/lib/server/rate-limit-store.d.ts +702 -0
  274. package/src/lib/server/rate-limit-store.js +1220 -0
  275. package/src/lib/server/rate-limit-store.js.map +1 -0
  276. package/src/lib/server/realm-plugins.d.ts +67 -0
  277. package/src/lib/server/realm-plugins.js +250 -0
  278. package/src/lib/server/realm-plugins.js.map +1 -0
  279. package/src/lib/server/recaptcha-allowlist.d.ts +90 -0
  280. package/src/lib/server/recaptcha-allowlist.js +409 -0
  281. package/src/lib/server/recaptcha-allowlist.js.map +1 -0
  282. package/src/lib/server/release-flags.d.ts +105 -0
  283. package/src/lib/server/release-flags.js +183 -0
  284. package/src/lib/server/release-flags.js.map +1 -0
  285. package/src/lib/server/replay-erasures.d.ts +126 -0
  286. package/src/lib/server/replay-erasures.js +217 -0
  287. package/src/lib/server/replay-erasures.js.map +1 -0
  288. package/src/lib/server/resolve-people.d.ts +66 -0
  289. package/src/lib/server/resolve-people.js +112 -0
  290. package/src/lib/server/resolve-people.js.map +1 -0
  291. package/src/lib/server/safe-equal.d.ts +45 -0
  292. package/src/lib/server/safe-equal.js +58 -0
  293. package/src/lib/server/safe-equal.js.map +1 -0
  294. package/src/lib/server/sending-domain-debt.d.ts +127 -0
  295. package/src/lib/server/sending-domain-debt.js +268 -0
  296. package/src/lib/server/sending-domain-debt.js.map +1 -0
  297. package/src/lib/server/sending-domain-recheck.d.ts +151 -0
  298. package/src/lib/server/sending-domain-recheck.js +253 -0
  299. package/src/lib/server/sending-domain-recheck.js.map +1 -0
  300. package/src/lib/server/sending-domains.d.ts +364 -0
  301. package/src/lib/server/sending-domains.js +683 -0
  302. package/src/lib/server/sending-domains.js.map +1 -0
  303. package/src/lib/server/serve-media-cdn.d.ts +433 -0
  304. package/src/lib/server/serve-media-cdn.js +1370 -0
  305. package/src/lib/server/serve-media-cdn.js.map +1 -0
  306. package/src/lib/server/serve-plugin-fetch.d.ts +61 -0
  307. package/src/lib/server/serve-plugin-fetch.js +294 -0
  308. package/src/lib/server/serve-plugin-fetch.js.map +1 -0
  309. package/src/lib/server/sms-keywords.d.ts +63 -0
  310. package/src/lib/server/sms-keywords.js +146 -0
  311. package/src/lib/server/sms-keywords.js.map +1 -0
  312. package/src/lib/server/sso-break-glass-owners.d.ts +91 -0
  313. package/src/lib/server/sso-break-glass-owners.js +227 -0
  314. package/src/lib/server/sso-break-glass-owners.js.map +1 -0
  315. package/src/lib/server/sso-domain-policy.d.ts +140 -0
  316. package/src/lib/server/sso-domain-policy.js +239 -0
  317. package/src/lib/server/sso-domain-policy.js.map +1 -0
  318. package/src/lib/server/sso-drift-logic.d.ts +106 -0
  319. package/src/lib/server/sso-drift-logic.js +95 -0
  320. package/src/lib/server/sso-drift-logic.js.map +1 -0
  321. package/src/lib/server/sso-enforcement.d.ts +204 -0
  322. package/src/lib/server/sso-enforcement.js +309 -0
  323. package/src/lib/server/sso-enforcement.js.map +1 -0
  324. package/src/lib/server/sso-provisioning.d.ts +320 -0
  325. package/src/lib/server/sso-provisioning.js +715 -0
  326. package/src/lib/server/sso-provisioning.js.map +1 -0
  327. package/src/lib/server/staff-alert-email.d.ts +41 -0
  328. package/src/lib/server/staff-alert-email.js +63 -0
  329. package/src/lib/server/staff-alert-email.js.map +1 -0
  330. package/src/lib/server/stripe-account-mode.d.ts +156 -0
  331. package/src/lib/server/stripe-account-mode.js +162 -0
  332. package/src/lib/server/stripe-account-mode.js.map +1 -0
  333. package/src/lib/server/tenant-write-lockdown.d.ts +131 -0
  334. package/src/lib/server/tenant-write-lockdown.js +176 -0
  335. package/src/lib/server/tenant-write-lockdown.js.map +1 -0
  336. package/src/lib/server/test-firestore.d.ts +45 -0
  337. package/src/lib/server/test-firestore.js +124 -0
  338. package/src/lib/server/test-firestore.js.map +1 -0
  339. package/src/lib/server/token-revocation.d.ts +140 -0
  340. package/src/lib/server/token-revocation.js +255 -0
  341. package/src/lib/server/token-revocation.js.map +1 -0
  342. package/src/lib/server/update-existing.d.ts +32 -0
  343. package/src/lib/server/update-existing.js +73 -0
  344. package/src/lib/server/update-existing.js.map +1 -0
  345. package/src/lib/server/upload-cors-reconcile.d.ts +118 -0
  346. package/src/lib/server/upload-cors-reconcile.js +234 -0
  347. package/src/lib/server/upload-cors-reconcile.js.map +1 -0
  348. package/src/lib/server/upsert-contact.d.ts +262 -0
  349. package/src/lib/server/upsert-contact.js +546 -0
  350. package/src/lib/server/upsert-contact.js.map +1 -0
  351. package/src/lib/server/usage-invoice.d.ts +203 -0
  352. package/src/lib/server/usage-invoice.js +397 -0
  353. package/src/lib/server/usage-invoice.js.map +1 -0
  354. package/src/lib/server/user-profiles.d.ts +151 -0
  355. package/src/lib/server/user-profiles.js +364 -0
  356. package/src/lib/server/user-profiles.js.map +1 -0
  357. package/src/lib/server/vercel-drain-signature.d.ts +30 -0
  358. package/src/lib/server/vercel-drain-signature.js +61 -0
  359. package/src/lib/server/vercel-drain-signature.js.map +1 -0
  360. package/src/lib/server/vercel-log-drain.d.ts +259 -0
  361. package/src/lib/server/vercel-log-drain.js +479 -0
  362. package/src/lib/server/vercel-log-drain.js.map +1 -0
  363. package/src/lib/server/verify-email-cooldown.d.ts +102 -0
  364. package/src/lib/server/verify-email-cooldown.js +114 -0
  365. package/src/lib/server/verify-email-cooldown.js.map +1 -0
  366. package/src/lib/server/visitor-write-rate-limit.d.ts +87 -0
  367. package/src/lib/server/visitor-write-rate-limit.js +117 -0
  368. package/src/lib/server/visitor-write-rate-limit.js.map +1 -0
  369. package/src/lib/server/workspace-domains.d.ts +156 -0
  370. package/src/lib/server/workspace-domains.js +271 -0
  371. package/src/lib/server/workspace-domains.js.map +1 -0
  372. package/src/tenancy.d.ts +115 -0
  373. package/src/tenancy.js +142 -0
  374. package/src/tenancy.js.map +1 -0
@@ -0,0 +1,490 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * The PLATFORM-WIDE email suppression list, `emailSuppressions/{emailKey}`
19
+ * (AGL-2407).
20
+ *
21
+ * ## What was missing
22
+ *
23
+ * AGL-1918 (`7a8f3cd68`) made `email.bounced` (permanent) and
24
+ * `email.complained` write a suppression — into `hosts/{hostId}/suppressions`,
25
+ * found from a Resend tag that only `campaign-send.ts` stamped. That closed
26
+ * the campaign half and could close no other, because there was nowhere to
27
+ * file the rest:
28
+ *
29
+ * Every other sender in the product goes through the shared `sendEmail` —
30
+ * invites,
31
+ * password resets, verification, receipts, booking confirmations, the monthly
32
+ * usage summary, the usage-alert fan-out, restock and abandoned-cart mail, the
33
+ * merchant-authored workflow `sendEmail` step. A bounce on any of those
34
+ * arrived at the webhook with no site to place it against and was answered
35
+ * `200 {ignored:true}`. A dead address was re-mailed on every subsequent send,
36
+ * forever, and a spam complaint had no effect on anything.
37
+ *
38
+ * That matters most exactly when it is hardest to fix: on Sept 1 the signup
39
+ * door opens, and verification and invite mail — addressed by strangers typing
40
+ * addresses — is the highest-bounce-rate mail we send, on the same Resend key
41
+ * and the same From address as everything else.
42
+ *
43
+ * ## Why a sibling of `contactSuppressions` and not a channel on it
44
+ *
45
+ * `contact-suppression.ts` is the same idea for phones and every argument it
46
+ * makes holds here: keyed on the identifier because that is what the sender
47
+ * holds at send time; one `get()` by document id, no query and no composite
48
+ * index that could go missing and fail the lookup open; a revocation is a
49
+ * FIELD and not a delete, because the record is the evidence that the
50
+ * suppression was honoured while it was in force.
51
+ *
52
+ * It is a separate collection for one concrete reason: the document id. That
53
+ * list's key is the E.164 digits, and its docblock argues at length that a
54
+ * phone number must NOT be hashed (NANP is ~10^10 values, so a hash buys the
55
+ * appearance of de-identification and none of the substance). An email address
56
+ * is not enumerable, `hosts/{hostId}/suppressions` already keys on
57
+ * `sha256(email)`, and one collection holding two incompatible key spaces is
58
+ * how a lookup comes to be performed against the wrong derivation. The
59
+ * address is stored in the document in the clear regardless, exactly as the
60
+ * per-host list stores it, so a staff reader still shows a human something
61
+ * they can act on.
62
+ *
63
+ * ## Who reads it, and who deliberately does NOT
64
+ *
65
+ * AGL-1438's rule is that a QUOTA may only ever refuse a campaign, because
66
+ * refusing a receipt or a password reset converts a billing event into an
67
+ * outage on a customer's business. A suppression is not a quota, but the same
68
+ * proportionality applies and lands in the same place:
69
+ *
70
+ * - **Bulk mail consults this list.** The monthly usage summary, the
71
+ * usage-alert fan-out and the marketplace review fan-out to a publisher's
72
+ * owners and admins go to a LIST of people who did not ask for that
73
+ * particular message, on a schedule or on every submission, forever. They
74
+ * are the sends that re-hit a dead mailbox every month and teach a mailbox
75
+ * provider that `aglyn.com` does not listen.
76
+ * - **Transactional mail does NOT.** A password reset, a verification, an
77
+ * invite, a receipt or a booking confirmation answers something the human
78
+ * just did. Refusing one because an address bounced or because somebody
79
+ * once pressed "report spam" on an unrelated message would lock a real
80
+ * customer out of their own account. The shared sender is therefore left
81
+ * unconditional on purpose, and this is the note that says so.
82
+ *
83
+ * (Written throughout without a literal call expression, on purpose:
84
+ * `email-send-metering-coverage.spec.ts` enumerates senders by grepping the
85
+ * tree for one, and a prose mention here would enrol a module that sends
86
+ * nothing into the AGL-1438 cost-meter sweep.)
87
+ */
88
+ import { Timestamp } from 'firebase-admin/firestore';
89
+ export declare const EMAIL_SUPPRESSIONS_COLLECTION = "emailSuppressions";
90
+ /**
91
+ * The PER-SITE list, `hosts/{hostId}/suppressions/{emailKey}` — unsubscribes
92
+ * from one site's campaigns, plus the bounces and complaints that arrived
93
+ * carrying that site's tag.
94
+ *
95
+ * Named here rather than at each call site because the two lists are read
96
+ * together by {@link filterSendableForHost}, and a sender that knows one path
97
+ * as a string literal and the other through this module is one rename away
98
+ * from consulting a collection that does not exist and finding nobody
99
+ * suppressed.
100
+ */
101
+ export declare const HOST_SUPPRESSIONS_SUBCOLLECTION = "suppressions";
102
+ /**
103
+ * Why an address is suppressed.
104
+ *
105
+ * `bounce` means PERMANENT only. Resend reports `data.bounce.type` as
106
+ * `Permanent` or `Transient`, and a transient bounce is a full mailbox or a
107
+ * greylisting server — recording one here would suppress a real recipient over
108
+ * a temporary condition at their provider. The webhook makes that distinction;
109
+ * this type only names the outcome.
110
+ */
111
+ export type EmailSuppressionReason =
112
+ /** Permanent bounce — the mailbox does not exist. */
113
+ 'bounce'
114
+ /** The recipient pressed "report spam". */
115
+ | 'complaint'
116
+ /** Recorded by staff (a written request, a court order, a correction). */
117
+ | 'staff';
118
+ /**
119
+ * The reasons that may be filed PLATFORM-WIDE, as a runtime set.
120
+ *
121
+ * ## The split this constant enforces
122
+ *
123
+ * A bounce and a complaint are facts about a MAILBOX and about the sending
124
+ * domain every tenant's mail leaves by: the address does not exist for
125
+ * anybody, and somebody who pressed "report spam" on `noreply@aglyn.com` has
126
+ * told every sender behind that domain at once. Those belong everywhere,
127
+ * immediately.
128
+ *
129
+ * An UNSUBSCRIBE is not that. It is a preference a person expressed to ONE
130
+ * brand — the sender line they read, the newsletter they joined — and an
131
+ * agency running twelve unrelated clients out of one account would, on a
132
+ * platform-wide entry, stop mailing that person on behalf of eleven brands
133
+ * they never heard from. So an unsubscribe lives only in
134
+ * `hosts/{hostId}/suppressions`, and {@link suppressEmail} refuses it.
135
+ *
136
+ * ## Why a runtime refusal and not just the type
137
+ *
138
+ * {@link EmailSuppressionReason} already excludes it, and a type is not a
139
+ * guard: every caller here builds its reason from a webhook payload or a
140
+ * ternary, `as` casts exist, and the plugin API surface is untyped at the
141
+ * boundary. The cost of the type being wrong once is an opt-out from one
142
+ * brand silently applied to every brand in the account, which is invisible
143
+ * from the console — the mail simply never arrives, and the merchant's own
144
+ * suppression list does not mention it.
145
+ */
146
+ export declare const PLATFORM_SUPPRESSION_REASONS: readonly EmailSuppressionReason[];
147
+ /**
148
+ * The reason a self-service opt-out is filed under, on the PER-SITE list.
149
+ *
150
+ * Named because three call sites compare against it — the unsubscribe writes
151
+ * it, the resubscribe link refuses to reverse anything else, and the
152
+ * preference page reads it to decide whether an address may opt back in. A
153
+ * literal in three places is a literal that can be changed in two.
154
+ */
155
+ export declare const UNSUBSCRIBE_SUPPRESSION_REASON = "unsubscribe";
156
+ export interface EmailSuppressionRecord {
157
+ /** The address, in the clear, lowercased. The id is its hash. */
158
+ email: string;
159
+ reason: EmailSuppressionReason;
160
+ /**
161
+ * The `context` tag the send carried (`'invite'`, `'usage-summary'`,
162
+ * `'campaign'`, …), so a human reading the list can tell which of our
163
+ * senders produced the address that died. Null when the send carried none.
164
+ */
165
+ context: string | null;
166
+ /** The site the failure was attributed to, when the send named one. */
167
+ hostId: string | null;
168
+ /** Non-null once released. A released record does not suppress. */
169
+ releasedAt: unknown | null;
170
+ /** What lifted it. Absent on records written before releases were typed. */
171
+ releasedVia?: EmailReleaseChannel;
172
+ /** The site whose confirmed double opt-in lifted it, when one did. */
173
+ releasedHostId?: string | null;
174
+ /** The stream that was confirmed, likewise. */
175
+ releasedTopicId?: string | null;
176
+ }
177
+ /**
178
+ * Document id for an address: `sha256` of the lowercased, trimmed form.
179
+ *
180
+ * The SAME derivation `campaign-send.ts` uses for `hosts/{hostId}/suppressions`
181
+ * — deliberately, so the two lists can never disagree about which document
182
+ * describes which person.
183
+ *
184
+ * @returns the id, or `null` for anything that is not an address. Never a
185
+ * best-guess id: suppressing the wrong person and believing you
186
+ * suppressed the right one is worse than refusing.
187
+ */
188
+ export declare function emailSuppressionKey(email: string | null | undefined): string | null;
189
+ export interface SuppressEmailInput {
190
+ email: string;
191
+ reason: EmailSuppressionReason;
192
+ /** The `context` tag the failed send carried, when it carried one. */
193
+ context?: string | null;
194
+ /** The site the failed send was attributed to, when it named one. */
195
+ hostId?: string | null;
196
+ /** Injectable for tests; defaults to the admin app's Firestore. */
197
+ firestore?: any;
198
+ }
199
+ /**
200
+ * Record a platform-wide suppression. Idempotent by document id.
201
+ *
202
+ * `createdAt` is stamped only when the document is new, matching the per-host
203
+ * list: a second bounce must not overwrite the moment the address first went
204
+ * bad, because that is the date a human is told when they ask. `suppressedAt`
205
+ * moves every time, so "when did we last see this fail" stays answerable.
206
+ *
207
+ * A previously released record is un-released — a fresh failure is a fresh
208
+ * failure.
209
+ *
210
+ * @returns `created: false` when the address was already on the list.
211
+ */
212
+ export declare function suppressEmail(input: SuppressEmailInput): Promise<{
213
+ key: string;
214
+ created: boolean;
215
+ }>;
216
+ /**
217
+ * What lifted a suppression, recorded on the record it lifted.
218
+ *
219
+ * Written explicitly by both paths rather than left to "absent means staff".
220
+ * The two are held to different rules — a staff release may lift any reason,
221
+ * a confirmed opt-in may lift exactly one — so the audit answer to "how did
222
+ * this address get back on the domain" has to be a stored fact and not an
223
+ * inference from which field happens to be missing.
224
+ */
225
+ export type EmailReleaseChannel =
226
+ /** A staff correction through the admin suppressions surface. */
227
+ 'staff'
228
+ /** A recipient completed a double opt-in from this address. */
229
+ | 'double-opt-in';
230
+ /**
231
+ * Put an address back in circulation (a staff correction, or the person asking
232
+ * to be re-added). The record is kept and marked released, never deleted —
233
+ * same reasoning as `releasePhoneContact`: a deleted record cannot show that
234
+ * the suppression was honored while it stood.
235
+ *
236
+ * Unconditional on the reason, and that is what separates it from
237
+ * {@link releaseEmailForConfirmedOptIn}: a human with the staff role has read
238
+ * the record and is accountable for the row, so they may lift a complaint —
239
+ * a report filed against the wrong message, an address entered by mistake.
240
+ * Nothing automatic gets that latitude.
241
+ *
242
+ * @returns false when there was no live record to release.
243
+ */
244
+ export declare function releaseEmail(input: {
245
+ email: string;
246
+ releasedByUid?: string | null;
247
+ note?: string | null;
248
+ firestore?: any;
249
+ }): Promise<boolean>;
250
+ /**
251
+ * The ONLY reason a completed round trip may lift, as a runtime set.
252
+ *
253
+ * ## Why a bounce is releasable
254
+ *
255
+ * A `bounce` record is a claim about a MAILBOX at a moment: mail addressed
256
+ * here was permanently refused. Somebody clicking a confirmation link that
257
+ * was delivered to that mailbox has refuted the claim with the only evidence
258
+ * that could refute it — the message arrived, a human read it, and the round
259
+ * trip closed. Leaving the record standing after that makes one transient
260
+ * failure recorded as permanent — a mailbox that was full, a receiving server
261
+ * that answered 550 while it was misconfigured — a life sentence no route can
262
+ * undo.
263
+ *
264
+ * ## Why a complaint is NOT, and never will be
265
+ *
266
+ * `complaint` is not a deliverability fact. It is a person stating they do not
267
+ * want this mail, and a round trip proves nothing about that statement — it
268
+ * proves the mailbox works, which nobody doubted. Releasing one here would
269
+ * make a public signup form into a laundry for spam complaints: submit the
270
+ * complainant's address, they receive a confirmation (the shared sender is
271
+ * transactional and consults no list), and one click anywhere in the chain
272
+ * puts them back on the sending domain that the complaint was filed against.
273
+ * The same reasoning refuses `staff`, which is a written request, a
274
+ * correction, or a legal instruction, and is nobody's to reverse from a link.
275
+ *
276
+ * A runtime set and not just the type, for the reason
277
+ * {@link PLATFORM_SUPPRESSION_REASONS} gives: reasons arrive from webhook
278
+ * payloads through an untyped boundary, and the cost of the type being wrong
279
+ * once here is a complaint silently laundered.
280
+ */
281
+ export declare const OPT_IN_RELEASABLE_REASONS: readonly EmailSuppressionReason[];
282
+ /** What a completed double opt-in did to a platform suppression. */
283
+ export type ConfirmedOptInRelease =
284
+ /** A live `bounce` record was lifted. The address is mailable again. */
285
+ 'released'
286
+ /** Nothing was suppressed, or it was already released. */
287
+ | 'nothing-to-release'
288
+ /** A record stands that a round trip may not lift — see the constant. */
289
+ | 'refused'
290
+ /** The read or the write failed. The record, whatever it is, still stands. */
291
+ | 'failed';
292
+ /**
293
+ * Lift a platform suppression that a completed double opt-in has disproved.
294
+ *
295
+ * THE ONE PLACE THE AUTOMATIC RULE IS STATED, mirroring
296
+ * `releaseSiteSuppression` for the per-site list: every path that puts an
297
+ * address back in circulation without a human deciding goes through here, so
298
+ * there is one line to read and one line to change.
299
+ *
300
+ * ## Platform-wide, from one site's round trip
301
+ *
302
+ * The record being lifted asserts something host-independent — this mailbox
303
+ * does not exist, learned anywhere in the product, including on transactional
304
+ * mail that carried no site tag. A confirmation delivered to that mailbox
305
+ * disproves it just as host-independently, so scoping the release to the
306
+ * confirming site would leave a record standing that says the mailbox is dead
307
+ * while we hold proof that it is not. The site and the topic are written onto
308
+ * the record instead, which is what makes the release reviewable: an operator
309
+ * reading the row sees which site's round trip lifted it and when.
310
+ *
311
+ * ## The per-site list is NOT touched
312
+ *
313
+ * `hosts/{hostId}/suppressions` mixes a deliverability fact with a stated
314
+ * preference — an unsubscribe from that one site lives there too — and the
315
+ * email plugin's `releaseSiteSuppression` is the single guarded path that
316
+ * lifts one. Reaching around it from here would put a second, differently
317
+ * reasoned releaser on a list whose whole protection is that there is one.
318
+ *
319
+ * Never throws: it runs inside a recipient's confirmation click, and a
320
+ * Firestore failure must degrade to a suppression that stays in force, not to
321
+ * a person told their confirmation failed.
322
+ */
323
+ export declare function releaseEmailForConfirmedOptIn(input: {
324
+ email: string;
325
+ /** The site whose confirmation link was clicked, for the audit trail. */
326
+ hostId: string;
327
+ /** The stream that was confirmed, likewise. */
328
+ topicId: string;
329
+ firestore?: any;
330
+ }): Promise<ConfirmedOptInRelease>;
331
+ /**
332
+ * The BULK-SEND gate. See the module note for which senders must call this and
333
+ * which must not.
334
+ *
335
+ * FAILS CLOSED, like `isPhoneContactSuppressed`: a read that throws answers
336
+ * `true`, meaning "treat as suppressed". The cost of failing closed here is
337
+ * one delayed informational email — every caller is a cron that runs again —
338
+ * and it is nearly free besides, because every one of them is already deep
339
+ * inside a Firestore-backed sweep that a Firestore outage has stopped anyway.
340
+ * The cost of failing open is another delivery attempt at a mailbox that has
341
+ * already told us permanently that it does not exist, which is precisely the
342
+ * behaviour a provider scores a sending domain on. Never "fix" a flaky read
343
+ * here by returning false.
344
+ */
345
+ export declare function isEmailSuppressed(email: string | null | undefined, injectedFirestore?: any): Promise<boolean>;
346
+ /**
347
+ * The sendable subset of a recipient list, for the bulk senders.
348
+ *
349
+ * One `get()` per DISTINCT address rather than a query, so the check needs no
350
+ * index and cannot fail open on a missing one. The list is deduplicated first
351
+ * because the callers build it by fanning out over an org's owners and admins,
352
+ * which routinely names the same person twice.
353
+ */
354
+ export declare function filterSuppressedEmails(emails: readonly string[], injectedFirestore?: any): Promise<string[]>;
355
+ /**
356
+ * The sendable subset for a send made in ONE SITE's name — BOTH lists.
357
+ *
358
+ * A per-site suppression says "not from this site". A platform suppression
359
+ * says the address hard-bounced or somebody pressed "report spam", learned
360
+ * anywhere in the product — including on transactional mail that carried no
361
+ * site tag at all and could therefore never have reached the per-site list.
362
+ * Consulting only the site's own list mails a known-dead or complaining
363
+ * address from the one shared sending domain every tenant's mail leaves by,
364
+ * which makes it every tenant's deliverability problem rather than one
365
+ * merchant's.
366
+ *
367
+ * Composed from {@link filterSuppressedEmails} rather than reimplementing the
368
+ * platform half: normalization, de-duplication and the fail-closed posture
369
+ * live there, and a second copy of them is a second set of rules for two
370
+ * senders to disagree about.
371
+ *
372
+ * ## Both halves fail CLOSED
373
+ *
374
+ * A read that throws answers "suppressed". The platform half already does; the
375
+ * per-site half matches it, because a list we could not read is not a list
376
+ * that said this address is safe to mail. The cost of the other choice is a
377
+ * message delivered to somebody who asked us to stop.
378
+ *
379
+ * ## One `getAll`, keyed, rather than a scan of the collection
380
+ *
381
+ * The per-site half looks up exactly the addresses being mailed, by document
382
+ * id, in one round trip. Reading the whole collection instead — which is what
383
+ * the campaign sender did — is bounded by however large the collection has
384
+ * grown, so a site with more suppressions than the read window fails OPEN on
385
+ * the remainder: the people most certain not to want the mail are the ones a
386
+ * truncated read drops.
387
+ */
388
+ export declare function filterSendableForHost(hostId: string, emails: readonly string[], injectedFirestore?: any): Promise<string[]>;
389
+ /**
390
+ * The subset of `emails` that may be mailed about `topicId` on this site.
391
+ *
392
+ * The third filter a campaign passes, after the platform list and the site's
393
+ * own: the two suppression lists answer "may we mail this person at all", and
394
+ * this answers "may we mail them about THIS". A recipient who unticked
395
+ * "Promotions and offers" on the preference page is not suppressed — they
396
+ * still get the newsletter — so the fact cannot live on either suppression
397
+ * list without meaning something it does not mean.
398
+ *
399
+ * ## Two ways to be excluded, and both are held here
400
+ *
401
+ * Somebody who LEFT the stream, and somebody who has been asked to confirm
402
+ * joining it and has not. The second is what makes a double opt-in worth
403
+ * recording: an unconfirmed subscriber has to be a real quarantine, not a
404
+ * field the send path never looks at. Both come back from
405
+ * `readTopicSubscriptionState`, which is the only place the three states are
406
+ * decided.
407
+ *
408
+ * Keyed by {@link emailSuppressionKey} and read with one `getAll`, which is
409
+ * both halves of the point: the same derivation as the two lists it runs
410
+ * beside, so one person is one document id everywhere; and one round trip
411
+ * bounded by the size of the send, so adding topics does not make a campaign
412
+ * cost more to resolve.
413
+ *
414
+ * ## This one fails OPEN, and that is the opposite of its neighbors
415
+ *
416
+ * Every other filter in this module answers "suppressed" when a read throws,
417
+ * because the cost of guessing wrong is mailing somebody who told us to stop.
418
+ * Here the cost of guessing wrong in that direction is refusing to send a
419
+ * newsletter somebody asked for, on a read that failed for an unrelated
420
+ * reason — and the campaign has already passed both suppression lists, so
421
+ * nobody who asked us to stop entirely can reach this line. A topic
422
+ * preference is a narrower fact than a suppression and it gets the treatment
423
+ * that matches. A caller that wants the strict posture already has it one
424
+ * layer up.
425
+ *
426
+ * An empty `topicId` is a campaign from before topics existed, or one whose
427
+ * topic was never resolved. It filters nobody: there is no stream to have
428
+ * left.
429
+ */
430
+ export declare function filterTopicSendable(hostId: string, topicId: string | null | undefined, emails: readonly string[], injectedFirestore?: any): Promise<string[]>;
431
+ /**
432
+ * The staff queue, newest first, ordered by `suppressedAt` so a re-recorded or
433
+ * released entry surfaces again — the operator's question is "what changed",
434
+ * not "what was first written". Mirrors `listContactSuppressions`.
435
+ */
436
+ export declare function listEmailSuppressions(options?: {
437
+ limit?: number;
438
+ /**
439
+ * Where the NEXT page starts: the `suppressedAt` of the last row already
440
+ * shown, as `seconds.nanoseconds`.
441
+ *
442
+ * The full timestamp rather than milliseconds, because `startAfter` skips
443
+ * exactly the value it is given: a millisecond-truncated cursor sits BEFORE
444
+ * the record it names, so that record would arrive again at the top of the
445
+ * following page. Repeating a row is a smaller fault than skipping one and
446
+ * neither is necessary.
447
+ */
448
+ startAfter?: string | null;
449
+ firestore?: any;
450
+ }): Promise<Array<EmailSuppressionRecord & {
451
+ $id: string;
452
+ }>>;
453
+ /**
454
+ * The cursor a page hands back, from the last row on it.
455
+ *
456
+ * Null when the row carries no `suppressedAt` — every entry written since
457
+ * AGL-1918 does, and `orderBy` has already excluded any that does not, so
458
+ * this is the type narrowing rather than a case that occurs.
459
+ */
460
+ export declare function suppressionCursorFrom(record: Record<string, any> | null | undefined): string | null;
461
+ /** The inverse, for the query. Invalid input yields no cursor, never a guess. */
462
+ export declare function suppressionCursorTimestamp(cursor: string | null | undefined): Timestamp | null;
463
+ /** The `reason` an erasure row carries. Read by the capture door, below. */
464
+ export declare const HOST_ERASURE_SUPPRESSION_REASON = "erasure";
465
+ /**
466
+ * Suppress an address on one site because the person was erased. Idempotent:
467
+ * a second erasure of the same person merges onto the same row.
468
+ */
469
+ export declare function suppressEmailForHostErasure(input: {
470
+ hostId: string;
471
+ email: string;
472
+ firestore?: any;
473
+ }): Promise<{
474
+ key: string;
475
+ created: boolean;
476
+ } | null>;
477
+ /**
478
+ * Whether a site has erased this address, so a capture must not create a
479
+ * contact for it. Only an ERASURE row refuses: an ordinary unsubscribe is a
480
+ * mailing preference, and a person who unsubscribed and then bought
481
+ * something is still a customer whose order the CRM should know about.
482
+ *
483
+ * Fails OPEN. A read that throws answers `false` and logs: the alternative
484
+ * refuses every capture on the site for as long as the list is unreadable,
485
+ * which turns a transient read failure into a silent drop of the site's
486
+ * leads and orders. The window this leaves — a recreate during an outage
487
+ * of the suppression read — is logged, and the next erasure run finds the
488
+ * recreated record by the same address.
489
+ */
490
+ export declare function hostRefusesCaptureForErasure(hostId: string, email: string | null | undefined, injectedFirestore?: any): Promise<boolean>;