@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,54 @@
|
|
|
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 wildcard driver — a container behind a proxy that already answers for
|
|
19
|
+
* `*.example.com`.
|
|
20
|
+
*
|
|
21
|
+
* This is the ordinary Docker shape and the reason the seam exists. An
|
|
22
|
+
* operator points one wildcard DNS record at their proxy, gets one wildcard
|
|
23
|
+
* certificate, and every workspace subdomain and every platform site subdomain
|
|
24
|
+
* resolves the moment it is created. There is no API to call because there is
|
|
25
|
+
* nothing to register: the name already works.
|
|
26
|
+
*
|
|
27
|
+
* So `attach` here is an assertion, not an action. That is exactly why the
|
|
28
|
+
* provider is never inferred — reporting a name as serving without checking is
|
|
29
|
+
* only honest when a human has said "my proxy answers for that whole apex",
|
|
30
|
+
* and `AGLYN_DOMAIN_PROVIDER=wildcard` is where they say it.
|
|
31
|
+
*
|
|
32
|
+
* ## What it will not claim
|
|
33
|
+
*
|
|
34
|
+
* A name OUTSIDE the configured suffixes — a customer's own `shop.acme.com` —
|
|
35
|
+
* is not covered by anyone's wildcard. This driver has no way to add it and no
|
|
36
|
+
* way to see it, so it says so: `skipped` on attach, `unknown` on status. It
|
|
37
|
+
* never reports such a name as serving on the strength of a suffix it does not
|
|
38
|
+
* match, and it never reports it as broken either, because an operator who
|
|
39
|
+
* added a vhost by hand has a working domain this cannot see. Operators who
|
|
40
|
+
* want custom domains registered automatically use the `webhook` driver, which
|
|
41
|
+
* can reach their proxy's own API.
|
|
42
|
+
*/
|
|
43
|
+
import { type DomainProvider } from './domain-provider';
|
|
44
|
+
/**
|
|
45
|
+
* Whether `domain` is a name the operator's wildcard actually answers for.
|
|
46
|
+
*
|
|
47
|
+
* A wildcard record covers ONE label. `*.example.com` serves `a.example.com`
|
|
48
|
+
* and does not serve `a.b.example.com` — nor `example.com` itself — and a
|
|
49
|
+
* certificate issued for `*.example.com` covers exactly the same set. Matching
|
|
50
|
+
* on "ends with the suffix" would report both of those as serving, which for
|
|
51
|
+
* the deeper name is a TLS error the operator sees before we do.
|
|
52
|
+
*/
|
|
53
|
+
export declare function wildcardCovers(domain: string, suffixes: string[]): boolean;
|
|
54
|
+
export declare function wildcardDomainProvider(): DomainProvider;
|
|
@@ -0,0 +1,163 @@
|
|
|
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
|
+
* The wildcard driver — a container behind a proxy that already answers for
|
|
18
|
+
* `*.example.com`.
|
|
19
|
+
*
|
|
20
|
+
* This is the ordinary Docker shape and the reason the seam exists. An
|
|
21
|
+
* operator points one wildcard DNS record at their proxy, gets one wildcard
|
|
22
|
+
* certificate, and every workspace subdomain and every platform site subdomain
|
|
23
|
+
* resolves the moment it is created. There is no API to call because there is
|
|
24
|
+
* nothing to register: the name already works.
|
|
25
|
+
*
|
|
26
|
+
* So `attach` here is an assertion, not an action. That is exactly why the
|
|
27
|
+
* provider is never inferred — reporting a name as serving without checking is
|
|
28
|
+
* only honest when a human has said "my proxy answers for that whole apex",
|
|
29
|
+
* and `AGLYN_DOMAIN_PROVIDER=wildcard` is where they say it.
|
|
30
|
+
*
|
|
31
|
+
* ## What it will not claim
|
|
32
|
+
*
|
|
33
|
+
* A name OUTSIDE the configured suffixes — a customer's own `shop.acme.com` —
|
|
34
|
+
* is not covered by anyone's wildcard. This driver has no way to add it and no
|
|
35
|
+
* way to see it, so it says so: `skipped` on attach, `unknown` on status. It
|
|
36
|
+
* never reports such a name as serving on the strength of a suffix it does not
|
|
37
|
+
* match, and it never reports it as broken either, because an operator who
|
|
38
|
+
* added a vhost by hand has a working domain this cannot see. Operators who
|
|
39
|
+
* want custom domains registered automatically use the `webhook` driver, which
|
|
40
|
+
* can reach their proxy's own API.
|
|
41
|
+
*/ import { domainStatus, normalizeHost } from "./domain-provider.js";
|
|
42
|
+
/**
|
|
43
|
+
* The apexes the operator's DNS and certificate already cover.
|
|
44
|
+
*
|
|
45
|
+
* Falls back to the two the product itself hands out — the console's workspace
|
|
46
|
+
* domain and the tenant apex — because those are the names Aglyn generates and
|
|
47
|
+
* therefore the ones an operator choosing this driver is choosing it FOR. A
|
|
48
|
+
* deployment serving more than those, or serving them under different names
|
|
49
|
+
* per scope, lists them explicitly.
|
|
50
|
+
*
|
|
51
|
+
* ⛔ NO hardcoded apex behind those two. Elsewhere in the product an unset
|
|
52
|
+
* `NEXT_PUBLIC_TENANT_DOMAIN` may default to Aglyn's own name, because the
|
|
53
|
+
* consequence is a visibly wrong URL the operator corrects on their first
|
|
54
|
+
* click. Here the consequence is different in kind: this driver ASSERTS that
|
|
55
|
+
* the names it covers are being served, so a default would have an operator's
|
|
56
|
+
* install report `serving` for `*.aglyn.com` — a domain they do not own,
|
|
57
|
+
* cannot serve, and never named. An empty list covers nothing, which is the
|
|
58
|
+
* only honest answer when nobody has said what the proxy answers for.
|
|
59
|
+
*/ function wildcardSuffixes() {
|
|
60
|
+
var _process_env_AGLYN_DOMAIN_WILDCARD_SUFFIXES, _process_env_NEXT_PUBLIC_WORKSPACE_DOMAIN, _process_env_NEXT_PUBLIC_TENANT_DOMAIN;
|
|
61
|
+
const configured = String((_process_env_AGLYN_DOMAIN_WILDCARD_SUFFIXES = process.env.AGLYN_DOMAIN_WILDCARD_SUFFIXES) != null ? _process_env_AGLYN_DOMAIN_WILDCARD_SUFFIXES : '').split(',').map((entry)=>normalizeHost(entry).replace(/^\*\./, '')).filter(Boolean);
|
|
62
|
+
if (configured.length) return configured;
|
|
63
|
+
return [
|
|
64
|
+
normalizeHost((_process_env_NEXT_PUBLIC_WORKSPACE_DOMAIN = process.env.NEXT_PUBLIC_WORKSPACE_DOMAIN) != null ? _process_env_NEXT_PUBLIC_WORKSPACE_DOMAIN : ''),
|
|
65
|
+
normalizeHost((_process_env_NEXT_PUBLIC_TENANT_DOMAIN = process.env.NEXT_PUBLIC_TENANT_DOMAIN) != null ? _process_env_NEXT_PUBLIC_TENANT_DOMAIN : '')
|
|
66
|
+
].filter(Boolean);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Whether `domain` is a name the operator's wildcard actually answers for.
|
|
70
|
+
*
|
|
71
|
+
* A wildcard record covers ONE label. `*.example.com` serves `a.example.com`
|
|
72
|
+
* and does not serve `a.b.example.com` — nor `example.com` itself — and a
|
|
73
|
+
* certificate issued for `*.example.com` covers exactly the same set. Matching
|
|
74
|
+
* on "ends with the suffix" would report both of those as serving, which for
|
|
75
|
+
* the deeper name is a TLS error the operator sees before we do.
|
|
76
|
+
*/ export function wildcardCovers(domain, suffixes) {
|
|
77
|
+
const host = normalizeHost(domain);
|
|
78
|
+
if (!host) return false;
|
|
79
|
+
return suffixes.some((suffix)=>{
|
|
80
|
+
if (!suffix || !host.endsWith(`.${suffix}`)) return false;
|
|
81
|
+
const label = host.slice(0, host.length - suffix.length - 1);
|
|
82
|
+
return label.length > 0 && !label.includes('.');
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function uncoveredDetail(suffixes) {
|
|
86
|
+
return 'outside the wildcard' + (suffixes.length ? ` (${suffixes.join(', ')})` : '');
|
|
87
|
+
}
|
|
88
|
+
export function wildcardDomainProvider() {
|
|
89
|
+
const attach = async (_scope, name, options = {})=>{
|
|
90
|
+
const domain = normalizeHost(name);
|
|
91
|
+
const suffixes = wildcardSuffixes();
|
|
92
|
+
if (!domain) return {
|
|
93
|
+
outcome: 'skipped',
|
|
94
|
+
domain
|
|
95
|
+
};
|
|
96
|
+
if (!wildcardCovers(domain, suffixes)) {
|
|
97
|
+
return {
|
|
98
|
+
outcome: 'skipped',
|
|
99
|
+
domain,
|
|
100
|
+
detail: uncoveredDetail(suffixes)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/*
|
|
104
|
+
* A redirect request is satisfied here without an edge rule, because the
|
|
105
|
+
* app already serves one. The renamed workspace's old slug still resolves
|
|
106
|
+
* under the wildcard, and the canonical redirect in the app 308s it to the
|
|
107
|
+
* new one — which is the behaviour the edge rule was imitating. Reporting
|
|
108
|
+
* `attached` is therefore true rather than convenient.
|
|
109
|
+
*/ void options.redirectTo;
|
|
110
|
+
return {
|
|
111
|
+
outcome: 'attached',
|
|
112
|
+
domain
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
return {
|
|
116
|
+
id: 'wildcard',
|
|
117
|
+
// Always, for the names it covers. There is no credential to be missing:
|
|
118
|
+
// the operator's assertion IS the configuration.
|
|
119
|
+
configured: ()=>true,
|
|
120
|
+
attach,
|
|
121
|
+
detach: async (_scope, name)=>{
|
|
122
|
+
const domain = normalizeHost(name);
|
|
123
|
+
const suffixes = wildcardSuffixes();
|
|
124
|
+
if (!domain) return {
|
|
125
|
+
outcome: 'skipped',
|
|
126
|
+
domain
|
|
127
|
+
};
|
|
128
|
+
/*
|
|
129
|
+
* Nothing to remove, and that is the honest answer rather than a
|
|
130
|
+
* comfortable one: a wildcard cannot un-serve one of its names, so a
|
|
131
|
+
* detached workspace subdomain keeps resolving until the app itself
|
|
132
|
+
* stops recognizing the slug. `not-found` says the entry this was asked
|
|
133
|
+
* to delete does not exist, which is exactly the case.
|
|
134
|
+
*/ if (!wildcardCovers(domain, suffixes)) {
|
|
135
|
+
return {
|
|
136
|
+
outcome: 'skipped',
|
|
137
|
+
domain,
|
|
138
|
+
detail: uncoveredDetail(suffixes)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
outcome: 'not-found',
|
|
143
|
+
domain
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
status: async (_scope, name)=>{
|
|
147
|
+
const domain = normalizeHost(name);
|
|
148
|
+
const suffixes = wildcardSuffixes();
|
|
149
|
+
if (!domain) return domainStatus(domain, 'skipped');
|
|
150
|
+
if (wildcardCovers(domain, suffixes)) {
|
|
151
|
+
return domainStatus(domain, 'serving');
|
|
152
|
+
}
|
|
153
|
+
// Not `not-attached`: this driver cannot see a custom domain either way,
|
|
154
|
+
// and `unknown` is the state that means "no evidence", which callers
|
|
155
|
+
// already treat as non-blocking.
|
|
156
|
+
return domainStatus(domain, 'unknown', {
|
|
157
|
+
detail: uncoveredDetail(suffixes)
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=domain-provider-wildcard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/tenant/data/admin/src/lib/server/domain-provider-wildcard.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The wildcard driver — a container behind a proxy that already answers for\n * `*.example.com`.\n *\n * This is the ordinary Docker shape and the reason the seam exists. An\n * operator points one wildcard DNS record at their proxy, gets one wildcard\n * certificate, and every workspace subdomain and every platform site subdomain\n * resolves the moment it is created. There is no API to call because there is\n * nothing to register: the name already works.\n *\n * So `attach` here is an assertion, not an action. That is exactly why the\n * provider is never inferred — reporting a name as serving without checking is\n * only honest when a human has said \"my proxy answers for that whole apex\",\n * and `AGLYN_DOMAIN_PROVIDER=wildcard` is where they say it.\n *\n * ## What it will not claim\n *\n * A name OUTSIDE the configured suffixes — a customer's own `shop.acme.com` —\n * is not covered by anyone's wildcard. This driver has no way to add it and no\n * way to see it, so it says so: `skipped` on attach, `unknown` on status. It\n * never reports such a name as serving on the strength of a suffix it does not\n * match, and it never reports it as broken either, because an operator who\n * added a vhost by hand has a working domain this cannot see. Operators who\n * want custom domains registered automatically use the `webhook` driver, which\n * can reach their proxy's own API.\n */\n\nimport {\n domainStatus,\n normalizeHost,\n type DomainAttachOptions,\n type DomainProvider,\n type DomainResult,\n type DomainScope,\n type ProjectDomainStatus,\n} from './domain-provider'\n\n/**\n * The apexes the operator's DNS and certificate already cover.\n *\n * Falls back to the two the product itself hands out — the console's workspace\n * domain and the tenant apex — because those are the names Aglyn generates and\n * therefore the ones an operator choosing this driver is choosing it FOR. A\n * deployment serving more than those, or serving them under different names\n * per scope, lists them explicitly.\n *\n * ⛔ NO hardcoded apex behind those two. Elsewhere in the product an unset\n * `NEXT_PUBLIC_TENANT_DOMAIN` may default to Aglyn's own name, because the\n * consequence is a visibly wrong URL the operator corrects on their first\n * click. Here the consequence is different in kind: this driver ASSERTS that\n * the names it covers are being served, so a default would have an operator's\n * install report `serving` for `*.aglyn.com` — a domain they do not own,\n * cannot serve, and never named. An empty list covers nothing, which is the\n * only honest answer when nobody has said what the proxy answers for.\n */\nfunction wildcardSuffixes(): string[] {\n const configured = String(process.env.AGLYN_DOMAIN_WILDCARD_SUFFIXES ?? '')\n .split(',')\n .map((entry) => normalizeHost(entry).replace(/^\\*\\./, ''))\n .filter(Boolean)\n if (configured.length) return configured\n return [\n normalizeHost(process.env.NEXT_PUBLIC_WORKSPACE_DOMAIN ?? ''),\n normalizeHost(process.env.NEXT_PUBLIC_TENANT_DOMAIN ?? ''),\n ].filter(Boolean)\n}\n\n/**\n * Whether `domain` is a name the operator's wildcard actually answers for.\n *\n * A wildcard record covers ONE label. `*.example.com` serves `a.example.com`\n * and does not serve `a.b.example.com` — nor `example.com` itself — and a\n * certificate issued for `*.example.com` covers exactly the same set. Matching\n * on \"ends with the suffix\" would report both of those as serving, which for\n * the deeper name is a TLS error the operator sees before we do.\n */\nexport function wildcardCovers(domain: string, suffixes: string[]): boolean {\n const host = normalizeHost(domain)\n if (!host) return false\n return suffixes.some((suffix) => {\n if (!suffix || !host.endsWith(`.${suffix}`)) return false\n const label = host.slice(0, host.length - suffix.length - 1)\n return label.length > 0 && !label.includes('.')\n })\n}\n\nfunction uncoveredDetail(suffixes: string[]): string {\n return (\n 'outside the wildcard' + (suffixes.length ? ` (${suffixes.join(', ')})` : '')\n )\n}\n\nexport function wildcardDomainProvider(): DomainProvider {\n const attach = async (\n _scope: DomainScope,\n name: string,\n options: DomainAttachOptions = {},\n ): Promise<DomainResult> => {\n const domain = normalizeHost(name)\n const suffixes = wildcardSuffixes()\n if (!domain) return { outcome: 'skipped', domain }\n if (!wildcardCovers(domain, suffixes)) {\n return { outcome: 'skipped', domain, detail: uncoveredDetail(suffixes) }\n }\n /*\n * A redirect request is satisfied here without an edge rule, because the\n * app already serves one. The renamed workspace's old slug still resolves\n * under the wildcard, and the canonical redirect in the app 308s it to the\n * new one — which is the behaviour the edge rule was imitating. Reporting\n * `attached` is therefore true rather than convenient.\n */\n void options.redirectTo\n return { outcome: 'attached', domain }\n }\n\n return {\n id: 'wildcard',\n // Always, for the names it covers. There is no credential to be missing:\n // the operator's assertion IS the configuration.\n configured: () => true,\n attach,\n detach: async (_scope, name) => {\n const domain = normalizeHost(name)\n const suffixes = wildcardSuffixes()\n if (!domain) return { outcome: 'skipped', domain }\n /*\n * Nothing to remove, and that is the honest answer rather than a\n * comfortable one: a wildcard cannot un-serve one of its names, so a\n * detached workspace subdomain keeps resolving until the app itself\n * stops recognizing the slug. `not-found` says the entry this was asked\n * to delete does not exist, which is exactly the case.\n */\n if (!wildcardCovers(domain, suffixes)) {\n return { outcome: 'skipped', domain, detail: uncoveredDetail(suffixes) }\n }\n return { outcome: 'not-found', domain }\n },\n status: async (_scope, name): Promise<ProjectDomainStatus> => {\n const domain = normalizeHost(name)\n const suffixes = wildcardSuffixes()\n if (!domain) return domainStatus(domain, 'skipped')\n if (wildcardCovers(domain, suffixes)) {\n return domainStatus(domain, 'serving')\n }\n // Not `not-attached`: this driver cannot see a custom domain either way,\n // and `unknown` is the state that means \"no evidence\", which callers\n // already treat as non-blocking.\n return domainStatus(domain, 'unknown', { detail: uncoveredDetail(suffixes) })\n },\n }\n}\n"],"names":["domainStatus","normalizeHost","wildcardSuffixes","process","configured","String","env","AGLYN_DOMAIN_WILDCARD_SUFFIXES","split","map","entry","replace","filter","Boolean","length","NEXT_PUBLIC_WORKSPACE_DOMAIN","NEXT_PUBLIC_TENANT_DOMAIN","wildcardCovers","domain","suffixes","host","some","suffix","endsWith","label","slice","includes","uncoveredDetail","join","wildcardDomainProvider","attach","_scope","name","options","outcome","detail","redirectTo","id","detach","status"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GAED,SACEA,YAAY,EACZC,aAAa,QAMR,uBAAmB;AAE1B;;;;;;;;;;;;;;;;;CAiBC,GACD,SAASC;QACmBC,6CAMVA,2CACAA;IAPhB,MAAMC,aAAaC,QAAOF,8CAAAA,QAAQG,GAAG,CAACC,8BAA8B,YAA1CJ,8CAA8C,IACrEK,KAAK,CAAC,KACNC,GAAG,CAAC,CAACC,QAAUT,cAAcS,OAAOC,OAAO,CAAC,SAAS,KACrDC,MAAM,CAACC;IACV,IAAIT,WAAWU,MAAM,EAAE,OAAOV;IAC9B,OAAO;QACLH,eAAcE,4CAAAA,QAAQG,GAAG,CAACS,4BAA4B,YAAxCZ,4CAA4C;QAC1DF,eAAcE,yCAAAA,QAAQG,GAAG,CAACU,yBAAyB,YAArCb,yCAAyC;KACxD,CAACS,MAAM,CAACC;AACX;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASI,eAAeC,MAAc,EAAEC,QAAkB;IAC/D,MAAMC,OAAOnB,cAAciB;IAC3B,IAAI,CAACE,MAAM,OAAO;IAClB,OAAOD,SAASE,IAAI,CAAC,CAACC;QACpB,IAAI,CAACA,UAAU,CAACF,KAAKG,QAAQ,CAAC,CAAC,CAAC,EAAED,QAAQ,GAAG,OAAO;QACpD,MAAME,QAAQJ,KAAKK,KAAK,CAAC,GAAGL,KAAKN,MAAM,GAAGQ,OAAOR,MAAM,GAAG;QAC1D,OAAOU,MAAMV,MAAM,GAAG,KAAK,CAACU,MAAME,QAAQ,CAAC;IAC7C;AACF;AAEA,SAASC,gBAAgBR,QAAkB;IACzC,OACE,yBAA0BA,CAAAA,SAASL,MAAM,GAAG,CAAC,EAAE,EAAEK,SAASS,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAC;AAE/E;AAEA,OAAO,SAASC;IACd,MAAMC,SAAS,OACbC,QACAC,MACAC,UAA+B,CAAC,CAAC;QAEjC,MAAMf,SAASjB,cAAc+B;QAC7B,MAAMb,WAAWjB;QACjB,IAAI,CAACgB,QAAQ,OAAO;YAAEgB,SAAS;YAAWhB;QAAO;QACjD,IAAI,CAACD,eAAeC,QAAQC,WAAW;YACrC,OAAO;gBAAEe,SAAS;gBAAWhB;gBAAQiB,QAAQR,gBAAgBR;YAAU;QACzE;QACA;;;;;;KAMC,GACD,KAAKc,QAAQG,UAAU;QACvB,OAAO;YAAEF,SAAS;YAAYhB;QAAO;IACvC;IAEA,OAAO;QACLmB,IAAI;QACJ,yEAAyE;QACzE,iDAAiD;QACjDjC,YAAY,IAAM;QAClB0B;QACAQ,QAAQ,OAAOP,QAAQC;YACrB,MAAMd,SAASjB,cAAc+B;YAC7B,MAAMb,WAAWjB;YACjB,IAAI,CAACgB,QAAQ,OAAO;gBAAEgB,SAAS;gBAAWhB;YAAO;YACjD;;;;;;OAMC,GACD,IAAI,CAACD,eAAeC,QAAQC,WAAW;gBACrC,OAAO;oBAAEe,SAAS;oBAAWhB;oBAAQiB,QAAQR,gBAAgBR;gBAAU;YACzE;YACA,OAAO;gBAAEe,SAAS;gBAAahB;YAAO;QACxC;QACAqB,QAAQ,OAAOR,QAAQC;YACrB,MAAMd,SAASjB,cAAc+B;YAC7B,MAAMb,WAAWjB;YACjB,IAAI,CAACgB,QAAQ,OAAOlB,aAAakB,QAAQ;YACzC,IAAID,eAAeC,QAAQC,WAAW;gBACpC,OAAOnB,aAAakB,QAAQ;YAC9B;YACA,yEAAyE;YACzE,qEAAqE;YACrE,iCAAiC;YACjC,OAAOlB,aAAakB,QAAQ,WAAW;gBAAEiB,QAAQR,gBAAgBR;YAAU;QAC7E;IACF;AACF"}
|
|
@@ -0,0 +1,197 @@
|
|
|
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
|
+
* How a hostname gets served — the one seam the hosting vendor lives behind.
|
|
19
|
+
*
|
|
20
|
+
* ## The lock-in this removes
|
|
21
|
+
*
|
|
22
|
+
* Attaching a name was `POST https://api.vercel.com/...`, written out five
|
|
23
|
+
* times across the console routes and this library. Every workspace subdomain
|
|
24
|
+
* and every customer's custom domain therefore required a Vercel project and a
|
|
25
|
+
* Vercel token, and a self-hosted install had no way to register a name at all
|
|
26
|
+
* — it got `skipped` and a console that advertised a URL nothing resolved.
|
|
27
|
+
* "Bring your own Firebase, run it on Docker" cannot be true while the way a
|
|
28
|
+
* site becomes reachable is one vendor's API.
|
|
29
|
+
*
|
|
30
|
+
* So the vendor is a driver now. The three operations a name needs are the
|
|
31
|
+
* whole contract, and an operator picks — or writes — the implementation:
|
|
32
|
+
*
|
|
33
|
+
* | provider | for |
|
|
34
|
+
* |------------|-----------------------------------------------------------|
|
|
35
|
+
* | `vercel` | Aglyn's own hosting, and anyone else on Vercel |
|
|
36
|
+
* | `wildcard` | a container behind a proxy with `*.example.com` DNS |
|
|
37
|
+
* | `webhook` | anything else — Caddy, Traefik, cert-manager, a registrar |
|
|
38
|
+
* | `none` | names are somebody else's job entirely |
|
|
39
|
+
*
|
|
40
|
+
* ## Why a webhook is the extension point and not a module path
|
|
41
|
+
*
|
|
42
|
+
* The obvious "supply your own layer" is a file path the app imports at boot.
|
|
43
|
+
* It does not survive the product: both apps are bundled by Next, so a path
|
|
44
|
+
* resolved at runtime is not in the bundle, and an operator running the
|
|
45
|
+
* published image has no build step to add one to. A webhook needs no rebuild,
|
|
46
|
+
* works from the shipped image, and is the same shape whether the operator's
|
|
47
|
+
* DNS lives in Caddy's admin API, a Traefik provider, or a shell script behind
|
|
48
|
+
* `nc`. The cost is one HTTP hop on an operation that already makes one.
|
|
49
|
+
*
|
|
50
|
+
* ## The contract every driver owes
|
|
51
|
+
*
|
|
52
|
+
* 1. **Never throw.** A caller creates orgs and renders cards with these
|
|
53
|
+
* results; an exception takes down an org creation over a DNS API. Return
|
|
54
|
+
* `failed` — or `skipped`, which is not a failure.
|
|
55
|
+
* 2. **Idempotent.** `attach` on a name already attached is `already-exists`,
|
|
56
|
+
* which is success. Reconcile passes and create paths both run.
|
|
57
|
+
* 3. **`skipped` means "not my job", not "it went wrong".** It is what an
|
|
58
|
+
* unconfigured driver returns, and callers treat it as neither success nor
|
|
59
|
+
* failure.
|
|
60
|
+
* 4. **`unknown` status is not evidence of a problem.** {@link domainStateServes}
|
|
61
|
+
* returns true for it deliberately: a probe that could not answer must not
|
|
62
|
+
* strand every domain on a deployment whose provider has no status API.
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* Which deployment a name should reach.
|
|
66
|
+
*
|
|
67
|
+
* Two, because Aglyn runs two apps: the console at `app.<domain>` with its
|
|
68
|
+
* per-workspace subdomains, and the tenant runtime that serves published
|
|
69
|
+
* sites and every customer's own domain. On Vercel they are separate projects;
|
|
70
|
+
* behind a proxy they are separate upstreams; for a webhook they are a field.
|
|
71
|
+
*/
|
|
72
|
+
export type DomainScope = 'console' | 'tenant';
|
|
73
|
+
export type DomainOutcome = 'attached' | 'detached' | 'already-exists' | 'not-found' | 'skipped' | 'failed';
|
|
74
|
+
export interface DomainResult {
|
|
75
|
+
outcome: DomainOutcome;
|
|
76
|
+
domain: string;
|
|
77
|
+
/** Why, when the outcome alone does not say it. Never user-facing prose. */
|
|
78
|
+
detail?: string;
|
|
79
|
+
}
|
|
80
|
+
export interface DomainAttachOptions {
|
|
81
|
+
/**
|
|
82
|
+
* Register the name as a REDIRECT to this bare hostname rather than serving
|
|
83
|
+
* the app on it — how a renamed workspace keeps its old slug working.
|
|
84
|
+
*
|
|
85
|
+
* A driver that cannot express a redirect returns `skipped` rather than
|
|
86
|
+
* attaching a serving name, because the two are not interchangeable: a
|
|
87
|
+
* serving twin is a second live copy of the console on a name that was
|
|
88
|
+
* supposed to forward.
|
|
89
|
+
*/
|
|
90
|
+
redirectTo?: string;
|
|
91
|
+
}
|
|
92
|
+
export type ProjectDomainState = 'serving' | 'certificate-pending' | 'ownership-pending' | 'dns-misconfigured' | 'not-attached' | 'skipped' | 'unknown';
|
|
93
|
+
/** One challenge record a provider wants before it will serve the name. */
|
|
94
|
+
export interface ProjectDomainVerification {
|
|
95
|
+
type: string;
|
|
96
|
+
domain: string;
|
|
97
|
+
value: string;
|
|
98
|
+
reason?: string;
|
|
99
|
+
}
|
|
100
|
+
export interface ProjectDomainStatus {
|
|
101
|
+
state: ProjectDomainState;
|
|
102
|
+
domain: string;
|
|
103
|
+
/** Present when `state` is `ownership-pending`; what to add at the registrar. */
|
|
104
|
+
verification: ProjectDomainVerification[];
|
|
105
|
+
/**
|
|
106
|
+
* Records answering for this name that are not ours, as the provider sees
|
|
107
|
+
* them. A non-empty list on an otherwise-serving domain is the shadowing
|
|
108
|
+
* case: it resolves correctly some of the time.
|
|
109
|
+
*/
|
|
110
|
+
conflicts: {
|
|
111
|
+
type?: string;
|
|
112
|
+
name?: string;
|
|
113
|
+
value?: string;
|
|
114
|
+
}[];
|
|
115
|
+
/** Why, when the state alone does not say it. */
|
|
116
|
+
detail?: string;
|
|
117
|
+
}
|
|
118
|
+
export interface DomainProvider {
|
|
119
|
+
/** Stable id, used in this module's log lines. Never a display name. */
|
|
120
|
+
readonly id: string;
|
|
121
|
+
/** Whether this deployment can actually register names for `scope`. */
|
|
122
|
+
configured(scope: DomainScope): boolean;
|
|
123
|
+
attach(scope: DomainScope, domain: string, options?: DomainAttachOptions): Promise<DomainResult>;
|
|
124
|
+
detach(scope: DomainScope, domain: string): Promise<DomainResult>;
|
|
125
|
+
status(scope: DomainScope, domain: string): Promise<ProjectDomainStatus>;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Whether a probed state means visitors may be sent to the domain (AGL-2011).
|
|
129
|
+
*
|
|
130
|
+
* The ONE definition of "serving", because it has to be. The predicate lived
|
|
131
|
+
* inline in `/api/domains/attach` and again in
|
|
132
|
+
* `/api/admin/finish-domain-attachments`, and the sweeper's own comment says
|
|
133
|
+
* why that is dangerous: a sweeper using a looser definition than the door it
|
|
134
|
+
* completes for re-introduces the bug that door was fixed to avoid.
|
|
135
|
+
*
|
|
136
|
+
* `certificate-pending` is NOT serving (AGL-1996): the name is accepted and
|
|
137
|
+
* routed but no certificate exists yet, so the destination answers with a TLS
|
|
138
|
+
* error. `unknown` and `skipped` ARE, deliberately — a status probe that could
|
|
139
|
+
* not answer is not evidence of a problem, and treating it as one would strand
|
|
140
|
+
* every domain on a deployment whose provider has no status API to ask.
|
|
141
|
+
*/
|
|
142
|
+
export declare function domainStateServes(state: ProjectDomainState): boolean;
|
|
143
|
+
export declare function domainStatus(domain: string, state: ProjectDomainState, extra?: Partial<ProjectDomainStatus>): ProjectDomainStatus;
|
|
144
|
+
export declare function normalizeHost(input: string): string;
|
|
145
|
+
/**
|
|
146
|
+
* A redirect target reduced to a BARE HOSTNAME, or `null` if it is not one.
|
|
147
|
+
*
|
|
148
|
+
* Vercel rejects `https://aglyn.com` here with `bad_request`, whose message
|
|
149
|
+
* reads "Unable to redirect to https://…, because that domain is not added to
|
|
150
|
+
* the project" — it blames the target for being absent when the format was
|
|
151
|
+
* wrong. That misreading is why AGL-1273's redirect shipped looking correct
|
|
152
|
+
* and never once succeeded, and survived weeks before AGL-1365 caught it.
|
|
153
|
+
*
|
|
154
|
+
* Enforced at the seam rather than trusted per driver, so a webhook operator
|
|
155
|
+
* receives the same shape Vercel demands and no driver has to re-derive it.
|
|
156
|
+
*/
|
|
157
|
+
export declare function redirectHostname(target: string): string | null;
|
|
158
|
+
/**
|
|
159
|
+
* Ceiling on any provider call (AGL-1136).
|
|
160
|
+
*
|
|
161
|
+
* These are awaited — org creation and rename wait for them — so an
|
|
162
|
+
* unresponsive DNS API would otherwise hang the operation until the platform
|
|
163
|
+
* killed the function, turning "the subdomain is not attached yet" into "the
|
|
164
|
+
* workspace could not be created". The whole point of the call being
|
|
165
|
+
* best-effort is that it can lose without taking anything with it, and a
|
|
166
|
+
* promise with no timeout cannot lose.
|
|
167
|
+
*/
|
|
168
|
+
export declare const DOMAIN_PROVIDER_TIMEOUT_MS = 5000;
|
|
169
|
+
/** `AbortSignal.timeout`, without assuming the runtime has it. */
|
|
170
|
+
export declare function domainDeadline(): AbortSignal | undefined;
|
|
171
|
+
/** Whether a rejection was our own deadline rather than the network's. */
|
|
172
|
+
export declare function abortedDetail(error: unknown): 'timeout' | 'network';
|
|
173
|
+
/**
|
|
174
|
+
* The driver that registers nothing.
|
|
175
|
+
*
|
|
176
|
+
* Not an error state. A deployment can legitimately have names handled
|
|
177
|
+
* entirely outside the product — a platform team's own DNS pipeline, or an
|
|
178
|
+
* install that only ever uses path routing — and the correct behaviour there
|
|
179
|
+
* is silence, not a failure logged on every signup forever.
|
|
180
|
+
*/
|
|
181
|
+
export declare const NO_DOMAIN_PROVIDER: DomainProvider;
|
|
182
|
+
export type DomainProviderId = 'vercel' | 'wildcard' | 'webhook' | 'none';
|
|
183
|
+
/**
|
|
184
|
+
* The provider this deployment uses.
|
|
185
|
+
*
|
|
186
|
+
* ⚠️ Detection, when `AGLYN_DOMAIN_PROVIDER` is unset, deliberately only ever
|
|
187
|
+
* selects `vercel` — never `wildcard`. Wildcard reports a name as SERVING
|
|
188
|
+
* without checking anything, and inferring it from an apex an operator merely
|
|
189
|
+
* configured would have the console advertise addresses that resolve nowhere
|
|
190
|
+
* while showing a green chip. Claiming to serve a name is the operator's
|
|
191
|
+
* assertion to make, so it takes their explicit setting.
|
|
192
|
+
*
|
|
193
|
+
* Memoized on the environment values it reads rather than once per process, so
|
|
194
|
+
* a spec can change them between cases without a reset hook that production
|
|
195
|
+
* would carry for nobody.
|
|
196
|
+
*/
|
|
197
|
+
export declare function domainProvider(): DomainProvider;
|
|
@@ -0,0 +1,221 @@
|
|
|
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
|
+
* How a hostname gets served — the one seam the hosting vendor lives behind.
|
|
18
|
+
*
|
|
19
|
+
* ## The lock-in this removes
|
|
20
|
+
*
|
|
21
|
+
* Attaching a name was `POST https://api.vercel.com/...`, written out five
|
|
22
|
+
* times across the console routes and this library. Every workspace subdomain
|
|
23
|
+
* and every customer's custom domain therefore required a Vercel project and a
|
|
24
|
+
* Vercel token, and a self-hosted install had no way to register a name at all
|
|
25
|
+
* — it got `skipped` and a console that advertised a URL nothing resolved.
|
|
26
|
+
* "Bring your own Firebase, run it on Docker" cannot be true while the way a
|
|
27
|
+
* site becomes reachable is one vendor's API.
|
|
28
|
+
*
|
|
29
|
+
* So the vendor is a driver now. The three operations a name needs are the
|
|
30
|
+
* whole contract, and an operator picks — or writes — the implementation:
|
|
31
|
+
*
|
|
32
|
+
* | provider | for |
|
|
33
|
+
* |------------|-----------------------------------------------------------|
|
|
34
|
+
* | `vercel` | Aglyn's own hosting, and anyone else on Vercel |
|
|
35
|
+
* | `wildcard` | a container behind a proxy with `*.example.com` DNS |
|
|
36
|
+
* | `webhook` | anything else — Caddy, Traefik, cert-manager, a registrar |
|
|
37
|
+
* | `none` | names are somebody else's job entirely |
|
|
38
|
+
*
|
|
39
|
+
* ## Why a webhook is the extension point and not a module path
|
|
40
|
+
*
|
|
41
|
+
* The obvious "supply your own layer" is a file path the app imports at boot.
|
|
42
|
+
* It does not survive the product: both apps are bundled by Next, so a path
|
|
43
|
+
* resolved at runtime is not in the bundle, and an operator running the
|
|
44
|
+
* published image has no build step to add one to. A webhook needs no rebuild,
|
|
45
|
+
* works from the shipped image, and is the same shape whether the operator's
|
|
46
|
+
* DNS lives in Caddy's admin API, a Traefik provider, or a shell script behind
|
|
47
|
+
* `nc`. The cost is one HTTP hop on an operation that already makes one.
|
|
48
|
+
*
|
|
49
|
+
* ## The contract every driver owes
|
|
50
|
+
*
|
|
51
|
+
* 1. **Never throw.** A caller creates orgs and renders cards with these
|
|
52
|
+
* results; an exception takes down an org creation over a DNS API. Return
|
|
53
|
+
* `failed` — or `skipped`, which is not a failure.
|
|
54
|
+
* 2. **Idempotent.** `attach` on a name already attached is `already-exists`,
|
|
55
|
+
* which is success. Reconcile passes and create paths both run.
|
|
56
|
+
* 3. **`skipped` means "not my job", not "it went wrong".** It is what an
|
|
57
|
+
* unconfigured driver returns, and callers treat it as neither success nor
|
|
58
|
+
* failure.
|
|
59
|
+
* 4. **`unknown` status is not evidence of a problem.** {@link domainStateServes}
|
|
60
|
+
* returns true for it deliberately: a probe that could not answer must not
|
|
61
|
+
* strand every domain on a deployment whose provider has no status API.
|
|
62
|
+
*/ /**
|
|
63
|
+
* Which deployment a name should reach.
|
|
64
|
+
*
|
|
65
|
+
* Two, because Aglyn runs two apps: the console at `app.<domain>` with its
|
|
66
|
+
* per-workspace subdomains, and the tenant runtime that serves published
|
|
67
|
+
* sites and every customer's own domain. On Vercel they are separate projects;
|
|
68
|
+
* behind a proxy they are separate upstreams; for a webhook they are a field.
|
|
69
|
+
*/ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
70
|
+
/**
|
|
71
|
+
* Whether a probed state means visitors may be sent to the domain (AGL-2011).
|
|
72
|
+
*
|
|
73
|
+
* The ONE definition of "serving", because it has to be. The predicate lived
|
|
74
|
+
* inline in `/api/domains/attach` and again in
|
|
75
|
+
* `/api/admin/finish-domain-attachments`, and the sweeper's own comment says
|
|
76
|
+
* why that is dangerous: a sweeper using a looser definition than the door it
|
|
77
|
+
* completes for re-introduces the bug that door was fixed to avoid.
|
|
78
|
+
*
|
|
79
|
+
* `certificate-pending` is NOT serving (AGL-1996): the name is accepted and
|
|
80
|
+
* routed but no certificate exists yet, so the destination answers with a TLS
|
|
81
|
+
* error. `unknown` and `skipped` ARE, deliberately — a status probe that could
|
|
82
|
+
* not answer is not evidence of a problem, and treating it as one would strand
|
|
83
|
+
* every domain on a deployment whose provider has no status API to ask.
|
|
84
|
+
*/ export function domainStateServes(state) {
|
|
85
|
+
return state !== 'not-attached' && state !== 'ownership-pending' && state !== 'dns-misconfigured' && state !== 'certificate-pending';
|
|
86
|
+
}
|
|
87
|
+
export function domainStatus(domain, state, extra = {}) {
|
|
88
|
+
return _extends({
|
|
89
|
+
state,
|
|
90
|
+
domain,
|
|
91
|
+
verification: [],
|
|
92
|
+
conflicts: []
|
|
93
|
+
}, extra);
|
|
94
|
+
}
|
|
95
|
+
const HOSTNAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$/;
|
|
96
|
+
export function normalizeHost(input) {
|
|
97
|
+
return String(input != null ? input : '').trim().toLowerCase().replace(/\.$/, '');
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A redirect target reduced to a BARE HOSTNAME, or `null` if it is not one.
|
|
101
|
+
*
|
|
102
|
+
* Vercel rejects `https://aglyn.com` here with `bad_request`, whose message
|
|
103
|
+
* reads "Unable to redirect to https://…, because that domain is not added to
|
|
104
|
+
* the project" — it blames the target for being absent when the format was
|
|
105
|
+
* wrong. That misreading is why AGL-1273's redirect shipped looking correct
|
|
106
|
+
* and never once succeeded, and survived weeks before AGL-1365 caught it.
|
|
107
|
+
*
|
|
108
|
+
* Enforced at the seam rather than trusted per driver, so a webhook operator
|
|
109
|
+
* receives the same shape Vercel demands and no driver has to re-derive it.
|
|
110
|
+
*/ export function redirectHostname(target) {
|
|
111
|
+
const raw = normalizeHost(target);
|
|
112
|
+
if (!raw) return null;
|
|
113
|
+
const host = raw.replace(/^[a-z][a-z0-9+.-]*:\/\//, '').split(/[/?#]/)[0].replace(/\.$/, '');
|
|
114
|
+
return HOSTNAME_PATTERN.test(host) ? host : null;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Ceiling on any provider call (AGL-1136).
|
|
118
|
+
*
|
|
119
|
+
* These are awaited — org creation and rename wait for them — so an
|
|
120
|
+
* unresponsive DNS API would otherwise hang the operation until the platform
|
|
121
|
+
* killed the function, turning "the subdomain is not attached yet" into "the
|
|
122
|
+
* workspace could not be created". The whole point of the call being
|
|
123
|
+
* best-effort is that it can lose without taking anything with it, and a
|
|
124
|
+
* promise with no timeout cannot lose.
|
|
125
|
+
*/ export const DOMAIN_PROVIDER_TIMEOUT_MS = 5000;
|
|
126
|
+
/** `AbortSignal.timeout`, without assuming the runtime has it. */ export function domainDeadline() {
|
|
127
|
+
try {
|
|
128
|
+
return AbortSignal.timeout(DOMAIN_PROVIDER_TIMEOUT_MS);
|
|
129
|
+
} catch (unused) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Whether a rejection was our own deadline rather than the network's. */ export function abortedDetail(error) {
|
|
134
|
+
const name = error == null ? void 0 : error.name;
|
|
135
|
+
return name === 'TimeoutError' || name === 'AbortError' ? 'timeout' : 'network';
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The driver that registers nothing.
|
|
139
|
+
*
|
|
140
|
+
* Not an error state. A deployment can legitimately have names handled
|
|
141
|
+
* entirely outside the product — a platform team's own DNS pipeline, or an
|
|
142
|
+
* install that only ever uses path routing — and the correct behaviour there
|
|
143
|
+
* is silence, not a failure logged on every signup forever.
|
|
144
|
+
*/ export const NO_DOMAIN_PROVIDER = {
|
|
145
|
+
id: 'none',
|
|
146
|
+
configured: ()=>false,
|
|
147
|
+
attach: async (_scope, domain)=>({
|
|
148
|
+
outcome: 'skipped',
|
|
149
|
+
domain
|
|
150
|
+
}),
|
|
151
|
+
detach: async (_scope, domain)=>({
|
|
152
|
+
outcome: 'skipped',
|
|
153
|
+
domain
|
|
154
|
+
}),
|
|
155
|
+
status: async (_scope, domain)=>domainStatus(domain, 'skipped')
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* The configured provider id, or `null` to let {@link domainProvider} infer it.
|
|
159
|
+
*
|
|
160
|
+
* An explicit value always wins, including `none` — an operator switching a
|
|
161
|
+
* driver off while its credentials are still in the environment means it.
|
|
162
|
+
*/ function requestedProviderId() {
|
|
163
|
+
var _process_env_AGLYN_DOMAIN_PROVIDER;
|
|
164
|
+
const raw = String((_process_env_AGLYN_DOMAIN_PROVIDER = process.env.AGLYN_DOMAIN_PROVIDER) != null ? _process_env_AGLYN_DOMAIN_PROVIDER : '').trim().toLowerCase();
|
|
165
|
+
if (!raw) return null;
|
|
166
|
+
if (raw === 'vercel' || raw === 'wildcard' || raw === 'webhook' || raw === 'none') {
|
|
167
|
+
return raw;
|
|
168
|
+
}
|
|
169
|
+
console.error(`[domain-provider] unknown AGLYN_DOMAIN_PROVIDER "${raw}" — falling back ` + 'to detection. Valid values: vercel, wildcard, webhook, none.');
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
let cached = null;
|
|
173
|
+
/**
|
|
174
|
+
* The provider this deployment uses.
|
|
175
|
+
*
|
|
176
|
+
* ⚠️ Detection, when `AGLYN_DOMAIN_PROVIDER` is unset, deliberately only ever
|
|
177
|
+
* selects `vercel` — never `wildcard`. Wildcard reports a name as SERVING
|
|
178
|
+
* without checking anything, and inferring it from an apex an operator merely
|
|
179
|
+
* configured would have the console advertise addresses that resolve nowhere
|
|
180
|
+
* while showing a green chip. Claiming to serve a name is the operator's
|
|
181
|
+
* assertion to make, so it takes their explicit setting.
|
|
182
|
+
*
|
|
183
|
+
* Memoized on the environment values it reads rather than once per process, so
|
|
184
|
+
* a spec can change them between cases without a reset hook that production
|
|
185
|
+
* would carry for nobody.
|
|
186
|
+
*/ export function domainProvider() {
|
|
187
|
+
var _process_env_AGLYN_DOMAIN_WEBHOOK_URL, _process_env_AGLYN_DOMAIN_WILDCARD_SUFFIXES, _process_env_NEXT_PUBLIC_WORKSPACE_DOMAIN, _process_env_NEXT_PUBLIC_TENANT_DOMAIN;
|
|
188
|
+
const requested = requestedProviderId();
|
|
189
|
+
const key = [
|
|
190
|
+
requested != null ? requested : '',
|
|
191
|
+
process.env.VERCEL_TOKEN ? '1' : '',
|
|
192
|
+
(_process_env_AGLYN_DOMAIN_WEBHOOK_URL = process.env.AGLYN_DOMAIN_WEBHOOK_URL) != null ? _process_env_AGLYN_DOMAIN_WEBHOOK_URL : '',
|
|
193
|
+
(_process_env_AGLYN_DOMAIN_WILDCARD_SUFFIXES = process.env.AGLYN_DOMAIN_WILDCARD_SUFFIXES) != null ? _process_env_AGLYN_DOMAIN_WILDCARD_SUFFIXES : '',
|
|
194
|
+
(_process_env_NEXT_PUBLIC_WORKSPACE_DOMAIN = process.env.NEXT_PUBLIC_WORKSPACE_DOMAIN) != null ? _process_env_NEXT_PUBLIC_WORKSPACE_DOMAIN : '',
|
|
195
|
+
(_process_env_NEXT_PUBLIC_TENANT_DOMAIN = process.env.NEXT_PUBLIC_TENANT_DOMAIN) != null ? _process_env_NEXT_PUBLIC_TENANT_DOMAIN : ''
|
|
196
|
+
].join('\x00');
|
|
197
|
+
if ((cached == null ? void 0 : cached.key) === key) return cached.provider;
|
|
198
|
+
const provider = selectProvider(requested);
|
|
199
|
+
cached = {
|
|
200
|
+
key,
|
|
201
|
+
provider
|
|
202
|
+
};
|
|
203
|
+
return provider;
|
|
204
|
+
}
|
|
205
|
+
function selectProvider(requested) {
|
|
206
|
+
// Required lazily so a deployment pays for only the driver it uses, and so
|
|
207
|
+
// this module stays importable from an edge runtime that has no `fetch`
|
|
208
|
+
// credentials of its own.
|
|
209
|
+
switch(requested != null ? requested : process.env.VERCEL_TOKEN ? 'vercel' : 'none'){
|
|
210
|
+
case 'vercel':
|
|
211
|
+
return require('./domain-provider-vercel').VERCEL_DOMAIN_PROVIDER;
|
|
212
|
+
case 'wildcard':
|
|
213
|
+
return require('./domain-provider-wildcard').wildcardDomainProvider();
|
|
214
|
+
case 'webhook':
|
|
215
|
+
return require('./domain-provider-webhook').webhookDomainProvider();
|
|
216
|
+
default:
|
|
217
|
+
return NO_DOMAIN_PROVIDER;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
//# sourceMappingURL=domain-provider.js.map
|