@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.
- package/LICENSE +201 -0
- package/README.md +7 -0
- package/jest.integration.config.d.ts +39 -0
- package/jest.integration.setup.d.ts +17 -0
- package/package.json +51 -0
- package/src/index.d.ts +17 -0
- package/src/index.js +18 -0
- package/src/index.js.map +1 -0
- package/src/lib/render-cache.d.ts +184 -0
- package/src/lib/render-cache.js +198 -0
- package/src/lib/render-cache.js.map +1 -0
- package/src/lib/server/account-addresses.d.ts +160 -0
- package/src/lib/server/account-addresses.js +311 -0
- package/src/lib/server/account-addresses.js.map +1 -0
- package/src/lib/server/account-emails.d.ts +219 -0
- package/src/lib/server/account-emails.js +640 -0
- package/src/lib/server/account-emails.js.map +1 -0
- package/src/lib/server/admin-audit.d.ts +180 -0
- package/src/lib/server/admin-audit.js +233 -0
- package/src/lib/server/admin-audit.js.map +1 -0
- package/src/lib/server/analytics-retention.d.ts +63 -0
- package/src/lib/server/analytics-retention.js +66 -0
- package/src/lib/server/analytics-retention.js.map +1 -0
- package/src/lib/server/api-http.d.ts +159 -0
- package/src/lib/server/api-http.js +230 -0
- package/src/lib/server/api-http.js.map +1 -0
- package/src/lib/server/api-keys.d.ts +117 -0
- package/src/lib/server/api-keys.js +298 -0
- package/src/lib/server/api-keys.js.map +1 -0
- package/src/lib/server/auth-handoff.d.ts +165 -0
- package/src/lib/server/auth-handoff.js +482 -0
- package/src/lib/server/auth-handoff.js.map +1 -0
- package/src/lib/server/auth-pools.d.ts +246 -0
- package/src/lib/server/auth-pools.js +551 -0
- package/src/lib/server/auth-pools.js.map +1 -0
- package/src/lib/server/billing-addons.d.ts +171 -0
- package/src/lib/server/billing-addons.js +277 -0
- package/src/lib/server/billing-addons.js.map +1 -0
- package/src/lib/server/campaign-attribution-store.d.ts +55 -0
- package/src/lib/server/campaign-attribution-store.js +95 -0
- package/src/lib/server/campaign-attribution-store.js.map +1 -0
- package/src/lib/server/campaign-conversion-attribution.d.ts +205 -0
- package/src/lib/server/campaign-conversion-attribution.js +279 -0
- package/src/lib/server/campaign-conversion-attribution.js.map +1 -0
- package/src/lib/server/client-error-report.d.ts +301 -0
- package/src/lib/server/client-error-report.js +755 -0
- package/src/lib/server/client-error-report.js.map +1 -0
- package/src/lib/server/connect-account-status.d.ts +74 -0
- package/src/lib/server/connect-account-status.js +94 -0
- package/src/lib/server/connect-account-status.js.map +1 -0
- package/src/lib/server/connect-payout-failure.d.ts +103 -0
- package/src/lib/server/connect-payout-failure.js +127 -0
- package/src/lib/server/connect-payout-failure.js.map +1 -0
- package/src/lib/server/console-api-rate-limit.d.ts +81 -0
- package/src/lib/server/console-api-rate-limit.js +111 -0
- package/src/lib/server/console-api-rate-limit.js.map +1 -0
- package/src/lib/server/console-domains.d.ts +326 -0
- package/src/lib/server/console-domains.js +779 -0
- package/src/lib/server/console-domains.js.map +1 -0
- package/src/lib/server/consume-once.d.ts +91 -0
- package/src/lib/server/consume-once.js +96 -0
- package/src/lib/server/consume-once.js.map +1 -0
- package/src/lib/server/contact-company-link.d.ts +85 -0
- package/src/lib/server/contact-company-link.js +105 -0
- package/src/lib/server/contact-company-link.js.map +1 -0
- package/src/lib/server/contact-email-engagement.d.ts +32 -0
- package/src/lib/server/contact-email-engagement.js +145 -0
- package/src/lib/server/contact-email-engagement.js.map +1 -0
- package/src/lib/server/contact-email-index.d.ts +56 -0
- package/src/lib/server/contact-email-index.js +158 -0
- package/src/lib/server/contact-email-index.js.map +1 -0
- package/src/lib/server/contact-lifecycle-floor.d.ts +89 -0
- package/src/lib/server/contact-lifecycle-floor.js +88 -0
- package/src/lib/server/contact-lifecycle-floor.js.map +1 -0
- package/src/lib/server/contact-merge.d.ts +55 -0
- package/src/lib/server/contact-merge.js +279 -0
- package/src/lib/server/contact-merge.js.map +1 -0
- package/src/lib/server/contact-suppression.d.ts +153 -0
- package/src/lib/server/contact-suppression.js +259 -0
- package/src/lib/server/contact-suppression.js.map +1 -0
- package/src/lib/server/crm-booking-activity.d.ts +86 -0
- package/src/lib/server/crm-booking-activity.js +251 -0
- package/src/lib/server/crm-booking-activity.js.map +1 -0
- package/src/lib/server/crm-email-activity.d.ts +112 -0
- package/src/lib/server/crm-email-activity.js +143 -0
- package/src/lib/server/crm-email-activity.js.map +1 -0
- package/src/lib/server/crm-inbound-email.d.ts +145 -0
- package/src/lib/server/crm-inbound-email.js +287 -0
- package/src/lib/server/crm-inbound-email.js.map +1 -0
- package/src/lib/server/crm-next-activity.d.ts +74 -0
- package/src/lib/server/crm-next-activity.js +194 -0
- package/src/lib/server/crm-next-activity.js.map +1 -0
- package/src/lib/server/crm-records.d.ts +144 -0
- package/src/lib/server/crm-records.js +218 -0
- package/src/lib/server/crm-records.js.map +1 -0
- package/src/lib/server/csp-aggregate.d.ts +62 -0
- package/src/lib/server/csp-aggregate.js +276 -0
- package/src/lib/server/csp-aggregate.js.map +1 -0
- package/src/lib/server/data-storage-gate.d.ts +66 -0
- package/src/lib/server/data-storage-gate.js +48 -0
- package/src/lib/server/data-storage-gate.js.map +1 -0
- package/src/lib/server/dataset-live-pages.d.ts +179 -0
- package/src/lib/server/dataset-live-pages.js +421 -0
- package/src/lib/server/dataset-live-pages.js.map +1 -0
- package/src/lib/server/dns-probe.d.ts +53 -0
- package/src/lib/server/dns-probe.js +184 -0
- package/src/lib/server/dns-probe.js.map +1 -0
- package/src/lib/server/document-id.d.ts +29 -0
- package/src/lib/server/document-id.js +100 -0
- package/src/lib/server/document-id.js.map +1 -0
- package/src/lib/server/domain-provider-vercel.d.ts +33 -0
- package/src/lib/server/domain-provider-vercel.js +298 -0
- package/src/lib/server/domain-provider-vercel.js.map +1 -0
- package/src/lib/server/domain-provider-webhook.d.ts +73 -0
- package/src/lib/server/domain-provider-webhook.js +223 -0
- package/src/lib/server/domain-provider-webhook.js.map +1 -0
- package/src/lib/server/domain-provider-wildcard.d.ts +54 -0
- package/src/lib/server/domain-provider-wildcard.js +163 -0
- package/src/lib/server/domain-provider-wildcard.js.map +1 -0
- package/src/lib/server/domain-provider.d.ts +197 -0
- package/src/lib/server/domain-provider.js +221 -0
- package/src/lib/server/domain-provider.js.map +1 -0
- package/src/lib/server/duplicate-activity.d.ts +54 -0
- package/src/lib/server/duplicate-activity.js +67 -0
- package/src/lib/server/duplicate-activity.js.map +1 -0
- package/src/lib/server/duplicate-resource.d.ts +55 -0
- package/src/lib/server/duplicate-resource.js +474 -0
- package/src/lib/server/duplicate-resource.js.map +1 -0
- package/src/lib/server/dynamic-list-materialize.d.ts +153 -0
- package/src/lib/server/dynamic-list-materialize.js +581 -0
- package/src/lib/server/dynamic-list-materialize.js.map +1 -0
- package/src/lib/server/edit-access-authz.d.ts +56 -0
- package/src/lib/server/edit-access-authz.js +107 -0
- package/src/lib/server/edit-access-authz.js.map +1 -0
- package/src/lib/server/edit-access-token.d.ts +72 -0
- package/src/lib/server/edit-access-token.js +116 -0
- package/src/lib/server/edit-access-token.js.map +1 -0
- package/src/lib/server/edit-hint-token.d.ts +83 -0
- package/src/lib/server/edit-hint-token.js +119 -0
- package/src/lib/server/edit-hint-token.js.map +1 -0
- package/src/lib/server/email-delivery-log.d.ts +509 -0
- package/src/lib/server/email-delivery-log.js +1043 -0
- package/src/lib/server/email-delivery-log.js.map +1 -0
- package/src/lib/server/email-flow-gate.d.ts +80 -0
- package/src/lib/server/email-flow-gate.js +153 -0
- package/src/lib/server/email-flow-gate.js.map +1 -0
- package/src/lib/server/email-marketing-gate.d.ts +333 -0
- package/src/lib/server/email-marketing-gate.js +639 -0
- package/src/lib/server/email-marketing-gate.js.map +1 -0
- package/src/lib/server/email-metering.d.ts +293 -0
- package/src/lib/server/email-metering.js +359 -0
- package/src/lib/server/email-metering.js.map +1 -0
- package/src/lib/server/email-revenue-attribution.d.ts +185 -0
- package/src/lib/server/email-revenue-attribution.js +300 -0
- package/src/lib/server/email-revenue-attribution.js.map +1 -0
- package/src/lib/server/email-send-rate.d.ts +232 -0
- package/src/lib/server/email-send-rate.js +417 -0
- package/src/lib/server/email-send-rate.js.map +1 -0
- package/src/lib/server/email-sender-reputation.d.ts +317 -0
- package/src/lib/server/email-sender-reputation.js +464 -0
- package/src/lib/server/email-sender-reputation.js.map +1 -0
- package/src/lib/server/email-suppression.d.ts +490 -0
- package/src/lib/server/email-suppression.js +648 -0
- package/src/lib/server/email-suppression.js.map +1 -0
- package/src/lib/server/email-topic-confirmation.d.ts +150 -0
- package/src/lib/server/email-topic-confirmation.js +272 -0
- package/src/lib/server/email-topic-confirmation.js.map +1 -0
- package/src/lib/server/email-unsubscribe-link.d.ts +174 -0
- package/src/lib/server/email-unsubscribe-link.js +236 -0
- package/src/lib/server/email-unsubscribe-link.js.map +1 -0
- package/src/lib/server/erase-person.d.ts +116 -0
- package/src/lib/server/erase-person.js +272 -0
- package/src/lib/server/erase-person.js.map +1 -0
- package/src/lib/server/erase.d.ts +458 -0
- package/src/lib/server/erase.js +1506 -0
- package/src/lib/server/erase.js.map +1 -0
- package/src/lib/server/firebase-admin.d.ts +71 -0
- package/src/lib/server/firebase-admin.js +343 -0
- package/src/lib/server/firebase-admin.js.map +1 -0
- package/src/lib/server/form-dataset-binding-token.d.ts +35 -0
- package/src/lib/server/form-dataset-binding-token.js +107 -0
- package/src/lib/server/form-dataset-binding-token.js.map +1 -0
- package/src/lib/server/free-workspace-cap.d.ts +201 -0
- package/src/lib/server/free-workspace-cap.js +404 -0
- package/src/lib/server/free-workspace-cap.js.map +1 -0
- package/src/lib/server/ga4-measurement-protocol.d.ts +256 -0
- package/src/lib/server/ga4-measurement-protocol.js +558 -0
- package/src/lib/server/ga4-measurement-protocol.js.map +1 -0
- package/src/lib/server/host-email-tokens.d.ts +47 -0
- package/src/lib/server/host-email-tokens.js +72 -0
- package/src/lib/server/host-email-tokens.js.map +1 -0
- package/src/lib/server/host-memberships.d.ts +54 -0
- package/src/lib/server/host-memberships.js +194 -0
- package/src/lib/server/host-memberships.js.map +1 -0
- package/src/lib/server/host-sending-domain.d.ts +292 -0
- package/src/lib/server/host-sending-domain.js +451 -0
- package/src/lib/server/host-sending-domain.js.map +1 -0
- package/src/lib/server/host-visitor-records.d.ts +150 -0
- package/src/lib/server/host-visitor-records.js +262 -0
- package/src/lib/server/host-visitor-records.js.map +1 -0
- package/src/lib/server/id-token-refusal.d.ts +28 -0
- package/src/lib/server/id-token-refusal.js +111 -0
- package/src/lib/server/id-token-refusal.js.map +1 -0
- package/src/lib/server/legal-acceptance.d.ts +214 -0
- package/src/lib/server/legal-acceptance.js +305 -0
- package/src/lib/server/legal-acceptance.js.map +1 -0
- package/src/lib/server/list-members.d.ts +211 -0
- package/src/lib/server/list-members.js +176 -0
- package/src/lib/server/list-members.js.map +1 -0
- package/src/lib/server/live-page-usage.d.ts +202 -0
- package/src/lib/server/live-page-usage.js +300 -0
- package/src/lib/server/live-page-usage.js.map +1 -0
- package/src/lib/server/lockdown.d.ts +313 -0
- package/src/lib/server/lockdown.js +643 -0
- package/src/lib/server/lockdown.js.map +1 -0
- package/src/lib/server/media-cdn-rate-limit.d.ts +188 -0
- package/src/lib/server/media-cdn-rate-limit.js +204 -0
- package/src/lib/server/media-cdn-rate-limit.js.map +1 -0
- package/src/lib/server/media-delivery.d.ts +267 -0
- package/src/lib/server/media-delivery.js +485 -0
- package/src/lib/server/media-delivery.js.map +1 -0
- package/src/lib/server/media-download-tokens.d.ts +161 -0
- package/src/lib/server/media-download-tokens.js +386 -0
- package/src/lib/server/media-download-tokens.js.map +1 -0
- package/src/lib/server/media-quarantine.d.ts +127 -0
- package/src/lib/server/media-quarantine.js +170 -0
- package/src/lib/server/media-quarantine.js.map +1 -0
- package/src/lib/server/media-signing.d.ts +126 -0
- package/src/lib/server/media-signing.js +159 -0
- package/src/lib/server/media-signing.js.map +1 -0
- package/src/lib/server/media-storage-path.d.ts +96 -0
- package/src/lib/server/media-storage-path.js +111 -0
- package/src/lib/server/media-storage-path.js.map +1 -0
- package/src/lib/server/media-strong-digest.d.ts +85 -0
- package/src/lib/server/media-strong-digest.js +190 -0
- package/src/lib/server/media-strong-digest.js.map +1 -0
- package/src/lib/server/media-tombstone.d.ts +276 -0
- package/src/lib/server/media-tombstone.js +421 -0
- package/src/lib/server/media-tombstone.js.map +1 -0
- package/src/lib/server/media-variants.d.ts +309 -0
- package/src/lib/server/media-variants.js +428 -0
- package/src/lib/server/media-variants.js.map +1 -0
- package/src/lib/server/member-email-aliases.d.ts +180 -0
- package/src/lib/server/member-email-aliases.js +420 -0
- package/src/lib/server/member-email-aliases.js.map +1 -0
- package/src/lib/server/member-photo.d.ts +88 -0
- package/src/lib/server/member-photo.js +185 -0
- package/src/lib/server/member-photo.js.map +1 -0
- package/src/lib/server/membership-recover-throttle.d.ts +211 -0
- package/src/lib/server/membership-recover-throttle.js +231 -0
- package/src/lib/server/membership-recover-throttle.js.map +1 -0
- package/src/lib/server/notifications.d.ts +55 -0
- package/src/lib/server/notifications.js +134 -0
- package/src/lib/server/notifications.js.map +1 -0
- package/src/lib/server/org-billing.d.ts +97 -0
- package/src/lib/server/org-billing.js +236 -0
- package/src/lib/server/org-billing.js.map +1 -0
- package/src/lib/server/organizations.d.ts +837 -0
- package/src/lib/server/organizations.js +1814 -0
- package/src/lib/server/organizations.js.map +1 -0
- package/src/lib/server/password-reset-throttle.d.ts +84 -0
- package/src/lib/server/password-reset-throttle.js +102 -0
- package/src/lib/server/password-reset-throttle.js.map +1 -0
- package/src/lib/server/personal-data-export.d.ts +241 -0
- package/src/lib/server/personal-data-export.js +858 -0
- package/src/lib/server/personal-data-export.js.map +1 -0
- package/src/lib/server/platform-domain-names.d.ts +62 -0
- package/src/lib/server/platform-domain-names.js +197 -0
- package/src/lib/server/platform-domain-names.js.map +1 -0
- package/src/lib/server/platform-marketing-consent.d.ts +133 -0
- package/src/lib/server/platform-marketing-consent.js +209 -0
- package/src/lib/server/platform-marketing-consent.js.map +1 -0
- package/src/lib/server/rate-limit-store.d.ts +702 -0
- package/src/lib/server/rate-limit-store.js +1220 -0
- package/src/lib/server/rate-limit-store.js.map +1 -0
- package/src/lib/server/realm-plugins.d.ts +67 -0
- package/src/lib/server/realm-plugins.js +250 -0
- package/src/lib/server/realm-plugins.js.map +1 -0
- package/src/lib/server/recaptcha-allowlist.d.ts +90 -0
- package/src/lib/server/recaptcha-allowlist.js +409 -0
- package/src/lib/server/recaptcha-allowlist.js.map +1 -0
- package/src/lib/server/release-flags.d.ts +105 -0
- package/src/lib/server/release-flags.js +183 -0
- package/src/lib/server/release-flags.js.map +1 -0
- package/src/lib/server/replay-erasures.d.ts +126 -0
- package/src/lib/server/replay-erasures.js +217 -0
- package/src/lib/server/replay-erasures.js.map +1 -0
- package/src/lib/server/resolve-people.d.ts +66 -0
- package/src/lib/server/resolve-people.js +112 -0
- package/src/lib/server/resolve-people.js.map +1 -0
- package/src/lib/server/safe-equal.d.ts +45 -0
- package/src/lib/server/safe-equal.js +58 -0
- package/src/lib/server/safe-equal.js.map +1 -0
- package/src/lib/server/sending-domain-debt.d.ts +127 -0
- package/src/lib/server/sending-domain-debt.js +268 -0
- package/src/lib/server/sending-domain-debt.js.map +1 -0
- package/src/lib/server/sending-domain-recheck.d.ts +151 -0
- package/src/lib/server/sending-domain-recheck.js +253 -0
- package/src/lib/server/sending-domain-recheck.js.map +1 -0
- package/src/lib/server/sending-domains.d.ts +364 -0
- package/src/lib/server/sending-domains.js +683 -0
- package/src/lib/server/sending-domains.js.map +1 -0
- package/src/lib/server/serve-media-cdn.d.ts +433 -0
- package/src/lib/server/serve-media-cdn.js +1370 -0
- package/src/lib/server/serve-media-cdn.js.map +1 -0
- package/src/lib/server/serve-plugin-fetch.d.ts +61 -0
- package/src/lib/server/serve-plugin-fetch.js +294 -0
- package/src/lib/server/serve-plugin-fetch.js.map +1 -0
- package/src/lib/server/sms-keywords.d.ts +63 -0
- package/src/lib/server/sms-keywords.js +146 -0
- package/src/lib/server/sms-keywords.js.map +1 -0
- package/src/lib/server/sso-break-glass-owners.d.ts +91 -0
- package/src/lib/server/sso-break-glass-owners.js +227 -0
- package/src/lib/server/sso-break-glass-owners.js.map +1 -0
- package/src/lib/server/sso-domain-policy.d.ts +140 -0
- package/src/lib/server/sso-domain-policy.js +239 -0
- package/src/lib/server/sso-domain-policy.js.map +1 -0
- package/src/lib/server/sso-drift-logic.d.ts +106 -0
- package/src/lib/server/sso-drift-logic.js +95 -0
- package/src/lib/server/sso-drift-logic.js.map +1 -0
- package/src/lib/server/sso-enforcement.d.ts +204 -0
- package/src/lib/server/sso-enforcement.js +309 -0
- package/src/lib/server/sso-enforcement.js.map +1 -0
- package/src/lib/server/sso-provisioning.d.ts +320 -0
- package/src/lib/server/sso-provisioning.js +715 -0
- package/src/lib/server/sso-provisioning.js.map +1 -0
- package/src/lib/server/staff-alert-email.d.ts +41 -0
- package/src/lib/server/staff-alert-email.js +63 -0
- package/src/lib/server/staff-alert-email.js.map +1 -0
- package/src/lib/server/stripe-account-mode.d.ts +156 -0
- package/src/lib/server/stripe-account-mode.js +162 -0
- package/src/lib/server/stripe-account-mode.js.map +1 -0
- package/src/lib/server/tenant-write-lockdown.d.ts +131 -0
- package/src/lib/server/tenant-write-lockdown.js +176 -0
- package/src/lib/server/tenant-write-lockdown.js.map +1 -0
- package/src/lib/server/test-firestore.d.ts +45 -0
- package/src/lib/server/test-firestore.js +124 -0
- package/src/lib/server/test-firestore.js.map +1 -0
- package/src/lib/server/token-revocation.d.ts +140 -0
- package/src/lib/server/token-revocation.js +255 -0
- package/src/lib/server/token-revocation.js.map +1 -0
- package/src/lib/server/update-existing.d.ts +32 -0
- package/src/lib/server/update-existing.js +73 -0
- package/src/lib/server/update-existing.js.map +1 -0
- package/src/lib/server/upload-cors-reconcile.d.ts +118 -0
- package/src/lib/server/upload-cors-reconcile.js +234 -0
- package/src/lib/server/upload-cors-reconcile.js.map +1 -0
- package/src/lib/server/upsert-contact.d.ts +262 -0
- package/src/lib/server/upsert-contact.js +546 -0
- package/src/lib/server/upsert-contact.js.map +1 -0
- package/src/lib/server/usage-invoice.d.ts +203 -0
- package/src/lib/server/usage-invoice.js +397 -0
- package/src/lib/server/usage-invoice.js.map +1 -0
- package/src/lib/server/user-profiles.d.ts +151 -0
- package/src/lib/server/user-profiles.js +364 -0
- package/src/lib/server/user-profiles.js.map +1 -0
- package/src/lib/server/vercel-drain-signature.d.ts +30 -0
- package/src/lib/server/vercel-drain-signature.js +61 -0
- package/src/lib/server/vercel-drain-signature.js.map +1 -0
- package/src/lib/server/vercel-log-drain.d.ts +259 -0
- package/src/lib/server/vercel-log-drain.js +479 -0
- package/src/lib/server/vercel-log-drain.js.map +1 -0
- package/src/lib/server/verify-email-cooldown.d.ts +102 -0
- package/src/lib/server/verify-email-cooldown.js +114 -0
- package/src/lib/server/verify-email-cooldown.js.map +1 -0
- package/src/lib/server/visitor-write-rate-limit.d.ts +87 -0
- package/src/lib/server/visitor-write-rate-limit.js +117 -0
- package/src/lib/server/visitor-write-rate-limit.js.map +1 -0
- package/src/lib/server/workspace-domains.d.ts +156 -0
- package/src/lib/server/workspace-domains.js +271 -0
- package/src/lib/server/workspace-domains.js.map +1 -0
- package/src/tenancy.d.ts +115 -0
- package/src/tenancy.js +142 -0
- package/src/tenancy.js.map +1 -0
|
@@ -0,0 +1,317 @@
|
|
|
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
|
+
* PER-TENANT SENDING REPUTATION — the durable half.
|
|
19
|
+
*
|
|
20
|
+
* The policy is pure and lives in `@aglyn/shared-util-email`
|
|
21
|
+
* (`sender-reputation.ts`); this adds the counters that make a rate a fact
|
|
22
|
+
* rather than an intention, and the daily claim that paces a workspace's
|
|
23
|
+
* first week.
|
|
24
|
+
*
|
|
25
|
+
* ## One document per workspace per day
|
|
26
|
+
*
|
|
27
|
+
* `rateLimits/emailRep_{YYYY-MM-DD}_{orgId}` holds four numbers:
|
|
28
|
+
*
|
|
29
|
+
* - `claimed` — campaign messages the day's ramp has granted. The PACING
|
|
30
|
+
* counter, taken before a send and reconciled to what actually left.
|
|
31
|
+
* - `accepted` — campaign messages that actually left. The DENOMINATOR every
|
|
32
|
+
* rate divides by.
|
|
33
|
+
* - `bounced`, `complained` — what the provider reported back.
|
|
34
|
+
*
|
|
35
|
+
* A day per document rather than a map of days on one, because the day is
|
|
36
|
+
* what the TTL policy can sweep: `rateLimits` already carries an `expiresAt`
|
|
37
|
+
* policy, and a document that ages out is a window that prunes itself. A map
|
|
38
|
+
* of every day a workspace has ever sent would grow forever and would have to
|
|
39
|
+
* be pruned by a job nobody would write.
|
|
40
|
+
*
|
|
41
|
+
* A per-ORG document rather than per-site, because the org is the tenant: the
|
|
42
|
+
* plan, the monthly allowance and the hourly share are all keyed on it, and a
|
|
43
|
+
* merchant with three sites on one domain is one sender to a mailbox
|
|
44
|
+
* provider.
|
|
45
|
+
*
|
|
46
|
+
* The window document deliberately carries **no `lastAtMs`** — the
|
|
47
|
+
* rate-limiter health probe queries this collection on that field, and a
|
|
48
|
+
* per-day document in its range would compete with the degradation markers it
|
|
49
|
+
* exists to find. The same reasoning as `sendRate_*` and `sendRateOrg_*`
|
|
50
|
+
* beside it.
|
|
51
|
+
*
|
|
52
|
+
* ## Which day a bounce is filed under
|
|
53
|
+
*
|
|
54
|
+
* The day the EVENT arrived, not the day the message was sent. The webhook
|
|
55
|
+
* knows the first and would need a per-message lookup for the second, and
|
|
56
|
+
* over a seven-day window the two differ only at the edges — a bounce lands
|
|
57
|
+
* within minutes and a complaint within hours or a day. Stated because the
|
|
58
|
+
* rate is a ratio of two things counted on slightly different clocks, and a
|
|
59
|
+
* reader comparing it against a provider's dashboard should know why they
|
|
60
|
+
* will not agree to the last decimal.
|
|
61
|
+
*
|
|
62
|
+
* ## Failure posture: OPEN, and that is not the usual answer here
|
|
63
|
+
*
|
|
64
|
+
* An unreadable counter grades `ok` and grants the send, matching
|
|
65
|
+
* `consumeEmailSendBudget` and `claimOrgEmailSendBudget`. The breaker is the
|
|
66
|
+
* one control in this file that could refuse a paying customer's campaign,
|
|
67
|
+
* and a refusal produced by a Firestore blip is an outage dressed as a policy
|
|
68
|
+
* decision. The reputation risk it fails to catch is bounded by an hour of
|
|
69
|
+
* sending; the refusal it would produce is not bounded by anything.
|
|
70
|
+
*/
|
|
71
|
+
import { type EmailRampVerdict, type EmailReputationCounts, type EmailReputationPolicy, type EmailReputationVerdict } from '@aglyn/shared-util-email';
|
|
72
|
+
/** Id prefix for the per-org, per-day reputation documents. */
|
|
73
|
+
export declare const EMAIL_REPUTATION_DOC_PREFIX = "emailRep_";
|
|
74
|
+
/** The document id for one workspace's day. */
|
|
75
|
+
export declare function emailReputationDocId(dayKey: string, orgId: string): string;
|
|
76
|
+
/** The counted fields, so a writer cannot invent a fifth by typo. */
|
|
77
|
+
export type EmailReputationCounter = 'claimed' | 'accepted' | 'bounced' | 'complained';
|
|
78
|
+
/**
|
|
79
|
+
* Adds to one of a workspace's daily counters.
|
|
80
|
+
*
|
|
81
|
+
* **Never throws.** Reputation accounting runs after mail has gone out, or
|
|
82
|
+
* inside a webhook the provider will retry — a counter write that failed must
|
|
83
|
+
* not turn a delivered campaign into a 500 or a webhook into a retry storm.
|
|
84
|
+
* `FieldValue.increment` rather than a transaction because nothing decides
|
|
85
|
+
* anything from this write: the decision is made by a separate read, and an
|
|
86
|
+
* increment is the contention-free way to record a fact.
|
|
87
|
+
*/
|
|
88
|
+
export declare function recordEmailReputationEvent(options: {
|
|
89
|
+
orgId: string;
|
|
90
|
+
counter: EmailReputationCounter;
|
|
91
|
+
count?: number;
|
|
92
|
+
atMs?: number;
|
|
93
|
+
firestore?: any;
|
|
94
|
+
}): Promise<void>;
|
|
95
|
+
/** Campaign messages that actually left, for a workspace. The denominator. */
|
|
96
|
+
export declare function recordCampaignAccepted(orgId: string, count: number, options?: {
|
|
97
|
+
atMs?: number;
|
|
98
|
+
firestore?: any;
|
|
99
|
+
}): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* A permanent bounce or a spam complaint, attributed to the workspace that
|
|
102
|
+
* sent it.
|
|
103
|
+
*
|
|
104
|
+
* The suppression the same event produces is a separate act and is not
|
|
105
|
+
* conditional on this: an address comes off the list whether or not the
|
|
106
|
+
* counter write lands.
|
|
107
|
+
*/
|
|
108
|
+
export declare function recordEmailReputationFailure(orgId: string, kind: 'bounce' | 'complaint', options?: {
|
|
109
|
+
atMs?: number;
|
|
110
|
+
firestore?: any;
|
|
111
|
+
}): Promise<void>;
|
|
112
|
+
/** The counts a workspace's window holds, plus what the ramp needs. */
|
|
113
|
+
export interface SenderReputationWindow extends EmailReputationCounts {
|
|
114
|
+
/**
|
|
115
|
+
* Campaign messages the ramp has granted TODAY.
|
|
116
|
+
*
|
|
117
|
+
* Read here rather than by a second query because today's document is
|
|
118
|
+
* already in this window: the ramp needs one number off it and the rates
|
|
119
|
+
* need three off all of them, and two reads of one document to answer two
|
|
120
|
+
* questions about the same workspace is a round trip nobody has to pay.
|
|
121
|
+
*/
|
|
122
|
+
claimedToday: number;
|
|
123
|
+
/** Days the window covers. */
|
|
124
|
+
windowDays: number;
|
|
125
|
+
/** True when the window could not be read and everything below is zero. */
|
|
126
|
+
degraded: boolean;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Sums a workspace's last {@link EMAIL_REPUTATION_WINDOW_DAYS} days.
|
|
130
|
+
*
|
|
131
|
+
* One `getAll` over the window's day documents — seven reads per campaign,
|
|
132
|
+
* not per message, and none at all for a workspace that has never sent. An
|
|
133
|
+
* absent day is a quiet day and reads as zero.
|
|
134
|
+
*/
|
|
135
|
+
export declare function readSenderReputationWindow(options: {
|
|
136
|
+
orgId: string;
|
|
137
|
+
now?: number;
|
|
138
|
+
windowDays?: number;
|
|
139
|
+
firestore?: any;
|
|
140
|
+
}): Promise<SenderReputationWindow>;
|
|
141
|
+
/** A workspace's reputation, and whether its campaigns may go out. */
|
|
142
|
+
export interface SenderReputationRead extends EmailReputationVerdict {
|
|
143
|
+
/** True when the window could not be read, so nothing was graded. */
|
|
144
|
+
degraded: boolean;
|
|
145
|
+
/** The counts the grade was made from, so a caller can size a ramp too. */
|
|
146
|
+
window: SenderReputationWindow;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Grades one workspace.
|
|
150
|
+
*
|
|
151
|
+
* The policy and the grace period come from the ORG DOCUMENT, which the
|
|
152
|
+
* campaign sender has already read — passed in rather than re-fetched, so
|
|
153
|
+
* this costs the window read and nothing else.
|
|
154
|
+
*/
|
|
155
|
+
export declare function readSenderReputation(options: {
|
|
156
|
+
orgId: string;
|
|
157
|
+
policy?: unknown;
|
|
158
|
+
reinstatedUntilMs?: unknown;
|
|
159
|
+
now?: number;
|
|
160
|
+
firestore?: any;
|
|
161
|
+
}): Promise<SenderReputationRead>;
|
|
162
|
+
/**
|
|
163
|
+
* The ramp step a workspace has EARNED, from a window it has already read.
|
|
164
|
+
*
|
|
165
|
+
* A thin wrapper over the pure policy that supplies the one number the policy
|
|
166
|
+
* cannot know: what a graduated workspace's day is, which is a share of the
|
|
167
|
+
* live platform ceiling and therefore moves with a staff ramp.
|
|
168
|
+
*/
|
|
169
|
+
export declare function resolveOrgEmailRamp(options: {
|
|
170
|
+
/** Days since the workspace was created; null or absent graduates it. */
|
|
171
|
+
ageDays: number | null | undefined;
|
|
172
|
+
/** Campaign messages it has delivered inside the window. */
|
|
173
|
+
deliveredLifetime: number;
|
|
174
|
+
/** The live platform ceiling. */
|
|
175
|
+
platformPerHour: number;
|
|
176
|
+
}): EmailRampVerdict;
|
|
177
|
+
/** A workspace's ramp step, and whether the history behind it was readable. */
|
|
178
|
+
export interface OrgEmailRampRead {
|
|
179
|
+
/** The step, from the age and the delivery history that resolved. */
|
|
180
|
+
ramp: EmailRampVerdict;
|
|
181
|
+
/**
|
|
182
|
+
* True when the ramp BINDS and the window it is sized from was unreadable,
|
|
183
|
+
* so {@link ramp} is a floor rather than an answer.
|
|
184
|
+
*
|
|
185
|
+
* A caller that pages a batch — the campaign path — may treat this as the
|
|
186
|
+
* step and carry on, because the floor is the lowest step and erring low
|
|
187
|
+
* defers mail rather than sending it. A caller that admits or refuses ONE
|
|
188
|
+
* message has no such third answer and must refuse: see
|
|
189
|
+
* {@link readOrgEmailRamp}.
|
|
190
|
+
*/
|
|
191
|
+
degraded: boolean;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* A workspace's ramp step, resolved from its record and its history.
|
|
195
|
+
*
|
|
196
|
+
* The reads {@link resolveOrgEmailRamp} needs, in the order that pays for
|
|
197
|
+
* the fewest of them. The platform ceiling comes first because it is process-
|
|
198
|
+
* cached for fifteen seconds and therefore free; the seven-day window is a
|
|
199
|
+
* `getAll` and is only paid when the ramp can still bind.
|
|
200
|
+
*
|
|
201
|
+
* ## A graduated workspace pays nothing
|
|
202
|
+
*
|
|
203
|
+
* Age alone decides graduation — delivery volume can only RAISE a step, never
|
|
204
|
+
* reach past the last one — so a workspace past its first week is answered
|
|
205
|
+
* from the org record with no window read at all. That is every existing
|
|
206
|
+
* customer and every org whose record predates the creation timestamp, which
|
|
207
|
+
* is to say almost every call.
|
|
208
|
+
*
|
|
209
|
+
* ## An unreadable window is `degraded`, and it is the caller's to answer
|
|
210
|
+
*
|
|
211
|
+
* The window read grades itself rather than throwing, and an unreadable one
|
|
212
|
+
* reads as zero delivered — the LOWEST step, which is the conservative
|
|
213
|
+
* direction for a ceiling. What it is not is a fact, so it is flagged: a
|
|
214
|
+
* surface admitting one message at a time cannot defer the remainder to
|
|
215
|
+
* tomorrow the way a campaign can, and a limiter with no answer must refuse
|
|
216
|
+
* rather than admit.
|
|
217
|
+
*
|
|
218
|
+
* ## The platform flag parks this control
|
|
219
|
+
*
|
|
220
|
+
* `enabled: false` on the send-rate config graduates every workspace here,
|
|
221
|
+
* exactly as it parks the hourly share and {@link claimOrgEmailSendDay} — one
|
|
222
|
+
* switch, and it turns the ramp off everywhere it is consulted.
|
|
223
|
+
*/
|
|
224
|
+
export declare function readOrgEmailRamp(options: {
|
|
225
|
+
orgId: string;
|
|
226
|
+
/** The org record's `createdAt`, in whatever shape it was stored. */
|
|
227
|
+
createdAt: unknown;
|
|
228
|
+
now?: number;
|
|
229
|
+
firestore?: any;
|
|
230
|
+
}): Promise<OrgEmailRampRead>;
|
|
231
|
+
/** The answer to a per-day ramp claim. Every field is a stated number. */
|
|
232
|
+
export interface OrgEmailSendDayClaim {
|
|
233
|
+
allowed: boolean;
|
|
234
|
+
/** Messages claimed today BEFORE this send. */
|
|
235
|
+
used: number;
|
|
236
|
+
/** What this workspace may send today. */
|
|
237
|
+
ceiling: number;
|
|
238
|
+
/** Headroom after this send, floored at 0. */
|
|
239
|
+
remaining: number;
|
|
240
|
+
/** When the day rolls and a deferred campaign may go, ms. */
|
|
241
|
+
retryAtMs: number;
|
|
242
|
+
/** The ramp decision the ceiling came from. */
|
|
243
|
+
ramp: EmailRampVerdict;
|
|
244
|
+
/** True when the counter was unreachable and this failed open. */
|
|
245
|
+
degraded: boolean;
|
|
246
|
+
/**
|
|
247
|
+
* What to hand {@link reconcileOrgEmailSendDay} once the batch is done.
|
|
248
|
+
* Null when nothing was claimed — a graduated workspace, a parked control,
|
|
249
|
+
* or a refusal.
|
|
250
|
+
*/
|
|
251
|
+
reservation: OrgEmailSendDayReservation | null;
|
|
252
|
+
}
|
|
253
|
+
/** A claim on a day's ramp, so an undelivered remainder can be given back. */
|
|
254
|
+
export interface OrgEmailSendDayReservation {
|
|
255
|
+
orgId: string;
|
|
256
|
+
dayKey: string;
|
|
257
|
+
claimed: number;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* THE NEW-SENDER RAMP, ENFORCED.
|
|
261
|
+
*
|
|
262
|
+
* Claims `count` campaign messages against what this workspace may send
|
|
263
|
+
* today, atomically. The transaction reads the counter and writes an ABSOLUTE
|
|
264
|
+
* value derived from that read rather than an increment, for the reason
|
|
265
|
+
* `reserveCampaignEmailSends` and `claimOrgEmailSendBudget` both do: the read
|
|
266
|
+
* is the authority for the decision, and an increment proves nothing about
|
|
267
|
+
* the value the decision was made from.
|
|
268
|
+
*
|
|
269
|
+
* The ceiling arrives as a resolved {@link EmailRampVerdict} rather than
|
|
270
|
+
* being derived here, because the caller has already paid the window read
|
|
271
|
+
* that decides which step the workspace is on — see
|
|
272
|
+
* {@link resolveOrgEmailRamp}. A graduated workspace claims nothing at all:
|
|
273
|
+
* the ramp does not bind it, and the hourly share that does has already been
|
|
274
|
+
* claimed by the time this runs.
|
|
275
|
+
*
|
|
276
|
+
* **Campaigns only**, like the hourly claim beside it. This function is not
|
|
277
|
+
* on `sendEmail`'s path and cannot be reached by a transactional message.
|
|
278
|
+
*
|
|
279
|
+
* A refused claim writes NOTHING — a campaign that resumes tomorrow must not
|
|
280
|
+
* have spent tomorrow's budget on being told no.
|
|
281
|
+
*/
|
|
282
|
+
export declare function claimOrgEmailSendDay(options: {
|
|
283
|
+
orgId: string;
|
|
284
|
+
/** Messages this batch would send. */
|
|
285
|
+
count: number;
|
|
286
|
+
/** What this workspace may send today, from {@link resolveOrgEmailRamp}. */
|
|
287
|
+
ramp: EmailRampVerdict;
|
|
288
|
+
/** False parks the control, exactly as the platform governor's flag does. */
|
|
289
|
+
enabled?: boolean;
|
|
290
|
+
now?: number;
|
|
291
|
+
firestore?: any;
|
|
292
|
+
}): Promise<OrgEmailSendDayClaim>;
|
|
293
|
+
/**
|
|
294
|
+
* Returns the undelivered part of a day's ramp claim.
|
|
295
|
+
*
|
|
296
|
+
* The hourly claim is deliberately never reconciled — its window is an hour
|
|
297
|
+
* and an unrefunded remainder costs the org the rest of it. A DAY is long
|
|
298
|
+
* enough that the same choice would cost a new workspace its whole first day
|
|
299
|
+
* over one failed batch, which is the opposite of what a ramp is for.
|
|
300
|
+
*
|
|
301
|
+
* **Never throws** and never drives the counter below zero, exactly as
|
|
302
|
+
* `reconcileCampaignSendReservation` does one surface over.
|
|
303
|
+
*/
|
|
304
|
+
export declare function reconcileOrgEmailSendDay(reservation: OrgEmailSendDayReservation | null | undefined, delivered: number, firestore?: any): Promise<void>;
|
|
305
|
+
/**
|
|
306
|
+
* How old a workspace is, in days, from whatever its `createdAt` turns out to
|
|
307
|
+
* be.
|
|
308
|
+
*
|
|
309
|
+
* Firestore hands back a `Timestamp`, a restore or a fixture can leave a
|
|
310
|
+
* number, and an org written before the field existed has nothing. All three
|
|
311
|
+
* are handled and the last one answers `null`, which
|
|
312
|
+
* {@link claimOrgEmailSendDay} reads as graduated — the only safe direction,
|
|
313
|
+
* for the reason stated there.
|
|
314
|
+
*/
|
|
315
|
+
export declare function orgAgeDays(createdAt: unknown, now?: number): number | null;
|
|
316
|
+
/** Re-exported so a caller reads one module for the whole control. */
|
|
317
|
+
export type { EmailReputationPolicy, EmailRampVerdict };
|