pyric 0.1.0-alpha.21 → 0.1.0-alpha.24

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 (1241) hide show
  1. package/README.md +12 -4
  2. package/dist/ai/activity.d.ts +9 -0
  3. package/dist/ai/activity.d.ts.map +1 -0
  4. package/dist/ai/activity.js +45 -0
  5. package/dist/ai/activity.js.map +1 -0
  6. package/dist/ai/broker/broker.d.ts +25 -0
  7. package/dist/ai/broker/broker.d.ts.map +1 -1
  8. package/dist/ai/broker/broker.js +46 -42
  9. package/dist/ai/broker/broker.js.map +1 -1
  10. package/dist/ai/broker/gemini-engine.d.ts +7 -0
  11. package/dist/ai/broker/gemini-engine.d.ts.map +1 -1
  12. package/dist/ai/broker/gemini-engine.js +15 -0
  13. package/dist/ai/broker/gemini-engine.js.map +1 -1
  14. package/dist/ai/broker/index.d.ts +1 -1
  15. package/dist/ai/broker/index.d.ts.map +1 -1
  16. package/dist/ai/broker/index.js.map +1 -1
  17. package/dist/ai/broker/openai-engine.d.ts.map +1 -1
  18. package/dist/ai/broker/openai-engine.js +7 -3
  19. package/dist/ai/broker/openai-engine.js.map +1 -1
  20. package/dist/ai/broker/scripted-engine.d.ts +9 -1
  21. package/dist/ai/broker/scripted-engine.d.ts.map +1 -1
  22. package/dist/ai/broker/scripted-engine.js +14 -5
  23. package/dist/ai/broker/scripted-engine.js.map +1 -1
  24. package/dist/ai/broker/types.d.ts +6 -2
  25. package/dist/ai/broker/types.d.ts.map +1 -1
  26. package/dist/ai/events.d.ts +12 -0
  27. package/dist/ai/events.d.ts.map +1 -0
  28. package/dist/ai/events.js +17 -0
  29. package/dist/ai/events.js.map +1 -0
  30. package/dist/ai/generation-enums.d.ts +43 -0
  31. package/dist/ai/generation-enums.d.ts.map +1 -0
  32. package/dist/ai/generation-enums.js +37 -0
  33. package/dist/ai/generation-enums.js.map +1 -0
  34. package/dist/ai/index.d.ts +1 -0
  35. package/dist/ai/index.d.ts.map +1 -1
  36. package/dist/ai/index.js +1 -0
  37. package/dist/ai/index.js.map +1 -1
  38. package/dist/ai/instances.d.ts +6 -0
  39. package/dist/ai/instances.d.ts.map +1 -1
  40. package/dist/ai/instances.js +20 -2
  41. package/dist/ai/instances.js.map +1 -1
  42. package/dist/ai/internal.d.ts +3 -0
  43. package/dist/ai/internal.d.ts.map +1 -1
  44. package/dist/ai/internal.js +3 -0
  45. package/dist/ai/internal.js.map +1 -1
  46. package/dist/ai/sandbox-plane.d.ts.map +1 -1
  47. package/dist/ai/sandbox-plane.js +23 -8
  48. package/dist/ai/sandbox-plane.js.map +1 -1
  49. package/dist/ai/scripting.d.ts +20 -2
  50. package/dist/ai/scripting.d.ts.map +1 -1
  51. package/dist/ai/scripting.js +30 -3
  52. package/dist/ai/scripting.js.map +1 -1
  53. package/dist/app/internal.d.ts +1 -0
  54. package/dist/app/internal.d.ts.map +1 -1
  55. package/dist/app/internal.js +1 -0
  56. package/dist/app/internal.js.map +1 -1
  57. package/dist/auth/email-link.d.ts +8 -1
  58. package/dist/auth/email-link.d.ts.map +1 -1
  59. package/dist/auth/email-link.js +29 -20
  60. package/dist/auth/email-link.js.map +1 -1
  61. package/dist/auth/events.d.ts +12 -0
  62. package/dist/auth/events.d.ts.map +1 -0
  63. package/dist/auth/events.js +18 -0
  64. package/dist/auth/events.js.map +1 -0
  65. package/dist/auth/factor-id.d.ts +7 -0
  66. package/dist/auth/factor-id.d.ts.map +1 -0
  67. package/dist/auth/factor-id.js +6 -0
  68. package/dist/auth/factor-id.js.map +1 -0
  69. package/dist/auth/index.d.ts +1 -0
  70. package/dist/auth/index.d.ts.map +1 -1
  71. package/dist/auth/index.js +1 -0
  72. package/dist/auth/index.js.map +1 -1
  73. package/dist/auth/instances.d.ts.map +1 -1
  74. package/dist/auth/instances.js +13 -1
  75. package/dist/auth/instances.js.map +1 -1
  76. package/dist/auth/internal.d.ts +20 -0
  77. package/dist/auth/internal.d.ts.map +1 -0
  78. package/dist/auth/internal.js +19 -0
  79. package/dist/auth/internal.js.map +1 -0
  80. package/dist/auth/modular.d.ts +9 -0
  81. package/dist/auth/modular.d.ts.map +1 -1
  82. package/dist/auth/modular.js +20 -0
  83. package/dist/auth/modular.js.map +1 -1
  84. package/dist/auth/reauth.js +3 -2
  85. package/dist/auth/reauth.js.map +1 -1
  86. package/dist/auth/sandbox/default-avatar.d.ts +64 -0
  87. package/dist/auth/sandbox/default-avatar.d.ts.map +1 -0
  88. package/dist/auth/sandbox/default-avatar.js +118 -0
  89. package/dist/auth/sandbox/default-avatar.js.map +1 -0
  90. package/dist/auth/sandbox/driver.d.ts +36 -0
  91. package/dist/auth/sandbox/driver.d.ts.map +1 -1
  92. package/dist/auth/sandbox/driver.js +47 -0
  93. package/dist/auth/sandbox/driver.js.map +1 -1
  94. package/dist/auth/sandbox/project-store.d.ts +0 -1
  95. package/dist/auth/sandbox/project-store.d.ts.map +1 -1
  96. package/dist/auth/sandbox/project-store.js +0 -1
  97. package/dist/auth/sandbox/project-store.js.map +1 -1
  98. package/dist/auth/sandbox-backend-types.d.ts +34 -20
  99. package/dist/auth/sandbox-backend-types.d.ts.map +1 -1
  100. package/dist/auth/sandbox-backend-types.js +2 -3
  101. package/dist/auth/sandbox-backend-types.js.map +1 -1
  102. package/dist/auth/sandbox-backend.d.ts +98 -20
  103. package/dist/auth/sandbox-backend.d.ts.map +1 -1
  104. package/dist/auth/sandbox-backend.js +403 -96
  105. package/dist/auth/sandbox-backend.js.map +1 -1
  106. package/dist/auth/seed-user.d.ts +38 -0
  107. package/dist/auth/seed-user.d.ts.map +1 -0
  108. package/dist/auth/seed-user.js +2 -0
  109. package/dist/auth/seed-user.js.map +1 -0
  110. package/dist/auth/tokens.d.ts +6 -1
  111. package/dist/auth/tokens.d.ts.map +1 -1
  112. package/dist/auth/tokens.js +19 -17
  113. package/dist/auth/tokens.js.map +1 -1
  114. package/dist/auth/types.d.ts +13 -1
  115. package/dist/auth/types.d.ts.map +1 -1
  116. package/dist/auth/types.js.map +1 -1
  117. package/dist/database/activity-coverage.d.ts +9 -0
  118. package/dist/database/activity-coverage.d.ts.map +1 -0
  119. package/dist/database/activity-coverage.js +11 -0
  120. package/dist/database/activity-coverage.js.map +1 -0
  121. package/dist/database/connection-lifecycle.d.ts +3 -0
  122. package/dist/database/connection-lifecycle.d.ts.map +1 -1
  123. package/dist/database/connection-lifecycle.js +54 -23
  124. package/dist/database/connection-lifecycle.js.map +1 -1
  125. package/dist/database/events.d.ts +12 -0
  126. package/dist/database/events.d.ts.map +1 -0
  127. package/dist/database/events.js +10 -0
  128. package/dist/database/events.js.map +1 -0
  129. package/dist/database/instances.d.ts +7 -7
  130. package/dist/database/instances.d.ts.map +1 -1
  131. package/dist/database/instances.js +35 -13
  132. package/dist/database/instances.js.map +1 -1
  133. package/dist/database/internal/query-projection.d.ts +102 -0
  134. package/dist/database/internal/query-projection.d.ts.map +1 -0
  135. package/dist/database/internal/query-projection.js +293 -0
  136. package/dist/database/internal/query-projection.js.map +1 -0
  137. package/dist/database/internal.d.ts +2 -0
  138. package/dist/database/internal.d.ts.map +1 -1
  139. package/dist/database/internal.js +2 -0
  140. package/dist/database/internal.js.map +1 -1
  141. package/dist/database/listeners.d.ts.map +1 -1
  142. package/dist/database/listeners.js +165 -37
  143. package/dist/database/listeners.js.map +1 -1
  144. package/dist/database/operations.d.ts.map +1 -1
  145. package/dist/database/operations.js +77 -50
  146. package/dist/database/operations.js.map +1 -1
  147. package/dist/database/replay.d.ts.map +1 -1
  148. package/dist/database/replay.js +6 -2
  149. package/dist/database/replay.js.map +1 -1
  150. package/dist/database/routing.d.ts +4 -0
  151. package/dist/database/routing.d.ts.map +1 -1
  152. package/dist/database/routing.js.map +1 -1
  153. package/dist/database/sandbox/backend-for.d.ts +4 -3
  154. package/dist/database/sandbox/backend-for.d.ts.map +1 -1
  155. package/dist/database/sandbox/backend-for.js +130 -24
  156. package/dist/database/sandbox/backend-for.js.map +1 -1
  157. package/dist/database/sandbox/backend-state.d.ts +7 -0
  158. package/dist/database/sandbox/backend-state.d.ts.map +1 -1
  159. package/dist/database/sandbox/backend-state.js +15 -1
  160. package/dist/database/sandbox/backend-state.js.map +1 -1
  161. package/dist/database/sandbox/backend.d.ts +2 -1
  162. package/dist/database/sandbox/backend.d.ts.map +1 -1
  163. package/dist/database/sandbox/backend.js +3 -3
  164. package/dist/database/sandbox/backend.js.map +1 -1
  165. package/dist/database/sandbox/child-listeners.d.ts +5 -0
  166. package/dist/database/sandbox/child-listeners.d.ts.map +1 -1
  167. package/dist/database/sandbox/child-listeners.js +34 -14
  168. package/dist/database/sandbox/child-listeners.js.map +1 -1
  169. package/dist/database/sandbox/listener-types.d.ts +5 -0
  170. package/dist/database/sandbox/listener-types.d.ts.map +1 -1
  171. package/dist/database/sandbox/operation-events.d.ts +5 -0
  172. package/dist/database/sandbox/operation-events.d.ts.map +1 -1
  173. package/dist/database/sandbox/operation-events.js +18 -3
  174. package/dist/database/sandbox/operation-events.js.map +1 -1
  175. package/dist/database/sandbox/persistence-state.d.ts.map +1 -1
  176. package/dist/database/sandbox/persistence-state.js +1 -8
  177. package/dist/database/sandbox/persistence-state.js.map +1 -1
  178. package/dist/database/sandbox/priority-writes.js +2 -2
  179. package/dist/database/sandbox/priority-writes.js.map +1 -1
  180. package/dist/database/sandbox/query.d.ts +2 -101
  181. package/dist/database/sandbox/query.d.ts.map +1 -1
  182. package/dist/database/sandbox/query.js +1 -225
  183. package/dist/database/sandbox/query.js.map +1 -1
  184. package/dist/database/sandbox/rules-eval.d.ts +28 -0
  185. package/dist/database/sandbox/rules-eval.d.ts.map +1 -1
  186. package/dist/database/sandbox/rules-eval.js +136 -9
  187. package/dist/database/sandbox/rules-eval.js.map +1 -1
  188. package/dist/database/sandbox/transactions.d.ts.map +1 -1
  189. package/dist/database/sandbox/transactions.js +17 -38
  190. package/dist/database/sandbox/transactions.js.map +1 -1
  191. package/dist/database/sandbox/value-listeners.d.ts +11 -1
  192. package/dist/database/sandbox/value-listeners.d.ts.map +1 -1
  193. package/dist/database/sandbox/value-listeners.js +65 -27
  194. package/dist/database/sandbox/value-listeners.js.map +1 -1
  195. package/dist/database/sandbox/write-plane.d.ts.map +1 -1
  196. package/dist/database/sandbox/write-plane.js +30 -22
  197. package/dist/database/sandbox/write-plane.js.map +1 -1
  198. package/dist/database/sdk-activity.d.ts +5 -0
  199. package/dist/database/sdk-activity.d.ts.map +1 -0
  200. package/dist/database/sdk-activity.js +20 -0
  201. package/dist/database/sdk-activity.js.map +1 -0
  202. package/dist/database/transactions.d.ts.map +1 -1
  203. package/dist/database/transactions.js +7 -3
  204. package/dist/database/transactions.js.map +1 -1
  205. package/dist/database/types.d.ts +9 -1
  206. package/dist/database/types.d.ts.map +1 -1
  207. package/dist/database/types.js.map +1 -1
  208. package/dist/deferred/entry.d.ts +6 -3
  209. package/dist/deferred/entry.d.ts.map +1 -1
  210. package/dist/deferred/entry.js +13 -10
  211. package/dist/deferred/entry.js.map +1 -1
  212. package/dist/firestore/activity-coverage.d.ts +9 -0
  213. package/dist/firestore/activity-coverage.d.ts.map +1 -0
  214. package/dist/firestore/activity-coverage.js +9 -0
  215. package/dist/firestore/activity-coverage.js.map +1 -0
  216. package/dist/firestore/aggregates.d.ts.map +1 -1
  217. package/dist/firestore/aggregates.js +32 -10
  218. package/dist/firestore/aggregates.js.map +1 -1
  219. package/dist/firestore/bytes.d.ts +13 -0
  220. package/dist/firestore/bytes.d.ts.map +1 -0
  221. package/dist/firestore/bytes.js +51 -0
  222. package/dist/firestore/bytes.js.map +1 -0
  223. package/dist/firestore/converter-method.d.ts +11 -0
  224. package/dist/firestore/converter-method.d.ts.map +1 -0
  225. package/dist/firestore/converter-method.js +39 -0
  226. package/dist/firestore/converter-method.js.map +1 -0
  227. package/dist/firestore/errors.d.ts.map +1 -1
  228. package/dist/firestore/errors.js +4 -0
  229. package/dist/firestore/errors.js.map +1 -1
  230. package/dist/firestore/field-values.d.ts +3 -36
  231. package/dist/firestore/field-values.d.ts.map +1 -1
  232. package/dist/firestore/field-values.js +3 -136
  233. package/dist/firestore/field-values.js.map +1 -1
  234. package/dist/firestore/geo-point.d.ts +15 -0
  235. package/dist/firestore/geo-point.d.ts.map +1 -0
  236. package/dist/firestore/geo-point.js +50 -0
  237. package/dist/firestore/geo-point.js.map +1 -0
  238. package/dist/firestore/index.d.ts +1 -1
  239. package/dist/firestore/index.d.ts.map +1 -1
  240. package/dist/firestore/index.js +1 -1
  241. package/dist/firestore/index.js.map +1 -1
  242. package/dist/firestore/instances.d.ts.map +1 -1
  243. package/dist/firestore/instances.js +23 -2
  244. package/dist/firestore/instances.js.map +1 -1
  245. package/dist/firestore/internal/document-data.d.ts +3 -0
  246. package/dist/firestore/internal/document-data.d.ts.map +1 -0
  247. package/dist/firestore/internal/document-data.js +10 -0
  248. package/dist/firestore/internal/document-data.js.map +1 -0
  249. package/dist/firestore/internal/index.d.ts +3 -0
  250. package/dist/firestore/internal/index.d.ts.map +1 -1
  251. package/dist/firestore/internal/index.js +5 -0
  252. package/dist/firestore/internal/index.js.map +1 -1
  253. package/dist/firestore/internal/value-codec.d.ts +16 -61
  254. package/dist/firestore/internal/value-codec.d.ts.map +1 -1
  255. package/dist/firestore/internal/value-codec.js +137 -82
  256. package/dist/firestore/internal/value-codec.js.map +1 -1
  257. package/dist/firestore/internal/value-depth.d.ts +3 -0
  258. package/dist/firestore/internal/value-depth.d.ts.map +1 -0
  259. package/dist/firestore/internal/value-depth.js +19 -0
  260. package/dist/firestore/internal/value-depth.js.map +1 -0
  261. package/dist/firestore/listeners.d.ts +18 -1
  262. package/dist/firestore/listeners.d.ts.map +1 -1
  263. package/dist/firestore/listeners.js +60 -21
  264. package/dist/firestore/listeners.js.map +1 -1
  265. package/dist/firestore/persistence.d.ts +0 -9
  266. package/dist/firestore/persistence.d.ts.map +1 -1
  267. package/dist/firestore/persistence.js +23 -9
  268. package/dist/firestore/persistence.js.map +1 -1
  269. package/dist/firestore/plain-object.d.ts +3 -0
  270. package/dist/firestore/plain-object.d.ts.map +1 -0
  271. package/dist/firestore/plain-object.js +9 -0
  272. package/dist/firestore/plain-object.js.map +1 -0
  273. package/dist/firestore/query-constraints.d.ts.map +1 -1
  274. package/dist/firestore/query-constraints.js +4 -3
  275. package/dist/firestore/query-constraints.js.map +1 -1
  276. package/dist/firestore/reads.d.ts +9 -7
  277. package/dist/firestore/reads.d.ts.map +1 -1
  278. package/dist/firestore/reads.js +74 -36
  279. package/dist/firestore/reads.js.map +1 -1
  280. package/dist/firestore/refs.d.ts +2 -1
  281. package/dist/firestore/refs.d.ts.map +1 -1
  282. package/dist/firestore/refs.js +37 -24
  283. package/dist/firestore/refs.js.map +1 -1
  284. package/dist/firestore/sandbox/activity-query-display.d.ts +67 -0
  285. package/dist/firestore/sandbox/activity-query-display.d.ts.map +1 -0
  286. package/dist/firestore/sandbox/activity-query-display.js +119 -0
  287. package/dist/firestore/sandbox/activity-query-display.js.map +1 -0
  288. package/dist/firestore/sandbox/admin-compat/batch.d.ts +4 -8
  289. package/dist/firestore/sandbox/admin-compat/batch.d.ts.map +1 -1
  290. package/dist/firestore/sandbox/admin-compat/batch.js +27 -19
  291. package/dist/firestore/sandbox/admin-compat/batch.js.map +1 -1
  292. package/dist/firestore/sandbox/admin-compat/query-comparison.d.ts.map +1 -1
  293. package/dist/firestore/sandbox/admin-compat/query-comparison.js +8 -3
  294. package/dist/firestore/sandbox/admin-compat/query-comparison.js.map +1 -1
  295. package/dist/firestore/sandbox/admin-compat/query.d.ts +8 -0
  296. package/dist/firestore/sandbox/admin-compat/query.d.ts.map +1 -1
  297. package/dist/firestore/sandbox/admin-compat/query.js +44 -5
  298. package/dist/firestore/sandbox/admin-compat/query.js.map +1 -1
  299. package/dist/firestore/sandbox/admin-compat/read-translation.d.ts.map +1 -1
  300. package/dist/firestore/sandbox/admin-compat/read-translation.js +18 -9
  301. package/dist/firestore/sandbox/admin-compat/read-translation.js.map +1 -1
  302. package/dist/firestore/sandbox/admin-compat/transaction.d.ts +2 -2
  303. package/dist/firestore/sandbox/admin-compat/transaction.d.ts.map +1 -1
  304. package/dist/firestore/sandbox/admin-compat/transaction.js +13 -4
  305. package/dist/firestore/sandbox/admin-compat/transaction.js.map +1 -1
  306. package/dist/firestore/sandbox/admin-compat/types.d.ts +6 -33
  307. package/dist/firestore/sandbox/admin-compat/types.d.ts.map +1 -1
  308. package/dist/firestore/sandbox/admin-compat/types.js +1 -76
  309. package/dist/firestore/sandbox/admin-compat/types.js.map +1 -1
  310. package/dist/firestore/sandbox/atomic-state.d.ts +4 -0
  311. package/dist/firestore/sandbox/atomic-state.d.ts.map +1 -0
  312. package/dist/firestore/sandbox/atomic-state.js +105 -0
  313. package/dist/firestore/sandbox/atomic-state.js.map +1 -0
  314. package/dist/firestore/sandbox/atomic-write-pipeline.d.ts +3 -2
  315. package/dist/firestore/sandbox/atomic-write-pipeline.d.ts.map +1 -1
  316. package/dist/firestore/sandbox/atomic-write-pipeline.js +128 -58
  317. package/dist/firestore/sandbox/atomic-write-pipeline.js.map +1 -1
  318. package/dist/firestore/sandbox/batch-write-executor.d.ts.map +1 -1
  319. package/dist/firestore/sandbox/batch-write-executor.js +54 -28
  320. package/dist/firestore/sandbox/batch-write-executor.js.map +1 -1
  321. package/dist/firestore/sandbox/converters/user-timestamp.d.ts +6 -40
  322. package/dist/firestore/sandbox/converters/user-timestamp.d.ts.map +1 -1
  323. package/dist/firestore/sandbox/converters/user-timestamp.js +20 -43
  324. package/dist/firestore/sandbox/converters/user-timestamp.js.map +1 -1
  325. package/dist/firestore/sandbox/document-copy.d.ts +4 -0
  326. package/dist/firestore/sandbox/document-copy.d.ts.map +1 -0
  327. package/dist/firestore/sandbox/document-copy.js +28 -0
  328. package/dist/firestore/sandbox/document-copy.js.map +1 -0
  329. package/dist/firestore/sandbox/document-store.d.ts +99 -0
  330. package/dist/firestore/sandbox/document-store.d.ts.map +1 -0
  331. package/dist/firestore/sandbox/document-store.js +2 -0
  332. package/dist/firestore/sandbox/document-store.js.map +1 -0
  333. package/dist/firestore/sandbox/errors.d.ts +4 -1
  334. package/dist/firestore/sandbox/errors.d.ts.map +1 -1
  335. package/dist/firestore/sandbox/errors.js +2 -25
  336. package/dist/firestore/sandbox/errors.js.map +1 -1
  337. package/dist/firestore/sandbox/event-log.d.ts +22 -4
  338. package/dist/firestore/sandbox/event-log.d.ts.map +1 -1
  339. package/dist/firestore/sandbox/event-log.js +66 -6
  340. package/dist/firestore/sandbox/event-log.js.map +1 -1
  341. package/dist/firestore/sandbox/field-merge.d.ts.map +1 -1
  342. package/dist/firestore/sandbox/field-merge.js +10 -20
  343. package/dist/firestore/sandbox/field-merge.js.map +1 -1
  344. package/dist/firestore/sandbox/history-controls.d.ts +1 -1
  345. package/dist/firestore/sandbox/history-controls.d.ts.map +1 -1
  346. package/dist/firestore/sandbox/history-controls.js +1 -1
  347. package/dist/firestore/sandbox/history-controls.js.map +1 -1
  348. package/dist/firestore/sandbox/list-query-proof.d.ts +4 -1
  349. package/dist/firestore/sandbox/list-query-proof.d.ts.map +1 -1
  350. package/dist/firestore/sandbox/list-query-proof.js +32 -96
  351. package/dist/firestore/sandbox/list-query-proof.js.map +1 -1
  352. package/dist/firestore/sandbox/listener-dispatch.d.ts +26 -1
  353. package/dist/firestore/sandbox/listener-dispatch.d.ts.map +1 -1
  354. package/dist/firestore/sandbox/listener-dispatch.js +58 -5
  355. package/dist/firestore/sandbox/listener-dispatch.js.map +1 -1
  356. package/dist/firestore/sandbox/local-environment.d.ts +16 -2
  357. package/dist/firestore/sandbox/local-environment.d.ts.map +1 -1
  358. package/dist/firestore/sandbox/local-environment.js +33 -9
  359. package/dist/firestore/sandbox/local-environment.js.map +1 -1
  360. package/dist/firestore/sandbox/local-state.d.ts +5 -99
  361. package/dist/firestore/sandbox/local-state.d.ts.map +1 -1
  362. package/dist/firestore/sandbox/local-state.js +64 -117
  363. package/dist/firestore/sandbox/local-state.js.map +1 -1
  364. package/dist/firestore/sandbox/query-execution.d.ts +4 -1
  365. package/dist/firestore/sandbox/query-execution.d.ts.map +1 -1
  366. package/dist/firestore/sandbox/query-execution.js +51 -26
  367. package/dist/firestore/sandbox/query-execution.js.map +1 -1
  368. package/dist/firestore/sandbox/query-operand-equality.d.ts.map +1 -1
  369. package/dist/firestore/sandbox/query-operand-equality.js +50 -14
  370. package/dist/firestore/sandbox/query-operand-equality.js.map +1 -1
  371. package/dist/firestore/sandbox/query-operators.d.ts +4 -0
  372. package/dist/firestore/sandbox/query-operators.d.ts.map +1 -0
  373. package/dist/firestore/sandbox/query-operators.js +17 -0
  374. package/dist/firestore/sandbox/query-operators.js.map +1 -0
  375. package/dist/firestore/sandbox/query-value-registry.d.ts +1 -1
  376. package/dist/firestore/sandbox/query-value-registry.d.ts.map +1 -1
  377. package/dist/firestore/sandbox/query-value-registry.js +3 -1
  378. package/dist/firestore/sandbox/query-value-registry.js.map +1 -1
  379. package/dist/firestore/sandbox/request-events.d.ts +3 -0
  380. package/dist/firestore/sandbox/request-events.d.ts.map +1 -1
  381. package/dist/firestore/sandbox/request-events.js +4 -0
  382. package/dist/firestore/sandbox/request-events.js.map +1 -1
  383. package/dist/firestore/sandbox/rules-evidence.d.ts +7 -0
  384. package/dist/firestore/sandbox/rules-evidence.d.ts.map +1 -0
  385. package/dist/firestore/sandbox/rules-evidence.js +87 -0
  386. package/dist/firestore/sandbox/rules-evidence.js.map +1 -0
  387. package/dist/firestore/sandbox/rules-list-authorizer.d.ts +13 -1
  388. package/dist/firestore/sandbox/rules-list-authorizer.d.ts.map +1 -1
  389. package/dist/firestore/sandbox/rules-list-authorizer.js +53 -74
  390. package/dist/firestore/sandbox/rules-list-authorizer.js.map +1 -1
  391. package/dist/firestore/sandbox/rules-operation-reader.d.ts +8 -1
  392. package/dist/firestore/sandbox/rules-operation-reader.d.ts.map +1 -1
  393. package/dist/firestore/sandbox/rules-operation-reader.js +13 -5
  394. package/dist/firestore/sandbox/rules-operation-reader.js.map +1 -1
  395. package/dist/firestore/sandbox/rules-read-engine.d.ts +8 -1
  396. package/dist/firestore/sandbox/rules-read-engine.d.ts.map +1 -1
  397. package/dist/firestore/sandbox/rules-read-engine.js +21 -10
  398. package/dist/firestore/sandbox/rules-read-engine.js.map +1 -1
  399. package/dist/firestore/sandbox/rules-state.d.ts +5 -0
  400. package/dist/firestore/sandbox/rules-state.d.ts.map +1 -1
  401. package/dist/firestore/sandbox/rules-state.js +16 -0
  402. package/dist/firestore/sandbox/rules-state.js.map +1 -1
  403. package/dist/firestore/sandbox/snapshot-listeners.d.ts +9 -1
  404. package/dist/firestore/sandbox/snapshot-listeners.d.ts.map +1 -1
  405. package/dist/firestore/sandbox/snapshot-listeners.js.map +1 -1
  406. package/dist/firestore/sandbox/transaction-merge.d.ts +2 -33
  407. package/dist/firestore/sandbox/transaction-merge.d.ts.map +1 -1
  408. package/dist/firestore/sandbox/transaction-merge.js +19 -7
  409. package/dist/firestore/sandbox/transaction-merge.js.map +1 -1
  410. package/dist/firestore/sandbox/transaction-types.d.ts +11 -21
  411. package/dist/firestore/sandbox/transaction-types.d.ts.map +1 -1
  412. package/dist/firestore/sandbox/transaction-types.js.map +1 -1
  413. package/dist/firestore/sandbox/transaction-write-executor.d.ts +2 -1
  414. package/dist/firestore/sandbox/transaction-write-executor.d.ts.map +1 -1
  415. package/dist/firestore/sandbox/transaction-write-executor.js +110 -69
  416. package/dist/firestore/sandbox/transaction-write-executor.js.map +1 -1
  417. package/dist/firestore/sandbox/transaction.d.ts +3 -2
  418. package/dist/firestore/sandbox/transaction.d.ts.map +1 -1
  419. package/dist/firestore/sandbox/transaction.js +23 -6
  420. package/dist/firestore/sandbox/transaction.js.map +1 -1
  421. package/dist/firestore/sandbox/value-resolver.d.ts +1 -8
  422. package/dist/firestore/sandbox/value-resolver.d.ts.map +1 -1
  423. package/dist/firestore/sandbox/value-resolver.js +2 -13
  424. package/dist/firestore/sandbox/value-resolver.js.map +1 -1
  425. package/dist/firestore/sandbox/write-engine.d.ts +5 -1
  426. package/dist/firestore/sandbox/write-engine.d.ts.map +1 -1
  427. package/dist/firestore/sandbox/write-engine.js +14 -7
  428. package/dist/firestore/sandbox/write-engine.js.map +1 -1
  429. package/dist/firestore/sandbox/write-runtime.d.ts +12 -4
  430. package/dist/firestore/sandbox/write-runtime.d.ts.map +1 -1
  431. package/dist/firestore/sandbox/write-runtime.js +72 -38
  432. package/dist/firestore/sandbox/write-runtime.js.map +1 -1
  433. package/dist/firestore/sandbox/writes.d.ts +3 -1
  434. package/dist/firestore/sandbox/writes.d.ts.map +1 -1
  435. package/dist/firestore/sdk-activity.d.ts +8 -0
  436. package/dist/firestore/sdk-activity.d.ts.map +1 -0
  437. package/dist/firestore/sdk-activity.js +23 -0
  438. package/dist/firestore/sdk-activity.js.map +1 -0
  439. package/dist/firestore/snapshots.d.ts +18 -2
  440. package/dist/firestore/snapshots.d.ts.map +1 -1
  441. package/dist/firestore/snapshots.js +69 -16
  442. package/dist/firestore/snapshots.js.map +1 -1
  443. package/dist/firestore/state.d.ts +8 -3
  444. package/dist/firestore/state.d.ts.map +1 -1
  445. package/dist/firestore/state.js +30 -13
  446. package/dist/firestore/state.js.map +1 -1
  447. package/dist/firestore/timestamp.d.ts +28 -0
  448. package/dist/firestore/timestamp.d.ts.map +1 -0
  449. package/dist/firestore/timestamp.js +80 -0
  450. package/dist/firestore/timestamp.js.map +1 -0
  451. package/dist/firestore/tools.d.ts.map +1 -1
  452. package/dist/firestore/tools.js +2 -4
  453. package/dist/firestore/tools.js.map +1 -1
  454. package/dist/firestore/transactions.d.ts.map +1 -1
  455. package/dist/firestore/transactions.js +76 -3
  456. package/dist/firestore/transactions.js.map +1 -1
  457. package/dist/firestore/types.d.ts +26 -5
  458. package/dist/firestore/types.d.ts.map +1 -1
  459. package/dist/firestore/types.js.map +1 -1
  460. package/dist/firestore/vector-value.d.ts +11 -0
  461. package/dist/firestore/vector-value.d.ts.map +1 -0
  462. package/dist/firestore/vector-value.js +51 -0
  463. package/dist/firestore/vector-value.js.map +1 -0
  464. package/dist/firestore/writes.d.ts +0 -7
  465. package/dist/firestore/writes.d.ts.map +1 -1
  466. package/dist/firestore/writes.js +42 -25
  467. package/dist/firestore/writes.js.map +1 -1
  468. package/dist/functions/events.d.ts +12 -0
  469. package/dist/functions/events.d.ts.map +1 -0
  470. package/dist/functions/events.js +10 -0
  471. package/dist/functions/events.js.map +1 -0
  472. package/dist/messaging/broker/broker.d.ts +43 -30
  473. package/dist/messaging/broker/broker.d.ts.map +1 -1
  474. package/dist/messaging/broker/broker.js +148 -43
  475. package/dist/messaging/broker/broker.js.map +1 -1
  476. package/dist/messaging/broker/delivery-history.d.ts +5 -0
  477. package/dist/messaging/broker/delivery-history.d.ts.map +1 -0
  478. package/dist/messaging/broker/delivery-history.js +46 -0
  479. package/dist/messaging/broker/delivery-history.js.map +1 -0
  480. package/dist/messaging/broker/index.d.ts +2 -1
  481. package/dist/messaging/broker/index.d.ts.map +1 -1
  482. package/dist/messaging/broker/index.js +7 -0
  483. package/dist/messaging/broker/index.js.map +1 -1
  484. package/dist/messaging/broker/persistence.d.ts +12 -0
  485. package/dist/messaging/broker/persistence.d.ts.map +1 -0
  486. package/dist/messaging/broker/persistence.js +42 -0
  487. package/dist/messaging/broker/persistence.js.map +1 -0
  488. package/dist/messaging/broker/types.d.ts +44 -0
  489. package/dist/messaging/broker/types.d.ts.map +1 -1
  490. package/dist/messaging/broker/types.js +10 -1
  491. package/dist/messaging/broker/types.js.map +1 -1
  492. package/dist/messaging/events.d.ts +12 -0
  493. package/dist/messaging/events.d.ts.map +1 -0
  494. package/dist/messaging/events.js +19 -0
  495. package/dist/messaging/events.js.map +1 -0
  496. package/dist/rules/api/case-types.d.ts +7 -0
  497. package/dist/rules/api/case-types.d.ts.map +1 -1
  498. package/dist/rules/api/rtdb.d.ts.map +1 -1
  499. package/dist/rules/api/rtdb.js +20 -7
  500. package/dist/rules/api/rtdb.js.map +1 -1
  501. package/dist/rules/grammar/parse-error-wording.d.ts +31 -0
  502. package/dist/rules/grammar/parse-error-wording.d.ts.map +1 -0
  503. package/dist/rules/grammar/parse-error-wording.js +86 -0
  504. package/dist/rules/grammar/parse-error-wording.js.map +1 -0
  505. package/dist/rules/indexes/query-analysis.d.ts +33 -0
  506. package/dist/rules/indexes/query-analysis.d.ts.map +1 -0
  507. package/dist/rules/indexes/query-analysis.js +153 -0
  508. package/dist/rules/indexes/query-analysis.js.map +1 -0
  509. package/dist/rules/indexes/service-query.d.ts +48 -0
  510. package/dist/rules/indexes/service-query.d.ts.map +1 -0
  511. package/dist/rules/indexes/service-query.js +60 -0
  512. package/dist/rules/indexes/service-query.js.map +1 -0
  513. package/dist/rules/internal/index.d.ts +4 -0
  514. package/dist/rules/internal/index.d.ts.map +1 -1
  515. package/dist/rules/internal/index.js +10 -0
  516. package/dist/rules/internal/index.js.map +1 -1
  517. package/dist/rules/modules/rules-capabilities.generated.d.ts +1 -1
  518. package/dist/rules/modules/rules-capabilities.generated.js +1 -1
  519. package/dist/rules/modules/rules-capabilities.generated.js.map +1 -1
  520. package/dist/rules/rtdb/constraints/atoms.d.ts.map +1 -1
  521. package/dist/rules/rtdb/constraints/atoms.js +7 -7
  522. package/dist/rules/rtdb/constraints/atoms.js.map +1 -1
  523. package/dist/rules/rtdb/constraints/data.d.ts +2 -2
  524. package/dist/rules/rtdb/constraints/data.d.ts.map +1 -1
  525. package/dist/rules/rtdb/constraints/data.js +4 -4
  526. package/dist/rules/rtdb/constraints/data.js.map +1 -1
  527. package/dist/rules/rtdb/constraints/document.d.ts.map +1 -1
  528. package/dist/rules/rtdb/constraints/document.js +6 -2
  529. package/dist/rules/rtdb/constraints/document.js.map +1 -1
  530. package/dist/rules/rtdb/constraints/policies.d.ts +2 -2
  531. package/dist/rules/rtdb/constraints/policies.d.ts.map +1 -1
  532. package/dist/rules/rtdb/constraints/policies.js +3 -3
  533. package/dist/rules/rtdb/constraints/policies.js.map +1 -1
  534. package/dist/rules/rtdb/constraints/schema.js +3 -3
  535. package/dist/rules/rtdb/constraints/schema.js.map +1 -1
  536. package/dist/rules/rtdb/grammar/RtdbExpr.ohm +1 -3
  537. package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.d.ts +1 -1
  538. package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.d.ts.map +1 -1
  539. package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.js +1 -3
  540. package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.js.map +1 -1
  541. package/dist/rules/rtdb/grammar/linter.d.ts.map +1 -1
  542. package/dist/rules/rtdb/grammar/linter.js +28 -30
  543. package/dist/rules/rtdb/grammar/linter.js.map +1 -1
  544. package/dist/rules/rtdb/grammar/simulator.d.ts +15 -1
  545. package/dist/rules/rtdb/grammar/simulator.d.ts.map +1 -1
  546. package/dist/rules/rtdb/grammar/simulator.js +93 -65
  547. package/dist/rules/rtdb/grammar/simulator.js.map +1 -1
  548. package/dist/rules/rtdb/grammar/validator.d.ts.map +1 -1
  549. package/dist/rules/rtdb/grammar/validator.js +25 -26
  550. package/dist/rules/rtdb/grammar/validator.js.map +1 -1
  551. package/dist/rules/rtdb/simulation/handler.d.ts.map +1 -1
  552. package/dist/rules/rtdb/simulation/handler.js +136 -32
  553. package/dist/rules/rtdb/simulation/handler.js.map +1 -1
  554. package/dist/rules/rtdb/simulation/spec.d.ts +95 -5
  555. package/dist/rules/rtdb/simulation/spec.d.ts.map +1 -1
  556. package/dist/rules/rtdb/simulation/spec.js +22 -1
  557. package/dist/rules/rtdb/simulation/spec.js.map +1 -1
  558. package/dist/rules/rtdb/types.d.ts +18 -18
  559. package/dist/rules/simulator/evaluator.js +35 -69
  560. package/dist/rules/simulator/evaluator.js.map +1 -1
  561. package/dist/rules/simulator/handler.d.ts.map +1 -1
  562. package/dist/rules/simulator/handler.js +12 -3
  563. package/dist/rules/simulator/handler.js.map +1 -1
  564. package/dist/rules/simulator/mapdiff.d.ts +2 -0
  565. package/dist/rules/simulator/mapdiff.d.ts.map +1 -1
  566. package/dist/rules/simulator/mapdiff.js +7 -5
  567. package/dist/rules/simulator/mapdiff.js.map +1 -1
  568. package/dist/rules/simulator/query-proof-residual.d.ts +11 -0
  569. package/dist/rules/simulator/query-proof-residual.d.ts.map +1 -0
  570. package/dist/rules/simulator/query-proof-residual.js +177 -0
  571. package/dist/rules/simulator/query-proof-residual.js.map +1 -0
  572. package/dist/rules/simulator/query-proof.d.ts +21 -47
  573. package/dist/rules/simulator/query-proof.d.ts.map +1 -1
  574. package/dist/rules/simulator/query-proof.js +78 -13
  575. package/dist/rules/simulator/query-proof.js.map +1 -1
  576. package/dist/rules/simulator/request-path.d.ts +26 -0
  577. package/dist/rules/simulator/request-path.d.ts.map +1 -0
  578. package/dist/rules/simulator/request-path.js +36 -0
  579. package/dist/rules/simulator/request-path.js.map +1 -0
  580. package/dist/rules/simulator/trace-recorder.d.ts +1 -0
  581. package/dist/rules/simulator/trace-recorder.d.ts.map +1 -1
  582. package/dist/rules/simulator/trace-recorder.js +4 -0
  583. package/dist/rules/simulator/trace-recorder.js.map +1 -1
  584. package/dist/rules/simulator/wrappers/timestamp.d.ts +6 -0
  585. package/dist/rules/simulator/wrappers/timestamp.d.ts.map +1 -1
  586. package/dist/rules/simulator/wrappers/timestamp.js +8 -1
  587. package/dist/rules/simulator/wrappers/timestamp.js.map +1 -1
  588. package/dist/rules/simulator-tools-impl.d.ts.map +1 -1
  589. package/dist/rules/simulator-tools-impl.js +6 -3
  590. package/dist/rules/simulator-tools-impl.js.map +1 -1
  591. package/dist/rules/stdlib-tools.js +4 -4
  592. package/dist/rules/stdlib-tools.js.map +1 -1
  593. package/dist/rules/test/spec.d.ts +4 -4
  594. package/dist/sandbox/active-listeners.d.ts +69 -0
  595. package/dist/sandbox/active-listeners.d.ts.map +1 -0
  596. package/dist/sandbox/active-listeners.js +159 -0
  597. package/dist/sandbox/active-listeners.js.map +1 -0
  598. package/dist/sandbox/admin-firestore/error-translation.d.ts.map +1 -1
  599. package/dist/sandbox/admin-firestore/error-translation.js +15 -2
  600. package/dist/sandbox/admin-firestore/error-translation.js.map +1 -1
  601. package/dist/sandbox/admin-firestore/listeners.d.ts +0 -25
  602. package/dist/sandbox/admin-firestore/listeners.d.ts.map +1 -1
  603. package/dist/sandbox/admin-firestore/listeners.js +26 -2
  604. package/dist/sandbox/admin-firestore/listeners.js.map +1 -1
  605. package/dist/sandbox/admin-firestore/remote/listeners.d.ts.map +1 -1
  606. package/dist/sandbox/admin-firestore/remote/listeners.js +50 -29
  607. package/dist/sandbox/admin-firestore/remote/listeners.js.map +1 -1
  608. package/dist/sandbox/admin-firestore/remote/value-codec.d.ts +5 -12
  609. package/dist/sandbox/admin-firestore/remote/value-codec.d.ts.map +1 -1
  610. package/dist/sandbox/admin-firestore/remote/value-codec.js +7 -14
  611. package/dist/sandbox/admin-firestore/remote/value-codec.js.map +1 -1
  612. package/dist/sandbox/admin-firestore/remote/wire-types.d.ts +2 -0
  613. package/dist/sandbox/admin-firestore/remote/wire-types.d.ts.map +1 -1
  614. package/dist/sandbox/attribution/attribution-mode.d.ts +36 -0
  615. package/dist/sandbox/attribution/attribution-mode.d.ts.map +1 -0
  616. package/dist/sandbox/attribution/attribution-mode.js +68 -0
  617. package/dist/sandbox/attribution/attribution-mode.js.map +1 -0
  618. package/dist/sandbox/attribution/effect-regions.d.ts +37 -0
  619. package/dist/sandbox/attribution/effect-regions.d.ts.map +1 -0
  620. package/dist/sandbox/attribution/effect-regions.js +114 -0
  621. package/dist/sandbox/attribution/effect-regions.js.map +1 -0
  622. package/dist/sandbox/attribution/element-selector.d.ts +42 -0
  623. package/dist/sandbox/attribution/element-selector.d.ts.map +1 -0
  624. package/dist/sandbox/attribution/element-selector.js +109 -0
  625. package/dist/sandbox/attribution/element-selector.js.map +1 -0
  626. package/dist/sandbox/attribution/listener-owners.d.ts +111 -0
  627. package/dist/sandbox/attribution/listener-owners.d.ts.map +1 -0
  628. package/dist/sandbox/attribution/listener-owners.js +215 -0
  629. package/dist/sandbox/attribution/listener-owners.js.map +1 -0
  630. package/dist/sandbox/branches/engine.d.ts +129 -0
  631. package/dist/sandbox/branches/engine.d.ts.map +1 -0
  632. package/dist/sandbox/branches/engine.js +280 -0
  633. package/dist/sandbox/branches/engine.js.map +1 -0
  634. package/dist/sandbox/branches/index.d.ts +12 -139
  635. package/dist/sandbox/branches/index.d.ts.map +1 -1
  636. package/dist/sandbox/branches/index.js +8 -390
  637. package/dist/sandbox/branches/index.js.map +1 -1
  638. package/dist/sandbox/branches/promotion.d.ts +27 -0
  639. package/dist/sandbox/branches/promotion.d.ts.map +1 -0
  640. package/dist/sandbox/branches/promotion.js +160 -0
  641. package/dist/sandbox/branches/promotion.js.map +1 -0
  642. package/dist/sandbox/branches/state-diff.d.ts +66 -0
  643. package/dist/sandbox/branches/state-diff.d.ts.map +1 -0
  644. package/dist/sandbox/branches/state-diff.js +270 -0
  645. package/dist/sandbox/branches/state-diff.js.map +1 -0
  646. package/dist/sandbox/branches/store.d.ts +64 -0
  647. package/dist/sandbox/branches/store.d.ts.map +1 -0
  648. package/dist/sandbox/branches/store.js +264 -0
  649. package/dist/sandbox/branches/store.js.map +1 -0
  650. package/dist/sandbox/checkpoints/capture.d.ts +39 -0
  651. package/dist/sandbox/checkpoints/capture.d.ts.map +1 -0
  652. package/dist/sandbox/checkpoints/capture.js +69 -0
  653. package/dist/sandbox/checkpoints/capture.js.map +1 -0
  654. package/dist/sandbox/checkpoints/directory-backend.d.ts +30 -0
  655. package/dist/sandbox/checkpoints/directory-backend.d.ts.map +1 -0
  656. package/dist/sandbox/checkpoints/directory-backend.js +98 -0
  657. package/dist/sandbox/checkpoints/directory-backend.js.map +1 -0
  658. package/dist/sandbox/checkpoints/index.d.ts +15 -0
  659. package/dist/sandbox/checkpoints/index.d.ts.map +1 -0
  660. package/dist/sandbox/checkpoints/index.js +13 -0
  661. package/dist/sandbox/checkpoints/index.js.map +1 -0
  662. package/dist/sandbox/checkpoints/record-backend.d.ts +25 -0
  663. package/dist/sandbox/checkpoints/record-backend.d.ts.map +1 -0
  664. package/dist/sandbox/checkpoints/record-backend.js +81 -0
  665. package/dist/sandbox/checkpoints/record-backend.js.map +1 -0
  666. package/dist/sandbox/checkpoints/saved-states.d.ts +35 -0
  667. package/dist/sandbox/checkpoints/saved-states.d.ts.map +1 -0
  668. package/dist/sandbox/checkpoints/saved-states.js +47 -0
  669. package/dist/sandbox/checkpoints/saved-states.js.map +1 -0
  670. package/dist/sandbox/checkpoints/types.d.ts +84 -0
  671. package/dist/sandbox/checkpoints/types.d.ts.map +1 -0
  672. package/dist/sandbox/checkpoints/types.js +51 -0
  673. package/dist/sandbox/checkpoints/types.js.map +1 -0
  674. package/dist/sandbox/checkpoints/validation.d.ts +3 -0
  675. package/dist/sandbox/checkpoints/validation.d.ts.map +1 -0
  676. package/dist/sandbox/checkpoints/validation.js +99 -0
  677. package/dist/sandbox/checkpoints/validation.js.map +1 -0
  678. package/dist/sandbox/clock.d.ts +121 -0
  679. package/dist/sandbox/clock.d.ts.map +1 -0
  680. package/dist/sandbox/clock.js +167 -0
  681. package/dist/sandbox/clock.js.map +1 -0
  682. package/dist/sandbox/full-state.d.ts +160 -0
  683. package/dist/sandbox/full-state.d.ts.map +1 -0
  684. package/dist/sandbox/full-state.js +267 -0
  685. package/dist/sandbox/full-state.js.map +1 -0
  686. package/dist/sandbox/index.d.ts +13 -6
  687. package/dist/sandbox/index.d.ts.map +1 -1
  688. package/dist/sandbox/index.js +23 -9
  689. package/dist/sandbox/index.js.map +1 -1
  690. package/dist/sandbox/internal/ai-evidence.d.ts +27 -0
  691. package/dist/sandbox/internal/ai-evidence.d.ts.map +1 -0
  692. package/dist/sandbox/internal/ai-evidence.js +29 -0
  693. package/dist/sandbox/internal/ai-evidence.js.map +1 -0
  694. package/dist/sandbox/internal/event-history.d.ts +32 -0
  695. package/dist/sandbox/internal/event-history.d.ts.map +1 -0
  696. package/dist/sandbox/internal/event-history.js +199 -0
  697. package/dist/sandbox/internal/event-history.js.map +1 -0
  698. package/dist/sandbox/internal/history-integrity.d.ts +3 -0
  699. package/dist/sandbox/internal/history-integrity.d.ts.map +1 -0
  700. package/dist/sandbox/internal/history-integrity.js +12 -0
  701. package/dist/sandbox/internal/history-integrity.js.map +1 -0
  702. package/dist/sandbox/internal/history-retention.d.ts +6 -0
  703. package/dist/sandbox/internal/history-retention.d.ts.map +1 -0
  704. package/dist/sandbox/internal/history-retention.js +12 -0
  705. package/dist/sandbox/internal/history-retention.js.map +1 -0
  706. package/dist/sandbox/internal/index.d.ts +27 -0
  707. package/dist/sandbox/internal/index.d.ts.map +1 -1
  708. package/dist/sandbox/internal/index.js +26 -0
  709. package/dist/sandbox/internal/index.js.map +1 -1
  710. package/dist/sandbox/internal/observation-history.d.ts +6 -0
  711. package/dist/sandbox/internal/observation-history.d.ts.map +1 -0
  712. package/dist/sandbox/internal/observation-history.js +6 -0
  713. package/dist/sandbox/internal/observation-history.js.map +1 -0
  714. package/dist/sandbox/internal/observation-payload.d.ts +6 -0
  715. package/dist/sandbox/internal/observation-payload.d.ts.map +1 -0
  716. package/dist/sandbox/internal/observation-payload.js +24 -0
  717. package/dist/sandbox/internal/observation-payload.js.map +1 -0
  718. package/dist/sandbox/internal/provenance.d.ts +0 -1
  719. package/dist/sandbox/internal/provenance.d.ts.map +1 -1
  720. package/dist/sandbox/internal/provenance.js +6 -0
  721. package/dist/sandbox/internal/provenance.js.map +1 -1
  722. package/dist/sandbox/internal/root.d.ts +2 -1
  723. package/dist/sandbox/internal/root.d.ts.map +1 -1
  724. package/dist/sandbox/internal/root.js +2 -2
  725. package/dist/sandbox/internal/root.js.map +1 -1
  726. package/dist/sandbox/internal/rules-evidence-retention.d.ts +11 -0
  727. package/dist/sandbox/internal/rules-evidence-retention.d.ts.map +1 -0
  728. package/dist/sandbox/internal/rules-evidence-retention.js +27 -0
  729. package/dist/sandbox/internal/rules-evidence-retention.js.map +1 -0
  730. package/dist/sandbox/internal/sandbox-impl.d.ts +40 -33
  731. package/dist/sandbox/internal/sandbox-impl.d.ts.map +1 -1
  732. package/dist/sandbox/internal/sandbox-impl.js +83 -40
  733. package/dist/sandbox/internal/sandbox-impl.js.map +1 -1
  734. package/dist/sandbox/internal/sdk-activity.d.ts +112 -0
  735. package/dist/sandbox/internal/sdk-activity.d.ts.map +1 -0
  736. package/dist/sandbox/internal/sdk-activity.js +240 -0
  737. package/dist/sandbox/internal/sdk-activity.js.map +1 -0
  738. package/dist/sandbox/internal/sdk-coverage.d.ts +10 -0
  739. package/dist/sandbox/internal/sdk-coverage.d.ts.map +1 -0
  740. package/dist/sandbox/internal/sdk-coverage.js +21 -0
  741. package/dist/sandbox/internal/sdk-coverage.js.map +1 -0
  742. package/dist/sandbox/internal/sdk-observation.d.ts +32 -0
  743. package/dist/sandbox/internal/sdk-observation.d.ts.map +1 -0
  744. package/dist/sandbox/internal/sdk-observation.js +29 -0
  745. package/dist/sandbox/internal/sdk-observation.js.map +1 -0
  746. package/dist/sandbox/internal/sdk-rates.d.ts +97 -0
  747. package/dist/sandbox/internal/sdk-rates.d.ts.map +1 -0
  748. package/dist/sandbox/internal/sdk-rates.js +187 -0
  749. package/dist/sandbox/internal/sdk-rates.js.map +1 -0
  750. package/dist/sandbox/internal/sdk-write-activity.d.ts +5 -0
  751. package/dist/sandbox/internal/sdk-write-activity.d.ts.map +1 -0
  752. package/dist/sandbox/internal/sdk-write-activity.js +13 -0
  753. package/dist/sandbox/internal/sdk-write-activity.js.map +1 -0
  754. package/dist/sandbox/internal/state-schemas.d.ts +120 -0
  755. package/dist/sandbox/internal/state-schemas.d.ts.map +1 -0
  756. package/dist/sandbox/internal/state-schemas.js +42 -0
  757. package/dist/sandbox/internal/state-schemas.js.map +1 -0
  758. package/dist/sandbox/internal/state-values.d.ts +6 -0
  759. package/dist/sandbox/internal/state-values.d.ts.map +1 -0
  760. package/dist/sandbox/internal/state-values.js +15 -0
  761. package/dist/sandbox/internal/state-values.js.map +1 -0
  762. package/dist/sandbox/internal/storage-activity.d.ts +13 -0
  763. package/dist/sandbox/internal/storage-activity.d.ts.map +1 -0
  764. package/dist/sandbox/internal/storage-activity.js +48 -0
  765. package/dist/sandbox/internal/storage-activity.js.map +1 -0
  766. package/dist/sandbox/internal/usage-evidence.d.ts +24 -0
  767. package/dist/sandbox/internal/usage-evidence.d.ts.map +1 -0
  768. package/dist/sandbox/internal/usage-evidence.js +56 -0
  769. package/dist/sandbox/internal/usage-evidence.js.map +1 -0
  770. package/dist/sandbox/operation-record.d.ts +20 -1
  771. package/dist/sandbox/operation-record.d.ts.map +1 -1
  772. package/dist/sandbox/operation-record.js +100 -4
  773. package/dist/sandbox/operation-record.js.map +1 -1
  774. package/dist/sandbox/persistence/changed-buckets.d.ts +19 -0
  775. package/dist/sandbox/persistence/changed-buckets.d.ts.map +1 -0
  776. package/dist/sandbox/persistence/changed-buckets.js +72 -0
  777. package/dist/sandbox/persistence/changed-buckets.js.map +1 -0
  778. package/dist/sandbox/persistence/chunk-format.d.ts +27 -1
  779. package/dist/sandbox/persistence/chunk-format.d.ts.map +1 -1
  780. package/dist/sandbox/persistence/chunk-format.js +37 -25
  781. package/dist/sandbox/persistence/chunk-format.js.map +1 -1
  782. package/dist/sandbox/persistence/controller.d.ts.map +1 -1
  783. package/dist/sandbox/persistence/controller.js +91 -36
  784. package/dist/sandbox/persistence/controller.js.map +1 -1
  785. package/dist/sandbox/persistence/import-bundle.d.ts +8 -0
  786. package/dist/sandbox/persistence/import-bundle.d.ts.map +1 -0
  787. package/dist/sandbox/persistence/import-bundle.js +66 -0
  788. package/dist/sandbox/persistence/import-bundle.js.map +1 -0
  789. package/dist/sandbox/persistence/serialize.d.ts +1 -1
  790. package/dist/sandbox/persistence/serialize.d.ts.map +1 -1
  791. package/dist/sandbox/persistence/serialize.js +16 -11
  792. package/dist/sandbox/persistence/serialize.js.map +1 -1
  793. package/dist/sandbox/persistence/types.d.ts +4 -0
  794. package/dist/sandbox/persistence/types.d.ts.map +1 -1
  795. package/dist/sandbox/persistence/validate-services.d.ts +7 -0
  796. package/dist/sandbox/persistence/validate-services.d.ts.map +1 -0
  797. package/dist/sandbox/persistence/validate-services.js +73 -0
  798. package/dist/sandbox/persistence/validate-services.js.map +1 -0
  799. package/dist/sandbox/remote.d.ts +6 -0
  800. package/dist/sandbox/remote.d.ts.map +1 -1
  801. package/dist/sandbox/remote.js.map +1 -1
  802. package/dist/sandbox/replay/index.d.ts +1 -1
  803. package/dist/sandbox/replay/index.d.ts.map +1 -1
  804. package/dist/sandbox/replay/index.js +18 -8
  805. package/dist/sandbox/replay/index.js.map +1 -1
  806. package/dist/sandbox/types/errors.d.ts +3 -1
  807. package/dist/sandbox/types/errors.d.ts.map +1 -1
  808. package/dist/sandbox/types/errors.js +0 -4
  809. package/dist/sandbox/types/errors.js.map +1 -1
  810. package/dist/sandbox/types/events.d.ts +105 -76
  811. package/dist/sandbox/types/events.d.ts.map +1 -1
  812. package/dist/sandbox/types/events.js +0 -5
  813. package/dist/sandbox/types/events.js.map +1 -1
  814. package/dist/sandbox/types/index.d.ts +2 -1
  815. package/dist/sandbox/types/index.d.ts.map +1 -1
  816. package/dist/sandbox/types/index.js +1 -0
  817. package/dist/sandbox/types/index.js.map +1 -1
  818. package/dist/sandbox/types/operation.d.ts +13 -4
  819. package/dist/sandbox/types/operation.d.ts.map +1 -1
  820. package/dist/sandbox/types/persistence.d.ts +2 -2
  821. package/dist/sandbox/types/query-proof.d.ts +25 -0
  822. package/dist/sandbox/types/query-proof.d.ts.map +1 -0
  823. package/dist/sandbox/types/query-proof.js +2 -0
  824. package/dist/sandbox/types/query-proof.js.map +1 -0
  825. package/dist/sandbox/types/request-observation.d.ts +19 -0
  826. package/dist/sandbox/types/request-observation.d.ts.map +1 -0
  827. package/dist/sandbox/types/request-observation.js +13 -0
  828. package/dist/sandbox/types/request-observation.js.map +1 -0
  829. package/dist/sandbox/types/rules-evidence.d.ts +48 -0
  830. package/dist/sandbox/types/rules-evidence.d.ts.map +1 -0
  831. package/dist/sandbox/types/rules-evidence.js +2 -0
  832. package/dist/sandbox/types/rules-evidence.js.map +1 -0
  833. package/dist/sandbox/types/service-event-record.d.ts +30 -0
  834. package/dist/sandbox/types/service-event-record.d.ts.map +1 -0
  835. package/dist/sandbox/types/service-event-record.js +13 -0
  836. package/dist/sandbox/types/service-event-record.js.map +1 -0
  837. package/dist/sandbox/types/service-event-records.d.ts +64 -0
  838. package/dist/sandbox/types/service-event-records.d.ts.map +1 -0
  839. package/dist/sandbox/types/service-event-records.js +31 -0
  840. package/dist/sandbox/types/service-event-records.js.map +1 -0
  841. package/dist/sandbox/types/service-mutation-event.d.ts +88 -0
  842. package/dist/sandbox/types/service-mutation-event.d.ts.map +1 -0
  843. package/dist/sandbox/types/service-mutation-event.js +2 -0
  844. package/dist/sandbox/types/service-mutation-event.js.map +1 -0
  845. package/dist/storage/activity-coverage.d.ts +9 -0
  846. package/dist/storage/activity-coverage.d.ts.map +1 -0
  847. package/dist/storage/activity-coverage.js +9 -0
  848. package/dist/storage/activity-coverage.js.map +1 -0
  849. package/dist/storage/base64.d.ts +14 -0
  850. package/dist/storage/base64.d.ts.map +1 -0
  851. package/dist/storage/base64.js +34 -0
  852. package/dist/storage/base64.js.map +1 -0
  853. package/dist/storage/download.d.ts +12 -4
  854. package/dist/storage/download.d.ts.map +1 -1
  855. package/dist/storage/download.js +19 -6
  856. package/dist/storage/download.js.map +1 -1
  857. package/dist/storage/enforce.d.ts +13 -2
  858. package/dist/storage/enforce.d.ts.map +1 -1
  859. package/dist/storage/enforce.js +21 -3
  860. package/dist/storage/enforce.js.map +1 -1
  861. package/dist/storage/errors.d.ts +29 -5
  862. package/dist/storage/errors.d.ts.map +1 -1
  863. package/dist/storage/errors.js +28 -0
  864. package/dist/storage/errors.js.map +1 -1
  865. package/dist/storage/events.d.ts +12 -0
  866. package/dist/storage/events.d.ts.map +1 -0
  867. package/dist/storage/events.js +10 -0
  868. package/dist/storage/events.js.map +1 -0
  869. package/dist/storage/index.d.ts +7 -7
  870. package/dist/storage/index.d.ts.map +1 -1
  871. package/dist/storage/index.js +7 -5
  872. package/dist/storage/index.js.map +1 -1
  873. package/dist/storage/internal.d.ts +10 -1
  874. package/dist/storage/internal.d.ts.map +1 -1
  875. package/dist/storage/internal.js +9 -1
  876. package/dist/storage/internal.js.map +1 -1
  877. package/dist/storage/metadata.d.ts +19 -0
  878. package/dist/storage/metadata.d.ts.map +1 -1
  879. package/dist/storage/metadata.js +50 -19
  880. package/dist/storage/metadata.js.map +1 -1
  881. package/dist/storage/observed.d.ts +16 -0
  882. package/dist/storage/observed.d.ts.map +1 -0
  883. package/dist/storage/observed.js +17 -0
  884. package/dist/storage/observed.js.map +1 -0
  885. package/dist/storage/persistence.d.ts +157 -20
  886. package/dist/storage/persistence.d.ts.map +1 -1
  887. package/dist/storage/persistence.js +423 -53
  888. package/dist/storage/persistence.js.map +1 -1
  889. package/dist/storage/reference.d.ts +3 -1
  890. package/dist/storage/reference.d.ts.map +1 -1
  891. package/dist/storage/reference.js +3 -2
  892. package/dist/storage/reference.js.map +1 -1
  893. package/dist/storage/remote-bytes.d.ts +44 -0
  894. package/dist/storage/remote-bytes.d.ts.map +1 -0
  895. package/dist/storage/remote-bytes.js +97 -0
  896. package/dist/storage/remote-bytes.js.map +1 -0
  897. package/dist/storage/resumable.d.ts.map +1 -1
  898. package/dist/storage/resumable.js +16 -0
  899. package/dist/storage/resumable.js.map +1 -1
  900. package/dist/storage/rules-resolution.d.ts +13 -1
  901. package/dist/storage/rules-resolution.d.ts.map +1 -1
  902. package/dist/storage/rules-resolution.js +28 -0
  903. package/dist/storage/rules-resolution.js.map +1 -1
  904. package/dist/storage/sandbox/persistence-state.d.ts +25 -0
  905. package/dist/storage/sandbox/persistence-state.d.ts.map +1 -0
  906. package/dist/storage/sandbox/persistence-state.js +53 -0
  907. package/dist/storage/sandbox/persistence-state.js.map +1 -0
  908. package/dist/storage/sandbox/rules-bindings.d.ts +15 -0
  909. package/dist/storage/sandbox/rules-bindings.d.ts.map +1 -0
  910. package/dist/storage/sandbox/rules-bindings.js +69 -0
  911. package/dist/storage/sandbox/rules-bindings.js.map +1 -0
  912. package/dist/storage/sandbox/rules-collection-methods.d.ts +3 -0
  913. package/dist/storage/sandbox/rules-collection-methods.d.ts.map +1 -0
  914. package/dist/storage/sandbox/rules-collection-methods.js +149 -0
  915. package/dist/storage/sandbox/rules-collection-methods.js.map +1 -0
  916. package/dist/storage/sandbox/rules-evaluator.d.ts +2 -2
  917. package/dist/storage/sandbox/rules-evaluator.d.ts.map +1 -1
  918. package/dist/storage/sandbox/rules-evaluator.js +51 -129
  919. package/dist/storage/sandbox/rules-evaluator.js.map +1 -1
  920. package/dist/storage/sandbox/rules-firestore-lookup.d.ts +25 -0
  921. package/dist/storage/sandbox/rules-firestore-lookup.d.ts.map +1 -0
  922. package/dist/storage/sandbox/rules-firestore-lookup.js +94 -0
  923. package/dist/storage/sandbox/rules-firestore-lookup.js.map +1 -0
  924. package/dist/storage/sandbox/rules-hashing-methods.d.ts +16 -0
  925. package/dist/storage/sandbox/rules-hashing-methods.d.ts.map +1 -0
  926. package/dist/storage/sandbox/rules-hashing-methods.js +41 -0
  927. package/dist/storage/sandbox/rules-hashing-methods.js.map +1 -0
  928. package/dist/storage/sandbox/rules-method-calls.d.ts +40 -0
  929. package/dist/storage/sandbox/rules-method-calls.d.ts.map +1 -0
  930. package/dist/storage/sandbox/rules-method-calls.js +47 -0
  931. package/dist/storage/sandbox/rules-method-calls.js.map +1 -0
  932. package/dist/storage/sandbox/rules-methods.d.ts +11 -12
  933. package/dist/storage/sandbox/rules-methods.d.ts.map +1 -1
  934. package/dist/storage/sandbox/rules-methods.js +62 -359
  935. package/dist/storage/sandbox/rules-methods.js.map +1 -1
  936. package/dist/storage/sandbox/rules-operators.d.ts +32 -0
  937. package/dist/storage/sandbox/rules-operators.d.ts.map +1 -0
  938. package/dist/storage/sandbox/rules-operators.js +85 -0
  939. package/dist/storage/sandbox/rules-operators.js.map +1 -0
  940. package/dist/storage/sandbox/rules-string-methods.d.ts +3 -0
  941. package/dist/storage/sandbox/rules-string-methods.d.ts.map +1 -0
  942. package/dist/storage/sandbox/rules-string-methods.js +199 -0
  943. package/dist/storage/sandbox/rules-string-methods.js.map +1 -0
  944. package/dist/storage/sandbox/rules-time-methods.d.ts +25 -0
  945. package/dist/storage/sandbox/rules-time-methods.d.ts.map +1 -0
  946. package/dist/storage/sandbox/rules-time-methods.js +89 -0
  947. package/dist/storage/sandbox/rules-time-methods.js.map +1 -0
  948. package/dist/storage/sandbox/rules-values.d.ts +6 -0
  949. package/dist/storage/sandbox/rules-values.d.ts.map +1 -1
  950. package/dist/storage/sandbox/rules-values.js +29 -2
  951. package/dist/storage/sandbox/rules-values.js.map +1 -1
  952. package/dist/storage/sandbox/rules.d.ts +25 -13
  953. package/dist/storage/sandbox/rules.d.ts.map +1 -1
  954. package/dist/storage/sandbox/rules.js +19 -10
  955. package/dist/storage/sandbox/rules.js.map +1 -1
  956. package/dist/storage/sandbox/running-service.d.ts +65 -0
  957. package/dist/storage/sandbox/running-service.d.ts.map +1 -0
  958. package/dist/storage/sandbox/running-service.js +30 -0
  959. package/dist/storage/sandbox/running-service.js.map +1 -0
  960. package/dist/storage/service.d.ts +46 -28
  961. package/dist/storage/service.d.ts.map +1 -1
  962. package/dist/storage/service.js +169 -57
  963. package/dist/storage/service.js.map +1 -1
  964. package/dist/storage/string-format.d.ts +9 -0
  965. package/dist/storage/string-format.d.ts.map +1 -0
  966. package/dist/storage/string-format.js +8 -0
  967. package/dist/storage/string-format.js.map +1 -0
  968. package/dist/storage/upload.d.ts +2 -1
  969. package/dist/storage/upload.d.ts.map +1 -1
  970. package/dist/storage/upload.js +6 -2
  971. package/dist/storage/upload.js.map +1 -1
  972. package/dist/storage/url.d.ts +18 -0
  973. package/dist/storage/url.d.ts.map +1 -0
  974. package/dist/storage/url.js +84 -0
  975. package/dist/storage/url.js.map +1 -0
  976. package/package.json +17 -1
  977. package/src/ai/activity.ts +43 -0
  978. package/src/ai/broker/broker.ts +59 -6
  979. package/src/ai/broker/gemini-engine.ts +16 -0
  980. package/src/ai/broker/index.ts +1 -1
  981. package/src/ai/broker/openai-engine.ts +6 -3
  982. package/src/ai/broker/scripted-engine.ts +16 -5
  983. package/src/ai/broker/types.ts +6 -2
  984. package/src/ai/events.ts +29 -0
  985. package/src/ai/generation-enums.ts +48 -0
  986. package/src/ai/index.ts +9 -0
  987. package/src/ai/instances.ts +22 -2
  988. package/src/ai/internal.ts +5 -0
  989. package/src/ai/sandbox-plane.ts +23 -8
  990. package/src/ai/scripting.ts +42 -7
  991. package/src/app/internal.ts +1 -0
  992. package/src/auth/email-link.ts +32 -21
  993. package/src/auth/events.ts +29 -0
  994. package/src/auth/factor-id.ts +7 -0
  995. package/src/auth/index.ts +2 -0
  996. package/src/auth/instances.ts +13 -1
  997. package/src/auth/internal.ts +24 -0
  998. package/src/auth/modular.ts +27 -0
  999. package/src/auth/reauth.ts +3 -2
  1000. package/src/auth/sandbox/default-avatar.ts +177 -0
  1001. package/src/auth/sandbox/driver.ts +54 -0
  1002. package/src/auth/sandbox/project-store.ts +0 -2
  1003. package/src/auth/sandbox-backend-types.ts +31 -20
  1004. package/src/auth/sandbox-backend.ts +400 -94
  1005. package/src/auth/seed-user.ts +38 -0
  1006. package/src/auth/tokens.ts +21 -18
  1007. package/src/auth/types.ts +13 -1
  1008. package/src/database/activity-coverage.ts +10 -0
  1009. package/src/database/connection-lifecycle.ts +53 -24
  1010. package/src/database/events.ts +20 -0
  1011. package/src/database/instances.ts +52 -21
  1012. package/src/database/internal/query-projection.ts +333 -0
  1013. package/src/database/internal.ts +2 -0
  1014. package/src/database/listeners.ts +162 -44
  1015. package/src/database/operations.ts +73 -50
  1016. package/src/database/replay.ts +6 -2
  1017. package/src/database/routing.ts +4 -0
  1018. package/src/database/sandbox/backend-for.ts +145 -25
  1019. package/src/database/sandbox/backend-state.ts +15 -1
  1020. package/src/database/sandbox/backend.ts +4 -2
  1021. package/src/database/sandbox/child-listeners.ts +32 -13
  1022. package/src/database/sandbox/listener-types.ts +5 -0
  1023. package/src/database/sandbox/operation-events.ts +23 -9
  1024. package/src/database/sandbox/persistence-state.ts +4 -11
  1025. package/src/database/sandbox/priority-writes.ts +2 -2
  1026. package/src/database/sandbox/query.ts +13 -268
  1027. package/src/database/sandbox/rules-eval.ts +144 -10
  1028. package/src/database/sandbox/transactions.ts +17 -39
  1029. package/src/database/sandbox/value-listeners.ts +66 -23
  1030. package/src/database/sandbox/write-plane.ts +29 -22
  1031. package/src/database/sdk-activity.ts +26 -0
  1032. package/src/database/transactions.ts +15 -11
  1033. package/src/database/types.ts +12 -1
  1034. package/src/deferred/entry.ts +16 -10
  1035. package/src/firestore/activity-coverage.ts +8 -0
  1036. package/src/firestore/aggregates.ts +17 -9
  1037. package/src/firestore/bytes.ts +56 -0
  1038. package/src/firestore/converter-method.ts +49 -0
  1039. package/src/firestore/errors.ts +8 -0
  1040. package/src/firestore/field-values.ts +3 -158
  1041. package/src/firestore/geo-point.ts +56 -0
  1042. package/src/firestore/index.ts +1 -1
  1043. package/src/firestore/instances.ts +23 -2
  1044. package/src/firestore/internal/document-data.ts +9 -0
  1045. package/src/firestore/internal/index.ts +7 -0
  1046. package/src/firestore/internal/value-codec.ts +150 -83
  1047. package/src/firestore/internal/value-depth.ts +19 -0
  1048. package/src/firestore/listeners.ts +60 -18
  1049. package/src/firestore/persistence.ts +14 -9
  1050. package/src/firestore/plain-object.ts +7 -0
  1051. package/src/firestore/query-constraints.ts +4 -8
  1052. package/src/firestore/reads.ts +81 -48
  1053. package/src/firestore/refs.ts +56 -41
  1054. package/src/firestore/sandbox/activity-query-display.ts +138 -0
  1055. package/src/firestore/sandbox/admin-compat/batch.ts +26 -19
  1056. package/src/firestore/sandbox/admin-compat/query-comparison.ts +9 -8
  1057. package/src/firestore/sandbox/admin-compat/query.ts +46 -12
  1058. package/src/firestore/sandbox/admin-compat/read-translation.ts +18 -6
  1059. package/src/firestore/sandbox/admin-compat/transaction.ts +14 -4
  1060. package/src/firestore/sandbox/admin-compat/types.ts +6 -88
  1061. package/src/firestore/sandbox/atomic-state.ts +112 -0
  1062. package/src/firestore/sandbox/atomic-write-pipeline.ts +129 -77
  1063. package/src/firestore/sandbox/batch-write-executor.ts +51 -29
  1064. package/src/firestore/sandbox/converters/user-timestamp.ts +19 -42
  1065. package/src/firestore/sandbox/document-copy.ts +27 -0
  1066. package/src/firestore/sandbox/document-store.ts +108 -0
  1067. package/src/firestore/sandbox/errors.ts +5 -1
  1068. package/src/firestore/sandbox/event-log.ts +72 -7
  1069. package/src/firestore/sandbox/field-merge.ts +10 -19
  1070. package/src/firestore/sandbox/history-controls.ts +1 -1
  1071. package/src/firestore/sandbox/list-query-proof.ts +43 -72
  1072. package/src/firestore/sandbox/listener-dispatch.ts +59 -4
  1073. package/src/firestore/sandbox/local-environment.ts +35 -7
  1074. package/src/firestore/sandbox/local-state.ts +72 -232
  1075. package/src/firestore/sandbox/query-execution.ts +56 -34
  1076. package/src/firestore/sandbox/query-operand-equality.ts +57 -14
  1077. package/src/firestore/sandbox/query-operators.ts +20 -0
  1078. package/src/firestore/sandbox/query-value-registry.ts +3 -2
  1079. package/src/firestore/sandbox/request-events.ts +5 -0
  1080. package/src/firestore/sandbox/rules-evidence.ts +94 -0
  1081. package/src/firestore/sandbox/rules-list-authorizer.ts +62 -107
  1082. package/src/firestore/sandbox/rules-operation-reader.ts +11 -4
  1083. package/src/firestore/sandbox/rules-read-engine.ts +19 -8
  1084. package/src/firestore/sandbox/rules-state.ts +21 -0
  1085. package/src/firestore/sandbox/snapshot-listeners.ts +12 -1
  1086. package/src/firestore/sandbox/transaction-merge.ts +33 -20
  1087. package/src/firestore/sandbox/transaction-types.ts +11 -21
  1088. package/src/firestore/sandbox/transaction-write-executor.ts +103 -69
  1089. package/src/firestore/sandbox/transaction.ts +24 -7
  1090. package/src/firestore/sandbox/value-resolver.ts +2 -13
  1091. package/src/firestore/sandbox/write-engine.ts +13 -5
  1092. package/src/firestore/sandbox/write-runtime.ts +68 -40
  1093. package/src/firestore/sandbox/writes.ts +3 -1
  1094. package/src/firestore/sdk-activity.ts +31 -0
  1095. package/src/firestore/snapshots.ts +84 -18
  1096. package/src/firestore/state.ts +34 -14
  1097. package/src/firestore/timestamp.ts +86 -0
  1098. package/src/firestore/tools.ts +3 -3
  1099. package/src/firestore/transactions.ts +88 -8
  1100. package/src/firestore/types.ts +26 -5
  1101. package/src/firestore/vector-value.ts +54 -0
  1102. package/src/firestore/writes.ts +53 -43
  1103. package/src/functions/events.ts +27 -0
  1104. package/src/messaging/broker/broker.test.ts +114 -0
  1105. package/src/messaging/broker/broker.ts +152 -65
  1106. package/src/messaging/broker/delivery-history.ts +49 -0
  1107. package/src/messaging/broker/index.ts +11 -0
  1108. package/src/messaging/broker/persistence.ts +54 -0
  1109. package/src/messaging/broker/types.ts +50 -0
  1110. package/src/messaging/events.ts +29 -0
  1111. package/src/rules/api/case-types.ts +7 -0
  1112. package/src/rules/api/rtdb.ts +15 -7
  1113. package/src/rules/grammar/parse-error-wording.ts +98 -0
  1114. package/src/rules/indexes/query-analysis.ts +136 -0
  1115. package/src/rules/indexes/service-query.ts +69 -0
  1116. package/src/rules/internal/index.ts +16 -0
  1117. package/src/rules/modules/rules-capabilities.generated.ts +1 -1
  1118. package/src/rules/rtdb/constraints/atoms.spec.ts +7 -7
  1119. package/src/rules/rtdb/constraints/atoms.ts +7 -7
  1120. package/src/rules/rtdb/constraints/data.ts +4 -4
  1121. package/src/rules/rtdb/constraints/document.ts +4 -2
  1122. package/src/rules/rtdb/constraints/game.spec.ts +4 -4
  1123. package/src/rules/rtdb/constraints/policies.spec.ts +5 -5
  1124. package/src/rules/rtdb/constraints/policies.ts +4 -4
  1125. package/src/rules/rtdb/constraints/schema.ts +3 -3
  1126. package/src/rules/rtdb/grammar/RtdbExpr.ohm +1 -3
  1127. package/src/rules/rtdb/grammar/RtdbExpr.ohm.generated.ts +1 -3
  1128. package/src/rules/rtdb/grammar/linter.ts +34 -30
  1129. package/src/rules/rtdb/grammar/simulator.ts +112 -74
  1130. package/src/rules/rtdb/grammar/validator.ts +30 -26
  1131. package/src/rules/rtdb/simulation/handler.ts +139 -36
  1132. package/src/rules/rtdb/simulation/spec.ts +24 -1
  1133. package/src/rules/simulator/evaluator.ts +34 -41
  1134. package/src/rules/simulator/handler.ts +12 -3
  1135. package/src/rules/simulator/mapdiff.ts +7 -5
  1136. package/src/rules/simulator/query-proof-residual.ts +209 -0
  1137. package/src/rules/simulator/query-proof.ts +53 -27
  1138. package/src/rules/simulator/request-path.ts +39 -0
  1139. package/src/rules/simulator/trace-recorder.ts +3 -0
  1140. package/src/rules/simulator/wrappers/timestamp.ts +8 -1
  1141. package/src/rules/simulator-tools-impl.ts +6 -3
  1142. package/src/rules/stdlib-tools.ts +4 -4
  1143. package/src/sandbox/active-listeners.ts +245 -0
  1144. package/src/sandbox/admin-firestore/error-translation.ts +16 -2
  1145. package/src/sandbox/admin-firestore/listeners.ts +26 -1
  1146. package/src/sandbox/admin-firestore/remote/listeners.ts +50 -32
  1147. package/src/sandbox/admin-firestore/remote/value-codec.ts +7 -14
  1148. package/src/sandbox/admin-firestore/remote/wire-types.ts +3 -0
  1149. package/src/sandbox/attribution/attribution-mode.ts +74 -0
  1150. package/src/sandbox/attribution/effect-regions.ts +130 -0
  1151. package/src/sandbox/attribution/element-selector.ts +118 -0
  1152. package/src/sandbox/attribution/listener-owners.ts +277 -0
  1153. package/src/sandbox/branches/engine.ts +362 -0
  1154. package/src/sandbox/branches/index.ts +12 -448
  1155. package/src/sandbox/branches/promotion.ts +207 -0
  1156. package/src/sandbox/branches/state-diff.ts +333 -0
  1157. package/src/sandbox/branches/store.ts +317 -0
  1158. package/src/sandbox/checkpoints/capture.ts +77 -0
  1159. package/src/sandbox/checkpoints/directory-backend.ts +110 -0
  1160. package/src/sandbox/checkpoints/index.ts +32 -0
  1161. package/src/sandbox/checkpoints/record-backend.ts +109 -0
  1162. package/src/sandbox/checkpoints/saved-states.ts +72 -0
  1163. package/src/sandbox/checkpoints/types.ts +115 -0
  1164. package/src/sandbox/checkpoints/validation.ts +102 -0
  1165. package/src/sandbox/clock.ts +205 -0
  1166. package/src/sandbox/full-state.ts +403 -0
  1167. package/src/sandbox/index.ts +53 -10
  1168. package/src/sandbox/internal/ai-evidence.ts +38 -0
  1169. package/src/sandbox/internal/event-history.ts +193 -0
  1170. package/src/sandbox/internal/history-integrity.ts +12 -0
  1171. package/src/sandbox/internal/history-retention.ts +16 -0
  1172. package/src/sandbox/internal/index.ts +65 -0
  1173. package/src/sandbox/internal/observation-history.ts +5 -0
  1174. package/src/sandbox/internal/observation-payload.ts +18 -0
  1175. package/src/sandbox/internal/provenance.ts +5 -0
  1176. package/src/sandbox/internal/root.ts +3 -2
  1177. package/src/sandbox/internal/rules-evidence-retention.ts +28 -0
  1178. package/src/sandbox/internal/sandbox-impl.ts +91 -45
  1179. package/src/sandbox/internal/sdk-activity.ts +291 -0
  1180. package/src/sandbox/internal/sdk-coverage.ts +28 -0
  1181. package/src/sandbox/internal/sdk-observation.ts +62 -0
  1182. package/src/sandbox/internal/sdk-rates.ts +240 -0
  1183. package/src/sandbox/internal/sdk-write-activity.ts +14 -0
  1184. package/src/sandbox/internal/state-schemas.ts +47 -0
  1185. package/src/sandbox/internal/state-values.ts +20 -0
  1186. package/src/sandbox/internal/storage-activity.ts +43 -0
  1187. package/src/sandbox/internal/usage-evidence.ts +77 -0
  1188. package/src/sandbox/operation-record.ts +107 -4
  1189. package/src/sandbox/persistence/changed-buckets.ts +61 -0
  1190. package/src/sandbox/persistence/chunk-format.ts +39 -27
  1191. package/src/sandbox/persistence/controller.ts +85 -33
  1192. package/src/sandbox/persistence/import-bundle.ts +64 -0
  1193. package/src/sandbox/persistence/serialize.ts +16 -10
  1194. package/src/sandbox/persistence/types.ts +4 -0
  1195. package/src/sandbox/persistence/validate-services.ts +70 -0
  1196. package/src/sandbox/remote.ts +7 -0
  1197. package/src/sandbox/replay/index.ts +15 -8
  1198. package/src/sandbox/types/errors.ts +3 -1
  1199. package/src/sandbox/types/events.ts +118 -75
  1200. package/src/sandbox/types/index.ts +12 -0
  1201. package/src/sandbox/types/operation.ts +14 -4
  1202. package/src/sandbox/types/persistence.ts +2 -2
  1203. package/src/sandbox/types/query-proof.ts +26 -0
  1204. package/src/sandbox/types/request-observation.ts +25 -0
  1205. package/src/sandbox/types/rules-evidence.ts +37 -0
  1206. package/src/sandbox/types/service-event-record.ts +34 -0
  1207. package/src/sandbox/types/service-event-records.ts +42 -0
  1208. package/src/sandbox/types/service-mutation-event.ts +93 -0
  1209. package/src/storage/activity-coverage.ts +8 -0
  1210. package/src/storage/base64.ts +35 -0
  1211. package/src/storage/download.ts +19 -6
  1212. package/src/storage/enforce.ts +26 -4
  1213. package/src/storage/errors.ts +29 -14
  1214. package/src/storage/events.ts +21 -0
  1215. package/src/storage/index.ts +7 -7
  1216. package/src/storage/internal.ts +21 -0
  1217. package/src/storage/metadata.ts +68 -19
  1218. package/src/storage/observed.ts +16 -0
  1219. package/src/storage/persistence.ts +574 -66
  1220. package/src/storage/reference.ts +6 -3
  1221. package/src/storage/remote-bytes.ts +122 -0
  1222. package/src/storage/resumable.ts +16 -3
  1223. package/src/storage/rules-resolution.ts +43 -1
  1224. package/src/storage/sandbox/persistence-state.ts +71 -0
  1225. package/src/storage/sandbox/rules-bindings.ts +69 -0
  1226. package/src/storage/sandbox/rules-collection-methods.ts +161 -0
  1227. package/src/storage/sandbox/rules-evaluator.ts +65 -142
  1228. package/src/storage/sandbox/rules-firestore-lookup.ts +112 -0
  1229. package/src/storage/sandbox/rules-hashing-methods.ts +50 -0
  1230. package/src/storage/sandbox/rules-method-calls.ts +67 -0
  1231. package/src/storage/sandbox/rules-methods.ts +63 -404
  1232. package/src/storage/sandbox/rules-operators.ts +93 -0
  1233. package/src/storage/sandbox/rules-string-methods.ts +214 -0
  1234. package/src/storage/sandbox/rules-time-methods.ts +98 -0
  1235. package/src/storage/sandbox/rules-values.ts +20 -1
  1236. package/src/storage/sandbox/rules.ts +27 -14
  1237. package/src/storage/sandbox/running-service.ts +52 -0
  1238. package/src/storage/service.ts +196 -85
  1239. package/src/storage/string-format.ts +8 -0
  1240. package/src/storage/upload.ts +8 -3
  1241. package/src/storage/url.ts +106 -0
