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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/jest.integration.config.d.ts +39 -0
  4. package/jest.integration.setup.d.ts +17 -0
  5. package/package.json +51 -0
  6. package/src/index.d.ts +17 -0
  7. package/src/index.js +18 -0
  8. package/src/index.js.map +1 -0
  9. package/src/lib/render-cache.d.ts +184 -0
  10. package/src/lib/render-cache.js +198 -0
  11. package/src/lib/render-cache.js.map +1 -0
  12. package/src/lib/server/account-addresses.d.ts +160 -0
  13. package/src/lib/server/account-addresses.js +311 -0
  14. package/src/lib/server/account-addresses.js.map +1 -0
  15. package/src/lib/server/account-emails.d.ts +219 -0
  16. package/src/lib/server/account-emails.js +640 -0
  17. package/src/lib/server/account-emails.js.map +1 -0
  18. package/src/lib/server/admin-audit.d.ts +180 -0
  19. package/src/lib/server/admin-audit.js +233 -0
  20. package/src/lib/server/admin-audit.js.map +1 -0
  21. package/src/lib/server/analytics-retention.d.ts +63 -0
  22. package/src/lib/server/analytics-retention.js +66 -0
  23. package/src/lib/server/analytics-retention.js.map +1 -0
  24. package/src/lib/server/api-http.d.ts +159 -0
  25. package/src/lib/server/api-http.js +230 -0
  26. package/src/lib/server/api-http.js.map +1 -0
  27. package/src/lib/server/api-keys.d.ts +117 -0
  28. package/src/lib/server/api-keys.js +298 -0
  29. package/src/lib/server/api-keys.js.map +1 -0
  30. package/src/lib/server/auth-handoff.d.ts +165 -0
  31. package/src/lib/server/auth-handoff.js +482 -0
  32. package/src/lib/server/auth-handoff.js.map +1 -0
  33. package/src/lib/server/auth-pools.d.ts +246 -0
  34. package/src/lib/server/auth-pools.js +551 -0
  35. package/src/lib/server/auth-pools.js.map +1 -0
  36. package/src/lib/server/billing-addons.d.ts +171 -0
  37. package/src/lib/server/billing-addons.js +277 -0
  38. package/src/lib/server/billing-addons.js.map +1 -0
  39. package/src/lib/server/campaign-attribution-store.d.ts +55 -0
  40. package/src/lib/server/campaign-attribution-store.js +95 -0
  41. package/src/lib/server/campaign-attribution-store.js.map +1 -0
  42. package/src/lib/server/campaign-conversion-attribution.d.ts +205 -0
  43. package/src/lib/server/campaign-conversion-attribution.js +279 -0
  44. package/src/lib/server/campaign-conversion-attribution.js.map +1 -0
  45. package/src/lib/server/client-error-report.d.ts +301 -0
  46. package/src/lib/server/client-error-report.js +755 -0
  47. package/src/lib/server/client-error-report.js.map +1 -0
  48. package/src/lib/server/connect-account-status.d.ts +74 -0
  49. package/src/lib/server/connect-account-status.js +94 -0
  50. package/src/lib/server/connect-account-status.js.map +1 -0
  51. package/src/lib/server/connect-payout-failure.d.ts +103 -0
  52. package/src/lib/server/connect-payout-failure.js +127 -0
  53. package/src/lib/server/connect-payout-failure.js.map +1 -0
  54. package/src/lib/server/console-api-rate-limit.d.ts +81 -0
  55. package/src/lib/server/console-api-rate-limit.js +111 -0
  56. package/src/lib/server/console-api-rate-limit.js.map +1 -0
  57. package/src/lib/server/console-domains.d.ts +326 -0
  58. package/src/lib/server/console-domains.js +779 -0
  59. package/src/lib/server/console-domains.js.map +1 -0
  60. package/src/lib/server/consume-once.d.ts +91 -0
  61. package/src/lib/server/consume-once.js +96 -0
  62. package/src/lib/server/consume-once.js.map +1 -0
  63. package/src/lib/server/contact-company-link.d.ts +85 -0
  64. package/src/lib/server/contact-company-link.js +105 -0
  65. package/src/lib/server/contact-company-link.js.map +1 -0
  66. package/src/lib/server/contact-email-engagement.d.ts +32 -0
  67. package/src/lib/server/contact-email-engagement.js +145 -0
  68. package/src/lib/server/contact-email-engagement.js.map +1 -0
  69. package/src/lib/server/contact-email-index.d.ts +56 -0
  70. package/src/lib/server/contact-email-index.js +158 -0
  71. package/src/lib/server/contact-email-index.js.map +1 -0
  72. package/src/lib/server/contact-lifecycle-floor.d.ts +89 -0
  73. package/src/lib/server/contact-lifecycle-floor.js +88 -0
  74. package/src/lib/server/contact-lifecycle-floor.js.map +1 -0
  75. package/src/lib/server/contact-merge.d.ts +55 -0
  76. package/src/lib/server/contact-merge.js +279 -0
  77. package/src/lib/server/contact-merge.js.map +1 -0
  78. package/src/lib/server/contact-suppression.d.ts +153 -0
  79. package/src/lib/server/contact-suppression.js +259 -0
  80. package/src/lib/server/contact-suppression.js.map +1 -0
  81. package/src/lib/server/crm-booking-activity.d.ts +86 -0
  82. package/src/lib/server/crm-booking-activity.js +251 -0
  83. package/src/lib/server/crm-booking-activity.js.map +1 -0
  84. package/src/lib/server/crm-email-activity.d.ts +112 -0
  85. package/src/lib/server/crm-email-activity.js +143 -0
  86. package/src/lib/server/crm-email-activity.js.map +1 -0
  87. package/src/lib/server/crm-inbound-email.d.ts +145 -0
  88. package/src/lib/server/crm-inbound-email.js +287 -0
  89. package/src/lib/server/crm-inbound-email.js.map +1 -0
  90. package/src/lib/server/crm-next-activity.d.ts +74 -0
  91. package/src/lib/server/crm-next-activity.js +194 -0
  92. package/src/lib/server/crm-next-activity.js.map +1 -0
  93. package/src/lib/server/crm-records.d.ts +144 -0
  94. package/src/lib/server/crm-records.js +218 -0
  95. package/src/lib/server/crm-records.js.map +1 -0
  96. package/src/lib/server/csp-aggregate.d.ts +62 -0
  97. package/src/lib/server/csp-aggregate.js +276 -0
  98. package/src/lib/server/csp-aggregate.js.map +1 -0
  99. package/src/lib/server/data-storage-gate.d.ts +66 -0
  100. package/src/lib/server/data-storage-gate.js +48 -0
  101. package/src/lib/server/data-storage-gate.js.map +1 -0
  102. package/src/lib/server/dataset-live-pages.d.ts +179 -0
  103. package/src/lib/server/dataset-live-pages.js +421 -0
  104. package/src/lib/server/dataset-live-pages.js.map +1 -0
  105. package/src/lib/server/dns-probe.d.ts +53 -0
  106. package/src/lib/server/dns-probe.js +184 -0
  107. package/src/lib/server/dns-probe.js.map +1 -0
  108. package/src/lib/server/document-id.d.ts +29 -0
  109. package/src/lib/server/document-id.js +100 -0
  110. package/src/lib/server/document-id.js.map +1 -0
  111. package/src/lib/server/domain-provider-vercel.d.ts +33 -0
  112. package/src/lib/server/domain-provider-vercel.js +298 -0
  113. package/src/lib/server/domain-provider-vercel.js.map +1 -0
  114. package/src/lib/server/domain-provider-webhook.d.ts +73 -0
  115. package/src/lib/server/domain-provider-webhook.js +223 -0
  116. package/src/lib/server/domain-provider-webhook.js.map +1 -0
  117. package/src/lib/server/domain-provider-wildcard.d.ts +54 -0
  118. package/src/lib/server/domain-provider-wildcard.js +163 -0
  119. package/src/lib/server/domain-provider-wildcard.js.map +1 -0
  120. package/src/lib/server/domain-provider.d.ts +197 -0
  121. package/src/lib/server/domain-provider.js +221 -0
  122. package/src/lib/server/domain-provider.js.map +1 -0
  123. package/src/lib/server/duplicate-activity.d.ts +54 -0
  124. package/src/lib/server/duplicate-activity.js +67 -0
  125. package/src/lib/server/duplicate-activity.js.map +1 -0
  126. package/src/lib/server/duplicate-resource.d.ts +55 -0
  127. package/src/lib/server/duplicate-resource.js +474 -0
  128. package/src/lib/server/duplicate-resource.js.map +1 -0
  129. package/src/lib/server/dynamic-list-materialize.d.ts +153 -0
  130. package/src/lib/server/dynamic-list-materialize.js +581 -0
  131. package/src/lib/server/dynamic-list-materialize.js.map +1 -0
  132. package/src/lib/server/edit-access-authz.d.ts +56 -0
  133. package/src/lib/server/edit-access-authz.js +107 -0
  134. package/src/lib/server/edit-access-authz.js.map +1 -0
  135. package/src/lib/server/edit-access-token.d.ts +72 -0
  136. package/src/lib/server/edit-access-token.js +116 -0
  137. package/src/lib/server/edit-access-token.js.map +1 -0
  138. package/src/lib/server/edit-hint-token.d.ts +83 -0
  139. package/src/lib/server/edit-hint-token.js +119 -0
  140. package/src/lib/server/edit-hint-token.js.map +1 -0
  141. package/src/lib/server/email-delivery-log.d.ts +509 -0
  142. package/src/lib/server/email-delivery-log.js +1043 -0
  143. package/src/lib/server/email-delivery-log.js.map +1 -0
  144. package/src/lib/server/email-flow-gate.d.ts +80 -0
  145. package/src/lib/server/email-flow-gate.js +153 -0
  146. package/src/lib/server/email-flow-gate.js.map +1 -0
  147. package/src/lib/server/email-marketing-gate.d.ts +333 -0
  148. package/src/lib/server/email-marketing-gate.js +639 -0
  149. package/src/lib/server/email-marketing-gate.js.map +1 -0
  150. package/src/lib/server/email-metering.d.ts +293 -0
  151. package/src/lib/server/email-metering.js +359 -0
  152. package/src/lib/server/email-metering.js.map +1 -0
  153. package/src/lib/server/email-revenue-attribution.d.ts +185 -0
  154. package/src/lib/server/email-revenue-attribution.js +300 -0
  155. package/src/lib/server/email-revenue-attribution.js.map +1 -0
  156. package/src/lib/server/email-send-rate.d.ts +232 -0
  157. package/src/lib/server/email-send-rate.js +417 -0
  158. package/src/lib/server/email-send-rate.js.map +1 -0
  159. package/src/lib/server/email-sender-reputation.d.ts +317 -0
  160. package/src/lib/server/email-sender-reputation.js +464 -0
  161. package/src/lib/server/email-sender-reputation.js.map +1 -0
  162. package/src/lib/server/email-suppression.d.ts +490 -0
  163. package/src/lib/server/email-suppression.js +648 -0
  164. package/src/lib/server/email-suppression.js.map +1 -0
  165. package/src/lib/server/email-topic-confirmation.d.ts +150 -0
  166. package/src/lib/server/email-topic-confirmation.js +272 -0
  167. package/src/lib/server/email-topic-confirmation.js.map +1 -0
  168. package/src/lib/server/email-unsubscribe-link.d.ts +174 -0
  169. package/src/lib/server/email-unsubscribe-link.js +236 -0
  170. package/src/lib/server/email-unsubscribe-link.js.map +1 -0
  171. package/src/lib/server/erase-person.d.ts +116 -0
  172. package/src/lib/server/erase-person.js +272 -0
  173. package/src/lib/server/erase-person.js.map +1 -0
  174. package/src/lib/server/erase.d.ts +458 -0
  175. package/src/lib/server/erase.js +1506 -0
  176. package/src/lib/server/erase.js.map +1 -0
  177. package/src/lib/server/firebase-admin.d.ts +71 -0
  178. package/src/lib/server/firebase-admin.js +343 -0
  179. package/src/lib/server/firebase-admin.js.map +1 -0
  180. package/src/lib/server/form-dataset-binding-token.d.ts +35 -0
  181. package/src/lib/server/form-dataset-binding-token.js +107 -0
  182. package/src/lib/server/form-dataset-binding-token.js.map +1 -0
  183. package/src/lib/server/free-workspace-cap.d.ts +201 -0
  184. package/src/lib/server/free-workspace-cap.js +404 -0
  185. package/src/lib/server/free-workspace-cap.js.map +1 -0
  186. package/src/lib/server/ga4-measurement-protocol.d.ts +256 -0
  187. package/src/lib/server/ga4-measurement-protocol.js +558 -0
  188. package/src/lib/server/ga4-measurement-protocol.js.map +1 -0
  189. package/src/lib/server/host-email-tokens.d.ts +47 -0
  190. package/src/lib/server/host-email-tokens.js +72 -0
  191. package/src/lib/server/host-email-tokens.js.map +1 -0
  192. package/src/lib/server/host-memberships.d.ts +54 -0
  193. package/src/lib/server/host-memberships.js +194 -0
  194. package/src/lib/server/host-memberships.js.map +1 -0
  195. package/src/lib/server/host-sending-domain.d.ts +292 -0
  196. package/src/lib/server/host-sending-domain.js +451 -0
  197. package/src/lib/server/host-sending-domain.js.map +1 -0
  198. package/src/lib/server/host-visitor-records.d.ts +150 -0
  199. package/src/lib/server/host-visitor-records.js +262 -0
  200. package/src/lib/server/host-visitor-records.js.map +1 -0
  201. package/src/lib/server/id-token-refusal.d.ts +28 -0
  202. package/src/lib/server/id-token-refusal.js +111 -0
  203. package/src/lib/server/id-token-refusal.js.map +1 -0
  204. package/src/lib/server/legal-acceptance.d.ts +214 -0
  205. package/src/lib/server/legal-acceptance.js +305 -0
  206. package/src/lib/server/legal-acceptance.js.map +1 -0
  207. package/src/lib/server/list-members.d.ts +211 -0
  208. package/src/lib/server/list-members.js +176 -0
  209. package/src/lib/server/list-members.js.map +1 -0
  210. package/src/lib/server/live-page-usage.d.ts +202 -0
  211. package/src/lib/server/live-page-usage.js +300 -0
  212. package/src/lib/server/live-page-usage.js.map +1 -0
  213. package/src/lib/server/lockdown.d.ts +313 -0
  214. package/src/lib/server/lockdown.js +643 -0
  215. package/src/lib/server/lockdown.js.map +1 -0
  216. package/src/lib/server/media-cdn-rate-limit.d.ts +188 -0
  217. package/src/lib/server/media-cdn-rate-limit.js +204 -0
  218. package/src/lib/server/media-cdn-rate-limit.js.map +1 -0
  219. package/src/lib/server/media-delivery.d.ts +267 -0
  220. package/src/lib/server/media-delivery.js +485 -0
  221. package/src/lib/server/media-delivery.js.map +1 -0
  222. package/src/lib/server/media-download-tokens.d.ts +161 -0
  223. package/src/lib/server/media-download-tokens.js +386 -0
  224. package/src/lib/server/media-download-tokens.js.map +1 -0
  225. package/src/lib/server/media-quarantine.d.ts +127 -0
  226. package/src/lib/server/media-quarantine.js +170 -0
  227. package/src/lib/server/media-quarantine.js.map +1 -0
  228. package/src/lib/server/media-signing.d.ts +126 -0
  229. package/src/lib/server/media-signing.js +159 -0
  230. package/src/lib/server/media-signing.js.map +1 -0
  231. package/src/lib/server/media-storage-path.d.ts +96 -0
  232. package/src/lib/server/media-storage-path.js +111 -0
  233. package/src/lib/server/media-storage-path.js.map +1 -0
  234. package/src/lib/server/media-strong-digest.d.ts +85 -0
  235. package/src/lib/server/media-strong-digest.js +190 -0
  236. package/src/lib/server/media-strong-digest.js.map +1 -0
  237. package/src/lib/server/media-tombstone.d.ts +276 -0
  238. package/src/lib/server/media-tombstone.js +421 -0
  239. package/src/lib/server/media-tombstone.js.map +1 -0
  240. package/src/lib/server/media-variants.d.ts +309 -0
  241. package/src/lib/server/media-variants.js +428 -0
  242. package/src/lib/server/media-variants.js.map +1 -0
  243. package/src/lib/server/member-email-aliases.d.ts +180 -0
  244. package/src/lib/server/member-email-aliases.js +420 -0
  245. package/src/lib/server/member-email-aliases.js.map +1 -0
  246. package/src/lib/server/member-photo.d.ts +88 -0
  247. package/src/lib/server/member-photo.js +185 -0
  248. package/src/lib/server/member-photo.js.map +1 -0
  249. package/src/lib/server/membership-recover-throttle.d.ts +211 -0
  250. package/src/lib/server/membership-recover-throttle.js +231 -0
  251. package/src/lib/server/membership-recover-throttle.js.map +1 -0
  252. package/src/lib/server/notifications.d.ts +55 -0
  253. package/src/lib/server/notifications.js +134 -0
  254. package/src/lib/server/notifications.js.map +1 -0
  255. package/src/lib/server/org-billing.d.ts +97 -0
  256. package/src/lib/server/org-billing.js +236 -0
  257. package/src/lib/server/org-billing.js.map +1 -0
  258. package/src/lib/server/organizations.d.ts +837 -0
  259. package/src/lib/server/organizations.js +1814 -0
  260. package/src/lib/server/organizations.js.map +1 -0
  261. package/src/lib/server/password-reset-throttle.d.ts +84 -0
  262. package/src/lib/server/password-reset-throttle.js +102 -0
  263. package/src/lib/server/password-reset-throttle.js.map +1 -0
  264. package/src/lib/server/personal-data-export.d.ts +241 -0
  265. package/src/lib/server/personal-data-export.js +858 -0
  266. package/src/lib/server/personal-data-export.js.map +1 -0
  267. package/src/lib/server/platform-domain-names.d.ts +62 -0
  268. package/src/lib/server/platform-domain-names.js +197 -0
  269. package/src/lib/server/platform-domain-names.js.map +1 -0
  270. package/src/lib/server/platform-marketing-consent.d.ts +133 -0
  271. package/src/lib/server/platform-marketing-consent.js +209 -0
  272. package/src/lib/server/platform-marketing-consent.js.map +1 -0
  273. package/src/lib/server/rate-limit-store.d.ts +702 -0
  274. package/src/lib/server/rate-limit-store.js +1220 -0
  275. package/src/lib/server/rate-limit-store.js.map +1 -0
  276. package/src/lib/server/realm-plugins.d.ts +67 -0
  277. package/src/lib/server/realm-plugins.js +250 -0
  278. package/src/lib/server/realm-plugins.js.map +1 -0
  279. package/src/lib/server/recaptcha-allowlist.d.ts +90 -0
  280. package/src/lib/server/recaptcha-allowlist.js +409 -0
  281. package/src/lib/server/recaptcha-allowlist.js.map +1 -0
  282. package/src/lib/server/release-flags.d.ts +105 -0
  283. package/src/lib/server/release-flags.js +183 -0
  284. package/src/lib/server/release-flags.js.map +1 -0
  285. package/src/lib/server/replay-erasures.d.ts +126 -0
  286. package/src/lib/server/replay-erasures.js +217 -0
  287. package/src/lib/server/replay-erasures.js.map +1 -0
  288. package/src/lib/server/resolve-people.d.ts +66 -0
  289. package/src/lib/server/resolve-people.js +112 -0
  290. package/src/lib/server/resolve-people.js.map +1 -0
  291. package/src/lib/server/safe-equal.d.ts +45 -0
  292. package/src/lib/server/safe-equal.js +58 -0
  293. package/src/lib/server/safe-equal.js.map +1 -0
  294. package/src/lib/server/sending-domain-debt.d.ts +127 -0
  295. package/src/lib/server/sending-domain-debt.js +268 -0
  296. package/src/lib/server/sending-domain-debt.js.map +1 -0
  297. package/src/lib/server/sending-domain-recheck.d.ts +151 -0
  298. package/src/lib/server/sending-domain-recheck.js +253 -0
  299. package/src/lib/server/sending-domain-recheck.js.map +1 -0
  300. package/src/lib/server/sending-domains.d.ts +364 -0
  301. package/src/lib/server/sending-domains.js +683 -0
  302. package/src/lib/server/sending-domains.js.map +1 -0
  303. package/src/lib/server/serve-media-cdn.d.ts +433 -0
  304. package/src/lib/server/serve-media-cdn.js +1370 -0
  305. package/src/lib/server/serve-media-cdn.js.map +1 -0
  306. package/src/lib/server/serve-plugin-fetch.d.ts +61 -0
  307. package/src/lib/server/serve-plugin-fetch.js +294 -0
  308. package/src/lib/server/serve-plugin-fetch.js.map +1 -0
  309. package/src/lib/server/sms-keywords.d.ts +63 -0
  310. package/src/lib/server/sms-keywords.js +146 -0
  311. package/src/lib/server/sms-keywords.js.map +1 -0
  312. package/src/lib/server/sso-break-glass-owners.d.ts +91 -0
  313. package/src/lib/server/sso-break-glass-owners.js +227 -0
  314. package/src/lib/server/sso-break-glass-owners.js.map +1 -0
  315. package/src/lib/server/sso-domain-policy.d.ts +140 -0
  316. package/src/lib/server/sso-domain-policy.js +239 -0
  317. package/src/lib/server/sso-domain-policy.js.map +1 -0
  318. package/src/lib/server/sso-drift-logic.d.ts +106 -0
  319. package/src/lib/server/sso-drift-logic.js +95 -0
  320. package/src/lib/server/sso-drift-logic.js.map +1 -0
  321. package/src/lib/server/sso-enforcement.d.ts +204 -0
  322. package/src/lib/server/sso-enforcement.js +309 -0
  323. package/src/lib/server/sso-enforcement.js.map +1 -0
  324. package/src/lib/server/sso-provisioning.d.ts +320 -0
  325. package/src/lib/server/sso-provisioning.js +715 -0
  326. package/src/lib/server/sso-provisioning.js.map +1 -0
  327. package/src/lib/server/staff-alert-email.d.ts +41 -0
  328. package/src/lib/server/staff-alert-email.js +63 -0
  329. package/src/lib/server/staff-alert-email.js.map +1 -0
  330. package/src/lib/server/stripe-account-mode.d.ts +156 -0
  331. package/src/lib/server/stripe-account-mode.js +162 -0
  332. package/src/lib/server/stripe-account-mode.js.map +1 -0
  333. package/src/lib/server/tenant-write-lockdown.d.ts +131 -0
  334. package/src/lib/server/tenant-write-lockdown.js +176 -0
  335. package/src/lib/server/tenant-write-lockdown.js.map +1 -0
  336. package/src/lib/server/test-firestore.d.ts +45 -0
  337. package/src/lib/server/test-firestore.js +124 -0
  338. package/src/lib/server/test-firestore.js.map +1 -0
  339. package/src/lib/server/token-revocation.d.ts +140 -0
  340. package/src/lib/server/token-revocation.js +255 -0
  341. package/src/lib/server/token-revocation.js.map +1 -0
  342. package/src/lib/server/update-existing.d.ts +32 -0
  343. package/src/lib/server/update-existing.js +73 -0
  344. package/src/lib/server/update-existing.js.map +1 -0
  345. package/src/lib/server/upload-cors-reconcile.d.ts +118 -0
  346. package/src/lib/server/upload-cors-reconcile.js +234 -0
  347. package/src/lib/server/upload-cors-reconcile.js.map +1 -0
  348. package/src/lib/server/upsert-contact.d.ts +262 -0
  349. package/src/lib/server/upsert-contact.js +546 -0
  350. package/src/lib/server/upsert-contact.js.map +1 -0
  351. package/src/lib/server/usage-invoice.d.ts +203 -0
  352. package/src/lib/server/usage-invoice.js +397 -0
  353. package/src/lib/server/usage-invoice.js.map +1 -0
  354. package/src/lib/server/user-profiles.d.ts +151 -0
  355. package/src/lib/server/user-profiles.js +364 -0
  356. package/src/lib/server/user-profiles.js.map +1 -0
  357. package/src/lib/server/vercel-drain-signature.d.ts +30 -0
  358. package/src/lib/server/vercel-drain-signature.js +61 -0
  359. package/src/lib/server/vercel-drain-signature.js.map +1 -0
  360. package/src/lib/server/vercel-log-drain.d.ts +259 -0
  361. package/src/lib/server/vercel-log-drain.js +479 -0
  362. package/src/lib/server/vercel-log-drain.js.map +1 -0
  363. package/src/lib/server/verify-email-cooldown.d.ts +102 -0
  364. package/src/lib/server/verify-email-cooldown.js +114 -0
  365. package/src/lib/server/verify-email-cooldown.js.map +1 -0
  366. package/src/lib/server/visitor-write-rate-limit.d.ts +87 -0
  367. package/src/lib/server/visitor-write-rate-limit.js +117 -0
  368. package/src/lib/server/visitor-write-rate-limit.js.map +1 -0
  369. package/src/lib/server/workspace-domains.d.ts +156 -0
  370. package/src/lib/server/workspace-domains.js +271 -0
  371. package/src/lib/server/workspace-domains.js.map +1 -0
  372. package/src/tenancy.d.ts +115 -0
  373. package/src/tenancy.js +142 -0
  374. package/src/tenancy.js.map +1 -0
@@ -0,0 +1,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