@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,236 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { deploymentLivemode } from "@aglyn/aglyn/app-utils/stripe-deployment-mode";
18
+ import { ORG_BILLING_DOC_ID, ORG_BILLING_SUBCOLLECTION, STRIPE_CUSTOMER_ID_TEST_FIELD, STRIPE_CUSTOMER_INDEX_COLLECTION, hasInlineOrgBilling, orgBillingStatusFrom, pickOrgBillingFields } from "@aglyn/aglyn/server";
19
+ import { firebaseAdmin } from "./firebase-admin.js";
20
+ /**
21
+ * Server-side accessors for the manager-gated billing document (AGL-1028).
22
+ *
23
+ * Every server surface that used to read `orgs/{orgId}.stripeCustomerId` /
24
+ * `.subscription` / `.seatAddons` goes through here instead. All of them are
25
+ * Admin SDK, so rules never applied to them — this is a path change, not a
26
+ * permission change. The permission change is entirely in the rules, where the
27
+ * new subcollection is gated on `canManageOrg()`.
28
+ */ const db = ()=>firebaseAdmin.app().firestore();
29
+ /**
30
+ * Which PHYSICAL field holds this deployment's Stripe customer id (AGL-2486).
31
+ *
32
+ * Live keeps `stripeCustomerId`, so live behaviour is byte-identical to before
33
+ * this existed and no stored document needs migrating. Test mode gets its own
34
+ * slot, which starts empty on every org — the first test-mode checkout mints a
35
+ * fresh test customer instead of sending a live `cus_…` to a `sk_test` key and
36
+ * taking a 502.
37
+ *
38
+ * Read at call time rather than at module load: a spec flips
39
+ * `process.env.STRIPE_SECRET_KEY` between cases, and a cached verdict would
40
+ * make the second case answer for the first.
41
+ */ function customerIdField() {
42
+ return deploymentLivemode() ? 'stripeCustomerId' : STRIPE_CUSTOMER_ID_TEST_FIELD;
43
+ }
44
+ /**
45
+ * Collapse a stored billing document to the logical shape callers expect.
46
+ *
47
+ * `stripeCustomerId` on the RESULT always means "the customer id for the mode
48
+ * this deployment spends in". The test id never leaks out under its physical
49
+ * name, and — the part that matters — test mode does NOT fall back to the live
50
+ * id when its own slot is empty. That fallback is precisely the bug: it is what
51
+ * sent `cus_UuQjDdd1oxPMNH` to a `sk_test` key.
52
+ */ function projectBillingMode(doc) {
53
+ const stored = _extends({}, doc != null ? doc : {});
54
+ const testId = stored[STRIPE_CUSTOMER_ID_TEST_FIELD];
55
+ // The physical twin never reaches a caller in either mode: every reader
56
+ // treats `stripeCustomerId` as THE customer, so a second field carrying a
57
+ // second answer is exactly the ambiguity this fix removes.
58
+ delete stored[STRIPE_CUSTOMER_ID_TEST_FIELD];
59
+ if (deploymentLivemode()) return stored;
60
+ // No `??` fallback to the live id. That fallback IS the bug.
61
+ stored['stripeCustomerId'] = testId != null ? testId : null;
62
+ return stored;
63
+ }
64
+ /** `orgs/{orgId}/billing/stripe`. */ export function orgBillingRef(orgId) {
65
+ return db().collection('orgs').doc(orgId).collection(ORG_BILLING_SUBCOLLECTION).doc(ORG_BILLING_DOC_ID);
66
+ }
67
+ /**
68
+ * Reads an org's commercial keys, falling back to the org doc.
69
+ *
70
+ * The fallback is what makes the migration safe to land in pieces: a reader
71
+ * repointed here keeps working against an org that has not been backfilled
72
+ * yet, and keeps working if the backfill missed one. It stops being reachable
73
+ * only when the inline fields are finally deleted from the org doc — which is
74
+ * the LAST step, taken once production has been observed reading from the new
75
+ * location.
76
+ *
77
+ * Without it, the failure mode is silent and expensive: a missing billing doc
78
+ * reads as `undefined`, which every caller downstream interprets as "no
79
+ * subscription", i.e. a paying workspace rendered as Free.
80
+ */ export async function readOrgBilling(orgId) {
81
+ if (!orgId) return {};
82
+ return projectBillingMode(await readStoredOrgBilling(orgId));
83
+ }
84
+ /**
85
+ * The STORED document, before any mode projection — both physical ids intact.
86
+ *
87
+ * Private on purpose: a caller holding this holds two answers to "which
88
+ * customer", which is the ambiguity `projectBillingMode` exists to remove. It
89
+ * is factored out only so the mode census below reads the very same bytes
90
+ * `readOrgBilling` reads, org-doc fallback included. Two separate reads would
91
+ * be two chances to diverge, and the census exists precisely to explain what
92
+ * `readOrgBilling` returned.
93
+ */ async function readStoredOrgBilling(orgId) {
94
+ const billingSnapshot = await orgBillingRef(orgId).get();
95
+ if (billingSnapshot.exists) {
96
+ var _billingSnapshot_data;
97
+ return (_billingSnapshot_data = billingSnapshot.data()) != null ? _billingSnapshot_data : {};
98
+ }
99
+ const orgSnapshot = await db().collection('orgs').doc(orgId).get();
100
+ // The legacy inline fields predate mode-keying entirely, so anything found
101
+ // there is a LIVE id by construction — the org doc was last written by a
102
+ // `sk_live_` deployment. Projected by the caller all the same, so a
103
+ // test-mode read of an un-backfilled org gets no customer rather than a live
104
+ // one.
105
+ return pickOrgBillingFields(orgSnapshot.data());
106
+ }
107
+ /**
108
+ * Which Stripe MODES this org has a stored customer for (AGL-2486, follow-up).
109
+ *
110
+ * `readOrgBilling` answering `stripeCustomerId: null` has two completely
111
+ * different meanings — "this workspace has never been billed" and "this
112
+ * workspace's customer lives in the other Stripe world and THIS deployment
113
+ * cannot see it" — and every surface downstream rendered them as the same
114
+ * sentence, "No invoices yet." That is the swallowed-query-as-measured-zero
115
+ * shape: nothing looks wrong, and the wrong reading is the reassuring one.
116
+ *
117
+ * The fix is NOT to fall back to the other mode's id — that fallback is the
118
+ * original bug, and it stays deleted. It is to let a caller say which of the
119
+ * two silences it is looking at.
120
+ *
121
+ * Returns BOOLEANS, never ids. A test-mode surface asking this question must
122
+ * not come away holding a live `cus_…`: it would have no legitimate use for
123
+ * one, and putting it in a JSON response would publish a live customer id to
124
+ * every browser on a test deployment.
125
+ */ export async function readOrgBillingCustomerModes(orgId) {
126
+ if (!orgId) return {
127
+ live: false,
128
+ test: false
129
+ };
130
+ const stored = await readStoredOrgBilling(orgId);
131
+ // A stored `null` (the webhook's "Stripe says this is gone") and an empty
132
+ // string are both absences, so presence is a non-empty STRING — not `in`,
133
+ // and not truthiness on an unknown.
134
+ const present = (value)=>typeof value === 'string' && value.length > 0;
135
+ return {
136
+ live: present(stored['stripeCustomerId']),
137
+ test: present(stored[STRIPE_CUSTOMER_ID_TEST_FIELD])
138
+ };
139
+ }
140
+ /**
141
+ * Writes the commercial keys to the billing doc, and onto the org doc the
142
+ * entitlement inputs that stay there.
143
+ *
144
+ * Three writes, one batch:
145
+ *
146
+ * 1. the billing doc itself, `merge: true` to match what the org-doc write did;
147
+ * 2. the org doc, merged, with what entitlement resolution reads there:
148
+ * `billingStatus`, so the AGL-275 dunning banner keeps working for
149
+ * non-managers who can no longer read `subscription`; and `seatAddons`,
150
+ * which never moved (`ORG_BILLING_MOVED_KEYS`), whenever the patch carries
151
+ * the add-on quantities;
152
+ * 3. the `stripeCustomers` reverse index, so the webhook can still resolve an
153
+ * org from a Stripe customer id without a query.
154
+ *
155
+ * `writeInline` mirrored the keys back onto the org doc as well. It was on
156
+ * during the migration so a rollback lost nothing, and is now OFF: writing them
157
+ * inline is what the whole issue exists to stop, and leaving it on would let the
158
+ * next Stripe webhook silently re-add the fields minutes after they were
159
+ * deleted, re-opening the exposure with nothing to show for it.
160
+ *
161
+ * The option survives for a deliberate one-off rollback, and nothing passes it.
162
+ *
163
+ * The READ fallback in `readOrgBilling` deliberately stays. It costs one get on
164
+ * a doc that no longer exists, and it is the only thing standing between an org
165
+ * the backfill somehow missed and a paying workspace rendering as Free.
166
+ */ export async function writeOrgBilling(orgId, patch, options = {}) {
167
+ if (!orgId) return;
168
+ const { writeInline = false } = options;
169
+ const fields = pickOrgBillingFields(patch);
170
+ // The logical key becomes the mode's PHYSICAL key (AGL-2486). A test-mode
171
+ // write therefore cannot overwrite the live customer id — which it silently
172
+ // did before this, destroying the live linkage on the first completed test
173
+ // checkout.
174
+ const field = customerIdField();
175
+ if (field !== 'stripeCustomerId' && 'stripeCustomerId' in fields) {
176
+ fields[field] = fields['stripeCustomerId'];
177
+ delete fields['stripeCustomerId'];
178
+ }
179
+ const batch = db().batch();
180
+ const orgRef = db().collection('orgs').doc(orgId);
181
+ batch.set(orgBillingRef(orgId), fields, {
182
+ merge: true
183
+ });
184
+ // The status mirror is derived, so it is only written when this patch
185
+ // actually carries a subscription — otherwise a partial update (a seat-addon
186
+ // change, say) would blank the banner's input.
187
+ const orgPatch = writeInline ? _extends({}, fields) : {};
188
+ if (patch.subscription !== undefined) {
189
+ orgPatch['billingStatus'] = orgBillingStatusFrom(patch);
190
+ }
191
+ // The add-on quantities are what grants and removes an add-on, and the org
192
+ // doc is the only place they are read from: a subscription sync that wrote
193
+ // them nowhere would charge for an add-on bought at checkout without
194
+ // granting it, and leave a removed one in place. Merged with the rest of
195
+ // this patch, so the explicit zeros of a sync converge while a key the
196
+ // subscription items do not name survives.
197
+ if (patch.seatAddons !== undefined) {
198
+ orgPatch['seatAddons'] = patch.seatAddons;
199
+ }
200
+ if (Object.keys(orgPatch).length) batch.set(orgRef, orgPatch, {
201
+ merge: true
202
+ });
203
+ // Off the PHYSICAL field, so a test-mode write indexes its own customer.
204
+ // The index needs no mode-keying of its own: it is keyed by the customer id,
205
+ // and Stripe ids are unique across modes, so the live and test entries are
206
+ // two documents that both resolve to this org.
207
+ const customerId = fields[field];
208
+ if (typeof customerId === 'string' && customerId) {
209
+ batch.set(db().collection(STRIPE_CUSTOMER_INDEX_COLLECTION).doc(customerId), {
210
+ orgId,
211
+ updatedAt: firebaseAdmin.firestore.FieldValue.serverTimestamp()
212
+ }, {
213
+ merge: true
214
+ });
215
+ }
216
+ await batch.commit();
217
+ }
218
+ /**
219
+ * Resolves an org id from a Stripe customer id.
220
+ *
221
+ * Prefers the reverse index; falls back to the legacy `where('stripeCustomerId')`
222
+ * query on `orgs` for customers whose index entry has not been written yet.
223
+ * The fallback disappears with the inline fields.
224
+ */ export async function findOrgIdByStripeCustomer(customerId) {
225
+ var _ref;
226
+ var _legacy_docs_;
227
+ if (!customerId) return null;
228
+ const indexed = await db().collection(STRIPE_CUSTOMER_INDEX_COLLECTION).doc(customerId).get();
229
+ const mapped = indexed.get('orgId');
230
+ if (typeof mapped === 'string' && mapped) return mapped;
231
+ const legacy = await db().collection('orgs').where('stripeCustomerId', '==', customerId).limit(1).get();
232
+ return (_ref = (_legacy_docs_ = legacy.docs[0]) == null ? void 0 : _legacy_docs_.id) != null ? _ref : null;
233
+ }
234
+ /** Re-exported so callers do not need a second import to test migration state. */ export { hasInlineOrgBilling };
235
+
236
+ //# sourceMappingURL=org-billing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/tenant/data/admin/src/lib/server/org-billing.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\nimport { deploymentLivemode } from '@aglyn/aglyn/app-utils/stripe-deployment-mode'\nimport {\n ORG_BILLING_DOC_ID,\n ORG_BILLING_SUBCOLLECTION,\n STRIPE_CUSTOMER_ID_TEST_FIELD,\n STRIPE_CUSTOMER_INDEX_COLLECTION,\n hasInlineOrgBilling,\n orgBillingStatusFrom,\n pickOrgBillingFields,\n type OrgBillingDoc,\n type OrgInlineBilling,\n} from '@aglyn/aglyn/server'\nimport { firebaseAdmin } from './firebase-admin'\n\n/**\n * Server-side accessors for the manager-gated billing document (AGL-1028).\n *\n * Every server surface that used to read `orgs/{orgId}.stripeCustomerId` /\n * `.subscription` / `.seatAddons` goes through here instead. All of them are\n * Admin SDK, so rules never applied to them — this is a path change, not a\n * permission change. The permission change is entirely in the rules, where the\n * new subcollection is gated on `canManageOrg()`.\n */\n\nconst db = () => firebaseAdmin.app().firestore()\n\n/**\n * Which PHYSICAL field holds this deployment's Stripe customer id (AGL-2486).\n *\n * Live keeps `stripeCustomerId`, so live behaviour is byte-identical to before\n * this existed and no stored document needs migrating. Test mode gets its own\n * slot, which starts empty on every org — the first test-mode checkout mints a\n * fresh test customer instead of sending a live `cus_…` to a `sk_test` key and\n * taking a 502.\n *\n * Read at call time rather than at module load: a spec flips\n * `process.env.STRIPE_SECRET_KEY` between cases, and a cached verdict would\n * make the second case answer for the first.\n */\nfunction customerIdField(): 'stripeCustomerId' | typeof STRIPE_CUSTOMER_ID_TEST_FIELD {\n return deploymentLivemode() ? 'stripeCustomerId' : STRIPE_CUSTOMER_ID_TEST_FIELD\n}\n\n/**\n * Collapse a stored billing document to the logical shape callers expect.\n *\n * `stripeCustomerId` on the RESULT always means \"the customer id for the mode\n * this deployment spends in\". The test id never leaks out under its physical\n * name, and — the part that matters — test mode does NOT fall back to the live\n * id when its own slot is empty. That fallback is precisely the bug: it is what\n * sent `cus_UuQjDdd1oxPMNH` to a `sk_test` key.\n */\nfunction projectBillingMode(doc: OrgBillingDoc): OrgBillingDoc {\n const stored = { ...(doc ?? {}) } as Record<string, unknown>\n const testId = stored[STRIPE_CUSTOMER_ID_TEST_FIELD]\n // The physical twin never reaches a caller in either mode: every reader\n // treats `stripeCustomerId` as THE customer, so a second field carrying a\n // second answer is exactly the ambiguity this fix removes.\n delete stored[STRIPE_CUSTOMER_ID_TEST_FIELD]\n if (deploymentLivemode()) return stored as OrgBillingDoc\n // No `??` fallback to the live id. That fallback IS the bug.\n stored['stripeCustomerId'] = (testId ?? null) as string | null\n return stored as OrgBillingDoc\n}\n\n/** `orgs/{orgId}/billing/stripe`. */\nexport function orgBillingRef(orgId: string) {\n return db()\n .collection('orgs')\n .doc(orgId)\n .collection(ORG_BILLING_SUBCOLLECTION)\n .doc(ORG_BILLING_DOC_ID)\n}\n\n/**\n * Reads an org's commercial keys, falling back to the org doc.\n *\n * The fallback is what makes the migration safe to land in pieces: a reader\n * repointed here keeps working against an org that has not been backfilled\n * yet, and keeps working if the backfill missed one. It stops being reachable\n * only when the inline fields are finally deleted from the org doc — which is\n * the LAST step, taken once production has been observed reading from the new\n * location.\n *\n * Without it, the failure mode is silent and expensive: a missing billing doc\n * reads as `undefined`, which every caller downstream interprets as \"no\n * subscription\", i.e. a paying workspace rendered as Free.\n */\nexport async function readOrgBilling(orgId: string): Promise<OrgBillingDoc> {\n if (!orgId) return {}\n return projectBillingMode(await readStoredOrgBilling(orgId))\n}\n\n/**\n * The STORED document, before any mode projection — both physical ids intact.\n *\n * Private on purpose: a caller holding this holds two answers to \"which\n * customer\", which is the ambiguity `projectBillingMode` exists to remove. It\n * is factored out only so the mode census below reads the very same bytes\n * `readOrgBilling` reads, org-doc fallback included. Two separate reads would\n * be two chances to diverge, and the census exists precisely to explain what\n * `readOrgBilling` returned.\n */\nasync function readStoredOrgBilling(orgId: string): Promise<OrgBillingDoc> {\n const billingSnapshot = await orgBillingRef(orgId).get()\n if (billingSnapshot.exists) {\n return (billingSnapshot.data() ?? {}) as OrgBillingDoc\n }\n const orgSnapshot = await db().collection('orgs').doc(orgId).get()\n // The legacy inline fields predate mode-keying entirely, so anything found\n // there is a LIVE id by construction — the org doc was last written by a\n // `sk_live_` deployment. Projected by the caller all the same, so a\n // test-mode read of an un-backfilled org gets no customer rather than a live\n // one.\n return pickOrgBillingFields(orgSnapshot.data() as never) as OrgBillingDoc\n}\n\n/**\n * Which Stripe MODES this org has a stored customer for (AGL-2486, follow-up).\n *\n * `readOrgBilling` answering `stripeCustomerId: null` has two completely\n * different meanings — \"this workspace has never been billed\" and \"this\n * workspace's customer lives in the other Stripe world and THIS deployment\n * cannot see it\" — and every surface downstream rendered them as the same\n * sentence, \"No invoices yet.\" That is the swallowed-query-as-measured-zero\n * shape: nothing looks wrong, and the wrong reading is the reassuring one.\n *\n * The fix is NOT to fall back to the other mode's id — that fallback is the\n * original bug, and it stays deleted. It is to let a caller say which of the\n * two silences it is looking at.\n *\n * Returns BOOLEANS, never ids. A test-mode surface asking this question must\n * not come away holding a live `cus_…`: it would have no legitimate use for\n * one, and putting it in a JSON response would publish a live customer id to\n * every browser on a test deployment.\n */\nexport async function readOrgBillingCustomerModes(\n orgId: string,\n): Promise<{ live: boolean; test: boolean }> {\n if (!orgId) return { live: false, test: false }\n const stored = (await readStoredOrgBilling(orgId)) as Record<string, unknown>\n // A stored `null` (the webhook's \"Stripe says this is gone\") and an empty\n // string are both absences, so presence is a non-empty STRING — not `in`,\n // and not truthiness on an unknown.\n const present = (value: unknown) => typeof value === 'string' && value.length > 0\n return {\n live: present(stored['stripeCustomerId']),\n test: present(stored[STRIPE_CUSTOMER_ID_TEST_FIELD]),\n }\n}\n\n/**\n * Writes the commercial keys to the billing doc, and onto the org doc the\n * entitlement inputs that stay there.\n *\n * Three writes, one batch:\n *\n * 1. the billing doc itself, `merge: true` to match what the org-doc write did;\n * 2. the org doc, merged, with what entitlement resolution reads there:\n * `billingStatus`, so the AGL-275 dunning banner keeps working for\n * non-managers who can no longer read `subscription`; and `seatAddons`,\n * which never moved (`ORG_BILLING_MOVED_KEYS`), whenever the patch carries\n * the add-on quantities;\n * 3. the `stripeCustomers` reverse index, so the webhook can still resolve an\n * org from a Stripe customer id without a query.\n *\n * `writeInline` mirrored the keys back onto the org doc as well. It was on\n * during the migration so a rollback lost nothing, and is now OFF: writing them\n * inline is what the whole issue exists to stop, and leaving it on would let the\n * next Stripe webhook silently re-add the fields minutes after they were\n * deleted, re-opening the exposure with nothing to show for it.\n *\n * The option survives for a deliberate one-off rollback, and nothing passes it.\n *\n * The READ fallback in `readOrgBilling` deliberately stays. It costs one get on\n * a doc that no longer exists, and it is the only thing standing between an org\n * the backfill somehow missed and a paying workspace rendering as Free.\n */\nexport async function writeOrgBilling(\n orgId: string,\n patch: Partial<OrgBillingDoc> & Pick<OrgInlineBilling, 'seatAddons'>,\n options: { writeInline?: boolean } = {},\n): Promise<void> {\n if (!orgId) return\n const { writeInline = false } = options\n const fields = pickOrgBillingFields(patch as never) as Record<string, unknown>\n // The logical key becomes the mode's PHYSICAL key (AGL-2486). A test-mode\n // write therefore cannot overwrite the live customer id — which it silently\n // did before this, destroying the live linkage on the first completed test\n // checkout.\n const field = customerIdField()\n if (field !== 'stripeCustomerId' && 'stripeCustomerId' in fields) {\n fields[field] = fields['stripeCustomerId']\n delete fields['stripeCustomerId']\n }\n const batch = db().batch()\n const orgRef = db().collection('orgs').doc(orgId)\n\n batch.set(orgBillingRef(orgId), fields, { merge: true })\n\n // The status mirror is derived, so it is only written when this patch\n // actually carries a subscription — otherwise a partial update (a seat-addon\n // change, say) would blank the banner's input.\n const orgPatch: Record<string, unknown> = writeInline ? { ...fields } : {}\n if (patch.subscription !== undefined) {\n orgPatch['billingStatus'] = orgBillingStatusFrom(patch)\n }\n // The add-on quantities are what grants and removes an add-on, and the org\n // doc is the only place they are read from: a subscription sync that wrote\n // them nowhere would charge for an add-on bought at checkout without\n // granting it, and leave a removed one in place. Merged with the rest of\n // this patch, so the explicit zeros of a sync converge while a key the\n // subscription items do not name survives.\n if (patch.seatAddons !== undefined) {\n orgPatch['seatAddons'] = patch.seatAddons\n }\n if (Object.keys(orgPatch).length) batch.set(orgRef, orgPatch, { merge: true })\n\n // Off the PHYSICAL field, so a test-mode write indexes its own customer.\n // The index needs no mode-keying of its own: it is keyed by the customer id,\n // and Stripe ids are unique across modes, so the live and test entries are\n // two documents that both resolve to this org.\n const customerId = fields[field]\n if (typeof customerId === 'string' && customerId) {\n batch.set(\n db().collection(STRIPE_CUSTOMER_INDEX_COLLECTION).doc(customerId),\n { orgId, updatedAt: firebaseAdmin.firestore.FieldValue.serverTimestamp() },\n { merge: true },\n )\n }\n\n await batch.commit()\n}\n\n/**\n * Resolves an org id from a Stripe customer id.\n *\n * Prefers the reverse index; falls back to the legacy `where('stripeCustomerId')`\n * query on `orgs` for customers whose index entry has not been written yet.\n * The fallback disappears with the inline fields.\n */\nexport async function findOrgIdByStripeCustomer(\n customerId: string,\n): Promise<string | null> {\n if (!customerId) return null\n const indexed = await db()\n .collection(STRIPE_CUSTOMER_INDEX_COLLECTION)\n .doc(customerId)\n .get()\n const mapped = indexed.get('orgId')\n if (typeof mapped === 'string' && mapped) return mapped\n const legacy = await db()\n .collection('orgs')\n .where('stripeCustomerId', '==', customerId)\n .limit(1)\n .get()\n return legacy.docs[0]?.id ?? null\n}\n\n/** Re-exported so callers do not need a second import to test migration state. */\nexport { hasInlineOrgBilling }\n"],"names":["deploymentLivemode","ORG_BILLING_DOC_ID","ORG_BILLING_SUBCOLLECTION","STRIPE_CUSTOMER_ID_TEST_FIELD","STRIPE_CUSTOMER_INDEX_COLLECTION","hasInlineOrgBilling","orgBillingStatusFrom","pickOrgBillingFields","firebaseAdmin","db","app","firestore","customerIdField","projectBillingMode","doc","stored","testId","orgBillingRef","orgId","collection","readOrgBilling","readStoredOrgBilling","billingSnapshot","get","exists","data","orgSnapshot","readOrgBillingCustomerModes","live","test","present","value","length","writeOrgBilling","patch","options","writeInline","fields","field","batch","orgRef","set","merge","orgPatch","subscription","undefined","seatAddons","Object","keys","customerId","updatedAt","FieldValue","serverTimestamp","commit","findOrgIdByStripeCustomer","legacy","indexed","mapped","where","limit","docs","id"],"mappings":"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"}