@@ -48,9 +48,11 @@ import {
48
48
  createAuthProjectStore,
49
49
  type AuthProjectStore,
50
50
  } from './sandbox/project-store.js';
51
+ import { defaultAvatarMint, type AvatarMint } from './sandbox/default-avatar.js';
51
52
 
52
- import type { AuthState, Sandbox } from 'pyric/sandbox';
53
- import { emitSandboxEvent, makeServiceMutationEvent } from 'pyric/sandbox/internal';
53
+ import { normalizeAuthState, type AuthState, type Sandbox } from 'pyric/sandbox';
54
+ import { emitSandboxEvent, getClock, makeServiceMutationEvent } from 'pyric/sandbox/internal';
55
+ import type { AuthEventOperation } from './events.js';
54
56
 
55
57
  import {
56
58
  USER_INTERNAL,
@@ -98,6 +100,17 @@ export type {
98
100
  * sibling app backends share account/provider maps but not currentUser,
99
101
  * listeners, tokens, flow staging, or persistence mode.
100
102
  */
103
+
104
+ /**
105
+ * The claims rules see on `auth.token` for a signed-in data context: the
106
+ * custom claims, plus the `firebase` namespace the minted ID token carries
107
+ * (`sign_in_provider`, and `tenant` for a tenant sign-in), as production's
108
+ * decoded ID token does.
109
+ */
110
+ function rulesTokenClaims(claims: Record<string, unknown>, minted: IdTokenResult): Record<string, unknown> {
111
+ return { ...claims, firebase: minted.claims.firebase };
112
+ }
113
+
101
114
  export class SandboxBackend {
102
115
  /** Email → stored user. Lowercase keys so lookups are case-
103
116
  * insensitive (matches upstream). */
@@ -131,7 +144,6 @@ export class SandboxBackend {
131
144
  /** Monotonic uid counter for `createUser` calls without a uid. */
132
145
  private readonly sharedCounters: {
133
146
  nextAdminUserId: number;
134
- nextAnonymousId: number;
135
147
  };
136
148
 
137
149
  /** Popup / redirect / credential flow-staging machinery — the
@@ -165,12 +177,12 @@ export class SandboxBackend {
165
177
  * (direct sandbox writes, `reset()`, another handle). */
166
178
  private applyingTransition = false;
167
179
 
168
- /** Per-uid current ID token + result. Refreshed on each
180
+ /** Per-uid and signed-in tenant current ID token + result. Refreshed on each
169
181
  * `getIdToken(forceRefresh=true)` and on each new sign-in
170
182
  * transition (so a sign-out / sign-in round-trip mints a fresh
171
183
  * token, matching prod's "new session = new token" semantics).
172
184
  * Subsequent `getIdToken(false)` reads return the cached value. */
173
- private readonly tokenCache = new Map<string, { token: string; result: IdTokenResult }>();
185
+ private readonly tokenCache = new Map<string, Map<string | null, { token: string; result: IdTokenResult }>>();
174
186
 
175
187
  /** Monotonic counter used to disambiguate freshly-minted tokens
176
188
  * for the same uid + claims map. Without this, two refreshes that
@@ -248,6 +260,42 @@ export class SandboxBackend {
248
260
  * persisted: a runtime wiring decision, not project config. */
249
261
  private providerEnforcementDelegated = false;
250
262
 
263
+ /**
264
+ * The hook that assigns a default `photoURL` to a federated-provider record
265
+ * at creation (see {@link makeStored}). The built-in mint returns a
266
+ * deterministic SVG data URI, which resolves with no server at all — so an
267
+ * in-page sandbox and any host that configures nothing behave identically.
268
+ *
269
+ * A HOST OVERRIDES IT ({@link setAvatarMint}): the served dev server swaps in
270
+ * a mint that returns its `/__pyric/assets/avatar/<uid>` route, and a server
271
+ * with avatars disabled swaps in one that returns `null`, which restores
272
+ * Firebase's own no-photo behaviour. Not persisted: a runtime wiring
273
+ * decision, not project config — but the URL it returns IS persisted, so a
274
+ * host must install its mint before any user record is created.
275
+ */
276
+ private avatarMint: AvatarMint = defaultAvatarMint;
277
+
278
+ /**
279
+ * Tenant the NEXT sign-in through this handle authenticates against, or
280
+ * `null` for the project-level pool. Backs `Auth.tenantId`: the handle is a
281
+ * thin accessor over this field, so the value an app assigns before calling
282
+ * a sign-in function is the value {@link applyTenantScope} stamps onto the
283
+ * user and its stored record.
284
+ */
285
+ private tenantId: string | null = null;
286
+
287
+ /** Read `Auth.tenantId`. */
288
+ getTenantId(): string | null {
289
+ return this.tenantId;
290
+ }
291
+
292
+ /** Write `Auth.tenantId`. Takes effect on the next sign-in; the current
293
+ * session keeps the tenant it authenticated with, matching prod, where the
294
+ * tenant is fixed at the moment credentials are exchanged. */
295
+ setTenantId(tenantId: string | null): void {
296
+ this.tenantId = tenantId;
297
+ }
298
+
251
299
  constructor(
252
300
  sandbox: Sandbox,
253
301
  session: Pick<Sandbox, 'currentUser' | 'onCurrentUserChanged'> = sandbox,
@@ -311,6 +359,20 @@ export class SandboxBackend {
311
359
  return this.cachedUser;
312
360
  }
313
361
 
362
+ /**
363
+ * The provider the current session signed in through. This is the same
364
+ * value {@link mintToken} puts on `IdTokenResult.signInProvider` and on the
365
+ * `firebase.sign_in_provider` claim, read without minting a token.
366
+ *
367
+ * `null` while the app is signed out, and `null` for an identity driven
368
+ * straight through the test driver, which records no provider.
369
+ */
370
+ getCurrentSignInProvider(): string | null {
371
+ const user = this.cachedUser;
372
+ if (user === null) return null;
373
+ return this.signInProviderByUid.get(user.uid) ?? null;
374
+ }
375
+
314
376
  // ─── Listener registries ────────────────────────────────────────────
315
377
 
316
378
  /**
@@ -412,11 +474,26 @@ export class SandboxBackend {
412
474
 
413
475
  // ─── User DB ────────────────────────────────────────────────────────
414
476
 
415
- /** Build a fresh {@link StoredUser} with admin-field defaults. */
477
+ /**
478
+ * Build a fresh {@link StoredUser} with admin-field defaults.
479
+ *
480
+ * THE ONE PLACE A DEFAULT PHOTO IS ASSIGNED. A federated-provider record
481
+ * that arrives without a photo gets one from {@link avatarMint} here, so
482
+ * `photoURL` is populated the instant the user object exists — never null
483
+ * for a moment and then patched. Every other path is untouched: an update,
484
+ * `updateProfile`, or `linkProvider` on an existing record never mints, and
485
+ * a caller-supplied photo always wins (see {@link mintsDefaultPhoto}).
486
+ *
487
+ * `signInProviderId` is the provider a flow is creating this record under,
488
+ * for the two paths that link the provider AFTER the record exists
489
+ * (`recordProviderSignIn`, `createSignInCredential`). Every other path
490
+ * carries its providers in `init.providerUserInfo`.
491
+ */
416
492
  private makeStored(
417
493
  init: Partial<StoredUser> & { uid: string },
494
+ signInProviderId: string | null = null,
418
495
  ): StoredUser {
419
- return {
496
+ const record: StoredUser = {
420
497
  email: null,
421
498
  password: null,
422
499
  displayName: null,
@@ -427,10 +504,21 @@ export class SandboxBackend {
427
504
  providerUserInfo: [],
428
505
  disabled: false,
429
506
  emailVerified: false,
430
- createdAt: new Date().toISOString(),
507
+ createdAt: this.now().toISOString(),
431
508
  lastLoginAt: null,
509
+ tenantId: null,
432
510
  ...init,
433
511
  };
512
+ const providerId = creationProviderId(record, signInProviderId);
513
+ if (mintsDefaultPhoto(record, providerId)) {
514
+ record.photoUrl = this.avatarMint({
515
+ uid: record.uid,
516
+ displayName: record.displayName,
517
+ email: record.email,
518
+ providerId,
519
+ });
520
+ }
521
+ return record;
434
522
  }
435
523
 
436
524
  /** Fan a coarse "user DB changed" notification out to
@@ -446,6 +534,17 @@ export class SandboxBackend {
446
534
  }
447
535
  }
448
536
 
537
+ /**
538
+ * The sandbox's current time. Every time this backend records reads it: an
539
+ * account's `createdAt` and `lastLoginAt`, and a minted token's `iat`,
540
+ * `auth_time`, and `exp`. So a token minted while the sandbox clock is
541
+ * pinned to a date carries that date, and a rule reading
542
+ * `request.auth.token.iat` sees the same instant the write pipeline stamps.
543
+ */
544
+ private now(): Date {
545
+ return getClock(this.sandbox).date();
546
+ }
547
+
449
548
  /**
450
549
  * Emit an auth {@link ServiceMutationEvent} onto the sandbox's unified
451
550
  * `onEvent`/`history()` stream (Pyric Studio keystone). Best-effort and
@@ -457,13 +556,14 @@ export class SandboxBackend {
457
556
  * via `stampProvenance`.
458
557
  */
459
558
  private emitAuthEvent(
460
- op: string,
559
+ op: AuthEventOperation,
461
560
  fields: { path?: string; auth?: AuthState; before?: unknown; after?: unknown; detail?: Record<string, unknown> } = {},
462
561
  ): void {
463
562
  try {
464
563
  emitSandboxEvent(
465
564
  this.sandbox,
466
565
  makeServiceMutationEvent({
566
+ at: this.now().getTime(),
467
567
  service: 'auth',
468
568
  op,
469
569
  path: fields.path,
@@ -556,6 +656,17 @@ export class SandboxBackend {
556
656
  this.providerEnforcementDelegated = delegated;
557
657
  }
558
658
 
659
+ /**
660
+ * Install the {@link AvatarMint} this backend assigns default photos with,
661
+ * replacing the built-in data-URI mint. A host installs its mint during
662
+ * boot, before it seeds or signs anyone in: the minted URL is written into
663
+ * the stored record, so records created earlier keep the mint that was
664
+ * installed when they were created.
665
+ */
666
+ setAvatarMint(mint: AvatarMint): void {
667
+ this.avatarMint = mint;
668
+ }
669
+
559
670
  /**
560
671
  * Gate a provider entry point. Throws real Firebase's
561
672
  * `auth/operation-not-allowed` (exactly the code/shape prod throws
@@ -694,46 +805,94 @@ export class SandboxBackend {
694
805
  // in (AUTH-B9) — otherwise both emails would resolve, the old one
695
806
  // to a now-orphaned record.
696
807
  const prior = this.usersByUid.get(u.uid);
697
- if (prior?.email && prior.email.toLowerCase() !== u.email.toLowerCase()) {
698
- this.usersByEmail.delete(prior.email.toLowerCase());
808
+ const priorEmail = prior?.email;
809
+ const hasPriorEmail = typeof priorEmail === 'string' && priorEmail.length > 0;
810
+ const changesEmail = hasPriorEmail && priorEmail.toLowerCase() !== u.email?.toLowerCase();
811
+ if (changesEmail) {
812
+ this.usersByEmail.delete(priorEmail.toLowerCase());
699
813
  }
814
+ const isAnonymousSeed = u.providerId === 'anonymous';
815
+ const linkedProviders = u.providerUserInfo ?? [{ providerId: u.providerId ?? 'password' }];
816
+ const providerUserInfo = isAnonymousSeed ? [] : linkedProviders.map(provider => ({ ...provider }));
817
+ const hasPasswordProvider = providerUserInfo.some(provider => provider.providerId === 'password');
818
+ const hasLegacyPlaceholder = u.password === NO_PASSWORD_SENTINEL || u.password === '__pyric_popup_no_password__';
819
+ const isLegacyPasswordlessAccount = hasLegacyPlaceholder && !hasPasswordProvider;
820
+ const hasNoPassword = isAnonymousSeed || isLegacyPasswordlessAccount;
700
821
  const record = this.makeStored({
701
822
  uid: u.uid,
702
- email: u.email,
703
- password: u.password,
823
+ email: isAnonymousSeed ? null : (u.email ?? null),
824
+ password: hasNoPassword ? null : (u.password ?? null),
704
825
  displayName: u.displayName ?? null,
826
+ phoneNumber: u.phoneNumber ?? null,
827
+ photoUrl: u.photoUrl ?? null,
705
828
  customClaims: u.customClaims ?? {},
706
- providerUserInfo: [{ providerId: u.providerId ?? 'password' }],
829
+ emailVerified: u.emailVerified ?? false,
830
+ disabled: u.disabled ?? false,
831
+ isAnonymous: isAnonymousSeed,
832
+ providerUserInfo,
833
+ tenantId: u.tenantId ?? null,
707
834
  });
708
- this.usersByEmail.set(u.email.toLowerCase(), record);
835
+ const { createdAt, lastLoginAt, email } = u;
836
+ const hasCreatedAt = createdAt !== undefined;
837
+ if (hasCreatedAt) record.createdAt = createdAt;
838
+ const hasLastLoginAt = lastLoginAt !== undefined;
839
+ if (hasLastLoginAt) record.lastLoginAt = lastLoginAt;
840
+ const indexesEmail = !isAnonymousSeed && email !== undefined;
841
+ if (indexesEmail) this.usersByEmail.set(email.toLowerCase(), record);
709
842
  this.usersByUid.set(u.uid, record);
710
843
  }
711
- if (users.length > 0) this.notifyUsersChanged();
844
+ const hasSeedUsers = users.length > 0;
845
+ if (hasSeedUsers) this.notifyUsersChanged();
712
846
  }
713
847
 
714
848
  /**
715
849
  * Export the user DB as `SeedUser`s — the exact shape `seedUsers`
716
- * accepts, so export → seed round-trips (the persistence substrate,
717
- * the design rationale section 3c). Identities with an email but no
718
- * password (provider-flow users created via `createSignInCredential`)
719
- * export with {@link NO_PASSWORD_SENTINEL} so they survive the
720
- * round-trip (same trick hosts already use when seeding popup
721
- * identities). Anonymous users (no email) are NOT exported — they are
722
- * ephemeral by design; documented divergence from prod's persisted
723
- * anonymous sessions.
850
+ * accepts, including every linked provider. Passwordless accounts omit
851
+ * the password; legacy placeholder values are decoded only on import.
852
+ * Anonymous users (no email) export with
853
+ * `providerId: 'anonymous'` and no email or password, so a checkpoint,
854
+ * a branch, and a restart keep them, matching real Firebase, which
855
+ * keeps anonymous accounts in its user pool rather than discarding them.
724
856
  */
725
857
  exportUsers(): SeedUser[] {
726
858
  const out: SeedUser[] = [];
727
859
  for (const u of this.usersByUid.values()) {
728
- if (u.email === null) continue; // anonymous — not round-trippable
860
+ const { email, displayName, photoUrl, tenantId, phoneNumber, isAnonymous, disabled, emailVerified } = u;
861
+ const hasDisplayName = displayName !== null;
862
+ const hasPhotoUrl = photoUrl !== null;
863
+ const hasCustomClaims = Object.keys(u.customClaims).length > 0;
864
+ const hasTenant = tenantId !== null;
865
+ if (isAnonymous) {
866
+ const seed: SeedUser = { uid: u.uid, providerId: 'anonymous', createdAt: u.createdAt, lastLoginAt: u.lastLoginAt };
867
+ if (hasDisplayName) seed.displayName = displayName;
868
+ if (hasPhotoUrl) seed.photoUrl = photoUrl;
869
+ if (hasCustomClaims) seed.customClaims = u.customClaims;
870
+ if (disabled) seed.disabled = true;
871
+ if (hasTenant) seed.tenantId = tenantId;
872
+ out.push(seed);
873
+ continue;
874
+ }
875
+ const hasNoEmail = email === null;
876
+ if (hasNoEmail) continue; // credential-less, non-anonymous: not round-trippable
729
877
  const seed: SeedUser = {
730
878
  uid: u.uid,
731
- email: u.email,
732
- password: u.password ?? NO_PASSWORD_SENTINEL,
879
+ createdAt: u.createdAt,
880
+ lastLoginAt: u.lastLoginAt,
881
+ email,
733
882
  providerId: u.providerUserInfo[0]?.providerId ?? 'password',
883
+ providerUserInfo: u.providerUserInfo.map(provider => ({ ...provider })),
734
884
  };
735
- if (u.displayName !== null) seed.displayName = u.displayName;
736
- if (Object.keys(u.customClaims).length > 0) seed.customClaims = u.customClaims;
885
+ const { password } = u;
886
+ const hasPassword = password !== null;
887
+ if (hasPassword) seed.password = password;
888
+ if (hasDisplayName) seed.displayName = displayName;
889
+ if (hasPhotoUrl) seed.photoUrl = photoUrl;
890
+ const hasPhoneNumber = phoneNumber !== null;
891
+ if (hasPhoneNumber) seed.phoneNumber = phoneNumber;
892
+ if (hasCustomClaims) seed.customClaims = u.customClaims;
893
+ if (emailVerified) seed.emailVerified = true;
894
+ if (disabled) seed.disabled = true;
895
+ if (hasTenant) seed.tenantId = tenantId;
737
896
  out.push(seed);
738
897
  }
739
898
  return out;
@@ -892,8 +1051,10 @@ export class SandboxBackend {
892
1051
  validateEmailFormat(email);
893
1052
  const key = email.toLowerCase();
894
1053
  const existing = this.usersByEmail.get(key);
895
- if (existing) {
896
- if (!existing.providerUserInfo.some((p) => p.providerId === 'password')) {
1054
+ const hasAccount = existing !== undefined;
1055
+ if (hasAccount) {
1056
+ const needsPasswordProvider = !existing.providerUserInfo.some((p) => p.providerId === 'password');
1057
+ if (needsPasswordProvider) {
897
1058
  existing.providerUserInfo.push({ providerId: 'password' });
898
1059
  }
899
1060
  // Redeeming a link mailed to this address proves control of it.
@@ -901,7 +1062,8 @@ export class SandboxBackend {
901
1062
  this.notifyUsersChanged();
902
1063
  return { stored: existing, isNewUser: false };
903
1064
  }
904
- const uid = `email-${key}-${this.usersByEmail.size + 1}`;
1065
+ // Email punctuation is invalid in common UID-keyed RTDB paths.
1066
+ const uid = `email-${globalThis.crypto.randomUUID()}`;
905
1067
  const record = this.makeStored({
906
1068
  uid,
907
1069
  email,
@@ -1042,13 +1204,15 @@ export class SandboxBackend {
1042
1204
  validateEmailFormat(email);
1043
1205
  validatePasswordStrength(password);
1044
1206
  const key = email.toLowerCase();
1045
- if (this.usersByEmail.has(key)) {
1207
+ const emailInUse = this.usersByEmail.has(key);
1208
+ if (emailInUse) {
1046
1209
  throw makeAuthError(
1047
1210
  'auth/email-already-in-use',
1048
1211
  `An account already exists for ${email}.`,
1049
1212
  );
1050
1213
  }
1051
- const uid = `email-${key}-${this.usersByEmail.size + 1}`;
1214
+ // Email punctuation is invalid in common UID-keyed RTDB paths.
1215
+ const uid = `email-${globalThis.crypto.randomUUID()}`;
1052
1216
  const record = this.makeStored({
1053
1217
  uid,
1054
1218
  email,
@@ -1160,6 +1324,13 @@ export class SandboxBackend {
1160
1324
  * pre-resolved promise on the fast path instead of ever suspending.
1161
1325
  */
1162
1326
  transitionCurrentUser(user: User | null, signInProvider?: string | null): Promise<void> {
1327
+ // A `signInProvider` argument marks a REAL sign-in, which is the moment
1328
+ // the tenant is fixed (the test driver omits it and leaves the tenant
1329
+ // alone). Applied before the gate runs so a `beforeAuthStateChanged`
1330
+ // callback inspecting the user sees the tenant it will sign in under.
1331
+ if (user !== null && signInProvider !== undefined) {
1332
+ this.scopeSignInToTenant(user);
1333
+ }
1163
1334
  const hasActiveGate = this.beforeStateSubs.some((reg) => reg.active);
1164
1335
  if (!hasActiveGate || user === this.cachedUser) {
1165
1336
  this.setCurrentUser(user, signInProvider);
@@ -1187,8 +1358,24 @@ export class SandboxBackend {
1187
1358
  * test driver (`sandbox.setUser`), which leaves any previous value
1188
1359
  * in place.
1189
1360
  */
1361
+ /**
1362
+ * Fix a signing-in user to the handle's current {@link tenantId}. This is
1363
+ * the sandbox's stand-in for Identity Platform resolving credentials against
1364
+ * one tenant's user pool. The value lands in two places: on the `User` (so
1365
+ * `user.tenantId` reads back, matching `firebase/auth`) and on the stored
1366
+ * record (so a session restored after a reload, which rebuilds the user from
1367
+ * that record, keeps the tenant it authenticated with).
1368
+ */
1369
+ private scopeSignInToTenant(user: User): void {
1370
+ const tenantId = this.tenantId;
1371
+ (user as Mutable<User>).tenantId = tenantId;
1372
+ const stored = this.usersByUid.get(user.uid);
1373
+ if (stored) stored.tenantId = tenantId;
1374
+ }
1375
+
1190
1376
  setCurrentUser(user: User | null, signInProvider?: string | null): void {
1191
- if (user === null) {
1377
+ const signsOut = user === null;
1378
+ if (signsOut) {
1192
1379
  // Sign-out. Drop the cached token so a later re-sign-in for the
1193
1380
  // same uid mints a fresh one ("new session = new token"). Fire
1194
1381
  // listeners only if we were actually signed in (signing out an
@@ -1201,7 +1388,8 @@ export class SandboxBackend {
1201
1388
  } finally {
1202
1389
  this.applyingTransition = false;
1203
1390
  }
1204
- if (previousUser) {
1391
+ const hadUser = previousUser !== null;
1392
+ if (hadUser) {
1205
1393
  this.tokenCache.delete(previousUser.uid);
1206
1394
  this.notifyAuthListeners();
1207
1395
  this.notifySessionChanged();
@@ -1216,9 +1404,10 @@ export class SandboxBackend {
1216
1404
  return;
1217
1405
  }
1218
1406
 
1407
+ const isSignIn = signInProvider !== undefined;
1219
1408
  // Record this session's provider BEFORE any token mint below so
1220
1409
  // the freshly-minted token carries the right sign_in_provider.
1221
- if (signInProvider !== undefined) {
1410
+ if (isSignIn) {
1222
1411
  this.signInProviderByUid.set(user.uid, signInProvider);
1223
1412
  }
1224
1413
 
@@ -1230,8 +1419,9 @@ export class SandboxBackend {
1230
1419
 
1231
1420
  // A `signInProvider` argument marks an actual sign-in (the test
1232
1421
  // driver omits it) — bump the record's lastLoginAt.
1233
- if (signInProvider !== undefined && stored) {
1234
- stored.lastLoginAt = new Date().toISOString();
1422
+ const recordsSignIn = isSignIn && stored !== undefined;
1423
+ if (recordsSignIn) {
1424
+ stored.lastLoginAt = this.now().toISOString();
1235
1425
  this.notifyUsersChanged();
1236
1426
  }
1237
1427
 
@@ -1242,12 +1432,15 @@ export class SandboxBackend {
1242
1432
  // is unchanged (AUTH-B8: a same-uid re-sign-in still rotates the
1243
1433
  // token, which `onIdTokenChanged` then observes). Matches prod's
1244
1434
  // "new session = new token".
1245
- this.tokenCache.set(user.uid, this.mintToken(user.uid, claims));
1435
+ const minted = this.mintToken(user.uid, claims, user.tenantId ?? null);
1246
1436
 
1247
1437
  // Push to the sandbox under the guard so the synchronous subscriber
1248
1438
  // doesn't notify — we drive the fan-out below with the correct
1249
1439
  // id-token / auth-state split.
1250
- const nextState: AuthState = { uid: user.uid, token: claims };
1440
+ const signedInState: NonNullable<AuthState> = { uid: user.uid, token: rulesTokenClaims(claims, minted.result) };
1441
+ const hasTenant = typeof user.tenantId === 'string';
1442
+ if (hasTenant) signedInState.tenant = user.tenantId;
1443
+ const nextState: AuthState = signedInState;
1251
1444
  this.applyingTransition = true;
1252
1445
  try {
1253
1446
  this.session.currentUser = nextState;
@@ -1265,7 +1458,7 @@ export class SandboxBackend {
1265
1458
  // the test driver (`sandbox.setUser`) omits it and is not a sign-in
1266
1459
  // worth surfacing on the activity stream. The acting identity IS the
1267
1460
  // user that just signed in.
1268
- if (signInProvider !== undefined) {
1461
+ if (isSignIn) {
1269
1462
  this.emitAuthEvent('sign_in', {
1270
1463
  path: user.uid,
1271
1464
  auth: nextState,
@@ -1310,21 +1503,27 @@ export class SandboxBackend {
1310
1503
  * with its real provider. Upserts: unknown uids get a fresh record
1311
1504
  * (no password — these identities can't sign in via
1312
1505
  * `signInWithEmailAndPassword`); known uids get the provider
1313
- * appended to `providerUserInfo` if it isn't already linked.
1506
+ * appended to `providerUserInfo` if it isn't already linked, and their
1507
+ * stored photo refreshed when the identity carries one (see
1508
+ * {@link refreshStoredPhoto}).
1314
1509
  */
1315
1510
  recordProviderSignIn(user: User, providerId: string): void {
1316
1511
  let changed = false;
1512
+ const identityPhotoUrl = user.photoURL ?? null;
1317
1513
  let stored = this.usersByUid.get(user.uid);
1318
1514
  if (!stored) {
1319
1515
  stored = this.makeStored({
1320
1516
  uid: user.uid,
1321
1517
  email: user.email,
1322
1518
  displayName: user.displayName,
1519
+ photoUrl: identityPhotoUrl,
1323
1520
  isAnonymous: user.isAnonymous,
1324
- });
1521
+ }, providerId);
1325
1522
  this.usersByUid.set(user.uid, stored);
1326
1523
  if (user.email) this.usersByEmail.set(user.email.toLowerCase(), stored);
1327
1524
  changed = true;
1525
+ } else if (refreshStoredPhoto(stored, identityPhotoUrl)) {
1526
+ changed = true;
1328
1527
  }
1329
1528
  if (!stored.providerUserInfo.some((p) => p.providerId === providerId)) {
1330
1529
  stored.providerUserInfo.push({ providerId });
@@ -1354,7 +1553,10 @@ export class SandboxBackend {
1354
1553
  * and NO password (provider identities can't sign in via
1355
1554
  * `signInWithEmailAndPassword`).
1356
1555
  *
1357
- * In both shapes the provider is linked into `providerUserInfo`.
1556
+ * In both shapes the provider is linked into `providerUserInfo`. A
1557
+ * `spec.photoUrl` is stored on a fresh record and refreshes a reused
1558
+ * same-email one; a spec without a photo never clears a stored one (see
1559
+ * {@link refreshStoredPhoto}).
1358
1560
  * The credential does NOT sign the user in — hand it to the
1359
1561
  * resolver's promise; `signInWithPopup`/`signInWithRedirect`
1360
1562
  * complete the sign-in.
@@ -1374,19 +1576,24 @@ export class SandboxBackend {
1374
1576
  `createSignInCredential: no identity with uid ${req.uid}. Use the {spec} shape to create one.`,
1375
1577
  );
1376
1578
  }
1579
+ this.assertUserEnabled(found);
1377
1580
  stored = found;
1378
1581
  } else {
1379
1582
  const { spec } = req;
1583
+ const specPhotoUrl = spec.photoUrl ?? null;
1380
1584
  const byEmail = this.usersByEmail.get(spec.email.toLowerCase());
1381
1585
  if (byEmail) {
1586
+ this.assertUserEnabled(byEmail);
1382
1587
  stored = byEmail;
1588
+ if (refreshStoredPhoto(stored, specPhotoUrl)) this.notifyUsersChanged();
1383
1589
  } else {
1384
1590
  stored = this.makeStored({
1385
1591
  uid: spec.uid ?? mintProviderUid(),
1386
1592
  email: spec.email,
1387
1593
  displayName: spec.displayName ?? null,
1594
+ photoUrl: specPhotoUrl,
1388
1595
  customClaims: spec.customClaims ?? {},
1389
- });
1596
+ }, providerId);
1390
1597
  this.usersByUid.set(stored.uid, stored);
1391
1598
  this.usersByEmail.set(spec.email.toLowerCase(), stored);
1392
1599
  this.notifyUsersChanged();
@@ -1447,6 +1654,7 @@ export class SandboxBackend {
1447
1654
  isAnonymous: u.isAnonymous,
1448
1655
  disabled: u.disabled,
1449
1656
  emailVerified: u.emailVerified,
1657
+ tenantId: u.tenantId,
1450
1658
  createdAt: u.createdAt,
1451
1659
  lastLoginAt: u.lastLoginAt,
1452
1660
  };
@@ -1487,11 +1695,20 @@ export class SandboxBackend {
1487
1695
  return next;
1488
1696
  }
1489
1697
 
1698
+ /** Restored or explicitly seeded users may already occupy generated IDs. */
1699
+ private nextAvailableAdminUid(): string {
1700
+ for (;;) {
1701
+ const uid = `user-${this.sharedCounters.nextAdminUserId++}`;
1702
+ const isAvailable = !this.usersByUid.has(uid);
1703
+ if (isAvailable) return uid;
1704
+ }
1705
+ }
1706
+
1490
1707
  /** Admin user creation. Does NOT sign the user in (unlike
1491
1708
  * `createUserWithEmailAndPassword`) — matches the emulator's
1492
1709
  * add-user flow / admin SDK semantics. */
1493
1710
  createUser(req: CreateUserRequest): AuthUserRecord {
1494
- const uid = req.uid ?? `user-${this.sharedCounters.nextAdminUserId++}`;
1711
+ const uid = req.uid ?? this.nextAvailableAdminUid();
1495
1712
  if (this.usersByUid.has(uid)) {
1496
1713
  throw makeAuthError(
1497
1714
  'auth/uid-already-exists',
@@ -1656,6 +1873,7 @@ export class SandboxBackend {
1656
1873
  emailVerified: stored.emailVerified,
1657
1874
  phoneNumber: stored.phoneNumber,
1658
1875
  providers: stored.providerUserInfo,
1876
+ tenantId: stored.tenantId,
1659
1877
  });
1660
1878
  }
1661
1879
 
@@ -1664,7 +1882,7 @@ export class SandboxBackend {
1664
1882
  * the emulator) so `listIdentities` / future user-admin surfaces
1665
1883
  * see anonymous accounts too. */
1666
1884
  mintAnonymousUser(): User {
1667
- const uid = `anonymous-${this.sharedCounters.nextAnonymousId++}`;
1885
+ const uid = `anonymous-${globalThis.crypto.randomUUID()}`;
1668
1886
  const record = this.makeStored({ uid, isAnonymous: true });
1669
1887
  this.usersByUid.set(uid, record);
1670
1888
  this.notifyUsersChanged();
@@ -1706,36 +1924,44 @@ export class SandboxBackend {
1706
1924
  * authenticated session, same as real Firebase.
1707
1925
  */
1708
1926
  mintDetachedSession(request: MintSessionRequest): MintedSession {
1927
+ const tenantId = request.tenantId ?? null;
1709
1928
  switch (request.kind) {
1710
1929
  case 'anonymous':
1711
1930
  this.assertProviderEnabled('anonymous');
1712
- return this.establishDetachedSession(this.mintAnonymousUser(), 'anonymous');
1931
+ return this.establishDetachedSession(this.mintAnonymousUser(), 'anonymous', tenantId);
1713
1932
  case 'password':
1714
1933
  this.assertProviderEnabled('password');
1715
1934
  return this.establishDetachedSession(
1716
1935
  this.buildUserFromStored(this.validatePassword(request.email, request.password)),
1717
1936
  'password',
1937
+ tenantId,
1718
1938
  );
1719
1939
  case 'createPassword':
1720
1940
  this.assertProviderEnabled('password');
1721
1941
  return this.establishDetachedSession(
1722
1942
  this.buildUserFromStored(this.createEmailPasswordUser(request.email, request.password)),
1723
1943
  'password',
1944
+ tenantId,
1724
1945
  );
1946
+ case 'provider':
1947
+ case 'custom':
1725
1948
  case 'uid': {
1949
+ const isProviderSignIn = request.kind === 'provider';
1950
+ if (isProviderSignIn) this.assertProviderEnabled(request.providerId);
1726
1951
  // restoreSession semantics minus the global set: an EXISTING
1727
1952
  // identity (per-tab session restore / provider-bridge accept).
1728
1953
  const stored = this.usersByUid.get(request.uid);
1729
- if (!stored) {
1954
+ const missingUser = stored === undefined;
1955
+ if (missingUser) {
1730
1956
  throw makeAuthError('auth/user-not-found', `mintSession: no identity with uid ${request.uid}.`);
1731
1957
  }
1732
- if (stored.disabled) {
1733
- throw makeAuthError('auth/user-disabled', `mintSession: user ${request.uid} is disabled.`);
1734
- }
1735
- const providerId = stored.isAnonymous
1736
- ? 'anonymous'
1737
- : (stored.providerUserInfo[0]?.providerId ?? 'password');
1738
- return this.establishDetachedSession(this.buildUserFromStored(stored), providerId);
1958
+ this.assertUserEnabled(stored);
1959
+ const isAnonymous = stored.isAnonymous;
1960
+ const restoredProvider = isAnonymous ? 'anonymous' : (stored.providerUserInfo[0]?.providerId ?? 'password');
1961
+ let providerId = isProviderSignIn ? request.providerId : restoredProvider;
1962
+ const isCustomSignIn = request.kind === 'custom';
1963
+ if (isCustomSignIn) providerId = 'custom';
1964
+ return this.establishDetachedSession(this.buildUserFromStored(stored), providerId, tenantId);
1739
1965
  }
1740
1966
  }
1741
1967
  }
@@ -1743,16 +1969,27 @@ export class SandboxBackend {
1743
1969
  /** The shared sign-in bookkeeping behind {@link mintDetachedSession} —
1744
1970
  * everything {@link setCurrentUser} does for a real sign-in EXCEPT the
1745
1971
  * global-session parts. */
1746
- private establishDetachedSession(user: User, signInProvider: string): MintedSession {
1972
+ private establishDetachedSession(
1973
+ user: User,
1974
+ signInProvider: string,
1975
+ tenantId: string | null,
1976
+ ): MintedSession {
1747
1977
  this.signInProviderByUid.set(user.uid, signInProvider);
1748
1978
  const stored = this.usersByUid.get(user.uid);
1749
1979
  const claims = stored?.customClaims ?? {};
1750
- if (stored) {
1751
- stored.lastLoginAt = new Date().toISOString();
1980
+ const hasStoredUser = stored !== undefined;
1981
+ if (hasStoredUser) {
1982
+ stored.lastLoginAt = this.now().toISOString();
1752
1983
  this.notifyUsersChanged();
1753
1984
  }
1754
- this.tokenCache.set(user.uid, this.mintToken(user.uid, claims));
1755
- const state = { uid: user.uid, token: claims };
1985
+ // The tenant rides on the session, not on the shared record: ports are
1986
+ // independent sessions over one user pool, so two ports can hold the same
1987
+ // identity under different tenants and neither may overwrite the other.
1988
+ (user as Mutable<User>).tenantId = tenantId;
1989
+ const minted = this.mintToken(user.uid, claims, tenantId);
1990
+ const state: NonNullable<AuthState> = { uid: user.uid, token: rulesTokenClaims(claims, minted.result) };
1991
+ const hasTenant = tenantId !== null;
1992
+ if (hasTenant) state.tenant = tenantId;
1756
1993
  this.emitAuthEvent('sign_in', {
1757
1994
  path: user.uid,
1758
1995
  auth: state,
@@ -1776,6 +2013,7 @@ export class SandboxBackend {
1776
2013
  return this.buildUserFromStored({
1777
2014
  ...stored,
1778
2015
  customClaims: state.token ?? stored.customClaims,
2016
+ tenantId: state.tenant ?? stored.tenantId,
1779
2017
  });
1780
2018
  }
1781
2019
  return this.makeUser({
@@ -1784,6 +2022,7 @@ export class SandboxBackend {
1784
2022
  displayName: null,
1785
2023
  isAnonymous: state.uid.startsWith('anonymous-'),
1786
2024
  claims: state.token ?? {},
2025
+ tenantId: state.tenant ?? null,
1787
2026
  });
1788
2027
  }
1789
2028
 
@@ -1799,12 +2038,12 @@ export class SandboxBackend {
1799
2038
  private mintToken(
1800
2039
  uid: string,
1801
2040
  claims: Record<string, unknown>,
2041
+ tenantId: string | null,
1802
2042
  ): { token: string; result: IdTokenResult } {
1803
- const issuedAt = new Date();
2043
+ const issuedAt = this.now();
1804
2044
  // 100 years out — sandbox tokens never expire.
1805
2045
  const expires = new Date(issuedAt.getTime() + 100 * 365 * 24 * 60 * 60 * 1000);
1806
2046
  const serial = this.nextTokenSerial++;
1807
- const token = sandboxTokenFor(uid, claims, serial);
1808
2047
  // The provider of the current sign-in session for this uid —
1809
2048
  // recorded by setCurrentUser at sign-in time. Null for identities
1810
2049
  // driven via the test driver (no prod analog for that path).
@@ -1823,15 +2062,23 @@ export class SandboxBackend {
1823
2062
  // `firebase.sign_in_provider`.
1824
2063
  firebase: { sign_in_provider: signInProvider },
1825
2064
  };
2065
+ const identity = normalizeAuthState({ uid, tenant: tenantId ?? undefined, token: fullClaims });
2066
+ const tokenClaims = identity?.token ?? fullClaims;
2067
+ const sessionClaims = { ...claims, firebase: tokenClaims.firebase };
2068
+ const token = sandboxTokenFor(uid, sessionClaims, serial);
1826
2069
  const result: IdTokenResult = {
1827
2070
  token,
1828
- claims: fullClaims,
2071
+ claims: tokenClaims,
1829
2072
  expirationTime: expires.toISOString(),
1830
2073
  issuedAtTime: issuedAt.toISOString(),
1831
2074
  authTime: issuedAt.toISOString(),
1832
2075
  signInProvider,
1833
2076
  };
1834
- return { token, result };
2077
+ const entry = { token, result };
2078
+ const tokens = this.tokenCache.get(uid) ?? new Map<string | null, typeof entry>();
2079
+ tokens.set(tenantId, entry);
2080
+ this.tokenCache.set(uid, tokens);
2081
+ return entry;
1835
2082
  }
1836
2083
 
1837
2084
  /**
@@ -1850,20 +2097,9 @@ export class SandboxBackend {
1850
2097
  uid: string,
1851
2098
  claims: Record<string, unknown>,
1852
2099
  forceRefresh: boolean,
2100
+ tenantId: string | null = null,
1853
2101
  ): string {
1854
- if (forceRefresh) {
1855
- const fresh = this.mintToken(uid, claims);
1856
- this.tokenCache.set(uid, fresh);
1857
- // Fan out to onIdTokenChanged listeners only — identity is
1858
- // unchanged, so onAuthStateChanged stays silent.
1859
- this.fanOut('id-token');
1860
- return fresh.token;
1861
- }
1862
- const cached = this.tokenCache.get(uid);
1863
- if (cached) return cached.token;
1864
- const fresh = this.mintToken(uid, claims);
1865
- this.tokenCache.set(uid, fresh);
1866
- return fresh.token;
2102
+ return this.getIdTokenResultFor(uid, claims, forceRefresh, tenantId).token;
1867
2103
  }
1868
2104
 
1869
2105
  /** {@link getIdTokenFor} variant returning the full IdTokenResult.
@@ -1872,17 +2108,28 @@ export class SandboxBackend {
1872
2108
  uid: string,
1873
2109
  claims: Record<string, unknown>,
1874
2110
  forceRefresh: boolean,
2111
+ tenantId: string | null = null,
1875
2112
  ): IdTokenResult {
1876
2113
  if (forceRefresh) {
1877
- const fresh = this.mintToken(uid, claims);
1878
- this.tokenCache.set(uid, fresh);
2114
+ const fresh = this.mintToken(uid, claims, tenantId);
2115
+ const current = this.session.currentUser;
2116
+ const refreshesCurrentUser = current !== null && current.uid === uid && (current.tenant ?? null) === tenantId;
2117
+ if (refreshesCurrentUser) {
2118
+ // Rules follow refreshed claims without turning a token refresh into a sign-in.
2119
+ this.applyingTransition = true;
2120
+ try {
2121
+ this.session.currentUser = { ...current, token: rulesTokenClaims(claims, fresh.result) };
2122
+ } finally {
2123
+ this.applyingTransition = false;
2124
+ }
2125
+ }
1879
2126
  this.fanOut('id-token');
1880
2127
  return fresh.result;
1881
2128
  }
1882
- const cached = this.tokenCache.get(uid);
1883
- if (cached) return cached.result;
1884
- const fresh = this.mintToken(uid, claims);
1885
- this.tokenCache.set(uid, fresh);
2129
+ const cached = this.tokenCache.get(uid)?.get(tenantId);
2130
+ const hasCachedToken = cached !== undefined;
2131
+ if (hasCachedToken) return cached.result;
2132
+ const fresh = this.mintToken(uid, claims, tenantId);
1886
2133
  return fresh.result;
1887
2134
  }
1888
2135
 
@@ -1903,6 +2150,8 @@ export class SandboxBackend {
1903
2150
  phoneNumber?: string | null;
1904
2151
  /** The identity's LINKED providers, from its stored record. */
1905
2152
  providers?: ProviderUserInfo[];
2153
+ /** Tenant this identity authenticated under. Absent means untenanted. */
2154
+ tenantId?: string | null;
1906
2155
  }): User {
1907
2156
  const photoURL = args.photoURL ?? null;
1908
2157
  const phoneNumber = args.phoneNumber ?? null;
@@ -1927,7 +2176,8 @@ export class SandboxBackend {
1927
2176
  // `unlink` of the last provider produces. Falling back on `[]` would
1928
2177
  // resurrect the very provider the user just removed.
1929
2178
  const linked: ProviderUserInfo[] = args.providers ?? [{ providerId: 'password' }];
1930
- const providerData: UserInfo[] = args.isAnonymous
2179
+ const isAnonymous = args.isAnonymous === true;
2180
+ const providerData: UserInfo[] = isAnonymous
1931
2181
  ? []
1932
2182
  : linked.map((p) => ({
1933
2183
  uid: args.uid,
@@ -1945,6 +2195,7 @@ export class SandboxBackend {
1945
2195
  photoURL,
1946
2196
  phoneNumber,
1947
2197
  isAnonymous: args.isAnonymous,
2198
+ tenantId: args.tenantId ?? null,
1948
2199
  providerId,
1949
2200
  providerData,
1950
2201
  // Read LIVE claims by uid on each token call (not the claims frozen
@@ -1954,9 +2205,9 @@ export class SandboxBackend {
1954
2205
  // Falls back to the closed-over claims for users not in the DB
1955
2206
  // (anonymous / popup), matching how they were minted.
1956
2207
  getIdToken: async (forceRefresh?: boolean) =>
1957
- this.getIdTokenFor(args.uid, this.liveClaims(args.uid, args.claims), forceRefresh === true),
2208
+ this.getIdTokenFor(args.uid, this.liveClaims(args.uid, args.claims), forceRefresh === true, user.tenantId),
1958
2209
  getIdTokenResult: async (forceRefresh?: boolean) =>
1959
- this.getIdTokenResultFor(args.uid, this.liveClaims(args.uid, args.claims), forceRefresh === true),
2210
+ this.getIdTokenResultFor(args.uid, this.liveClaims(args.uid, args.claims), forceRefresh === true, user.tenantId),
1960
2211
  };
1961
2212
  // Stamp the backend-dispatch hook non-enumerably so the top-level
1962
2213
  // `updateProfile(user, …)` free function can update THIS user (and the
@@ -2200,6 +2451,12 @@ export class SandboxBackend {
2200
2451
  return this.usersByUid.get(uid)?.customClaims ?? fallback;
2201
2452
  }
2202
2453
 
2454
+ private assertUserEnabled(user: StoredUser): void {
2455
+ if (user.disabled) {
2456
+ throw makeAuthError('auth/user-disabled', 'The user account has been disabled by an administrator.');
2457
+ }
2458
+ }
2459
+
2203
2460
  /** Internal validator for email/password — checks the password
2204
2461
  * matches the stored record. Throws `auth/invalid-email` on a
2205
2462
  * malformed email, `auth/wrong-password` on mismatch,
@@ -2238,12 +2495,7 @@ export class SandboxBackend {
2238
2495
  // exact prod ordering (disabled-vs-wrong-password) is flagged for
2239
2496
  // an oracle capture; the code (`auth/user-disabled`) and message
2240
2497
  // match prod's documented shape.
2241
- if (stored.disabled) {
2242
- throw makeAuthError(
2243
- 'auth/user-disabled',
2244
- 'The user account has been disabled by an administrator.',
2245
- );
2246
- }
2498
+ this.assertUserEnabled(stored);
2247
2499
  if (stored.password !== password) {
2248
2500
  throw makeAuthError(
2249
2501
  'auth/wrong-password',
@@ -2254,6 +2506,60 @@ export class SandboxBackend {
2254
2506
  }
2255
2507
  }
2256
2508
 
2509
+ /**
2510
+ * Apply a provider sign-in's photo to an already-stored identity, reporting
2511
+ * whether the record changed.
2512
+ *
2513
+ * A provider sign-in refreshes the provider profile data it actually carries.
2514
+ * An identity that carries no photo leaves the stored one alone rather than
2515
+ * blanking it, mirroring Firebase: a provider refresh updates the fields the
2516
+ * provider supplied and never clears one it omitted.
2517
+ */
2518
+ /**
2519
+ * The provider a record is being created under: the provider a sign-in flow
2520
+ * names explicitly, otherwise the first provider already on the record. Null
2521
+ * when neither exists — an anonymous or provider-less record.
2522
+ */
2523
+ function creationProviderId(
2524
+ record: StoredUser,
2525
+ signInProviderId: string | null,
2526
+ ): string | null {
2527
+ if (signInProviderId !== null) return signInProviderId;
2528
+ const firstLinked = record.providerUserInfo[0];
2529
+ if (firstLinked === undefined) return null;
2530
+ return firstLinked.providerId;
2531
+ }
2532
+
2533
+ /**
2534
+ * Whether a freshly built record gets a default photo.
2535
+ *
2536
+ * Firebase populates `photoURL` only for federated identities: a real Google
2537
+ * or GitHub sign-in always returns one, while `password`, `phone`, email-link,
2538
+ * and anonymous users return null in production. Federated provider ids are
2539
+ * exactly the dotted ones (`google.com`, `github.com`, `oidc.acme`,
2540
+ * `saml.corp`); the first-party ids never contain a dot. Defaulting everyone
2541
+ * would trade this divergence for a new one.
2542
+ *
2543
+ * A photo the caller supplied always wins — the mint only fills a record that
2544
+ * would otherwise be photo-less.
2545
+ */
2546
+ function mintsDefaultPhoto(
2547
+ record: StoredUser,
2548
+ providerId: string | null,
2549
+ ): providerId is string {
2550
+ if (record.photoUrl !== null) return false;
2551
+ if (record.isAnonymous) return false;
2552
+ if (providerId === null) return false;
2553
+ return providerId.includes('.');
2554
+ }
2555
+
2556
+ function refreshStoredPhoto(stored: StoredUser, photoUrl: string | null): boolean {
2557
+ if (photoUrl === null) return false;
2558
+ if (stored.photoUrl === photoUrl) return false;
2559
+ stored.photoUrl = photoUrl;
2560
+ return true;
2561
+ }
2562
+
2257
2563
  /** Provider UIDs are opaque Firebase identifiers, not encoded credentials. */
2258
2564
  function mintProviderUid(): string {
2259
2565
  return `provider-${globalThis.crypto.randomUUID()}`;