pyric 0.1.0-alpha.24 → 0.1.0-alpha.26

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 (1523) hide show
  1. package/README.md +1 -1
  2. package/dist/ai/broker/broker.d.ts +5 -5
  3. package/dist/ai/broker/broker.js +4 -4
  4. package/dist/ai/broker/gemini-engine.d.ts +53 -12
  5. package/dist/ai/broker/gemini-engine.d.ts.map +1 -1
  6. package/dist/ai/broker/gemini-engine.js +165 -65
  7. package/dist/ai/broker/gemini-engine.js.map +1 -1
  8. package/dist/ai/broker/index.d.ts +1 -1
  9. package/dist/ai/broker/index.d.ts.map +1 -1
  10. package/dist/ai/broker/index.js +1 -1
  11. package/dist/ai/broker/index.js.map +1 -1
  12. package/dist/ai/broker/openai-engine.d.ts +8 -2
  13. package/dist/ai/broker/openai-engine.d.ts.map +1 -1
  14. package/dist/ai/broker/openai-engine.js +31 -31
  15. package/dist/ai/broker/openai-engine.js.map +1 -1
  16. package/dist/ai/broker/synthesizer.d.ts +9 -4
  17. package/dist/ai/broker/synthesizer.d.ts.map +1 -1
  18. package/dist/ai/broker/synthesizer.js +9 -16
  19. package/dist/ai/broker/synthesizer.js.map +1 -1
  20. package/dist/ai/broker/types.d.ts +2 -2
  21. package/dist/ai/internal.d.ts +1 -1
  22. package/dist/ai/internal.d.ts.map +1 -1
  23. package/dist/ai/internal.js +1 -1
  24. package/dist/ai/internal.js.map +1 -1
  25. package/dist/app/client-sdk-refusal.d.ts +25 -0
  26. package/dist/app/client-sdk-refusal.d.ts.map +1 -0
  27. package/dist/app/client-sdk-refusal.js +38 -0
  28. package/dist/app/client-sdk-refusal.js.map +1 -0
  29. package/dist/app/internal.d.ts +4 -2
  30. package/dist/app/internal.d.ts.map +1 -1
  31. package/dist/app/internal.js +4 -2
  32. package/dist/app/internal.js.map +1 -1
  33. package/dist/app/register-rules.d.ts +4 -0
  34. package/dist/app/register-rules.d.ts.map +1 -0
  35. package/dist/app/register-rules.js +100 -0
  36. package/dist/app/register-rules.js.map +1 -0
  37. package/dist/app/register.d.ts +1 -0
  38. package/dist/app/register.d.ts.map +1 -1
  39. package/dist/app/register.js +9 -20
  40. package/dist/app/register.js.map +1 -1
  41. package/dist/app/registry.d.ts +2 -0
  42. package/dist/app/registry.d.ts.map +1 -1
  43. package/dist/app/registry.js +22 -5
  44. package/dist/app/registry.js.map +1 -1
  45. package/dist/app/runtime.d.ts +5 -0
  46. package/dist/app/runtime.d.ts.map +1 -1
  47. package/dist/app/runtime.js +11 -0
  48. package/dist/app/runtime.js.map +1 -1
  49. package/dist/auth/action-codes.d.ts +1 -0
  50. package/dist/auth/action-codes.d.ts.map +1 -1
  51. package/dist/auth/action-codes.js +2 -0
  52. package/dist/auth/action-codes.js.map +1 -1
  53. package/dist/auth/reauth.d.ts +9 -22
  54. package/dist/auth/reauth.d.ts.map +1 -1
  55. package/dist/auth/reauth.js +12 -25
  56. package/dist/auth/reauth.js.map +1 -1
  57. package/dist/auth/sandbox-backend.d.ts +27 -8
  58. package/dist/auth/sandbox-backend.d.ts.map +1 -1
  59. package/dist/auth/sandbox-backend.js +98 -30
  60. package/dist/auth/sandbox-backend.js.map +1 -1
  61. package/dist/database/connection-lifecycle.d.ts.map +1 -1
  62. package/dist/database/connection-lifecycle.js +10 -3
  63. package/dist/database/connection-lifecycle.js.map +1 -1
  64. package/dist/database/disconnect-operation-queue.d.ts.map +1 -1
  65. package/dist/database/disconnect-operation-queue.js +120 -38
  66. package/dist/database/disconnect-operation-queue.js.map +1 -1
  67. package/dist/database/instances.d.ts.map +1 -1
  68. package/dist/database/instances.js +64 -13
  69. package/dist/database/instances.js.map +1 -1
  70. package/dist/database/internal/value-children.d.ts +16 -0
  71. package/dist/database/internal/value-children.d.ts.map +1 -0
  72. package/dist/database/internal/value-children.js +46 -0
  73. package/dist/database/internal/value-children.js.map +1 -0
  74. package/dist/database/internal.d.ts +5 -1
  75. package/dist/database/internal.d.ts.map +1 -1
  76. package/dist/database/internal.js +5 -1
  77. package/dist/database/internal.js.map +1 -1
  78. package/dist/database/listen-index-warning.d.ts +9 -0
  79. package/dist/database/listen-index-warning.d.ts.map +1 -0
  80. package/dist/database/listen-index-warning.js +17 -0
  81. package/dist/database/listen-index-warning.js.map +1 -0
  82. package/dist/database/listeners.d.ts.map +1 -1
  83. package/dist/database/listeners.js +58 -56
  84. package/dist/database/listeners.js.map +1 -1
  85. package/dist/database/on-disconnect.d.ts.map +1 -1
  86. package/dist/database/on-disconnect.js +5 -0
  87. package/dist/database/on-disconnect.js.map +1 -1
  88. package/dist/database/operations.d.ts.map +1 -1
  89. package/dist/database/operations.js +10 -19
  90. package/dist/database/operations.js.map +1 -1
  91. package/dist/database/queries.d.ts +7 -8
  92. package/dist/database/queries.d.ts.map +1 -1
  93. package/dist/database/queries.js +7 -8
  94. package/dist/database/queries.js.map +1 -1
  95. package/dist/database/replay.d.ts +15 -0
  96. package/dist/database/replay.d.ts.map +1 -1
  97. package/dist/database/replay.js +129 -16
  98. package/dist/database/replay.js.map +1 -1
  99. package/dist/database/sandbox/backend-for.d.ts +14 -4
  100. package/dist/database/sandbox/backend-for.d.ts.map +1 -1
  101. package/dist/database/sandbox/backend-for.js +101 -124
  102. package/dist/database/sandbox/backend-for.js.map +1 -1
  103. package/dist/database/sandbox/backend-state.d.ts +21 -1
  104. package/dist/database/sandbox/backend-state.d.ts.map +1 -1
  105. package/dist/database/sandbox/backend-state.js +49 -8
  106. package/dist/database/sandbox/backend-state.js.map +1 -1
  107. package/dist/database/sandbox/backend.d.ts +11 -3
  108. package/dist/database/sandbox/backend.d.ts.map +1 -1
  109. package/dist/database/sandbox/backend.js +57 -11
  110. package/dist/database/sandbox/backend.js.map +1 -1
  111. package/dist/database/sandbox/child-listeners.d.ts +5 -1
  112. package/dist/database/sandbox/child-listeners.d.ts.map +1 -1
  113. package/dist/database/sandbox/child-listeners.js +99 -75
  114. package/dist/database/sandbox/child-listeners.js.map +1 -1
  115. package/dist/database/sandbox/data-tree.d.ts.map +1 -1
  116. package/dist/database/sandbox/data-tree.js +4 -0
  117. package/dist/database/sandbox/data-tree.js.map +1 -1
  118. package/dist/database/sandbox/listener-types.d.ts +23 -7
  119. package/dist/database/sandbox/listener-types.d.ts.map +1 -1
  120. package/dist/database/sandbox/normalize.d.ts +36 -36
  121. package/dist/database/sandbox/normalize.d.ts.map +1 -1
  122. package/dist/database/sandbox/normalize.js +140 -1
  123. package/dist/database/sandbox/normalize.js.map +1 -1
  124. package/dist/database/sandbox/operation-events.d.ts +21 -2
  125. package/dist/database/sandbox/operation-events.d.ts.map +1 -1
  126. package/dist/database/sandbox/operation-events.js +49 -13
  127. package/dist/database/sandbox/operation-events.js.map +1 -1
  128. package/dist/database/sandbox/persistence-state.d.ts +2 -1
  129. package/dist/database/sandbox/persistence-state.d.ts.map +1 -1
  130. package/dist/database/sandbox/persistence-state.js +16 -2
  131. package/dist/database/sandbox/persistence-state.js.map +1 -1
  132. package/dist/database/sandbox/priority-state.d.ts +7 -2
  133. package/dist/database/sandbox/priority-state.d.ts.map +1 -1
  134. package/dist/database/sandbox/priority-state.js +29 -6
  135. package/dist/database/sandbox/priority-state.js.map +1 -1
  136. package/dist/database/sandbox/priority-writes.d.ts.map +1 -1
  137. package/dist/database/sandbox/priority-writes.js +34 -12
  138. package/dist/database/sandbox/priority-writes.js.map +1 -1
  139. package/dist/database/sandbox/query-index.d.ts +23 -0
  140. package/dist/database/sandbox/query-index.d.ts.map +1 -0
  141. package/dist/database/sandbox/query-index.js +21 -0
  142. package/dist/database/sandbox/query-index.js.map +1 -0
  143. package/dist/database/sandbox/query.d.ts +2 -11
  144. package/dist/database/sandbox/query.d.ts.map +1 -1
  145. package/dist/database/sandbox/query.js.map +1 -1
  146. package/dist/database/sandbox/rules-eval.d.ts +31 -14
  147. package/dist/database/sandbox/rules-eval.d.ts.map +1 -1
  148. package/dist/database/sandbox/rules-eval.js +39 -79
  149. package/dist/database/sandbox/rules-eval.js.map +1 -1
  150. package/dist/database/sandbox/sentinels.d.ts +0 -16
  151. package/dist/database/sandbox/sentinels.d.ts.map +1 -1
  152. package/dist/database/sandbox/sentinels.js +15 -6
  153. package/dist/database/sandbox/sentinels.js.map +1 -1
  154. package/dist/database/sandbox/transactions.d.ts +3 -0
  155. package/dist/database/sandbox/transactions.d.ts.map +1 -1
  156. package/dist/database/sandbox/transactions.js +78 -34
  157. package/dist/database/sandbox/transactions.js.map +1 -1
  158. package/dist/database/sandbox/value-listeners.d.ts +2 -2
  159. package/dist/database/sandbox/value-listeners.d.ts.map +1 -1
  160. package/dist/database/sandbox/value-listeners.js +14 -19
  161. package/dist/database/sandbox/value-listeners.js.map +1 -1
  162. package/dist/database/sandbox/write-plane.d.ts +15 -2
  163. package/dist/database/sandbox/write-plane.d.ts.map +1 -1
  164. package/dist/database/sandbox/write-plane.js +254 -74
  165. package/dist/database/sandbox/write-plane.js.map +1 -1
  166. package/dist/database/sandbox-controls.d.ts +1 -6
  167. package/dist/database/sandbox-controls.d.ts.map +1 -1
  168. package/dist/database/sandbox-controls.js +1 -81
  169. package/dist/database/sandbox-controls.js.map +1 -1
  170. package/dist/database/snapshots.d.ts +7 -1
  171. package/dist/database/snapshots.d.ts.map +1 -1
  172. package/dist/database/snapshots.js +27 -14
  173. package/dist/database/snapshots.js.map +1 -1
  174. package/dist/database/transactions.d.ts +5 -4
  175. package/dist/database/transactions.d.ts.map +1 -1
  176. package/dist/database/transactions.js +12 -7
  177. package/dist/database/transactions.js.map +1 -1
  178. package/dist/database/writable-path.d.ts +21 -0
  179. package/dist/database/writable-path.d.ts.map +1 -0
  180. package/dist/database/writable-path.js +57 -0
  181. package/dist/database/writable-path.js.map +1 -0
  182. package/dist/deferred/entry.d.ts +14 -0
  183. package/dist/deferred/entry.d.ts.map +1 -1
  184. package/dist/deferred/entry.js +12 -1
  185. package/dist/deferred/entry.js.map +1 -1
  186. package/dist/deferred/member.d.ts +58 -0
  187. package/dist/deferred/member.d.ts.map +1 -0
  188. package/dist/deferred/member.js +80 -0
  189. package/dist/deferred/member.js.map +1 -0
  190. package/dist/firestore/aggregates.d.ts.map +1 -1
  191. package/dist/firestore/aggregates.js +3 -2
  192. package/dist/firestore/aggregates.js.map +1 -1
  193. package/dist/firestore/chain-update.d.ts +13 -0
  194. package/dist/firestore/chain-update.d.ts.map +1 -0
  195. package/dist/firestore/chain-update.js +22 -0
  196. package/dist/firestore/chain-update.js.map +1 -0
  197. package/dist/firestore/internal/atomic-create.d.ts +11 -0
  198. package/dist/firestore/internal/atomic-create.d.ts.map +1 -0
  199. package/dist/firestore/internal/atomic-create.js +16 -0
  200. package/dist/firestore/internal/atomic-create.js.map +1 -0
  201. package/dist/firestore/internal/index.d.ts +1 -0
  202. package/dist/firestore/internal/index.d.ts.map +1 -1
  203. package/dist/firestore/internal/index.js +1 -0
  204. package/dist/firestore/internal/index.js.map +1 -1
  205. package/dist/firestore/internal/update-fields.d.ts +6 -0
  206. package/dist/firestore/internal/update-fields.d.ts.map +1 -0
  207. package/dist/firestore/internal/update-fields.js +6 -0
  208. package/dist/firestore/internal/update-fields.js.map +1 -0
  209. package/dist/firestore/persistence.d.ts.map +1 -1
  210. package/dist/firestore/persistence.js +2 -0
  211. package/dist/firestore/persistence.js.map +1 -1
  212. package/dist/firestore/reads.d.ts.map +1 -1
  213. package/dist/firestore/reads.js +3 -1
  214. package/dist/firestore/reads.js.map +1 -1
  215. package/dist/firestore/sandbox/admin-compat/batch.d.ts +3 -1
  216. package/dist/firestore/sandbox/admin-compat/batch.d.ts.map +1 -1
  217. package/dist/firestore/sandbox/admin-compat/batch.js +9 -2
  218. package/dist/firestore/sandbox/admin-compat/batch.js.map +1 -1
  219. package/dist/firestore/sandbox/admin-compat/collection-ref.d.ts +5 -1
  220. package/dist/firestore/sandbox/admin-compat/collection-ref.d.ts.map +1 -1
  221. package/dist/firestore/sandbox/admin-compat/collection-ref.js +18 -4
  222. package/dist/firestore/sandbox/admin-compat/collection-ref.js.map +1 -1
  223. package/dist/firestore/sandbox/admin-compat/doc-ref.d.ts +5 -1
  224. package/dist/firestore/sandbox/admin-compat/doc-ref.d.ts.map +1 -1
  225. package/dist/firestore/sandbox/admin-compat/doc-ref.js +20 -2
  226. package/dist/firestore/sandbox/admin-compat/doc-ref.js.map +1 -1
  227. package/dist/firestore/sandbox/admin-compat/field-path.d.ts +13 -0
  228. package/dist/firestore/sandbox/admin-compat/field-path.d.ts.map +1 -1
  229. package/dist/firestore/sandbox/admin-compat/field-path.js +80 -36
  230. package/dist/firestore/sandbox/admin-compat/field-path.js.map +1 -1
  231. package/dist/firestore/sandbox/admin-compat/query.d.ts +5 -0
  232. package/dist/firestore/sandbox/admin-compat/query.d.ts.map +1 -1
  233. package/dist/firestore/sandbox/admin-compat/query.js +9 -1
  234. package/dist/firestore/sandbox/admin-compat/query.js.map +1 -1
  235. package/dist/firestore/sandbox/admin-compat/transaction.d.ts +3 -1
  236. package/dist/firestore/sandbox/admin-compat/transaction.d.ts.map +1 -1
  237. package/dist/firestore/sandbox/admin-compat/transaction.js +9 -2
  238. package/dist/firestore/sandbox/admin-compat/transaction.js.map +1 -1
  239. package/dist/firestore/sandbox/admin-compat/types.d.ts +11 -2
  240. package/dist/firestore/sandbox/admin-compat/types.d.ts.map +1 -1
  241. package/dist/firestore/sandbox/admin-compat/types.js.map +1 -1
  242. package/dist/firestore/sandbox/admin-writes.d.ts +28 -0
  243. package/dist/firestore/sandbox/admin-writes.d.ts.map +1 -0
  244. package/dist/firestore/sandbox/admin-writes.js +27 -0
  245. package/dist/firestore/sandbox/admin-writes.js.map +1 -0
  246. package/dist/firestore/sandbox/atomic-write-pipeline.d.ts +1 -1
  247. package/dist/firestore/sandbox/atomic-write-pipeline.d.ts.map +1 -1
  248. package/dist/firestore/sandbox/atomic-write-pipeline.js +21 -13
  249. package/dist/firestore/sandbox/atomic-write-pipeline.js.map +1 -1
  250. package/dist/firestore/sandbox/collection-group-rule-proof.d.ts +12 -6
  251. package/dist/firestore/sandbox/collection-group-rule-proof.d.ts.map +1 -1
  252. package/dist/firestore/sandbox/collection-group-rule-proof.js +31 -11
  253. package/dist/firestore/sandbox/collection-group-rule-proof.js.map +1 -1
  254. package/dist/firestore/sandbox/converters/fieldvalue.d.ts +3 -4
  255. package/dist/firestore/sandbox/converters/fieldvalue.d.ts.map +1 -1
  256. package/dist/firestore/sandbox/converters/fieldvalue.js +15 -25
  257. package/dist/firestore/sandbox/converters/fieldvalue.js.map +1 -1
  258. package/dist/firestore/sandbox/errors.d.ts +10 -2
  259. package/dist/firestore/sandbox/errors.d.ts.map +1 -1
  260. package/dist/firestore/sandbox/errors.js +3 -0
  261. package/dist/firestore/sandbox/errors.js.map +1 -1
  262. package/dist/firestore/sandbox/field-merge.d.ts +4 -2
  263. package/dist/firestore/sandbox/field-merge.d.ts.map +1 -1
  264. package/dist/firestore/sandbox/field-merge.js +6 -3
  265. package/dist/firestore/sandbox/field-merge.js.map +1 -1
  266. package/dist/firestore/sandbox/for-each-document.d.ts +12 -0
  267. package/dist/firestore/sandbox/for-each-document.d.ts.map +1 -0
  268. package/dist/firestore/sandbox/for-each-document.js +17 -0
  269. package/dist/firestore/sandbox/for-each-document.js.map +1 -0
  270. package/dist/firestore/sandbox/list-query-proof.d.ts +1 -86
  271. package/dist/firestore/sandbox/list-query-proof.d.ts.map +1 -1
  272. package/dist/firestore/sandbox/list-query-proof.js +1 -179
  273. package/dist/firestore/sandbox/list-query-proof.js.map +1 -1
  274. package/dist/firestore/sandbox/list-rule-path-proof.d.ts +1 -18
  275. package/dist/firestore/sandbox/list-rule-path-proof.d.ts.map +1 -1
  276. package/dist/firestore/sandbox/list-rule-path-proof.js +1 -87
  277. package/dist/firestore/sandbox/list-rule-path-proof.js.map +1 -1
  278. package/dist/firestore/sandbox/listener-delivery.d.ts +9 -8
  279. package/dist/firestore/sandbox/listener-delivery.d.ts.map +1 -1
  280. package/dist/firestore/sandbox/listener-delivery.js +15 -9
  281. package/dist/firestore/sandbox/listener-delivery.js.map +1 -1
  282. package/dist/firestore/sandbox/listener-dispatch.d.ts +16 -3
  283. package/dist/firestore/sandbox/listener-dispatch.d.ts.map +1 -1
  284. package/dist/firestore/sandbox/listener-dispatch.js +111 -39
  285. package/dist/firestore/sandbox/listener-dispatch.js.map +1 -1
  286. package/dist/firestore/sandbox/local-environment.js +1 -1
  287. package/dist/firestore/sandbox/local-environment.js.map +1 -1
  288. package/dist/firestore/sandbox/reads.d.ts +1 -1
  289. package/dist/firestore/sandbox/reads.d.ts.map +1 -1
  290. package/dist/firestore/sandbox/reads.js +2 -8
  291. package/dist/firestore/sandbox/reads.js.map +1 -1
  292. package/dist/firestore/sandbox/request-events.d.ts +3 -0
  293. package/dist/firestore/sandbox/request-events.d.ts.map +1 -1
  294. package/dist/firestore/sandbox/request-events.js +2 -0
  295. package/dist/firestore/sandbox/request-events.js.map +1 -1
  296. package/dist/firestore/sandbox/rules-list-authorizer.d.ts +3 -1
  297. package/dist/firestore/sandbox/rules-list-authorizer.d.ts.map +1 -1
  298. package/dist/firestore/sandbox/rules-list-authorizer.js +31 -15
  299. package/dist/firestore/sandbox/rules-list-authorizer.js.map +1 -1
  300. package/dist/firestore/sandbox/rules-read-engine.d.ts +10 -7
  301. package/dist/firestore/sandbox/rules-read-engine.d.ts.map +1 -1
  302. package/dist/firestore/sandbox/rules-read-engine.js +17 -33
  303. package/dist/firestore/sandbox/rules-read-engine.js.map +1 -1
  304. package/dist/firestore/sandbox/rules-simulator.d.ts +8 -0
  305. package/dist/firestore/sandbox/rules-simulator.d.ts.map +1 -1
  306. package/dist/firestore/sandbox/rules-simulator.js +17 -1
  307. package/dist/firestore/sandbox/rules-simulator.js.map +1 -1
  308. package/dist/firestore/sandbox/rules-state.d.ts +16 -5
  309. package/dist/firestore/sandbox/rules-state.d.ts.map +1 -1
  310. package/dist/firestore/sandbox/rules-state.js +26 -6
  311. package/dist/firestore/sandbox/rules-state.js.map +1 -1
  312. package/dist/firestore/sandbox/rules-test-case.d.ts.map +1 -1
  313. package/dist/firestore/sandbox/rules-test-case.js +26 -15
  314. package/dist/firestore/sandbox/rules-test-case.js.map +1 -1
  315. package/dist/firestore/sandbox/snapshot-listeners.d.ts +51 -18
  316. package/dist/firestore/sandbox/snapshot-listeners.d.ts.map +1 -1
  317. package/dist/firestore/sandbox/snapshot-listeners.js +68 -73
  318. package/dist/firestore/sandbox/snapshot-listeners.js.map +1 -1
  319. package/dist/firestore/sandbox/transaction-write-executor.d.ts +2 -0
  320. package/dist/firestore/sandbox/transaction-write-executor.d.ts.map +1 -1
  321. package/dist/firestore/sandbox/transaction-write-executor.js +169 -7
  322. package/dist/firestore/sandbox/transaction-write-executor.js.map +1 -1
  323. package/dist/firestore/sandbox/transaction.d.ts +6 -0
  324. package/dist/firestore/sandbox/transaction.d.ts.map +1 -1
  325. package/dist/firestore/sandbox/transaction.js +11 -0
  326. package/dist/firestore/sandbox/transaction.js.map +1 -1
  327. package/dist/firestore/sandbox/trigger-scope.d.ts +11 -0
  328. package/dist/firestore/sandbox/trigger-scope.d.ts.map +1 -1
  329. package/dist/firestore/sandbox/update-fields.d.ts +70 -0
  330. package/dist/firestore/sandbox/update-fields.d.ts.map +1 -0
  331. package/dist/firestore/sandbox/update-fields.js +280 -0
  332. package/dist/firestore/sandbox/update-fields.js.map +1 -0
  333. package/dist/firestore/sandbox/value-resolver.d.ts +7 -1
  334. package/dist/firestore/sandbox/value-resolver.d.ts.map +1 -1
  335. package/dist/firestore/sandbox/value-resolver.js +8 -3
  336. package/dist/firestore/sandbox/value-resolver.js.map +1 -1
  337. package/dist/firestore/sandbox/write-engine.d.ts +2 -2
  338. package/dist/firestore/sandbox/write-engine.d.ts.map +1 -1
  339. package/dist/firestore/sandbox/write-engine.js +23 -24
  340. package/dist/firestore/sandbox/write-engine.js.map +1 -1
  341. package/dist/firestore/sandbox/write-runtime.d.ts +11 -3
  342. package/dist/firestore/sandbox/write-runtime.d.ts.map +1 -1
  343. package/dist/firestore/sandbox/write-runtime.js +18 -7
  344. package/dist/firestore/sandbox/write-runtime.js.map +1 -1
  345. package/dist/firestore/sandbox-controls.d.ts.map +1 -1
  346. package/dist/firestore/sandbox-controls.js +12 -1
  347. package/dist/firestore/sandbox-controls.js.map +1 -1
  348. package/dist/firestore/ssr-snapshots.d.ts.map +1 -1
  349. package/dist/firestore/ssr-snapshots.js +2 -0
  350. package/dist/firestore/ssr-snapshots.js.map +1 -1
  351. package/dist/firestore/tools.d.ts +3 -1
  352. package/dist/firestore/tools.d.ts.map +1 -1
  353. package/dist/firestore/tools.js +1 -0
  354. package/dist/firestore/tools.js.map +1 -1
  355. package/dist/firestore/transactions.d.ts.map +1 -1
  356. package/dist/firestore/transactions.js +21 -9
  357. package/dist/firestore/transactions.js.map +1 -1
  358. package/dist/firestore/types.d.ts +7 -2
  359. package/dist/firestore/types.d.ts.map +1 -1
  360. package/dist/firestore/types.js.map +1 -1
  361. package/dist/firestore/writes.d.ts +9 -2
  362. package/dist/firestore/writes.d.ts.map +1 -1
  363. package/dist/firestore/writes.js +4 -10
  364. package/dist/firestore/writes.js.map +1 -1
  365. package/dist/rules/api/assert.d.ts.map +1 -1
  366. package/dist/rules/api/assert.js +24 -3
  367. package/dist/rules/api/assert.js.map +1 -1
  368. package/dist/rules/api/case-types.d.ts +101 -7
  369. package/dist/rules/api/case-types.d.ts.map +1 -1
  370. package/dist/rules/api/firestore.d.ts +5 -3
  371. package/dist/rules/api/firestore.d.ts.map +1 -1
  372. package/dist/rules/api/firestore.js +43 -7
  373. package/dist/rules/api/firestore.js.map +1 -1
  374. package/dist/rules/api/issue.d.ts +18 -4
  375. package/dist/rules/api/issue.d.ts.map +1 -1
  376. package/dist/rules/api/issue.js +49 -5
  377. package/dist/rules/api/issue.js.map +1 -1
  378. package/dist/rules/api/lint.d.ts.map +1 -1
  379. package/dist/rules/api/lint.js +5 -2
  380. package/dist/rules/api/lint.js.map +1 -1
  381. package/dist/rules/api/rtdb-case-input.d.ts +18 -0
  382. package/dist/rules/api/rtdb-case-input.d.ts.map +1 -0
  383. package/dist/rules/api/rtdb-case-input.js +136 -0
  384. package/dist/rules/api/rtdb-case-input.js.map +1 -0
  385. package/dist/rules/api/rtdb-firebase-json.d.ts +46 -0
  386. package/dist/rules/api/rtdb-firebase-json.d.ts.map +1 -0
  387. package/dist/rules/api/rtdb-firebase-json.js +112 -0
  388. package/dist/rules/api/rtdb-firebase-json.js.map +1 -0
  389. package/dist/rules/api/rtdb-instance-case.d.ts +59 -0
  390. package/dist/rules/api/rtdb-instance-case.d.ts.map +1 -0
  391. package/dist/rules/api/rtdb-instance-case.js +110 -0
  392. package/dist/rules/api/rtdb-instance-case.js.map +1 -0
  393. package/dist/rules/api/rtdb.d.ts +67 -7
  394. package/dist/rules/api/rtdb.d.ts.map +1 -1
  395. package/dist/rules/api/rtdb.js +145 -62
  396. package/dist/rules/api/rtdb.js.map +1 -1
  397. package/dist/rules/api/values.d.ts +4 -2
  398. package/dist/rules/api/values.d.ts.map +1 -1
  399. package/dist/rules/api/values.js +4 -2
  400. package/dist/rules/api/values.js.map +1 -1
  401. package/dist/rules/grammar/FirestoreAST.d.ts +7 -1
  402. package/dist/rules/grammar/FirestoreAST.d.ts.map +1 -1
  403. package/dist/rules/grammar/FirestoreAssembler.d.ts.map +1 -1
  404. package/dist/rules/grammar/FirestoreAssembler.js +26 -23
  405. package/dist/rules/grammar/FirestoreAssembler.js.map +1 -1
  406. package/dist/rules/grammar/FirestoreParser.d.ts +5 -1
  407. package/dist/rules/grammar/FirestoreParser.d.ts.map +1 -1
  408. package/dist/rules/grammar/FirestoreParser.js +295 -248
  409. package/dist/rules/grammar/FirestoreParser.js.map +1 -1
  410. package/dist/rules/grammar/FirestoreRules.ohm +45 -18
  411. package/dist/rules/grammar/FirestoreRules.ohm.generated.d.ts +1 -1
  412. package/dist/rules/grammar/FirestoreRules.ohm.generated.d.ts.map +1 -1
  413. package/dist/rules/grammar/FirestoreRules.ohm.generated.js +45 -18
  414. package/dist/rules/grammar/FirestoreRules.ohm.generated.js.map +1 -1
  415. package/dist/rules/grammar/FirestoreValidator.d.ts.map +1 -1
  416. package/dist/rules/grammar/FirestoreValidator.js +257 -231
  417. package/dist/rules/grammar/FirestoreValidator.js.map +1 -1
  418. package/dist/rules/grammar/bracket-scan.d.ts +80 -0
  419. package/dist/rules/grammar/bracket-scan.d.ts.map +1 -0
  420. package/dist/rules/grammar/bracket-scan.js +259 -0
  421. package/dist/rules/grammar/bracket-scan.js.map +1 -0
  422. package/dist/rules/grammar/compile-limits.d.ts +167 -0
  423. package/dist/rules/grammar/compile-limits.d.ts.map +1 -0
  424. package/dist/rules/grammar/compile-limits.js +482 -0
  425. package/dist/rules/grammar/compile-limits.js.map +1 -0
  426. package/dist/rules/grammar/document-access-count.d.ts +3 -2
  427. package/dist/rules/grammar/document-access-count.d.ts.map +1 -1
  428. package/dist/rules/grammar/document-access-count.js +79 -38
  429. package/dist/rules/grammar/document-access-count.js.map +1 -1
  430. package/dist/rules/grammar/expression-positions.d.ts +54 -0
  431. package/dist/rules/grammar/expression-positions.d.ts.map +1 -0
  432. package/dist/rules/grammar/expression-positions.js +90 -0
  433. package/dist/rules/grammar/expression-positions.js.map +1 -0
  434. package/dist/rules/grammar/function-scopes.d.ts +99 -0
  435. package/dist/rules/grammar/function-scopes.d.ts.map +1 -0
  436. package/dist/rules/grammar/function-scopes.js +409 -0
  437. package/dist/rules/grammar/function-scopes.js.map +1 -0
  438. package/dist/rules/grammar/paren-groups.d.ts +12 -0
  439. package/dist/rules/grammar/paren-groups.d.ts.map +1 -0
  440. package/dist/rules/grammar/paren-groups.js +10 -0
  441. package/dist/rules/grammar/paren-groups.js.map +1 -0
  442. package/dist/rules/grammar/parse-error-wording.d.ts +10 -8
  443. package/dist/rules/grammar/parse-error-wording.d.ts.map +1 -1
  444. package/dist/rules/grammar/parse-error-wording.js +172 -44
  445. package/dist/rules/grammar/parse-error-wording.js.map +1 -1
  446. package/dist/rules/grammar/re2-pattern.d.ts +7 -0
  447. package/dist/rules/grammar/re2-pattern.d.ts.map +1 -0
  448. package/dist/rules/grammar/re2-pattern.js +102 -0
  449. package/dist/rules/grammar/re2-pattern.js.map +1 -0
  450. package/dist/rules/grammar/recursive-scope.d.ts +20 -0
  451. package/dist/rules/grammar/recursive-scope.d.ts.map +1 -0
  452. package/dist/rules/grammar/recursive-scope.js +32 -0
  453. package/dist/rules/grammar/recursive-scope.js.map +1 -0
  454. package/dist/rules/grammar/source-compile-limits.d.ts +41 -0
  455. package/dist/rules/grammar/source-compile-limits.d.ts.map +1 -0
  456. package/dist/rules/grammar/source-compile-limits.js +37 -0
  457. package/dist/rules/grammar/source-compile-limits.js.map +1 -0
  458. package/dist/rules/grammar/source-segments.d.ts +108 -0
  459. package/dist/rules/grammar/source-segments.d.ts.map +1 -0
  460. package/dist/rules/grammar/source-segments.js +285 -0
  461. package/dist/rules/grammar/source-segments.js.map +1 -0
  462. package/dist/rules/index.d.ts +13 -4
  463. package/dist/rules/index.d.ts.map +1 -1
  464. package/dist/rules/index.js +8 -1
  465. package/dist/rules/index.js.map +1 -1
  466. package/dist/rules/indexes/extract/composite.d.ts +3 -3
  467. package/dist/rules/indexes/extract/composite.d.ts.map +1 -1
  468. package/dist/rules/indexes/extract/composite.js +36 -13
  469. package/dist/rules/indexes/extract/composite.js.map +1 -1
  470. package/dist/rules/indexes/extractTool.d.ts +1 -1
  471. package/dist/rules/indexes/extractTool.d.ts.map +1 -1
  472. package/dist/rules/inspect/tools.d.ts +1 -1
  473. package/dist/rules/inspect/tools.d.ts.map +1 -1
  474. package/dist/rules/internal/index.d.ts +11 -3
  475. package/dist/rules/internal/index.d.ts.map +1 -1
  476. package/dist/rules/internal/index.js +6 -2
  477. package/dist/rules/internal/index.js.map +1 -1
  478. package/dist/rules/internal/rtdb.d.ts +15 -3
  479. package/dist/rules/internal/rtdb.d.ts.map +1 -1
  480. package/dist/rules/internal/rtdb.js +9 -2
  481. package/dist/rules/internal/rtdb.js.map +1 -1
  482. package/dist/rules/linter/ast-utils.d.ts +27 -14
  483. package/dist/rules/linter/ast-utils.d.ts.map +1 -1
  484. package/dist/rules/linter/ast-utils.js +200 -79
  485. package/dist/rules/linter/ast-utils.js.map +1 -1
  486. package/dist/rules/linter/expression-cost.d.ts +93 -0
  487. package/dist/rules/linter/expression-cost.d.ts.map +1 -0
  488. package/dist/rules/linter/expression-cost.js +438 -0
  489. package/dist/rules/linter/expression-cost.js.map +1 -0
  490. package/dist/rules/linter/hallucinations.d.ts +3 -2
  491. package/dist/rules/linter/hallucinations.d.ts.map +1 -1
  492. package/dist/rules/linter/hallucinations.js +154 -68
  493. package/dist/rules/linter/hallucinations.js.map +1 -1
  494. package/dist/rules/linter/library-calls.d.ts +38 -0
  495. package/dist/rules/linter/library-calls.d.ts.map +1 -0
  496. package/dist/rules/linter/library-calls.js +83 -0
  497. package/dist/rules/linter/library-calls.js.map +1 -0
  498. package/dist/rules/linter/linter.d.ts +2 -1
  499. package/dist/rules/linter/linter.d.ts.map +1 -1
  500. package/dist/rules/linter/linter.js +426 -364
  501. package/dist/rules/linter/linter.js.map +1 -1
  502. package/dist/rules/modules/receiver-types.d.ts +1 -1
  503. package/dist/rules/modules/receiver-types.d.ts.map +1 -1
  504. package/dist/rules/modules/receiver-types.js +12 -12
  505. package/dist/rules/modules/receiver-types.js.map +1 -1
  506. package/dist/rules/modules/resolver-browser.d.ts +14 -4
  507. package/dist/rules/modules/resolver-browser.d.ts.map +1 -1
  508. package/dist/rules/modules/resolver-browser.js +18 -5
  509. package/dist/rules/modules/resolver-browser.js.map +1 -1
  510. package/dist/rules/modules/resolver-call-sites.d.ts +2 -2
  511. package/dist/rules/modules/resolver-call-sites.d.ts.map +1 -1
  512. package/dist/rules/modules/resolver-call-sites.js +21 -3
  513. package/dist/rules/modules/resolver-call-sites.js.map +1 -1
  514. package/dist/rules/modules/resolver-core.d.ts +16 -0
  515. package/dist/rules/modules/resolver-core.d.ts.map +1 -1
  516. package/dist/rules/modules/resolver-core.js +349 -176
  517. package/dist/rules/modules/resolver-core.js.map +1 -1
  518. package/dist/rules/modules/resolver-transform.d.ts.map +1 -1
  519. package/dist/rules/modules/resolver-transform.js +34 -19
  520. package/dist/rules/modules/resolver-transform.js.map +1 -1
  521. package/dist/rules/modules/resolver.d.ts +1 -0
  522. package/dist/rules/modules/resolver.d.ts.map +1 -1
  523. package/dist/rules/modules/rules-capabilities.generated.d.ts +48 -7
  524. package/dist/rules/modules/rules-capabilities.generated.d.ts.map +1 -1
  525. package/dist/rules/modules/rules-capabilities.generated.js +48 -7
  526. package/dist/rules/modules/rules-capabilities.generated.js.map +1 -1
  527. package/dist/rules/modules/service-bindings.d.ts +1 -0
  528. package/dist/rules/modules/service-bindings.d.ts.map +1 -1
  529. package/dist/rules/modules/service-bindings.js +13 -0
  530. package/dist/rules/modules/service-bindings.js.map +1 -1
  531. package/dist/rules/modules/service-compatibility.d.ts.map +1 -1
  532. package/dist/rules/modules/service-compatibility.js +10 -19
  533. package/dist/rules/modules/service-compatibility.js.map +1 -1
  534. package/dist/rules/modules/source-expression-analysis.d.ts.map +1 -1
  535. package/dist/rules/modules/source-expression-analysis.js +23 -9
  536. package/dist/rules/modules/source-expression-analysis.js.map +1 -1
  537. package/dist/rules/modules/stdlib/atomic.rules +6 -0
  538. package/dist/rules/modules/stdlib/atomic.test.json +158 -152
  539. package/dist/rules/modules/stdlib/auth.rules +6 -0
  540. package/dist/rules/modules/stdlib/auth.test.json +59 -53
  541. package/dist/rules/modules/stdlib/content.rules +43 -7
  542. package/dist/rules/modules/stdlib/content.test.json +492 -237
  543. package/dist/rules/modules/stdlib/counters.rules +44 -4
  544. package/dist/rules/modules/stdlib/counters.test.json +753 -253
  545. package/dist/rules/modules/stdlib/fairness.rules +56 -0
  546. package/dist/rules/modules/stdlib/fairness.test.json +568 -0
  547. package/dist/rules/modules/stdlib/geometry.rules +71 -0
  548. package/dist/rules/modules/stdlib/geometry.test.json +730 -180
  549. package/dist/rules/modules/stdlib/joining.rules +6 -0
  550. package/dist/rules/modules/stdlib/joining.test.json +341 -287
  551. package/dist/rules/modules/stdlib/lifecycle.rules +44 -1
  552. package/dist/rules/modules/stdlib/lifecycle.test.json +562 -287
  553. package/dist/rules/modules/stdlib/lobby.rules +35 -2
  554. package/dist/rules/modules/stdlib/lobby.test.json +466 -32
  555. package/dist/rules/modules/stdlib/membership.rules +8 -0
  556. package/dist/rules/modules/stdlib/membership.test.json +141 -107
  557. package/dist/rules/modules/stdlib/results.rules +69 -0
  558. package/dist/rules/modules/stdlib/results.test.json +668 -0
  559. package/dist/rules/modules/stdlib/spaces.rules +7 -0
  560. package/dist/rules/modules/stdlib/spaces.test.json +405 -345
  561. package/dist/rules/modules/stdlib/state.rules +7 -0
  562. package/dist/rules/modules/stdlib/state.test.json +83 -55
  563. package/dist/rules/modules/stdlib/storage/metadata.rules +8 -0
  564. package/dist/rules/modules/stdlib/storage/metadata.test.json +104 -43
  565. package/dist/rules/modules/stdlib/storage/objects.rules +58 -2
  566. package/dist/rules/modules/stdlib/storage/objects.test.json +318 -40
  567. package/dist/rules/modules/stdlib/storage/time.rules +6 -0
  568. package/dist/rules/modules/stdlib/storage/time.test.json +38 -32
  569. package/dist/rules/modules/stdlib/storage/uploads.rules +8 -0
  570. package/dist/rules/modules/stdlib/storage/uploads.test.json +70 -38
  571. package/dist/rules/modules/stdlib/timing.rules +5 -0
  572. package/dist/rules/modules/stdlib/timing.test.json +107 -102
  573. package/dist/rules/modules/stdlib/transitions.rules +7 -0
  574. package/dist/rules/modules/stdlib/transitions.test.json +93 -86
  575. package/dist/rules/modules/stdlib/turns.rules +40 -3
  576. package/dist/rules/modules/stdlib/turns.test.json +392 -64
  577. package/dist/rules/modules/stdlib/validation.rules +11 -2
  578. package/dist/rules/modules/stdlib/validation.test.json +180 -172
  579. package/dist/rules/modules/stdlib-content.d.ts.map +1 -1
  580. package/dist/rules/modules/stdlib-content.js +547 -21
  581. package/dist/rules/modules/stdlib-content.js.map +1 -1
  582. package/dist/rules/modules/stdlib-cost.d.ts +63 -0
  583. package/dist/rules/modules/stdlib-cost.d.ts.map +1 -0
  584. package/dist/rules/modules/stdlib-cost.js +155 -0
  585. package/dist/rules/modules/stdlib-cost.js.map +1 -0
  586. package/dist/rules/modules/stdlib-services.generated.d.ts +4 -0
  587. package/dist/rules/modules/stdlib-services.generated.d.ts.map +1 -1
  588. package/dist/rules/modules/stdlib-services.generated.js +4 -0
  589. package/dist/rules/modules/stdlib-services.generated.js.map +1 -1
  590. package/dist/rules/rtdb/compiled-rules.d.ts.map +1 -1
  591. package/dist/rules/rtdb/compiled-rules.js +56 -14
  592. package/dist/rules/rtdb/compiled-rules.js.map +1 -1
  593. package/dist/rules/rtdb/constraints/atoms.d.ts.map +1 -1
  594. package/dist/rules/rtdb/constraints/atoms.js +13 -12
  595. package/dist/rules/rtdb/constraints/atoms.js.map +1 -1
  596. package/dist/rules/rtdb/constraints/compose.d.ts +31 -6
  597. package/dist/rules/rtdb/constraints/compose.d.ts.map +1 -1
  598. package/dist/rules/rtdb/constraints/compose.js +123 -6
  599. package/dist/rules/rtdb/constraints/compose.js.map +1 -1
  600. package/dist/rules/rtdb/constraints/data.d.ts +2 -0
  601. package/dist/rules/rtdb/constraints/data.d.ts.map +1 -1
  602. package/dist/rules/rtdb/constraints/data.js +50 -20
  603. package/dist/rules/rtdb/constraints/data.js.map +1 -1
  604. package/dist/rules/rtdb/constraints/document.d.ts +9 -0
  605. package/dist/rules/rtdb/constraints/document.d.ts.map +1 -1
  606. package/dist/rules/rtdb/constraints/document.js +100 -27
  607. package/dist/rules/rtdb/constraints/document.js.map +1 -1
  608. package/dist/rules/rtdb/constraints/game.d.ts.map +1 -1
  609. package/dist/rules/rtdb/constraints/game.js +15 -3
  610. package/dist/rules/rtdb/constraints/game.js.map +1 -1
  611. package/dist/rules/rtdb/constraints/index.d.ts +3 -2
  612. package/dist/rules/rtdb/constraints/index.d.ts.map +1 -1
  613. package/dist/rules/rtdb/constraints/index.js +2 -2
  614. package/dist/rules/rtdb/constraints/index.js.map +1 -1
  615. package/dist/rules/rtdb/constraints/policies.d.ts +6 -1
  616. package/dist/rules/rtdb/constraints/policies.d.ts.map +1 -1
  617. package/dist/rules/rtdb/constraints/policies.js +22 -6
  618. package/dist/rules/rtdb/constraints/policies.js.map +1 -1
  619. package/dist/rules/rtdb/constraints/ruleset.d.ts.map +1 -1
  620. package/dist/rules/rtdb/constraints/ruleset.js +69 -38
  621. package/dist/rules/rtdb/constraints/ruleset.js.map +1 -1
  622. package/dist/rules/rtdb/constraints/schema.d.ts +5 -6
  623. package/dist/rules/rtdb/constraints/schema.d.ts.map +1 -1
  624. package/dist/rules/rtdb/constraints/schema.js +103 -21
  625. package/dist/rules/rtdb/constraints/schema.js.map +1 -1
  626. package/dist/rules/rtdb/constraints/types.d.ts +5 -0
  627. package/dist/rules/rtdb/constraints/types.d.ts.map +1 -1
  628. package/dist/rules/rtdb/coverage.d.ts +108 -0
  629. package/dist/rules/rtdb/coverage.d.ts.map +1 -0
  630. package/dist/rules/rtdb/coverage.js +185 -0
  631. package/dist/rules/rtdb/coverage.js.map +1 -0
  632. package/dist/rules/rtdb/expression-engine.d.ts +21 -2
  633. package/dist/rules/rtdb/expression-engine.d.ts.map +1 -1
  634. package/dist/rules/rtdb/expression-engine.js +34 -2
  635. package/dist/rules/rtdb/expression-engine.js.map +1 -1
  636. package/dist/rules/rtdb/grammar/RtdbExpr.ohm +24 -9
  637. package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.d.ts +1 -1
  638. package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.d.ts.map +1 -1
  639. package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.js +24 -9
  640. package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.js.map +1 -1
  641. package/dist/rules/rtdb/grammar/RtdbExprParser.d.ts +2 -0
  642. package/dist/rules/rtdb/grammar/RtdbExprParser.d.ts.map +1 -1
  643. package/dist/rules/rtdb/grammar/RtdbExprParser.js +37 -5
  644. package/dist/rules/rtdb/grammar/RtdbExprParser.js.map +1 -1
  645. package/dist/rules/rtdb/grammar/canonical.d.ts +52 -0
  646. package/dist/rules/rtdb/grammar/canonical.d.ts.map +1 -0
  647. package/dist/rules/rtdb/grammar/canonical.js +328 -0
  648. package/dist/rules/rtdb/grammar/canonical.js.map +1 -0
  649. package/dist/rules/rtdb/grammar/expression-tree.d.ts +86 -0
  650. package/dist/rules/rtdb/grammar/expression-tree.d.ts.map +1 -0
  651. package/dist/rules/rtdb/grammar/expression-tree.js +212 -0
  652. package/dist/rules/rtdb/grammar/expression-tree.js.map +1 -0
  653. package/dist/rules/rtdb/grammar/linter.d.ts +1 -0
  654. package/dist/rules/rtdb/grammar/linter.d.ts.map +1 -1
  655. package/dist/rules/rtdb/grammar/linter.js +209 -18
  656. package/dist/rules/rtdb/grammar/linter.js.map +1 -1
  657. package/dist/rules/rtdb/grammar/ruleset-lint.d.ts +12 -0
  658. package/dist/rules/rtdb/grammar/ruleset-lint.d.ts.map +1 -0
  659. package/dist/rules/rtdb/grammar/ruleset-lint.js +507 -0
  660. package/dist/rules/rtdb/grammar/ruleset-lint.js.map +1 -0
  661. package/dist/rules/rtdb/grammar/simulator.d.ts +21 -2
  662. package/dist/rules/rtdb/grammar/simulator.d.ts.map +1 -1
  663. package/dist/rules/rtdb/grammar/simulator.js +260 -97
  664. package/dist/rules/rtdb/grammar/simulator.js.map +1 -1
  665. package/dist/rules/rtdb/grammar/string-literal.d.ts +18 -0
  666. package/dist/rules/rtdb/grammar/string-literal.d.ts.map +1 -0
  667. package/dist/rules/rtdb/grammar/string-literal.js +133 -0
  668. package/dist/rules/rtdb/grammar/string-literal.js.map +1 -0
  669. package/dist/rules/rtdb/grammar/type-rules.d.ts +35 -0
  670. package/dist/rules/rtdb/grammar/type-rules.d.ts.map +1 -0
  671. package/dist/rules/rtdb/grammar/type-rules.js +67 -0
  672. package/dist/rules/rtdb/grammar/type-rules.js.map +1 -0
  673. package/dist/rules/rtdb/grammar/types.d.ts +85 -0
  674. package/dist/rules/rtdb/grammar/types.d.ts.map +1 -0
  675. package/dist/rules/rtdb/grammar/types.js +192 -0
  676. package/dist/rules/rtdb/grammar/types.js.map +1 -0
  677. package/dist/rules/rtdb/grammar/validator.d.ts +7 -0
  678. package/dist/rules/rtdb/grammar/validator.d.ts.map +1 -1
  679. package/dist/rules/rtdb/grammar/validator.js +258 -54
  680. package/dist/rules/rtdb/grammar/validator.js.map +1 -1
  681. package/dist/rules/rtdb/index-lookup.d.ts +14 -0
  682. package/dist/rules/rtdb/index-lookup.d.ts.map +1 -0
  683. package/dist/rules/rtdb/index-lookup.js +30 -0
  684. package/dist/rules/rtdb/index-lookup.js.map +1 -0
  685. package/dist/rules/rtdb/rules-diff.d.ts +30 -0
  686. package/dist/rules/rtdb/rules-diff.d.ts.map +1 -0
  687. package/dist/rules/rtdb/rules-diff.js +81 -0
  688. package/dist/rules/rtdb/rules-diff.js.map +1 -0
  689. package/dist/rules/rtdb/rules-text.d.ts +19 -0
  690. package/dist/rules/rtdb/rules-text.d.ts.map +1 -0
  691. package/dist/rules/rtdb/rules-text.js +151 -0
  692. package/dist/rules/rtdb/rules-text.js.map +1 -0
  693. package/dist/rules/rtdb/simulation/handler.d.ts.map +1 -1
  694. package/dist/rules/rtdb/simulation/handler.js +188 -220
  695. package/dist/rules/rtdb/simulation/handler.js.map +1 -1
  696. package/dist/rules/rtdb/simulation/post-write-tree.d.ts +28 -0
  697. package/dist/rules/rtdb/simulation/post-write-tree.d.ts.map +1 -0
  698. package/dist/rules/rtdb/simulation/post-write-tree.js +92 -0
  699. package/dist/rules/rtdb/simulation/post-write-tree.js.map +1 -0
  700. package/dist/rules/rtdb/simulation/spec.d.ts +155 -32
  701. package/dist/rules/rtdb/simulation/spec.d.ts.map +1 -1
  702. package/dist/rules/rtdb/simulation/spec.js +78 -0
  703. package/dist/rules/rtdb/simulation/spec.js.map +1 -1
  704. package/dist/rules/rtdb/source-locations.d.ts +49 -0
  705. package/dist/rules/rtdb/source-locations.d.ts.map +1 -0
  706. package/dist/rules/rtdb/source-locations.js +235 -0
  707. package/dist/rules/rtdb/source-locations.js.map +1 -0
  708. package/dist/rules/rtdb/source-rejection.d.ts +21 -0
  709. package/dist/rules/rtdb/source-rejection.d.ts.map +1 -0
  710. package/dist/rules/rtdb/source-rejection.js +38 -0
  711. package/dist/rules/rtdb/source-rejection.js.map +1 -0
  712. package/dist/rules/rtdb/stdlib/auth.d.ts +59 -0
  713. package/dist/rules/rtdb/stdlib/auth.d.ts.map +1 -0
  714. package/dist/rules/rtdb/stdlib/auth.js +67 -0
  715. package/dist/rules/rtdb/stdlib/auth.js.map +1 -0
  716. package/dist/rules/rtdb/stdlib/catalog.d.ts +48 -0
  717. package/dist/rules/rtdb/stdlib/catalog.d.ts.map +1 -0
  718. package/dist/rules/rtdb/stdlib/catalog.js +241 -0
  719. package/dist/rules/rtdb/stdlib/catalog.js.map +1 -0
  720. package/dist/rules/rtdb/stdlib/collections.d.ts +23 -0
  721. package/dist/rules/rtdb/stdlib/collections.d.ts.map +1 -0
  722. package/dist/rules/rtdb/stdlib/collections.js +17 -0
  723. package/dist/rules/rtdb/stdlib/collections.js.map +1 -0
  724. package/dist/rules/rtdb/stdlib/counters.d.ts +48 -0
  725. package/dist/rules/rtdb/stdlib/counters.d.ts.map +1 -0
  726. package/dist/rules/rtdb/stdlib/counters.js +62 -0
  727. package/dist/rules/rtdb/stdlib/counters.js.map +1 -0
  728. package/dist/rules/rtdb/stdlib/expr.d.ts +23 -0
  729. package/dist/rules/rtdb/stdlib/expr.d.ts.map +1 -0
  730. package/dist/rules/rtdb/stdlib/expr.js +47 -0
  731. package/dist/rules/rtdb/stdlib/expr.js.map +1 -0
  732. package/dist/rules/rtdb/stdlib/index.d.ts +39 -0
  733. package/dist/rules/rtdb/stdlib/index.d.ts.map +1 -0
  734. package/dist/rules/rtdb/stdlib/index.js +37 -0
  735. package/dist/rules/rtdb/stdlib/index.js.map +1 -0
  736. package/dist/rules/rtdb/stdlib/lifecycle.d.ts +46 -0
  737. package/dist/rules/rtdb/stdlib/lifecycle.d.ts.map +1 -0
  738. package/dist/rules/rtdb/stdlib/lifecycle.js +63 -0
  739. package/dist/rules/rtdb/stdlib/lifecycle.js.map +1 -0
  740. package/dist/rules/rtdb/stdlib/lobby.d.ts +60 -0
  741. package/dist/rules/rtdb/stdlib/lobby.d.ts.map +1 -0
  742. package/dist/rules/rtdb/stdlib/lobby.js +36 -0
  743. package/dist/rules/rtdb/stdlib/lobby.js.map +1 -0
  744. package/dist/rules/rtdb/stdlib/membership.d.ts +34 -0
  745. package/dist/rules/rtdb/stdlib/membership.d.ts.map +1 -0
  746. package/dist/rules/rtdb/stdlib/membership.js +28 -0
  747. package/dist/rules/rtdb/stdlib/membership.js.map +1 -0
  748. package/dist/rules/rtdb/stdlib/presence.d.ts +35 -0
  749. package/dist/rules/rtdb/stdlib/presence.d.ts.map +1 -0
  750. package/dist/rules/rtdb/stdlib/presence.js +33 -0
  751. package/dist/rules/rtdb/stdlib/presence.js.map +1 -0
  752. package/dist/rules/rtdb/stdlib/results.d.ts +28 -0
  753. package/dist/rules/rtdb/stdlib/results.d.ts.map +1 -0
  754. package/dist/rules/rtdb/stdlib/results.js +33 -0
  755. package/dist/rules/rtdb/stdlib/results.js.map +1 -0
  756. package/dist/rules/rtdb/stdlib/timing.d.ts +71 -0
  757. package/dist/rules/rtdb/stdlib/timing.d.ts.map +1 -0
  758. package/dist/rules/rtdb/stdlib/timing.js +87 -0
  759. package/dist/rules/rtdb/stdlib/timing.js.map +1 -0
  760. package/dist/rules/rtdb/stdlib/turns.d.ts +29 -0
  761. package/dist/rules/rtdb/stdlib/turns.d.ts.map +1 -0
  762. package/dist/rules/rtdb/stdlib/turns.js +34 -0
  763. package/dist/rules/rtdb/stdlib/turns.js.map +1 -0
  764. package/dist/rules/rtdb/stdlib/validation.d.ts +59 -0
  765. package/dist/rules/rtdb/stdlib/validation.d.ts.map +1 -0
  766. package/dist/rules/rtdb/stdlib/validation.js +125 -0
  767. package/dist/rules/rtdb/stdlib/validation.js.map +1 -0
  768. package/dist/rules/rtdb/structure.d.ts +15 -0
  769. package/dist/rules/rtdb/structure.d.ts.map +1 -0
  770. package/dist/rules/rtdb/structure.js +66 -0
  771. package/dist/rules/rtdb/structure.js.map +1 -0
  772. package/dist/rules/rtdb/types.d.ts +34 -24
  773. package/dist/rules/rtdb/types.d.ts.map +1 -1
  774. package/dist/rules/simulator/conversions.d.ts +28 -0
  775. package/dist/rules/simulator/conversions.d.ts.map +1 -0
  776. package/dist/rules/simulator/conversions.js +136 -0
  777. package/dist/rules/simulator/conversions.js.map +1 -0
  778. package/dist/rules/simulator/document-lookups.d.ts.map +1 -1
  779. package/dist/rules/simulator/document-lookups.js +20 -9
  780. package/dist/rules/simulator/document-lookups.js.map +1 -1
  781. package/dist/rules/simulator/eval-error.d.ts +21 -0
  782. package/dist/rules/simulator/eval-error.d.ts.map +1 -1
  783. package/dist/rules/simulator/eval-error.js +26 -0
  784. package/dist/rules/simulator/eval-error.js.map +1 -1
  785. package/dist/rules/simulator/evaluation-builtins.d.ts.map +1 -1
  786. package/dist/rules/simulator/evaluation-builtins.js +304 -307
  787. package/dist/rules/simulator/evaluation-builtins.js.map +1 -1
  788. package/dist/rules/simulator/evaluation-context.d.ts +14 -0
  789. package/dist/rules/simulator/evaluation-context.d.ts.map +1 -1
  790. package/dist/rules/simulator/evaluator.d.ts +23 -0
  791. package/dist/rules/simulator/evaluator.d.ts.map +1 -1
  792. package/dist/rules/simulator/evaluator.js +232 -156
  793. package/dist/rules/simulator/evaluator.js.map +1 -1
  794. package/dist/rules/simulator/expression-budget.d.ts +91 -0
  795. package/dist/rules/simulator/expression-budget.d.ts.map +1 -0
  796. package/dist/rules/simulator/expression-budget.js +117 -0
  797. package/dist/rules/simulator/expression-budget.js.map +1 -0
  798. package/dist/rules/simulator/firestore-set.d.ts +30 -0
  799. package/dist/rules/simulator/firestore-set.d.ts.map +1 -1
  800. package/dist/rules/simulator/firestore-set.js +79 -14
  801. package/dist/rules/simulator/firestore-set.js.map +1 -1
  802. package/dist/rules/simulator/firestore-values.d.ts +4 -2
  803. package/dist/rules/simulator/firestore-values.d.ts.map +1 -1
  804. package/dist/rules/simulator/firestore-values.js +120 -11
  805. package/dist/rules/simulator/firestore-values.js.map +1 -1
  806. package/dist/rules/simulator/handler.d.ts +32 -13
  807. package/dist/rules/simulator/handler.d.ts.map +1 -1
  808. package/dist/rules/simulator/handler.js +245 -72
  809. package/dist/rules/simulator/handler.js.map +1 -1
  810. package/dist/rules/simulator/hashing-builtins.d.ts.map +1 -1
  811. package/dist/rules/simulator/hashing-builtins.js +177 -11
  812. package/dist/rules/simulator/hashing-builtins.js.map +1 -1
  813. package/dist/rules/simulator/index-access.d.ts +45 -0
  814. package/dist/rules/simulator/index-access.d.ts.map +1 -0
  815. package/dist/rules/simulator/index-access.js +127 -0
  816. package/dist/rules/simulator/index-access.js.map +1 -0
  817. package/dist/rules/simulator/list-methods.d.ts +45 -0
  818. package/dist/rules/simulator/list-methods.d.ts.map +1 -0
  819. package/dist/rules/simulator/list-methods.js +96 -0
  820. package/dist/rules/simulator/list-methods.js.map +1 -0
  821. package/dist/rules/simulator/list-query-proof.d.ts +137 -0
  822. package/dist/rules/simulator/list-query-proof.d.ts.map +1 -0
  823. package/dist/rules/simulator/list-query-proof.js +283 -0
  824. package/dist/rules/simulator/list-query-proof.js.map +1 -0
  825. package/dist/rules/simulator/list-rule-path-proof.d.ts +19 -0
  826. package/dist/rules/simulator/list-rule-path-proof.d.ts.map +1 -0
  827. package/dist/rules/simulator/list-rule-path-proof.js +144 -0
  828. package/dist/rules/simulator/list-rule-path-proof.js.map +1 -0
  829. package/dist/rules/simulator/lookup-budget.d.ts +8 -2
  830. package/dist/rules/simulator/lookup-budget.d.ts.map +1 -1
  831. package/dist/rules/simulator/lookup-budget.js +41 -7
  832. package/dist/rules/simulator/lookup-budget.js.map +1 -1
  833. package/dist/rules/simulator/map-keys.d.ts +48 -0
  834. package/dist/rules/simulator/map-keys.d.ts.map +1 -0
  835. package/dist/rules/simulator/map-keys.js +82 -0
  836. package/dist/rules/simulator/map-keys.js.map +1 -0
  837. package/dist/rules/simulator/mapdiff.d.ts +2 -1
  838. package/dist/rules/simulator/mapdiff.d.ts.map +1 -1
  839. package/dist/rules/simulator/mapdiff.js +6 -5
  840. package/dist/rules/simulator/mapdiff.js.map +1 -1
  841. package/dist/rules/simulator/match-resolution.d.ts +24 -4
  842. package/dist/rules/simulator/match-resolution.d.ts.map +1 -1
  843. package/dist/rules/simulator/match-resolution.js +110 -35
  844. package/dist/rules/simulator/match-resolution.js.map +1 -1
  845. package/dist/rules/simulator/math-builtins.d.ts +29 -0
  846. package/dist/rules/simulator/math-builtins.d.ts.map +1 -0
  847. package/dist/rules/simulator/math-builtins.js +80 -0
  848. package/dist/rules/simulator/math-builtins.js.map +1 -0
  849. package/dist/rules/simulator/membership.d.ts +26 -0
  850. package/dist/rules/simulator/membership.d.ts.map +1 -0
  851. package/dist/rules/simulator/membership.js +45 -0
  852. package/dist/rules/simulator/membership.js.map +1 -0
  853. package/dist/rules/simulator/project-after-state.d.ts.map +1 -1
  854. package/dist/rules/simulator/project-after-state.js +16 -9
  855. package/dist/rules/simulator/project-after-state.js.map +1 -1
  856. package/dist/rules/simulator/query-proof-residual.d.ts +22 -0
  857. package/dist/rules/simulator/query-proof-residual.d.ts.map +1 -1
  858. package/dist/rules/simulator/query-proof-residual.js +288 -53
  859. package/dist/rules/simulator/query-proof-residual.js.map +1 -1
  860. package/dist/rules/simulator/query-proof.d.ts.map +1 -1
  861. package/dist/rules/simulator/query-proof.js +58 -45
  862. package/dist/rules/simulator/query-proof.js.map +1 -1
  863. package/dist/rules/simulator/rules-type.d.ts +22 -0
  864. package/dist/rules/simulator/rules-type.d.ts.map +1 -0
  865. package/dist/rules/simulator/rules-type.js +472 -0
  866. package/dist/rules/simulator/rules-type.js.map +1 -0
  867. package/dist/rules/simulator/slice-bounds.d.ts +3 -0
  868. package/dist/rules/simulator/slice-bounds.d.ts.map +1 -0
  869. package/dist/rules/simulator/slice-bounds.js +23 -0
  870. package/dist/rules/simulator/slice-bounds.js.map +1 -0
  871. package/dist/rules/simulator/value-equality.d.ts +30 -3
  872. package/dist/rules/simulator/value-equality.d.ts.map +1 -1
  873. package/dist/rules/simulator/value-equality.js +64 -21
  874. package/dist/rules/simulator/value-equality.js.map +1 -1
  875. package/dist/rules/simulator/wrappers/bytes.d.ts +1 -1
  876. package/dist/rules/simulator/wrappers/bytes.d.ts.map +1 -1
  877. package/dist/rules/simulator/wrappers/bytes.js +12 -4
  878. package/dist/rules/simulator/wrappers/bytes.js.map +1 -1
  879. package/dist/rules/simulator/wrappers/duration.d.ts +1 -1
  880. package/dist/rules/simulator/wrappers/duration.d.ts.map +1 -1
  881. package/dist/rules/simulator/wrappers/duration.js +5 -3
  882. package/dist/rules/simulator/wrappers/duration.js.map +1 -1
  883. package/dist/rules/simulator/wrappers/float.d.ts +7 -5
  884. package/dist/rules/simulator/wrappers/float.d.ts.map +1 -1
  885. package/dist/rules/simulator/wrappers/float.js +39 -6
  886. package/dist/rules/simulator/wrappers/float.js.map +1 -1
  887. package/dist/rules/simulator/wrappers/latlng.d.ts.map +1 -1
  888. package/dist/rules/simulator/wrappers/latlng.js +7 -2
  889. package/dist/rules/simulator/wrappers/latlng.js.map +1 -1
  890. package/dist/rules/simulator/wrappers/path.d.ts +3 -16
  891. package/dist/rules/simulator/wrappers/path.d.ts.map +1 -1
  892. package/dist/rules/simulator/wrappers/path.js +7 -33
  893. package/dist/rules/simulator/wrappers/path.js.map +1 -1
  894. package/dist/rules/simulator/wrappers/timestamp.d.ts +1 -1
  895. package/dist/rules/simulator/wrappers/timestamp.d.ts.map +1 -1
  896. package/dist/rules/simulator/wrappers/timestamp.js +29 -2
  897. package/dist/rules/simulator/wrappers/timestamp.js.map +1 -1
  898. package/dist/rules/simulator-tools-impl.d.ts +1 -1
  899. package/dist/rules/simulator-tools-impl.d.ts.map +1 -1
  900. package/dist/rules/simulator.d.ts +1 -1
  901. package/dist/rules/simulator.d.ts.map +1 -1
  902. package/dist/rules/stdlib-modules.d.ts +15 -0
  903. package/dist/rules/stdlib-modules.d.ts.map +1 -1
  904. package/dist/rules/stdlib-modules.js +320 -27
  905. package/dist/rules/stdlib-modules.js.map +1 -1
  906. package/dist/rules/stdlib-tools.d.ts +1 -1
  907. package/dist/rules/stdlib-tools.d.ts.map +1 -1
  908. package/dist/rules/stdlib-tools.js +111 -18
  909. package/dist/rules/stdlib-tools.js.map +1 -1
  910. package/dist/rules/test/spec.d.ts +158 -25
  911. package/dist/rules/test/spec.d.ts.map +1 -1
  912. package/dist/rules/test/spec.js +27 -6
  913. package/dist/rules/test/spec.js.map +1 -1
  914. package/dist/rules/tools.d.ts +1 -1
  915. package/dist/rules/tools.d.ts.map +1 -1
  916. package/dist/sandbox/admin-firestore/error-translation.d.ts.map +1 -1
  917. package/dist/sandbox/admin-firestore/error-translation.js +18 -2
  918. package/dist/sandbox/admin-firestore/error-translation.js.map +1 -1
  919. package/dist/sandbox/admin-firestore/listeners.d.ts.map +1 -1
  920. package/dist/sandbox/admin-firestore/listeners.js +30 -2
  921. package/dist/sandbox/admin-firestore/listeners.js.map +1 -1
  922. package/dist/sandbox/admin-firestore/remote/batch.d.ts +6 -1
  923. package/dist/sandbox/admin-firestore/remote/batch.d.ts.map +1 -1
  924. package/dist/sandbox/admin-firestore/remote/batch.js +29 -5
  925. package/dist/sandbox/admin-firestore/remote/batch.js.map +1 -1
  926. package/dist/sandbox/admin-firestore/remote/channel.d.ts +3 -3
  927. package/dist/sandbox/admin-firestore/remote/channel.js +3 -3
  928. package/dist/sandbox/admin-firestore/remote/doc-ref.d.ts.map +1 -1
  929. package/dist/sandbox/admin-firestore/remote/doc-ref.js +13 -3
  930. package/dist/sandbox/admin-firestore/remote/doc-ref.js.map +1 -1
  931. package/dist/sandbox/admin-firestore/remote/remote-firestore.d.ts +3 -3
  932. package/dist/sandbox/admin-firestore/remote/remote-firestore.js +3 -3
  933. package/dist/sandbox/admin-firestore/remote/snapshots.d.ts.map +1 -1
  934. package/dist/sandbox/admin-firestore/remote/snapshots.js +2 -3
  935. package/dist/sandbox/admin-firestore/remote/snapshots.js.map +1 -1
  936. package/dist/sandbox/admin-firestore/remote/transaction.d.ts.map +1 -1
  937. package/dist/sandbox/admin-firestore/remote/transaction.js +25 -5
  938. package/dist/sandbox/admin-firestore/remote/transaction.js.map +1 -1
  939. package/dist/sandbox/admin-firestore/remote/value-codec.d.ts +4 -0
  940. package/dist/sandbox/admin-firestore/remote/value-codec.d.ts.map +1 -1
  941. package/dist/sandbox/admin-firestore/remote/value-codec.js +4 -0
  942. package/dist/sandbox/admin-firestore/remote/value-codec.js.map +1 -1
  943. package/dist/sandbox/admin-firestore/remote/wire-types.d.ts +10 -1
  944. package/dist/sandbox/admin-firestore/remote/wire-types.d.ts.map +1 -1
  945. package/dist/sandbox/attribution/listener-owners.d.ts +10 -6
  946. package/dist/sandbox/attribution/listener-owners.d.ts.map +1 -1
  947. package/dist/sandbox/attribution/listener-owners.js +55 -33
  948. package/dist/sandbox/attribution/listener-owners.js.map +1 -1
  949. package/dist/sandbox/attribution/owner-frames.d.ts +58 -0
  950. package/dist/sandbox/attribution/owner-frames.d.ts.map +1 -0
  951. package/dist/sandbox/attribution/owner-frames.js +103 -0
  952. package/dist/sandbox/attribution/owner-frames.js.map +1 -0
  953. package/dist/sandbox/branches/engine.d.ts.map +1 -1
  954. package/dist/sandbox/branches/engine.js +5 -4
  955. package/dist/sandbox/branches/engine.js.map +1 -1
  956. package/dist/sandbox/branches/promotion.d.ts.map +1 -1
  957. package/dist/sandbox/branches/promotion.js +18 -6
  958. package/dist/sandbox/branches/promotion.js.map +1 -1
  959. package/dist/sandbox/branches/store.d.ts.map +1 -1
  960. package/dist/sandbox/branches/store.js +13 -1
  961. package/dist/sandbox/branches/store.js.map +1 -1
  962. package/dist/sandbox/checkpoints/capture.d.ts.map +1 -1
  963. package/dist/sandbox/checkpoints/capture.js +5 -2
  964. package/dist/sandbox/checkpoints/capture.js.map +1 -1
  965. package/dist/sandbox/full-state.d.ts +5 -0
  966. package/dist/sandbox/full-state.d.ts.map +1 -1
  967. package/dist/sandbox/full-state.js +55 -8
  968. package/dist/sandbox/full-state.js.map +1 -1
  969. package/dist/sandbox/index.d.ts +1 -1
  970. package/dist/sandbox/index.d.ts.map +1 -1
  971. package/dist/sandbox/index.js.map +1 -1
  972. package/dist/sandbox/internal/auth-token-claims.d.ts +82 -0
  973. package/dist/sandbox/internal/auth-token-claims.d.ts.map +1 -0
  974. package/dist/sandbox/internal/auth-token-claims.js +152 -0
  975. package/dist/sandbox/internal/auth-token-claims.js.map +1 -0
  976. package/dist/sandbox/internal/database-rules-config.d.ts +74 -0
  977. package/dist/sandbox/internal/database-rules-config.d.ts.map +1 -0
  978. package/dist/sandbox/internal/database-rules-config.js +126 -0
  979. package/dist/sandbox/internal/database-rules-config.js.map +1 -0
  980. package/dist/sandbox/internal/index.d.ts +12 -0
  981. package/dist/sandbox/internal/index.d.ts.map +1 -1
  982. package/dist/sandbox/internal/index.js +18 -0
  983. package/dist/sandbox/internal/index.js.map +1 -1
  984. package/dist/sandbox/internal/inline-storage-limit.d.ts +50 -0
  985. package/dist/sandbox/internal/inline-storage-limit.d.ts.map +1 -0
  986. package/dist/sandbox/internal/inline-storage-limit.js +81 -0
  987. package/dist/sandbox/internal/inline-storage-limit.js.map +1 -0
  988. package/dist/sandbox/internal/instances.d.ts +119 -0
  989. package/dist/sandbox/internal/instances.d.ts.map +1 -0
  990. package/dist/sandbox/internal/instances.js +254 -0
  991. package/dist/sandbox/internal/instances.js.map +1 -0
  992. package/dist/sandbox/internal/process-activation.d.ts +41 -0
  993. package/dist/sandbox/internal/process-activation.d.ts.map +1 -0
  994. package/dist/sandbox/internal/process-activation.js +36 -0
  995. package/dist/sandbox/internal/process-activation.js.map +1 -0
  996. package/dist/sandbox/internal/sandbox-activation.d.ts +40 -0
  997. package/dist/sandbox/internal/sandbox-activation.d.ts.map +1 -0
  998. package/dist/sandbox/internal/sandbox-activation.js +35 -0
  999. package/dist/sandbox/internal/sandbox-activation.js.map +1 -0
  1000. package/dist/sandbox/internal/sandbox-impl.d.ts +3 -0
  1001. package/dist/sandbox/internal/sandbox-impl.d.ts.map +1 -1
  1002. package/dist/sandbox/internal/sandbox-impl.js +11 -3
  1003. package/dist/sandbox/internal/sandbox-impl.js.map +1 -1
  1004. package/dist/sandbox/internal/sdk-activity.d.ts +4 -0
  1005. package/dist/sandbox/internal/sdk-activity.d.ts.map +1 -1
  1006. package/dist/sandbox/internal/sdk-activity.js +2 -0
  1007. package/dist/sandbox/internal/sdk-activity.js.map +1 -1
  1008. package/dist/sandbox/internal/sentence.d.ts +7 -0
  1009. package/dist/sandbox/internal/sentence.d.ts.map +1 -0
  1010. package/dist/sandbox/internal/sentence.js +9 -0
  1011. package/dist/sandbox/internal/sentence.js.map +1 -0
  1012. package/dist/sandbox/internal/tool-handler.d.ts +39 -0
  1013. package/dist/sandbox/internal/tool-handler.d.ts.map +1 -0
  1014. package/dist/sandbox/internal/tool-handler.js +11 -0
  1015. package/dist/sandbox/internal/tool-handler.js.map +1 -0
  1016. package/dist/sandbox/persistence/controller.js +8 -2
  1017. package/dist/sandbox/persistence/controller.js.map +1 -1
  1018. package/dist/sandbox/replay/index.d.ts.map +1 -1
  1019. package/dist/sandbox/replay/index.js +316 -41
  1020. package/dist/sandbox/replay/index.js.map +1 -1
  1021. package/dist/sandbox/tab-sync/index.js +3 -3
  1022. package/dist/sandbox/tab-sync/index.js.map +1 -1
  1023. package/dist/sandbox/types/errors.d.ts +50 -1
  1024. package/dist/sandbox/types/errors.d.ts.map +1 -1
  1025. package/dist/sandbox/types/errors.js.map +1 -1
  1026. package/dist/sandbox/types/events.d.ts +56 -2
  1027. package/dist/sandbox/types/events.d.ts.map +1 -1
  1028. package/dist/sandbox/types/index.d.ts +2 -2
  1029. package/dist/sandbox/types/index.d.ts.map +1 -1
  1030. package/dist/sandbox/types/index.js.map +1 -1
  1031. package/dist/sandbox/types/query-proof.d.ts +1 -24
  1032. package/dist/sandbox/types/query-proof.d.ts.map +1 -1
  1033. package/dist/sandbox/types/service-mutation-event.d.ts +6 -0
  1034. package/dist/sandbox/types/service-mutation-event.d.ts.map +1 -1
  1035. package/dist/sandbox/types/service.d.ts +6 -2
  1036. package/dist/sandbox/types/service.d.ts.map +1 -1
  1037. package/dist/storage/admin/tools.d.ts +2 -2
  1038. package/dist/storage/admin/tools.d.ts.map +1 -1
  1039. package/dist/storage/content-defaults.d.ts +30 -0
  1040. package/dist/storage/content-defaults.d.ts.map +1 -0
  1041. package/dist/storage/content-defaults.js +47 -0
  1042. package/dist/storage/content-defaults.js.map +1 -0
  1043. package/dist/storage/copy.d.ts +16 -0
  1044. package/dist/storage/copy.d.ts.map +1 -0
  1045. package/dist/storage/copy.js +49 -0
  1046. package/dist/storage/copy.js.map +1 -0
  1047. package/dist/storage/download.d.ts +8 -0
  1048. package/dist/storage/download.d.ts.map +1 -1
  1049. package/dist/storage/download.js +23 -0
  1050. package/dist/storage/download.js.map +1 -1
  1051. package/dist/storage/enforce.d.ts.map +1 -1
  1052. package/dist/storage/enforce.js +1 -0
  1053. package/dist/storage/enforce.js.map +1 -1
  1054. package/dist/storage/errors.d.ts +0 -22
  1055. package/dist/storage/errors.d.ts.map +1 -1
  1056. package/dist/storage/errors.js +2 -1
  1057. package/dist/storage/errors.js.map +1 -1
  1058. package/dist/storage/generation.d.ts +32 -0
  1059. package/dist/storage/generation.d.ts.map +1 -0
  1060. package/dist/storage/generation.js +56 -0
  1061. package/dist/storage/generation.js.map +1 -0
  1062. package/dist/storage/internal.d.ts +7 -3
  1063. package/dist/storage/internal.d.ts.map +1 -1
  1064. package/dist/storage/internal.js +7 -1
  1065. package/dist/storage/internal.js.map +1 -1
  1066. package/dist/storage/metadata.d.ts +6 -5
  1067. package/dist/storage/metadata.d.ts.map +1 -1
  1068. package/dist/storage/metadata.js +16 -12
  1069. package/dist/storage/metadata.js.map +1 -1
  1070. package/dist/storage/persistence.d.ts +62 -11
  1071. package/dist/storage/persistence.d.ts.map +1 -1
  1072. package/dist/storage/persistence.js +230 -57
  1073. package/dist/storage/persistence.js.map +1 -1
  1074. package/dist/storage/remote-bytes.d.ts +6 -0
  1075. package/dist/storage/remote-bytes.d.ts.map +1 -1
  1076. package/dist/storage/remote-bytes.js +4 -1
  1077. package/dist/storage/remote-bytes.js.map +1 -1
  1078. package/dist/storage/resumable.d.ts.map +1 -1
  1079. package/dist/storage/resumable.js +126 -47
  1080. package/dist/storage/resumable.js.map +1 -1
  1081. package/dist/storage/rules-resolution.d.ts.map +1 -1
  1082. package/dist/storage/rules-resolution.js +105 -1
  1083. package/dist/storage/rules-resolution.js.map +1 -1
  1084. package/dist/storage/sandbox/persistence-state.d.ts +5 -0
  1085. package/dist/storage/sandbox/persistence-state.d.ts.map +1 -1
  1086. package/dist/storage/sandbox/persistence-state.js +11 -5
  1087. package/dist/storage/sandbox/persistence-state.js.map +1 -1
  1088. package/dist/storage/sandbox/rules-bindings.d.ts +0 -10
  1089. package/dist/storage/sandbox/rules-bindings.d.ts.map +1 -1
  1090. package/dist/storage/sandbox/rules-bindings.js +16 -4
  1091. package/dist/storage/sandbox/rules-bindings.js.map +1 -1
  1092. package/dist/storage/sandbox/rules-collection-methods.d.ts.map +1 -1
  1093. package/dist/storage/sandbox/rules-collection-methods.js +92 -57
  1094. package/dist/storage/sandbox/rules-collection-methods.js.map +1 -1
  1095. package/dist/storage/sandbox/rules-evaluation-error.d.ts +15 -4
  1096. package/dist/storage/sandbox/rules-evaluation-error.d.ts.map +1 -1
  1097. package/dist/storage/sandbox/rules-evaluation-error.js +17 -4
  1098. package/dist/storage/sandbox/rules-evaluation-error.js.map +1 -1
  1099. package/dist/storage/sandbox/rules-evaluator.d.ts +25 -5
  1100. package/dist/storage/sandbox/rules-evaluator.d.ts.map +1 -1
  1101. package/dist/storage/sandbox/rules-evaluator.js +328 -182
  1102. package/dist/storage/sandbox/rules-evaluator.js.map +1 -1
  1103. package/dist/storage/sandbox/rules-firestore-lookup.d.ts +0 -17
  1104. package/dist/storage/sandbox/rules-firestore-lookup.d.ts.map +1 -1
  1105. package/dist/storage/sandbox/rules-firestore-lookup.js +95 -24
  1106. package/dist/storage/sandbox/rules-firestore-lookup.js.map +1 -1
  1107. package/dist/storage/sandbox/rules-hashing-methods.d.ts.map +1 -1
  1108. package/dist/storage/sandbox/rules-hashing-methods.js +4 -3
  1109. package/dist/storage/sandbox/rules-hashing-methods.js.map +1 -1
  1110. package/dist/storage/sandbox/rules-latlng.d.ts +23 -0
  1111. package/dist/storage/sandbox/rules-latlng.d.ts.map +1 -0
  1112. package/dist/storage/sandbox/rules-latlng.js +129 -0
  1113. package/dist/storage/sandbox/rules-latlng.js.map +1 -0
  1114. package/dist/storage/sandbox/rules-math-methods.d.ts +12 -0
  1115. package/dist/storage/sandbox/rules-math-methods.d.ts.map +1 -0
  1116. package/dist/storage/sandbox/rules-math-methods.js +19 -0
  1117. package/dist/storage/sandbox/rules-math-methods.js.map +1 -0
  1118. package/dist/storage/sandbox/rules-method-calls.d.ts +8 -1
  1119. package/dist/storage/sandbox/rules-method-calls.d.ts.map +1 -1
  1120. package/dist/storage/sandbox/rules-method-calls.js +17 -11
  1121. package/dist/storage/sandbox/rules-method-calls.js.map +1 -1
  1122. package/dist/storage/sandbox/rules-methods.d.ts +2 -2
  1123. package/dist/storage/sandbox/rules-methods.d.ts.map +1 -1
  1124. package/dist/storage/sandbox/rules-methods.js +19 -6
  1125. package/dist/storage/sandbox/rules-methods.js.map +1 -1
  1126. package/dist/storage/sandbox/rules-operators.d.ts +23 -6
  1127. package/dist/storage/sandbox/rules-operators.d.ts.map +1 -1
  1128. package/dist/storage/sandbox/rules-operators.js +77 -22
  1129. package/dist/storage/sandbox/rules-operators.js.map +1 -1
  1130. package/dist/storage/sandbox/rules-path-match.d.ts +8 -6
  1131. package/dist/storage/sandbox/rules-path-match.d.ts.map +1 -1
  1132. package/dist/storage/sandbox/rules-path-match.js +13 -6
  1133. package/dist/storage/sandbox/rules-path-match.js.map +1 -1
  1134. package/dist/storage/sandbox/rules-path.d.ts +18 -0
  1135. package/dist/storage/sandbox/rules-path.d.ts.map +1 -0
  1136. package/dist/storage/sandbox/rules-path.js +83 -0
  1137. package/dist/storage/sandbox/rules-path.js.map +1 -0
  1138. package/dist/storage/sandbox/rules-resources.d.ts +33 -9
  1139. package/dist/storage/sandbox/rules-resources.d.ts.map +1 -1
  1140. package/dist/storage/sandbox/rules-resources.js +46 -11
  1141. package/dist/storage/sandbox/rules-resources.js.map +1 -1
  1142. package/dist/storage/sandbox/rules-string-methods.d.ts.map +1 -1
  1143. package/dist/storage/sandbox/rules-string-methods.js +73 -9
  1144. package/dist/storage/sandbox/rules-string-methods.js.map +1 -1
  1145. package/dist/storage/sandbox/rules-time-methods.d.ts.map +1 -1
  1146. package/dist/storage/sandbox/rules-time-methods.js +34 -11
  1147. package/dist/storage/sandbox/rules-time-methods.js.map +1 -1
  1148. package/dist/storage/sandbox/rules-values.d.ts +0 -10
  1149. package/dist/storage/sandbox/rules-values.d.ts.map +1 -1
  1150. package/dist/storage/sandbox/rules-values.js +0 -63
  1151. package/dist/storage/sandbox/rules-values.js.map +1 -1
  1152. package/dist/storage/sandbox/rules.d.ts +71 -14
  1153. package/dist/storage/sandbox/rules.d.ts.map +1 -1
  1154. package/dist/storage/sandbox/rules.js +89 -26
  1155. package/dist/storage/sandbox/rules.js.map +1 -1
  1156. package/dist/storage/service.d.ts +7 -1
  1157. package/dist/storage/service.d.ts.map +1 -1
  1158. package/dist/storage/service.js +34 -10
  1159. package/dist/storage/service.js.map +1 -1
  1160. package/dist/storage/upload-rollback.d.ts +70 -0
  1161. package/dist/storage/upload-rollback.d.ts.map +1 -0
  1162. package/dist/storage/upload-rollback.js +116 -0
  1163. package/dist/storage/upload-rollback.js.map +1 -0
  1164. package/dist/storage/upload.d.ts +32 -5
  1165. package/dist/storage/upload.d.ts.map +1 -1
  1166. package/dist/storage/upload.js +42 -27
  1167. package/dist/storage/upload.js.map +1 -1
  1168. package/package.json +11 -7
  1169. package/src/ai/broker/broker.ts +5 -5
  1170. package/src/ai/broker/gemini-engine.ts +196 -81
  1171. package/src/ai/broker/index.ts +1 -1
  1172. package/src/ai/broker/openai-engine.ts +36 -29
  1173. package/src/ai/broker/synthesizer.ts +9 -17
  1174. package/src/ai/broker/types.ts +2 -2
  1175. package/src/ai/internal.ts +1 -1
  1176. package/src/app/client-sdk-refusal.ts +44 -0
  1177. package/src/app/internal.ts +16 -2
  1178. package/src/app/register-rules.ts +111 -0
  1179. package/src/app/register.test.ts +11 -4
  1180. package/src/app/register.ts +9 -19
  1181. package/src/app/registry.ts +25 -8
  1182. package/src/app/runtime.ts +12 -0
  1183. package/src/auth/action-codes.ts +2 -0
  1184. package/src/auth/reauth.ts +12 -25
  1185. package/src/auth/sandbox-backend.ts +97 -29
  1186. package/src/database/connection-lifecycle.ts +10 -2
  1187. package/src/database/disconnect-operation-queue.ts +122 -30
  1188. package/src/database/instances.ts +76 -13
  1189. package/src/database/internal/value-children.ts +53 -0
  1190. package/src/database/internal.ts +5 -1
  1191. package/src/database/listen-index-warning.ts +16 -0
  1192. package/src/database/listeners.ts +81 -73
  1193. package/src/database/on-disconnect.ts +5 -0
  1194. package/src/database/operations.ts +10 -22
  1195. package/src/database/queries.ts +7 -8
  1196. package/src/database/replay.ts +167 -14
  1197. package/src/database/sandbox/backend-for.ts +106 -136
  1198. package/src/database/sandbox/backend-state.ts +50 -8
  1199. package/src/database/sandbox/backend.ts +64 -12
  1200. package/src/database/sandbox/child-listeners.ts +141 -74
  1201. package/src/database/sandbox/data-tree.ts +3 -0
  1202. package/src/database/sandbox/listener-types.ts +21 -3
  1203. package/src/database/sandbox/normalize.ts +112 -1
  1204. package/src/database/sandbox/operation-events.ts +59 -14
  1205. package/src/database/sandbox/persistence-state.ts +19 -3
  1206. package/src/database/sandbox/priority-state.ts +32 -6
  1207. package/src/database/sandbox/priority-writes.ts +34 -12
  1208. package/src/database/sandbox/query-index.ts +41 -0
  1209. package/src/database/sandbox/query.ts +2 -11
  1210. package/src/database/sandbox/rules-eval.ts +56 -87
  1211. package/src/database/sandbox/sentinels.ts +16 -7
  1212. package/src/database/sandbox/transactions.ts +88 -35
  1213. package/src/database/sandbox/value-listeners.ts +15 -20
  1214. package/src/database/sandbox/write-plane.ts +267 -74
  1215. package/src/database/sandbox-controls.ts +2 -90
  1216. package/src/database/snapshots.ts +38 -14
  1217. package/src/database/transactions.ts +12 -7
  1218. package/src/database/writable-path.ts +65 -0
  1219. package/src/deferred/entry.ts +14 -1
  1220. package/src/deferred/member.ts +106 -0
  1221. package/src/firestore/aggregates.ts +3 -2
  1222. package/src/firestore/chain-update.ts +30 -0
  1223. package/src/firestore/internal/atomic-create.ts +26 -0
  1224. package/src/firestore/internal/index.ts +1 -0
  1225. package/src/firestore/internal/update-fields.ts +5 -0
  1226. package/src/firestore/persistence.ts +2 -0
  1227. package/src/firestore/reads.ts +3 -1
  1228. package/src/firestore/sandbox/admin-compat/batch.ts +10 -2
  1229. package/src/firestore/sandbox/admin-compat/collection-ref.ts +22 -10
  1230. package/src/firestore/sandbox/admin-compat/doc-ref.ts +21 -2
  1231. package/src/firestore/sandbox/admin-compat/field-path.ts +85 -36
  1232. package/src/firestore/sandbox/admin-compat/query.ts +10 -1
  1233. package/src/firestore/sandbox/admin-compat/transaction.ts +10 -2
  1234. package/src/firestore/sandbox/admin-compat/types.ts +11 -2
  1235. package/src/firestore/sandbox/admin-writes.ts +44 -0
  1236. package/src/firestore/sandbox/atomic-write-pipeline.ts +23 -17
  1237. package/src/firestore/sandbox/collection-group-rule-proof.ts +34 -11
  1238. package/src/firestore/sandbox/converters/fieldvalue.ts +13 -23
  1239. package/src/firestore/sandbox/errors.ts +13 -2
  1240. package/src/firestore/sandbox/field-merge.ts +6 -3
  1241. package/src/firestore/sandbox/for-each-document.ts +15 -0
  1242. package/src/firestore/sandbox/list-query-proof.ts +13 -275
  1243. package/src/firestore/sandbox/list-rule-path-proof.ts +6 -148
  1244. package/src/firestore/sandbox/listener-delivery.ts +15 -9
  1245. package/src/firestore/sandbox/listener-dispatch.ts +134 -62
  1246. package/src/firestore/sandbox/local-environment.ts +1 -1
  1247. package/src/firestore/sandbox/reads.ts +2 -9
  1248. package/src/firestore/sandbox/request-events.ts +4 -0
  1249. package/src/firestore/sandbox/rules-list-authorizer.ts +35 -15
  1250. package/src/firestore/sandbox/rules-read-engine.ts +18 -32
  1251. package/src/firestore/sandbox/rules-simulator.ts +22 -1
  1252. package/src/firestore/sandbox/rules-state.ts +34 -6
  1253. package/src/firestore/sandbox/rules-test-case.ts +27 -13
  1254. package/src/firestore/sandbox/snapshot-listeners.ts +104 -86
  1255. package/src/firestore/sandbox/transaction-write-executor.ts +235 -6
  1256. package/src/firestore/sandbox/transaction.ts +13 -0
  1257. package/src/firestore/sandbox/trigger-scope.ts +12 -0
  1258. package/src/firestore/sandbox/update-fields.ts +321 -0
  1259. package/src/firestore/sandbox/value-resolver.ts +15 -4
  1260. package/src/firestore/sandbox/write-engine.ts +26 -26
  1261. package/src/firestore/sandbox/write-runtime.ts +22 -11
  1262. package/src/firestore/sandbox-controls.ts +12 -1
  1263. package/src/firestore/ssr-snapshots.ts +2 -0
  1264. package/src/firestore/tools.ts +4 -1
  1265. package/src/firestore/transactions.ts +42 -25
  1266. package/src/firestore/types.ts +7 -2
  1267. package/src/firestore/writes.ts +22 -2
  1268. package/src/rules/api/assert.ts +25 -3
  1269. package/src/rules/api/case-types.ts +101 -7
  1270. package/src/rules/api/firestore.ts +49 -7
  1271. package/src/rules/api/issue.ts +64 -7
  1272. package/src/rules/api/lint.ts +5 -2
  1273. package/src/rules/api/rtdb-case-input.ts +141 -0
  1274. package/src/rules/api/rtdb-firebase-json.ts +157 -0
  1275. package/src/rules/api/rtdb-instance-case.ts +155 -0
  1276. package/src/rules/api/rtdb.ts +217 -63
  1277. package/src/rules/api/values.ts +4 -2
  1278. package/src/rules/grammar/FirestoreAST.ts +10 -2
  1279. package/src/rules/grammar/FirestoreAssembler.ts +27 -23
  1280. package/src/rules/grammar/FirestoreParser.ts +286 -233
  1281. package/src/rules/grammar/FirestoreRules.ohm +45 -18
  1282. package/src/rules/grammar/FirestoreRules.ohm.generated.ts +45 -18
  1283. package/src/rules/grammar/FirestoreValidator.ts +309 -205
  1284. package/src/rules/grammar/bracket-scan.ts +305 -0
  1285. package/src/rules/grammar/compile-limits.ts +571 -0
  1286. package/src/rules/grammar/document-access-count.ts +76 -30
  1287. package/src/rules/grammar/expression-positions.ts +101 -0
  1288. package/src/rules/grammar/function-scopes.ts +394 -0
  1289. package/src/rules/grammar/paren-groups.ts +19 -0
  1290. package/src/rules/grammar/parse-error-wording.ts +174 -44
  1291. package/src/rules/grammar/re2-pattern.ts +101 -0
  1292. package/src/rules/grammar/recursive-scope.ts +47 -0
  1293. package/src/rules/grammar/source-compile-limits.ts +65 -0
  1294. package/src/rules/grammar/source-segments.ts +349 -0
  1295. package/src/rules/index.ts +37 -1
  1296. package/src/rules/indexes/extract/composite.ts +40 -15
  1297. package/src/rules/indexes/extractTool.ts +1 -1
  1298. package/src/rules/inspect/tools.ts +1 -1
  1299. package/src/rules/internal/index.ts +32 -1
  1300. package/src/rules/internal/rtdb.ts +31 -0
  1301. package/src/rules/linter/ast-utils.ts +204 -74
  1302. package/src/rules/linter/expression-cost.ts +522 -0
  1303. package/src/rules/linter/hallucinations.ts +156 -62
  1304. package/src/rules/linter/library-calls.ts +113 -0
  1305. package/src/rules/linter/linter.ts +466 -328
  1306. package/src/rules/modules/receiver-types.ts +12 -9
  1307. package/src/rules/modules/resolver-browser.ts +31 -5
  1308. package/src/rules/modules/resolver-call-sites.ts +26 -3
  1309. package/src/rules/modules/resolver-core.ts +396 -186
  1310. package/src/rules/modules/resolver-transform.ts +34 -19
  1311. package/src/rules/modules/rules-capabilities.generated.ts +48 -7
  1312. package/src/rules/modules/service-bindings.ts +13 -0
  1313. package/src/rules/modules/service-compatibility.ts +10 -18
  1314. package/src/rules/modules/source-expression-analysis.ts +24 -14
  1315. package/src/rules/modules/stdlib/atomic.rules +6 -0
  1316. package/src/rules/modules/stdlib/atomic.test.json +158 -152
  1317. package/src/rules/modules/stdlib/auth.rules +6 -0
  1318. package/src/rules/modules/stdlib/auth.test.json +59 -53
  1319. package/src/rules/modules/stdlib/content.rules +43 -7
  1320. package/src/rules/modules/stdlib/content.test.json +492 -237
  1321. package/src/rules/modules/stdlib/counters.rules +44 -4
  1322. package/src/rules/modules/stdlib/counters.test.json +753 -253
  1323. package/src/rules/modules/stdlib/fairness.rules +56 -0
  1324. package/src/rules/modules/stdlib/fairness.test.json +568 -0
  1325. package/src/rules/modules/stdlib/geometry.rules +71 -0
  1326. package/src/rules/modules/stdlib/geometry.test.json +730 -180
  1327. package/src/rules/modules/stdlib/joining.rules +6 -0
  1328. package/src/rules/modules/stdlib/joining.test.json +341 -287
  1329. package/src/rules/modules/stdlib/lifecycle.rules +44 -1
  1330. package/src/rules/modules/stdlib/lifecycle.test.json +562 -287
  1331. package/src/rules/modules/stdlib/lobby.rules +35 -2
  1332. package/src/rules/modules/stdlib/lobby.test.json +466 -32
  1333. package/src/rules/modules/stdlib/membership.rules +8 -0
  1334. package/src/rules/modules/stdlib/membership.test.json +141 -107
  1335. package/src/rules/modules/stdlib/results.rules +69 -0
  1336. package/src/rules/modules/stdlib/results.test.json +668 -0
  1337. package/src/rules/modules/stdlib/spaces.rules +7 -0
  1338. package/src/rules/modules/stdlib/spaces.test.json +405 -345
  1339. package/src/rules/modules/stdlib/state.rules +7 -0
  1340. package/src/rules/modules/stdlib/state.test.json +83 -55
  1341. package/src/rules/modules/stdlib/storage/metadata.rules +8 -0
  1342. package/src/rules/modules/stdlib/storage/metadata.test.json +104 -43
  1343. package/src/rules/modules/stdlib/storage/objects.rules +58 -2
  1344. package/src/rules/modules/stdlib/storage/objects.test.json +318 -40
  1345. package/src/rules/modules/stdlib/storage/time.rules +6 -0
  1346. package/src/rules/modules/stdlib/storage/time.test.json +38 -32
  1347. package/src/rules/modules/stdlib/storage/uploads.rules +8 -0
  1348. package/src/rules/modules/stdlib/storage/uploads.test.json +70 -38
  1349. package/src/rules/modules/stdlib/timing.rules +5 -0
  1350. package/src/rules/modules/stdlib/timing.test.json +107 -102
  1351. package/src/rules/modules/stdlib/transitions.rules +7 -0
  1352. package/src/rules/modules/stdlib/transitions.test.json +93 -86
  1353. package/src/rules/modules/stdlib/turns.rules +40 -3
  1354. package/src/rules/modules/stdlib/turns.test.json +392 -64
  1355. package/src/rules/modules/stdlib/validation.rules +11 -2
  1356. package/src/rules/modules/stdlib/validation.test.json +180 -172
  1357. package/src/rules/modules/stdlib-content.ts +547 -21
  1358. package/src/rules/modules/stdlib-cost.ts +179 -0
  1359. package/src/rules/modules/stdlib-services.generated.ts +4 -0
  1360. package/src/rules/rtdb/compiled-rules.ts +52 -16
  1361. package/src/rules/rtdb/constraints/atoms.spec.ts +10 -10
  1362. package/src/rules/rtdb/constraints/atoms.ts +13 -13
  1363. package/src/rules/rtdb/constraints/compose.ts +112 -8
  1364. package/src/rules/rtdb/constraints/data.ts +56 -18
  1365. package/src/rules/rtdb/constraints/document.ts +98 -27
  1366. package/src/rules/rtdb/constraints/game.spec.ts +4 -4
  1367. package/src/rules/rtdb/constraints/game.ts +19 -7
  1368. package/src/rules/rtdb/constraints/index.ts +3 -2
  1369. package/src/rules/rtdb/constraints/policies.spec.ts +7 -7
  1370. package/src/rules/rtdb/constraints/policies.ts +24 -8
  1371. package/src/rules/rtdb/constraints/ruleset.ts +84 -40
  1372. package/src/rules/rtdb/constraints/schema.ts +110 -22
  1373. package/src/rules/rtdb/constraints/types.ts +5 -0
  1374. package/src/rules/rtdb/coverage.ts +279 -0
  1375. package/src/rules/rtdb/expression-engine.ts +39 -3
  1376. package/src/rules/rtdb/grammar/RtdbExpr.ohm +24 -9
  1377. package/src/rules/rtdb/grammar/RtdbExpr.ohm.generated.ts +24 -9
  1378. package/src/rules/rtdb/grammar/RtdbExprParser.ts +45 -4
  1379. package/src/rules/rtdb/grammar/canonical.ts +339 -0
  1380. package/src/rules/rtdb/grammar/expression-tree.ts +256 -0
  1381. package/src/rules/rtdb/grammar/linter.ts +207 -20
  1382. package/src/rules/rtdb/grammar/ruleset-lint.ts +578 -0
  1383. package/src/rules/rtdb/grammar/simulator.ts +272 -84
  1384. package/src/rules/rtdb/grammar/string-literal.ts +145 -0
  1385. package/src/rules/rtdb/grammar/type-rules.ts +76 -0
  1386. package/src/rules/rtdb/grammar/types.ts +282 -0
  1387. package/src/rules/rtdb/grammar/validator.ts +285 -60
  1388. package/src/rules/rtdb/index-lookup.ts +43 -0
  1389. package/src/rules/rtdb/rules-diff.ts +118 -0
  1390. package/src/rules/rtdb/rules-text.ts +162 -0
  1391. package/src/rules/rtdb/simulation/handler.ts +206 -287
  1392. package/src/rules/rtdb/simulation/post-write-tree.ts +102 -0
  1393. package/src/rules/rtdb/simulation/spec.ts +80 -1
  1394. package/src/rules/rtdb/source-locations.ts +264 -0
  1395. package/src/rules/rtdb/source-rejection.ts +50 -0
  1396. package/src/rules/rtdb/stdlib/auth.ts +96 -0
  1397. package/src/rules/rtdb/stdlib/catalog.ts +299 -0
  1398. package/src/rules/rtdb/stdlib/collections.ts +35 -0
  1399. package/src/rules/rtdb/stdlib/counters.ts +97 -0
  1400. package/src/rules/rtdb/stdlib/expr.ts +56 -0
  1401. package/src/rules/rtdb/stdlib/index.ts +40 -0
  1402. package/src/rules/rtdb/stdlib/lifecycle.ts +91 -0
  1403. package/src/rules/rtdb/stdlib/lobby.ts +107 -0
  1404. package/src/rules/rtdb/stdlib/membership.ts +46 -0
  1405. package/src/rules/rtdb/stdlib/presence.ts +59 -0
  1406. package/src/rules/rtdb/stdlib/results.ts +67 -0
  1407. package/src/rules/rtdb/stdlib/timing.ts +140 -0
  1408. package/src/rules/rtdb/stdlib/turns.ts +71 -0
  1409. package/src/rules/rtdb/stdlib/validation.ts +149 -0
  1410. package/src/rules/rtdb/structure.ts +78 -0
  1411. package/src/rules/rtdb/types.ts +16 -0
  1412. package/src/rules/simulator/conversions.ts +142 -0
  1413. package/src/rules/simulator/document-lookups.ts +20 -9
  1414. package/src/rules/simulator/eval-error.ts +28 -0
  1415. package/src/rules/simulator/evaluation-builtins.ts +350 -309
  1416. package/src/rules/simulator/evaluation-context.ts +14 -0
  1417. package/src/rules/simulator/evaluator.ts +221 -157
  1418. package/src/rules/simulator/expression-budget.ts +132 -0
  1419. package/src/rules/simulator/firestore-set.ts +90 -15
  1420. package/src/rules/simulator/firestore-values.ts +120 -8
  1421. package/src/rules/simulator/handler.ts +288 -86
  1422. package/src/rules/simulator/hashing-builtins.ts +179 -11
  1423. package/src/rules/simulator/index-access.ts +137 -0
  1424. package/src/rules/simulator/list-methods.ts +109 -0
  1425. package/src/rules/simulator/list-query-proof.ts +421 -0
  1426. package/src/rules/simulator/list-rule-path-proof.ts +201 -0
  1427. package/src/rules/simulator/lookup-budget.ts +42 -7
  1428. package/src/rules/simulator/map-keys.ts +93 -0
  1429. package/src/rules/simulator/mapdiff.ts +6 -5
  1430. package/src/rules/simulator/match-resolution.ts +119 -37
  1431. package/src/rules/simulator/math-builtins.ts +86 -0
  1432. package/src/rules/simulator/membership.ts +42 -0
  1433. package/src/rules/simulator/project-after-state.ts +16 -11
  1434. package/src/rules/simulator/query-proof-residual.ts +326 -62
  1435. package/src/rules/simulator/query-proof.ts +73 -56
  1436. package/src/rules/simulator/rules-type.ts +475 -0
  1437. package/src/rules/simulator/slice-bounds.ts +21 -0
  1438. package/src/rules/simulator/value-equality.ts +85 -18
  1439. package/src/rules/simulator/wrappers/bytes.ts +12 -4
  1440. package/src/rules/simulator/wrappers/duration.ts +7 -3
  1441. package/src/rules/simulator/wrappers/float.ts +36 -6
  1442. package/src/rules/simulator/wrappers/latlng.ts +11 -2
  1443. package/src/rules/simulator/wrappers/path.ts +9 -32
  1444. package/src/rules/simulator/wrappers/timestamp.ts +33 -2
  1445. package/src/rules/simulator-tools-impl.ts +1 -1
  1446. package/src/rules/simulator.ts +1 -1
  1447. package/src/rules/stdlib-modules.ts +363 -27
  1448. package/src/rules/stdlib-tools.ts +123 -20
  1449. package/src/rules/test/spec.ts +89 -6
  1450. package/src/rules/tools.ts +1 -1
  1451. package/src/sandbox/admin-firestore/error-translation.ts +18 -6
  1452. package/src/sandbox/admin-firestore/listeners.ts +32 -5
  1453. package/src/sandbox/admin-firestore/remote/batch.ts +31 -6
  1454. package/src/sandbox/admin-firestore/remote/channel.ts +3 -3
  1455. package/src/sandbox/admin-firestore/remote/doc-ref.ts +13 -3
  1456. package/src/sandbox/admin-firestore/remote/remote-firestore.ts +3 -3
  1457. package/src/sandbox/admin-firestore/remote/snapshots.ts +2 -3
  1458. package/src/sandbox/admin-firestore/remote/transaction.ts +25 -5
  1459. package/src/sandbox/admin-firestore/remote/value-codec.ts +7 -0
  1460. package/src/sandbox/admin-firestore/remote/wire-types.ts +8 -1
  1461. package/src/sandbox/attribution/listener-owners.ts +48 -33
  1462. package/src/sandbox/attribution/owner-frames.ts +119 -0
  1463. package/src/sandbox/branches/engine.ts +5 -4
  1464. package/src/sandbox/branches/promotion.ts +17 -4
  1465. package/src/sandbox/branches/store.ts +14 -0
  1466. package/src/sandbox/checkpoints/capture.ts +5 -2
  1467. package/src/sandbox/full-state.ts +62 -6
  1468. package/src/sandbox/index.ts +3 -0
  1469. package/src/sandbox/internal/auth-token-claims.ts +189 -0
  1470. package/src/sandbox/internal/database-rules-config.ts +184 -0
  1471. package/src/sandbox/internal/index.ts +66 -0
  1472. package/src/sandbox/internal/inline-storage-limit.ts +103 -0
  1473. package/src/sandbox/internal/instances.ts +314 -0
  1474. package/src/sandbox/internal/process-activation.ts +70 -0
  1475. package/src/sandbox/internal/sandbox-activation.ts +44 -0
  1476. package/src/sandbox/internal/sandbox-impl.ts +11 -3
  1477. package/src/sandbox/internal/sdk-activity.ts +2 -0
  1478. package/src/sandbox/internal/sentence.ts +8 -0
  1479. package/src/sandbox/internal/tool-handler.ts +42 -0
  1480. package/src/sandbox/persistence/controller.ts +6 -2
  1481. package/src/sandbox/replay/index.ts +337 -43
  1482. package/src/sandbox/tab-sync/index.ts +3 -3
  1483. package/src/sandbox/types/errors.ts +52 -1
  1484. package/src/sandbox/types/events.ts +55 -6
  1485. package/src/sandbox/types/index.ts +3 -0
  1486. package/src/sandbox/types/query-proof.ts +5 -26
  1487. package/src/sandbox/types/service-mutation-event.ts +6 -0
  1488. package/src/sandbox/types/service.ts +6 -2
  1489. package/src/storage/admin/tools.ts +2 -2
  1490. package/src/storage/content-defaults.ts +55 -0
  1491. package/src/storage/copy.ts +55 -0
  1492. package/src/storage/download.ts +33 -0
  1493. package/src/storage/enforce.ts +1 -0
  1494. package/src/storage/errors.ts +2 -1
  1495. package/src/storage/generation.ts +59 -0
  1496. package/src/storage/internal.ts +18 -2
  1497. package/src/storage/metadata.ts +15 -12
  1498. package/src/storage/persistence.ts +273 -87
  1499. package/src/storage/remote-bytes.ts +10 -1
  1500. package/src/storage/resumable.ts +140 -44
  1501. package/src/storage/rules-resolution.ts +104 -1
  1502. package/src/storage/sandbox/persistence-state.ts +10 -4
  1503. package/src/storage/sandbox/rules-bindings.ts +17 -4
  1504. package/src/storage/sandbox/rules-collection-methods.ts +92 -61
  1505. package/src/storage/sandbox/rules-evaluation-error.ts +18 -4
  1506. package/src/storage/sandbox/rules-evaluator.ts +327 -178
  1507. package/src/storage/sandbox/rules-firestore-lookup.ts +98 -24
  1508. package/src/storage/sandbox/rules-hashing-methods.ts +4 -3
  1509. package/src/storage/sandbox/rules-latlng.ts +140 -0
  1510. package/src/storage/sandbox/rules-math-methods.ts +19 -0
  1511. package/src/storage/sandbox/rules-method-calls.ts +17 -10
  1512. package/src/storage/sandbox/rules-methods.ts +20 -7
  1513. package/src/storage/sandbox/rules-operators.ts +72 -20
  1514. package/src/storage/sandbox/rules-path-match.ts +17 -9
  1515. package/src/storage/sandbox/rules-path.ts +91 -0
  1516. package/src/storage/sandbox/rules-resources.ts +69 -15
  1517. package/src/storage/sandbox/rules-string-methods.ts +71 -9
  1518. package/src/storage/sandbox/rules-time-methods.ts +35 -11
  1519. package/src/storage/sandbox/rules-values.ts +0 -54
  1520. package/src/storage/sandbox/rules.ts +154 -35
  1521. package/src/storage/service.ts +46 -11
  1522. package/src/storage/upload-rollback.ts +185 -0
  1523. package/src/storage/upload.ts +76 -29
@@ -10,6 +10,10 @@
10
10
 
11
11
  export const STDLIB_INLINE: Record<string, string> = {
12
12
  "atomic": `// @pyric-services cloud.firestore
13
+ // Costs are production expressions per call, not counting arguments. Calls
14
+ // are not memoized: every call pays its full cost again, and a let inside a
15
+ // function is paid on every call.
16
+ //
13
17
  // Atomic module — cross-document integrity for BATCH writes, via the
14
18
  // get()/getAfter() pair. Firestore evaluates every write in a batch
15
19
  // against rules, and getAfter() returns another document's POST-BATCH
@@ -52,6 +56,7 @@ export const STDLIB_INLINE: Record<string, string> = {
52
56
 
53
57
  // The companion doc's field changed by EXACTLY n in this batch.
54
58
  // before/after are the SAME doc's get()/getAfter() data.
59
+ // cost 10 to 10 expressions per call
55
60
  export function companionChangedBy(before, after, field, n) {
56
61
  return after[field] == before[field] + n;
57
62
  }
@@ -59,27 +64,38 @@ export function companionChangedBy(before, after, field, n) {
59
64
  // A single-use flag was consumed IN THIS BATCH: pre-batch false,
60
65
  // post-batch true. Replays deny (pre-batch is already true), and a
61
66
  // solo write denies (getAfter == get, so false != true).
67
+ // cost 7 to 13 expressions per call
62
68
  export function consumedFlag(before, after, flagField) {
63
69
  return before[flagField] == false && after[flagField] == true;
64
70
  }
65
71
  `,
66
72
  "auth": `// @pyric-services cloud.firestore,firebase.storage
67
73
  // @pyric-evidence storage-rules#125,firestore-rules#189
74
+ // Costs are production expressions per call, not counting arguments. Calls
75
+ // are not memoized: every call pays its full cost again, and a let inside a
76
+ // function is paid on every call.
77
+ //
78
+ // cost 5 to 5 expressions per call
68
79
  export function isAuthenticated() {
69
80
  return request.auth != null;
70
81
  }
71
82
 
83
+ // cost 7 to 13 expressions per call
72
84
  export function isOwner(userId) {
73
85
  return isAuthenticated() && request.auth.uid == userId;
74
86
  }
75
87
  `,
76
88
  "content": `// @pyric-services cloud.firestore
77
- // Content module for author-owned documents — the most common
89
+ // Costs are production expressions per call, not counting arguments. Calls
90
+ // are not memoized: every call pays its full cost again, and a let inside a
91
+ // function is paid on every call.
92
+ //
93
+ // Content module for author-owned documents, the most common
78
94
  // Firebase app shape (posts, notes, docs, comments, tasks).
79
95
  //
80
96
  // Convention: documents carry an author field (a UID string) and
81
97
  // usually a status field ('draft' | 'published' | ...). Field names
82
- // are parameters, not conventions — pass yours.
98
+ // are parameters, not conventions: pass yours.
83
99
  //
84
100
  // Usage:
85
101
  // import { validAuthorCreate, isAuthor, canReadContent, notDeleted } from 'content';
@@ -94,9 +110,23 @@ export function isOwner(userId) {
94
110
  // allow update: if isAuthor('author') && onlyFieldsChanged(['title', 'body', 'status']);
95
111
  // allow delete: if isAuthor('author');
96
112
  // }
113
+ //
114
+ // Hidden per-player documents: a fleet, a hand or a secret pick that only
115
+ // its owner reads until the match ends. The document lives under its match,
116
+ // at {collection}/{matchId}/{sub}/{uid}: the document id is the owner's UID,
117
+ // and the parent match document carries a \`status\` field. When your owner is
118
+ // a field instead, pass resource.data.<field> as the owner.
119
+ //
120
+ // import { ownerOnlyUntil } from 'content';
121
+ //
122
+ // match /battleship/{matchId}/boards/{uid} {
123
+ // allow read: if ownerOnlyUntil(
124
+ // /databases/$(database)/documents/battleship/$(matchId), uid, ['won', 'resigned']);
125
+ // }
97
126
 
98
127
  // Create guard: signed in, and the incoming doc's author field is the
99
128
  // caller. Use on \`create\` (reads request.resource).
129
+ // cost 6 to 16 expressions per call
100
130
  export function validAuthorCreate(authorField) {
101
131
  return request.auth != null
102
132
  && request.resource.data[authorField] == request.auth.uid;
@@ -104,6 +134,7 @@ export function validAuthorCreate(authorField) {
104
134
 
105
135
  // The caller is the EXISTING document's author. Use on update/delete
106
136
  // (reads resource).
137
+ // cost 6 to 15 expressions per call
107
138
  export function isAuthor(authorField) {
108
139
  return request.auth != null
109
140
  && resource.data[authorField] == request.auth.uid;
@@ -111,31 +142,52 @@ export function isAuthor(authorField) {
111
142
 
112
143
  // Read visibility: published content is public; anything else is
113
144
  // visible to its author only. Works for get; for list queries the
114
- // client must filter (rules are not filters — a bare collection query
115
- // will be denied unless it proves status == 'published').
145
+ // client must filter (rules are not filters: a bare collection query
146
+ // is denied unless it proves status == 'published').
147
+ // cost 8 to 23 expressions per call
116
148
  export function canReadContent(statusField, authorField) {
117
149
  return resource.data[statusField] == 'published'
118
150
  || (request.auth != null && resource.data[authorField] == request.auth.uid);
119
151
  }
120
152
 
121
153
  // Soft-delete guard: the document is not marked deleted. Reads the
122
- // EXISTING doc; a doc without the field passes — bracket access is
123
- // the null-on-miss idiom (dotted access of a missing key ERRORS).
154
+ // EXISTING doc. A doc without the field passes: map.get() returns the
155
+ // default for a missing key, while dotted or bracket access of a missing
156
+ // key is an error in production and denies.
157
+ // cost 8 to 8 expressions per call
124
158
  export function notDeleted() {
125
- return resource.data['deleted'] != true;
159
+ return resource.data.get('deleted', false) != true;
160
+ }
161
+
162
+ // Read rule for a hidden per-player document: the owner reads it at any
163
+ // time, and any other signed-in caller reads it once the status of the match
164
+ // at \`parentPath\` is in \`statuses\`. Pass one status as a one-item list, such
165
+ // as ['finished'], or several, such as ['won', 'draw', 'resigned']. The owner
166
+ // check runs before the get(), so the owner's read stops there and spends no
167
+ // read. A missing parent match is an error and denies every caller but the
168
+ // owner.
169
+ // cost 6 to 20 expressions per call, reads 1
170
+ export function ownerOnlyUntil(parentPath, ownerUid, statuses) {
171
+ return request.auth != null
172
+ && (request.auth.uid == ownerUid
173
+ || get(parentPath).data.status in statuses);
126
174
  }
127
175
  `,
128
176
  "counters": `// @pyric-services cloud.firestore
177
+ // Costs are production expressions per call, not counting arguments. Calls
178
+ // are not memoized: every call pays its full cost again, and a let inside a
179
+ // function is paid on every call.
180
+ //
129
181
  // Counters module for denormalized numeric integrity.
130
182
  //
131
183
  // The recurring shape: a client-maintained count (likes, votes, moves,
132
- // quantities) that rules must keep honest — it may only change by a
184
+ // quantities) that rules must keep honest: it may only change by a
133
185
  // known step, or stay within known bounds. Generalizes the
134
186
  // state-module's moveIncremented() (hardcoded to moveCount) to any
135
187
  // field.
136
188
  //
137
189
  // Usage:
138
- // import { incrementedBy, changedBy, boundedNumber } from 'counters';
190
+ // import { incrementedBy, changedBy, boundedNumber, improvedBy } from 'counters';
139
191
  //
140
192
  // // A like toggle: likeCount moves by exactly ±1:
141
193
  // allow update: if changedBy('likeCount', -1, 1);
@@ -145,30 +197,127 @@ export function notDeleted() {
145
197
  //
146
198
  // // A rating: any write keeps it in [1, 5]:
147
199
  // allow write: if boundedNumber('rating', 1, 5);
200
+ //
201
+ // // A best score: a new score replaces the old one only when it is
202
+ // // higher, and only the score and its solve id change:
203
+ // allow update: if improvedBy('score', 'up', ['solve']);
204
+ //
205
+ // A best-score check: improvedBy(field, direction, mayChange) allows an
206
+ // update where \`field\` moves strictly 'up' or 'down' and every other
207
+ // changed top-level field is in \`mayChange\`. Write the score's shape
208
+ // checks (type, bounds, owner) beside it: improvedBy only compares the
209
+ // old and new values and pins the unlisted fields. For a score ranked on
210
+ // two fields, such as fewest moves and then fewest pushes, call it once
211
+ // per field. The second call leaves \`moves\` out of \`mayChange\`, so it
212
+ // allows fewer pushes only on as many moves:
213
+ // improvedBy('moves', 'down', ['pushes', 'solve'])
214
+ // || improvedBy('pushes', 'down', ['solve'])
148
215
 
149
216
  // The field changed by EXACTLY n relative to the existing document.
150
217
  // n may be negative (decrement). Update rules only (needs resource).
218
+ // cost 13 to 13 expressions per call
151
219
  export function incrementedBy(field, n) {
152
220
  return request.resource.data[field] == resource.data[field] + n;
153
221
  }
154
222
 
155
223
  // The field's delta is within [min, max] (inclusive) — and it is NOT
156
224
  // required to change (delta 0 passes when min <= 0 <= max).
225
+ // cost 14 to 27 expressions per call
157
226
  export function changedBy(field, min, max) {
158
227
  return request.resource.data[field] - resource.data[field] >= min
159
228
  && request.resource.data[field] - resource.data[field] <= max;
160
229
  }
161
230
 
162
231
  // The incoming value is a number within [min, max] (inclusive).
163
- // Works on create and update. Missing field reads null (dynamic
164
- // access) and fails the type check rather than erroring.
232
+ // Works on create and update. A missing field is an error under dynamic
233
+ // access, so the call denies.
234
+ // cost 19 to 35 expressions per call
165
235
  export function boundedNumber(field, min, max) {
166
236
  return (request.resource.data[field] is int || request.resource.data[field] is float)
167
237
  && request.resource.data[field] >= min
168
238
  && request.resource.data[field] <= max;
169
239
  }
240
+
241
+ // The numeric \`field\` moved strictly in \`direction\`, 'up' or 'down', and no
242
+ // other top-level field changed except the ones in \`mayChange\`, a List. A
243
+ // listed field may stay unchanged. Both values must be numbers, int or
244
+ // float; they compare by value. An unchanged value, a move the other way, a
245
+ // non-numeric value on either side, an unlisted field added, removed, or
246
+ // changed, and any other direction make the call false. A field missing
247
+ // from either document is an error in production, which denies, and stays
248
+ // an error under \`!\`. Update rules only: on create the call is an error and
249
+ // the rule denies.
250
+ // cost 18 to 50 expressions per call
251
+ export function improvedBy(field, direction, mayChange) {
252
+ let before = resource.data[field];
253
+ let after = request.resource.data[field];
254
+ return before is number && after is number
255
+ && ((direction == 'up' && after > before) || (direction == 'down' && after < before))
256
+ && request.resource.data.diff(resource.data).affectedKeys().hasOnly(mayChange.concat([field]));
257
+ }
258
+ `,
259
+ "fairness": `// @pyric-services cloud.firestore
260
+ // Costs are production expressions per call, not counting arguments. Calls
261
+ // are not memoized: every call pays its full cost again, and a let inside a
262
+ // function is paid on every call.
263
+ //
264
+ // Fairness for hidden choices and commit-reveal randomness: a player commits
265
+ // to a secret salt before the other players add their input, then reveals
266
+ // the salt. The rules check the reveal against the commitment and derive
267
+ // values from a digest.
268
+ //
269
+ // Convention: commit-reveal as Yacht stores it:
270
+ // commit: string, the uppercase hex SHA-256 of the salt, the form
271
+ // hashing.sha256(salt).toHexString() produces (64 characters)
272
+ // salt: string, the secret, written on the reveal
273
+ //
274
+ // The commitment is a hex string, not Bytes, because the client computes it
275
+ // and writes it as a string field. A commitment stored as Bytes, or as
276
+ // lowercase hex, does not match. The salt is hashed as its UTF-8 bytes.
277
+ //
278
+ // Production Bytes have no index operator: digest[0] is an error.
279
+ // digestByte reads the byte from the digest's hex string instead, two
280
+ // characters per byte, and pays for a 16-entry lookup map on every call.
281
+ //
282
+ // Usage:
283
+ // import { commitmentMatches, digestByte } from 'fairness';
284
+ //
285
+ // // The reveal matches the commitment stored by the commit write:
286
+ // allow update: if commitmentMatches(resource.data.commit, request.resource.data.salt);
287
+ //
288
+ // // A die face from the digest of the salt and another player's nonce:
289
+ // allow update: if request.resource.data.die
290
+ // == digestByte(hashing.sha256(request.resource.data.salt + resource.data.nonce), 0) % 6 + 1;
291
+
292
+ // The salt is a non-empty string and its SHA-256, as uppercase hex, equals
293
+ // \`commitment\`. An empty salt is refused because anyone can compute its
294
+ // digest, so it hides nothing.
295
+ // cost 6 to 16 expressions per call
296
+ export function commitmentMatches(commitment, salt) {
297
+ return salt is string
298
+ && salt != ''
299
+ && hashing.sha256(salt).toHexString() == commitment;
300
+ }
301
+
302
+ // Byte \`index\` of the Bytes value \`digest\`, as an int from 0 to 255. An
303
+ // index outside the digest, or a digest that is not Bytes, is an error, so
304
+ // the rule that uses the value denies. A die face is digestByte(d, i) % 6 + 1:
305
+ // 256 is not a multiple of 6, so faces 1 to 4 come up 43 times in 256 and
306
+ // faces 5 and 6 come up 42 times. Read a new index for each value.
307
+ // cost 63 to 63 expressions per call
308
+ export function digestByte(digest, index) {
309
+ let hex = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7,
310
+ '8': 8, '9': 9, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15};
311
+ let h = digest.toHexString();
312
+ let i = index * 2;
313
+ return hex[h[i:i + 1]] * 16 + hex[h[i + 1:i + 2]];
314
+ }
170
315
  `,
171
316
  "geometry": `// @pyric-services cloud.firestore
317
+ // Costs are production expressions per call, not counting arguments. Calls
318
+ // are not memoized: every call pays its full cost again, and a let inside a
319
+ // function is paid on every call.
320
+ //
172
321
  // Geometry module for movement game validation via config document lookup.
173
322
  //
174
323
  // Caller must pass the config document data as an explicit parameter.
@@ -191,10 +340,43 @@ export function boundedNumber(field, min, max) {
191
340
  //
192
341
  // allow update: if validJumpMove(config())
193
342
  // && captureValid() && captureDecrement() && moveIntegrity();
343
+ //
344
+ // Named squares: file, rank, step and inBounds read squares named the way
345
+ // chess and checkers name them, on an 8 by 8 board.
346
+ //
347
+ // Convention: a square is a string of two characters:
348
+ // file: 'a' to 'h', left to right; file() reads 'a' as 1 and 'h' as 8
349
+ // rank: '1' to '8', bottom to top; rank() reads '1' as 1
350
+ //
351
+ // file, rank and step read a square; they don't check it. A malformed
352
+ // square is an error, which denies, except that rank reads only the second
353
+ // character, so rank('e9') is 9 and rank('e44') is 4. Call inBounds on a
354
+ // square the client wrote before you trust it. A board keyed by rank and
355
+ // file digits, such as '34' for rank 3 and file 4, needs none of these:
356
+ // string(int(sq) + 10 * dr + df) is the step.
357
+ //
358
+ // Each costs what the same check costs written inline: file 23 and rank 6,
359
+ // the same map lookup and int(). step(from, df, dr) == to costs 51, where
360
+ // the same test written as file and rank differences costs 53 to 71. To
361
+ // test that \`to\` is any one diagonal neighbor of \`from\`, compare file and
362
+ // rank differences (73 to 145) rather than calling step four times (over
363
+ // 200 when none match).
364
+ //
365
+ // Usage:
366
+ // import { file, rank, step, inBounds } from 'geometry';
367
+ //
368
+ // // The piece moves one square diagonally forward:
369
+ // allow update: if inBounds(request.resource.data.to)
370
+ // && (request.resource.data.to == step(resource.data.from, 1, 1)
371
+ // || request.resource.data.to == step(resource.data.from, -1, 1));
372
+ //
373
+ // // A man crowns only on the far rank:
374
+ // allow update: if rank(request.resource.data.to) == 8;
194
375
 
195
376
  // Validate a simple (non-capture) move via config document lookup.
196
377
  // Uses 3-level dynamic nesting: cfg.moves[piece][from][to].
197
378
  // piece comes from resource.data (pre-write board) so client can't fake it.
379
+ // cost 26 to 26 expressions per call
198
380
  export function validSimpleMove(cfg) {
199
381
  let mf = request.resource.data.moveFrom;
200
382
  let mt = request.resource.data.moveTo;
@@ -205,6 +387,7 @@ export function validSimpleMove(cfg) {
205
387
  // Validate a jump (capture) move via config document lookup.
206
388
  // cfg.jumps[piece][from][to] returns the expected captured cell name.
207
389
  // Caller must separately verify the captured piece is an opponent piece.
390
+ // cost 31 to 31 expressions per call
208
391
  export function validJumpMove(cfg) {
209
392
  let mf = request.resource.data.moveFrom;
210
393
  let mt = request.resource.data.moveTo;
@@ -212,8 +395,45 @@ export function validJumpMove(cfg) {
212
395
  let piece = resource.data[mf];
213
396
  return cfg.jumps[piece][mf][mt] == cap;
214
397
  }
398
+
399
+ // The file of a square as a number, 'a' is 1 and 'h' is 8. A first
400
+ // character outside 'a' to 'h', an empty string, or a non-string square is
401
+ // an error, which denies.
402
+ // cost 23 to 23 expressions per call
403
+ export function file(square) {
404
+ return {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8}[square[0:1]];
405
+ }
406
+
407
+ // The rank of a square as a number: the second character read as a digit.
408
+ // A second character that is not a digit, a square shorter than two
409
+ // characters, or a non-string square is an error, which denies.
410
+ // cost 6 to 6 expressions per call
411
+ export function rank(square) {
412
+ return int(square[1:2]);
413
+ }
414
+
415
+ // The square \`df\` files and \`dr\` ranks away from \`square\`, as a name. A
416
+ // step off the board in any direction is an error, which denies.
417
+ // cost 49 to 49 expressions per call
418
+ export function step(square, df, dr) {
419
+ let f = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7}[square[0:1]] + df;
420
+ let r = int(square[1:2]) - 1 + dr;
421
+ return 'abcdefgh'[f:f + 1] + '12345678'[r:r + 1];
422
+ }
423
+
424
+ // The square names a square of the board: a string of one file letter
425
+ // 'a' to 'h' and one rank digit '1' to '8'. Anything else, a non-string
426
+ // included, is false.
427
+ // cost 5 to 9 expressions per call
428
+ export function inBounds(square) {
429
+ return square is string && square.matches('[a-h][1-8]');
430
+ }
215
431
  `,
216
432
  "joining": `// @pyric-services cloud.firestore
433
+ // Costs are production expressions per call, not counting arguments. Calls
434
+ // are not memoized: every call pays its full cost again, and a let inside a
435
+ // function is paid on every call.
436
+ //
217
437
  // Joining module — how membership CHANGES, safely. The connective
218
438
  // tissue between content/spaces: spaces gates children behind a
219
439
  // members field; joining lets users enter and leave that field
@@ -245,6 +465,7 @@ export function validJumpMove(cfg) {
245
465
 
246
466
  // The write adds EXACTLY the caller to the members map, at EXACTLY
247
467
  // \`role\`, changing and removing nobody. Update rules only.
468
+ // cost 20 to 53 expressions per call
248
469
  export function onlyAddedSelf(membersField, role) {
249
470
  let diff = request.resource.data[membersField].diff(resource.data[membersField]);
250
471
  return request.auth != null
@@ -256,6 +477,7 @@ export function onlyAddedSelf(membersField, role) {
256
477
 
257
478
  // The write removes EXACTLY the caller from the members map, adding
258
479
  // and changing nobody. Self-service leave. Update rules only.
480
+ // cost 19 to 40 expressions per call
259
481
  export function onlyRemovedSelf(membersField) {
260
482
  let diff = request.resource.data[membersField].diff(resource.data[membersField]);
261
483
  return request.auth != null
@@ -265,13 +487,17 @@ export function onlyRemovedSelf(membersField) {
265
487
  }
266
488
  `,
267
489
  "lifecycle": `// @pyric-services cloud.firestore
490
+ // Costs are production expressions per call, not counting arguments. Calls
491
+ // are not memoized: every call pays its full cost again, and a let inside a
492
+ // function is paid on every call.
493
+ //
268
494
  // Lifecycle module for field immutability and timestamp enforcement.
269
495
  //
270
496
  // Common pattern: certain fields must never change after document creation
271
497
  // (createdBy, createdAt, authorId).
272
498
  //
273
499
  // Usage:
274
- // import { fieldUnchanged, immutableFields, isServerTimestamp } from 'lifecycle';
500
+ // import { fieldUnchanged, immutableFields, onlyFieldsChanged, exactlyChanged, isServerTimestamp } from 'lifecycle';
275
501
  //
276
502
  // // Single field:
277
503
  // allow update: if fieldUnchanged('createdBy');
@@ -282,22 +508,49 @@ export function onlyRemovedSelf(membersField) {
282
508
  // // The dual: users may edit title/body but NOTHING else:
283
509
  // allow update: if onlyFieldsChanged(['title', 'body']);
284
510
  //
511
+ // // Every listed field changes and nothing else does:
512
+ // allow update: if exactlyChanged(['board', 'lastMove', 'currentTurn', 'moveCount']);
513
+ //
285
514
  // allow create: if isServerTimestamp('createdAt');
515
+ //
516
+ // Changed-key checks: each one compares the set of top-level keys the write
517
+ // adds, removes, or changes against the keys you pass, as a List or a Set.
518
+ // onlyFieldsChanged(keys): the changed keys are a subset of \`keys\`. A
519
+ // listed key may stay unchanged. Use it when a transition may leave
520
+ // some listed fields alone, such as the move checks in reversi, chess,
521
+ // and checkers, where status and winner change only on the last move.
522
+ // exactlyChanged(keys): the changed keys equal \`keys\`. Every listed key
523
+ // changes. Use it when each transition always writes the same fields,
524
+ // such as a tic-tac-toe move, which changes board, lastMove,
525
+ // currentTurn, and moveCount, and never status or winner. In
526
+ // tic-tac-toe it replaces one affectedKeys().hasOnly([...]) shared by
527
+ // the move, win, and draw rules with one list per rule: a win adds
528
+ // status and winner, and a draw adds status.
529
+ // Both read resource.data, so on create, where there is no existing
530
+ // document, the call is an error and the rule denies. On create, check
531
+ // request.resource.data.keys() instead.
532
+ //
533
+ // A "the move squares changed" check on a nested map, such as
534
+ // board.diff(resource.data.board), is not a top-level diff: write it in the
535
+ // game with diff() on the two maps.
286
536
 
287
537
  // Ensure a field's value is identical between existing and incoming document.
288
538
  // Use on update rules to enforce immutability.
539
+ // cost 11 to 11 expressions per call
289
540
  export function fieldUnchanged(field) {
290
541
  return resource.data[field] == request.resource.data[field];
291
542
  }
292
543
 
293
544
  // Ensure multiple fields are unchanged between existing and incoming document.
294
545
  // Uses MapDiff — one expression instead of N chained fieldUnchanged() calls.
546
+ // cost 10 to 10 expressions per call
295
547
  export function immutableFields(fields) {
296
548
  return request.resource.data.diff(resource.data).unchangedKeys().hasAll(fields);
297
549
  }
298
550
 
299
551
  // Ensure a field is set to the server timestamp.
300
552
  // Use on create or update rules to enforce server-side time.
553
+ // cost 9 to 9 expressions per call
301
554
  export function isServerTimestamp(field) {
302
555
  return request.resource.data[field] == request.time;
303
556
  }
@@ -306,6 +559,7 @@ export function isServerTimestamp(field) {
306
559
  // list (fields NOT listed are implicitly immutable). Top-level keys
307
560
  // only — nested-map diffs are unreliable in production; flatten the
308
561
  // schema instead of reaching for a nested diff.
562
+ // cost 10 to 10 expressions per call
309
563
  export function onlyFieldsChanged(fields) {
310
564
  return request.resource.data.diff(resource.data).affectedKeys().hasOnly(fields);
311
565
  }
@@ -313,24 +567,50 @@ export function onlyFieldsChanged(fields) {
313
567
  // Exactly n top-level fields changed in this write. n == 1 is the
314
568
  // board-integrity / edit-one-field-per-write guard (Pattern 5,
315
569
  // generalized beyond games).
570
+ // cost 11 to 11 expressions per call
316
571
  export function nFieldsChanged(n) {
317
572
  return request.resource.data.diff(resource.data).affectedKeys().size() == n;
318
573
  }
574
+
575
+ // The top-level fields this write adds, removes, or changes are exactly
576
+ // \`keys\`, a List or a Set: every listed field changed and no other field
577
+ // did. A key listed twice counts once. An empty \`keys\` allows only a write
578
+ // that changes nothing. On create the call is an error, so the rule denies.
579
+ // cost 13 to 17 expressions per call
580
+ export function exactlyChanged(keys) {
581
+ let changed = request.resource.data.diff(resource.data).affectedKeys();
582
+ return changed.hasAll(keys) && changed.hasOnly(keys);
583
+ }
319
584
  `,
320
585
  "lobby": `// @pyric-services cloud.firestore
586
+ // Costs are production expressions per call, not counting arguments. Calls
587
+ // are not memoized: every call pays its full cost again, and a let inside a
588
+ // function is paid on every call.
589
+ //
321
590
  // Lobby module for 2-participant coordination.
322
591
  //
323
592
  // Convention: documents must have these fields:
324
593
  // host: string (creator's UID)
325
594
  // guest: string ('' when waiting, joiner's UID when joined)
326
- // status: 'waiting' | 'playing' | 'ready' (or any active state)
595
+ // status: 'waiting' | 'playing' | 'ready' (or any active state);
596
+ // 'won' | 'draw' | 'resigned' once finished
597
+ //
598
+ // Rematch convention: the player who asks for a rematch hosts the new match,
599
+ // which opens like any other lobby: guest '' and status 'waiting'. Either
600
+ // seat of the finished match can ask, so the seats swap when the guest asks.
601
+ // The other player takes the open seat through validJoin. Tic-tac-toe, Chess
602
+ // and Reversi start their rematches this way.
327
603
  //
328
604
  // Usage:
329
- // import { validCreate, validJoin, canCancel } from 'lobby';
605
+ // import { validCreate, validJoin, canCancel, validRematch } from 'lobby';
330
606
  //
331
607
  // allow create: if validCreate();
332
608
  // allow update: if validJoin();
333
609
  // allow delete: if canCancel();
610
+ //
611
+ // // A new match that names the finished match it follows in \`rematchOf\`:
612
+ // allow create: if validRematch(
613
+ // /databases/$(database)/documents/matches/$(request.resource.data.rematchOf));
334
614
 
335
615
  // Is this a waiting lobby with an open seat?
336
616
  function isWaiting() {
@@ -339,6 +619,7 @@ function isWaiting() {
339
619
  }
340
620
 
341
621
  // Create: caller is host, seat empty, status waiting
622
+ // cost 8 to 31 expressions per call
342
623
  export function validCreate() {
343
624
  return request.auth != null
344
625
  && request.resource.data.host == request.auth.uid
@@ -347,6 +628,7 @@ export function validCreate() {
347
628
  }
348
629
 
349
630
  // Join: fill empty seat, transition to next status, no self-join
631
+ // cost 10 to 57 expressions per call
350
632
  export function validJoin() {
351
633
  return request.auth != null
352
634
  && isWaiting()
@@ -357,14 +639,34 @@ export function validJoin() {
357
639
  }
358
640
 
359
641
  // Cancel: only host, only while waiting
642
+ // cost 7 to 21 expressions per call
360
643
  export function canCancel() {
361
644
  return request.auth != null
362
645
  && resource.data.status == 'waiting'
363
646
  && request.auth.uid == resource.data.host;
364
647
  }
648
+
649
+ // Rematch: the finished match at \`previousPath\` ('won', 'draw' or
650
+ // 'resigned') seated the caller as host or guest, and the new match opens
651
+ // with the caller as host, the other seat open and status 'waiting'. A
652
+ // missing previous match is an error and denies the request.
653
+ // cost 14 to 55 expressions per call, reads 1
654
+ export function validRematch(previousPath) {
655
+ let previous = get(previousPath).data;
656
+ return request.auth != null
657
+ && previous.status in ['won', 'draw', 'resigned']
658
+ && request.auth.uid in [previous.host, previous.guest]
659
+ && request.resource.data.host == request.auth.uid
660
+ && request.resource.data.guest == ''
661
+ && request.resource.data.status == 'waiting';
662
+ }
365
663
  `,
366
664
  "membership": `// @pyric-services cloud.firestore,firebase.storage
367
665
  // @pyric-evidence storage-rules#125,firestore-rules#189
666
+ // Costs are production expressions per call, not counting arguments. Calls
667
+ // are not memoized: every call pays its full cost again, and a let inside a
668
+ // function is paid on every call.
669
+ //
368
670
  // Membership module for role-based and claims-based access control.
369
671
  //
370
672
  // Two access patterns:
@@ -383,30 +685,108 @@ export function canCancel() {
383
685
  // allow update: if hasRole(resource.data.members, 'admin');
384
686
 
385
687
  // Check if the auth token has a non-null value for a claim key.
688
+ // cost 6 to 14 expressions per call
386
689
  export function hasClaim(claim) {
387
690
  return request.auth != null
388
691
  && request.auth.token[claim] != null;
389
692
  }
390
693
 
391
694
  // Check if the auth token has a specific value for a claim key.
695
+ // cost 6 to 14 expressions per call
392
696
  export function hasClaimRole(claim, role) {
393
697
  return request.auth != null
394
698
  && request.auth.token[claim] == role;
395
699
  }
396
700
 
397
701
  // Check if the caller's UID exists as a key in a members map.
702
+ // cost 6 to 12 expressions per call
398
703
  export function isMemberOf(membersMap) {
399
704
  return request.auth != null
400
705
  && request.auth.uid in membersMap;
401
706
  }
402
707
 
403
708
  // Check if the caller has a specific role in a members map.
709
+ // cost 6 to 14 expressions per call
404
710
  export function hasRole(membersMap, role) {
405
711
  return request.auth != null
406
712
  && membersMap[request.auth.uid] == role;
407
713
  }
714
+ `,
715
+ "results": `// @pyric-services cloud.firestore
716
+ // Costs are production expressions per call, not counting arguments. Calls
717
+ // are not memoized: every call pays its full cost again, and a let inside a
718
+ // function is paid on every call.
719
+ //
720
+ // Game results for 2-participant games/sessions: how a game in play ends,
721
+ // and that other writes leave the result alone.
722
+ //
723
+ // Convention: documents must have these fields:
724
+ // host: string (UID)
725
+ // guest: string (UID)
726
+ // status: 'playing' while in play; 'won' | 'draw' | 'resigned' once finished
727
+ // winner: 'host' | 'guest' on 'won' and 'resigned'; '' while playing and on 'draw'
728
+ //
729
+ // The status names how the game ended, so a result needs no separate reason
730
+ // field. This is the shape the 2-player turn games share: a resignation is
731
+ // status 'resigned' with the other seat as winner, a win is 'won' with the
732
+ // winning seat, and a draw is 'draw' with winner ''.
733
+ //
734
+ // Usage:
735
+ // import { resignedBy, finishedWithWinner, resultUnchanged } from 'results';
736
+ //
737
+ // // The caller resigns their own seat:
738
+ // allow update: if resignedBy(request.auth.uid == resource.data.host ? 'host' : 'guest');
739
+ //
740
+ // // A finish write names the winner and how the game ended:
741
+ // allow update: if finishedWithWinner('host', 'won');
742
+ //
743
+ // // Every other update leaves the result alone:
744
+ // allow update: if resultUnchanged() && isMyTurn();
745
+
746
+ import { onlyFieldsChanged, immutableFields } from 'lifecycle';
747
+ import { statusIs, newStatusIs } from 'transitions';
748
+
749
+ // The caller holds \`seat\` ('host' or 'guest') and resigns: status goes from
750
+ // 'playing' to 'resigned', the other seat wins, and only status and winner
751
+ // change. The auth check comes first so a signed-out request stops there
752
+ // instead of evaluating every clause after the null uid.
753
+ // cost 10 to 72 expressions per call
754
+ export function resignedBy(seat) {
755
+ return request.auth != null
756
+ && ((seat == 'host' && request.resource.data.winner == 'guest')
757
+ || (seat == 'guest' && request.resource.data.winner == 'host'))
758
+ && resource.data[seat] == request.auth.uid
759
+ && statusIs('status', 'playing')
760
+ && newStatusIs('status', 'resigned')
761
+ && onlyFieldsChanged(['status', 'winner']);
762
+ }
763
+
764
+ // A game in play finishes: status goes from 'playing' to \`reason\`, 'won' or
765
+ // 'draw'. \`winner\` is 'host' or 'guest' for 'won' and '' for 'draw', and
766
+ // only status and winner change. Resignations go through resignedBy, which
767
+ // also checks the caller.
768
+ // cost 14 to 61 expressions per call
769
+ export function finishedWithWinner(winner, reason) {
770
+ return statusIs('status', 'playing')
771
+ && ((reason == 'won' && winner in ['host', 'guest'])
772
+ || (reason == 'draw' && winner == ''))
773
+ && newStatusIs('status', reason)
774
+ && request.resource.data.winner == winner
775
+ && onlyFieldsChanged(['status', 'winner']);
776
+ }
777
+
778
+ // The write keeps the result: status and winner are unchanged. Use on every
779
+ // update that is not a finish.
780
+ // cost 14 to 14 expressions per call
781
+ export function resultUnchanged() {
782
+ return immutableFields(['status', 'winner']);
783
+ }
408
784
  `,
409
785
  "spaces": `// @pyric-services cloud.firestore
786
+ // Costs are production expressions per call, not counting arguments. Calls
787
+ // are not memoized: every call pays its full cost again, and a let inside a
788
+ // function is paid on every call.
789
+ //
410
790
  // Spaces module — cross-document membership gating for shared spaces
411
791
  // (teams, rooms, groups, projects, parties). The second-most-common
412
792
  // app shape after author-owned content: a PARENT document defines who
@@ -436,12 +816,14 @@ export function hasRole(membersMap, role) {
436
816
 
437
817
  // The caller is in the space's members field. \`in\` covers both
438
818
  // shapes: list membership and map keys.
819
+ // cost 6 to 13 expressions per call
439
820
  export function isSpaceMember(spaceData) {
440
821
  return request.auth != null && request.auth.uid in spaceData.members;
441
822
  }
442
823
 
443
824
  // The caller's role in a MAP-shaped members field equals \`role\`.
444
825
  // List-shaped members carry no roles — this denies on them.
826
+ // cost 6 to 15 expressions per call
445
827
  export function hasSpaceRole(spaceData, role) {
446
828
  return request.auth != null && spaceData.members[request.auth.uid] == role;
447
829
  }
@@ -449,12 +831,17 @@ export function hasSpaceRole(spaceData, role) {
449
831
  // Member-gated authored create: the caller is a member AND the
450
832
  // incoming child doc's author field is the caller. The "post a
451
833
  // message / add a task" guard.
834
+ // cost 9 to 26 expressions per call
452
835
  export function validMemberCreate(spaceData, authorField) {
453
836
  return isSpaceMember(spaceData)
454
837
  && request.resource.data[authorField] == request.auth.uid;
455
838
  }
456
839
  `,
457
840
  "state": `// @pyric-services cloud.firestore
841
+ // Costs are production expressions per call, not counting arguments. Calls
842
+ // are not memoized: every call pays its full cost again, and a let inside a
843
+ // function is paid on every call.
844
+ //
458
845
  // Game state machine helpers.
459
846
  //
460
847
  // Convention: documents must have these fields:
@@ -469,16 +856,19 @@ export function validMemberCreate(spaceData, authorField) {
469
856
  // allow update: if isPlaying() && moveIncremented() && participantsUnchanged();
470
857
 
471
858
  // Is the game actively in play?
859
+ // cost 6 to 6 expressions per call
472
860
  export function isPlaying() {
473
861
  return resource.data.status == 'playing';
474
862
  }
475
863
 
476
864
  // Did moveCount increment by exactly 1?
865
+ // cost 11 to 11 expressions per call
477
866
  export function moveIncremented() {
478
867
  return request.resource.data.moveCount == resource.data.moveCount + 1;
479
868
  }
480
869
 
481
870
  // Are host and guest unchanged? (prevents mid-game identity swap)
871
+ // cost 10 to 19 expressions per call
482
872
  export function participantsUnchanged() {
483
873
  return request.resource.data.host == resource.data.host
484
874
  && request.resource.data.guest == resource.data.guest;
@@ -486,23 +876,31 @@ export function participantsUnchanged() {
486
876
  `,
487
877
  "storage/metadata": `// @pyric-services firebase.storage
488
878
  // @pyric-evidence storage-rules#132
879
+ // Costs are production expressions per call, not counting arguments. Calls
880
+ // are not memoized: every call pays its full cost again, and a let inside a
881
+ // function is paid on every call.
882
+ //
489
883
  // Storage custom-metadata policies. Custom metadata is a flat string map.
490
884
 
885
+ // cost 7 to 7 expressions per call
491
886
  export function hasRequiredMetadata(keys) {
492
887
  return request.resource.metadata.keys().hasAll(keys);
493
888
  }
494
889
 
890
+ // cost 28 to 28 expressions per call
495
891
  export function metadataString(key, min, max) {
496
892
  return request.resource.metadata[key] is string
497
893
  && request.resource.metadata[key].size() >= min
498
894
  && request.resource.metadata[key].size() <= max;
499
895
  }
500
896
 
897
+ // cost 6 to 16 expressions per call
501
898
  export function incomingMetadataOwner(key) {
502
899
  return request.auth != null
503
900
  && request.resource.metadata[key] == request.auth.uid;
504
901
  }
505
902
 
903
+ // cost 6 to 15 expressions per call
506
904
  export function existingMetadataOwner(key) {
507
905
  return request.auth != null
508
906
  && resource.metadata[key] == request.auth.uid;
@@ -510,57 +908,131 @@ export function existingMetadataOwner(key) {
510
908
  `,
511
909
  "storage/objects": `// @pyric-services firebase.storage
512
910
  // @pyric-evidence storage-rules#132
513
- // Storage operation identity. Use request.method rather than null checks:
514
- // production treats missing resource/request.resource bindings as errors.
911
+ // Costs are production expressions per call, not counting arguments. Calls
912
+ // are not memoized: every call pays its full cost again, and a let inside a
913
+ // function is paid on every call. matchesDocument reads one Firestore
914
+ // document per call.
915
+ //
916
+ // Storage operation identity and object names. Use request.method rather
917
+ // than null checks: production treats missing resource/request.resource
918
+ // bindings as errors.
919
+ //
920
+ // Convention: the object name is the full path within the bucket, such as
921
+ // 'scores/alice/3/abc-33-8.txt'. On create and update the name comes from
922
+ // request.resource.name, since a create may have no stored object yet. On
923
+ // get and delete it comes from resource.name, since those requests carry no
924
+ // incoming object. Call nameSegment and matchesDocument from get, create,
925
+ // update and delete rules.
926
+ //
927
+ // A Storage rule reads at most two distinct Firestore documents, so a rule
928
+ // may call matchesDocument at most twice with different paths. A third
929
+ // distinct document denies the request.
930
+ //
931
+ // Usage:
932
+ // import { nameSegment, matchesDocument } from 'storage/objects';
933
+ //
934
+ // // The user named in the second segment reads every object below it:
935
+ // match /scores/{allPaths=**} {
936
+ // allow get: if nameSegment(1) == request.auth.uid;
937
+ // }
938
+ //
939
+ // // An upload is allowed once the score document names it in \`object\`:
940
+ // match /scores/{uid}/{level}/{file} {
941
+ // allow create: if matchesDocument(
942
+ // /databases/(default)/documents/levels/$(level)/scores/$(uid), 'object');
943
+ // }
515
944
 
945
+ // cost 5 to 5 expressions per call
516
946
  export function isCreate() {
517
947
  return request.method == 'create';
518
948
  }
519
949
 
950
+ // cost 5 to 5 expressions per call
520
951
  export function isUpdate() {
521
952
  return request.method == 'update';
522
953
  }
523
954
 
955
+ // cost 5 to 5 expressions per call
524
956
  export function isDelete() {
525
957
  return request.method == 'delete';
526
958
  }
959
+
960
+ // The object's name for this request (see the convention above).
961
+ function objectName() {
962
+ return request.method in ['create', 'update'] ? request.resource.name : resource.name;
963
+ }
964
+
965
+ // Segment \`index\` of the object name split on '/', counting from 0. An index
966
+ // past the last segment is an error that denies the request, and a name with
967
+ // no '/' has one segment.
968
+ // cost 17 to 18 expressions per call
969
+ export function nameSegment(index) {
970
+ return objectName().split('/')[index];
971
+ }
972
+
973
+ // The Firestore document at \`path\` exists and its \`field\` equals the object
974
+ // name. A signed-out request denies before the read. A missing document or
975
+ // field is an error that denies the request. Each call reads one document.
976
+ // cost 6 to 26 expressions per call, reads 1
977
+ export function matchesDocument(path, field) {
978
+ return request.auth != null
979
+ && firestore.get(path).data[field] == objectName();
980
+ }
527
981
  `,
528
982
  "storage/time": `// @pyric-services firebase.storage
529
983
  // @pyric-evidence storage-rules#132
984
+ // Costs are production expressions per call, not counting arguments. Calls
985
+ // are not memoized: every call pays its full cost again, and a let inside a
986
+ // function is paid on every call.
987
+ //
530
988
  // Freshness checks over server-owned Storage object timestamps. Boundaries are
531
989
  // strict: equality with the deadline is not "within" the window.
532
990
 
991
+ // cost 10 to 10 expressions per call
533
992
  export function createdWithin(seconds) {
534
993
  return request.time < resource.timeCreated + duration.value(seconds, 's');
535
994
  }
536
995
 
996
+ // cost 10 to 10 expressions per call
537
997
  export function updatedWithin(seconds) {
538
998
  return request.time < resource.updated + duration.value(seconds, 's');
539
999
  }
540
1000
  `,
541
1001
  "storage/uploads": `// @pyric-services firebase.storage
542
1002
  // @pyric-evidence storage-rules#132
1003
+ // Costs are production expressions per call, not counting arguments. Calls
1004
+ // are not memoized: every call pays its full cost again, and a let inside a
1005
+ // function is paid on every call.
1006
+ //
543
1007
  // Storage upload request primitives. These inspect declared object metadata;
544
1008
  // MIME helpers do not inspect or authenticate the uploaded bytes.
545
1009
 
1010
+ // cost 6 to 6 expressions per call
546
1011
  export function sizeAtMost(maxBytes) {
547
1012
  return request.resource.size <= maxBytes;
548
1013
  }
549
1014
 
1015
+ // cost 7 to 13 expressions per call
550
1016
  export function sizeBetween(minBytes, maxBytes) {
551
1017
  return request.resource.size >= minBytes
552
1018
  && request.resource.size <= maxBytes;
553
1019
  }
554
1020
 
1021
+ // cost 6 to 6 expressions per call
555
1022
  export function contentTypeMatches(pattern) {
556
1023
  return request.resource.contentType.matches(pattern);
557
1024
  }
558
1025
 
1026
+ // cost 6 to 6 expressions per call
559
1027
  export function contentTypeIsOneOf(types) {
560
1028
  return request.resource.contentType in types;
561
1029
  }
562
1030
  `,
563
1031
  "timing": `// @pyric-services cloud.firestore
1032
+ // Costs are production expressions per call, not counting arguments. Calls
1033
+ // are not memoized: every call pays its full cost again, and a let inside a
1034
+ // function is paid on every call.
1035
+ //
564
1036
  // Timing module for cooldown / rate-limit enforcement.
565
1037
  //
566
1038
  // Rules CAN rate-limit (contrary to a common assumption — jrpg
@@ -578,11 +1050,16 @@ export function contentTypeIsOneOf(types) {
578
1050
  // The stored timestamp is more than \`seconds\` old (strict). Update
579
1051
  // rules only — needs \`resource\`. The field must be a Timestamp; a
580
1052
  // missing field errors, which denies (fail-closed).
1053
+ // cost 12 to 12 expressions per call
581
1054
  export function cooldownElapsed(field, seconds) {
582
1055
  return request.time > resource.data[field] + duration.value(seconds, 's');
583
1056
  }
584
1057
  `,
585
1058
  "transitions": `// @pyric-services cloud.firestore
1059
+ // Costs are production expressions per call, not counting arguments. Calls
1060
+ // are not memoized: every call pays its full cost again, and a let inside a
1061
+ // function is paid on every call.
1062
+ //
586
1063
  // Transitions module for state machine enforcement.
587
1064
  //
588
1065
  // Validates that a field transitions from one known value to another.
@@ -603,35 +1080,57 @@ export function cooldownElapsed(field, seconds) {
603
1080
  // || validTransition('status', 'completed', 'archived');
604
1081
 
605
1082
  // Check that a field transitions from one value to another.
1083
+ // cost 8 to 16 expressions per call
606
1084
  export function validTransition(field, from, to) {
607
1085
  return resource.data[field] == from
608
1086
  && request.resource.data[field] == to;
609
1087
  }
610
1088
 
611
1089
  // Check the current (existing) value of a field.
1090
+ // cost 7 to 7 expressions per call
612
1091
  export function statusIs(field, value) {
613
1092
  return resource.data[field] == value;
614
1093
  }
615
1094
 
616
1095
  // Check the incoming (new) value of a field.
1096
+ // cost 8 to 8 expressions per call
617
1097
  export function newStatusIs(field, value) {
618
1098
  return request.resource.data[field] == value;
619
1099
  }
620
1100
  `,
621
1101
  "turns": `// @pyric-services cloud.firestore
622
- // Turn enforcement for 2-participant games/sessions.
1102
+ // Costs are production expressions per call, not counting arguments. Calls
1103
+ // are not memoized: every call pays its full cost again, and a let inside a
1104
+ // function is paid on every call.
623
1105
  //
624
- // Convention: documents must have these fields:
1106
+ // Turn enforcement for games/sessions: two-seat games with named seats, and
1107
+ // games of any size with a seat list.
1108
+ //
1109
+ // Two-seat convention: documents must have these fields:
625
1110
  // host: string (UID)
626
1111
  // guest: string (UID)
627
1112
  // currentTurn: 'host' | 'guest'
628
1113
  //
1114
+ // Seat-list convention: documents must have these fields:
1115
+ // players: list of UIDs, one per seat, in turn order
1116
+ // turn: int, the index in \`players\` of the seat whose turn it is
1117
+ //
1118
+ // Yacht and Uno store these two fields under these names. isSeatTurn takes
1119
+ // the list and the index as arguments, so a document that names them
1120
+ // differently can still use it; turnAdvanced reads \`players\` and \`turn\`.
1121
+ //
629
1122
  // Usage:
630
- // import { isMyTurn, turnFlipped } from 'turns';
1123
+ // import { isMyTurn, turnFlipped, isSeatTurn, turnAdvanced } from 'turns';
631
1124
  //
1125
+ // // Two seats:
632
1126
  // allow update: if isMyTurn() && turnFlipped();
1127
+ //
1128
+ // // A seat list:
1129
+ // allow update: if isSeatTurn(resource.data.players, resource.data.turn)
1130
+ // && turnAdvanced(resource.data.players.size());
633
1131
 
634
1132
  // Is the caller the participant whose turn it is?
1133
+ // cost 16 to 23 expressions per call
635
1134
  export function isMyTurn() {
636
1135
  return (resource.data.currentTurn == 'host'
637
1136
  && request.auth.uid == resource.data.host)
@@ -640,14 +1139,36 @@ export function isMyTurn() {
640
1139
  }
641
1140
 
642
1141
  // Did the turn alternate?
1142
+ // cost 15 to 22 expressions per call
643
1143
  export function turnFlipped() {
644
1144
  return (resource.data.currentTurn == 'host'
645
1145
  && request.resource.data.currentTurn == 'guest')
646
1146
  || (resource.data.currentTurn == 'guest'
647
1147
  && request.resource.data.currentTurn == 'host');
648
1148
  }
1149
+
1150
+ // Is the caller's uid \`seats[turnIndex]\`? \`seats\` is a list of UIDs and
1151
+ // \`turnIndex\` an int. A signed-out request is false. An index past the last
1152
+ // seat, or below 0, is an error, and the request is denied.
1153
+ // cost 6 to 14 expressions per call
1154
+ export function isSeatTurn(seats, turnIndex) {
1155
+ return request.auth != null && seats[turnIndex] == request.auth.uid;
1156
+ }
1157
+
1158
+ // Did the turn move to the next seat? The new \`turn\` equals the old \`turn\`
1159
+ // plus one, modulo \`seatCount\`, so the last seat wraps to seat 0. \`%\` on two
1160
+ // ints is the remainder, as in production. The \`players\` list is unchanged.
1161
+ // cost 14 to 23 expressions per call
1162
+ export function turnAdvanced(seatCount) {
1163
+ return request.resource.data.turn == (resource.data.turn + 1) % seatCount
1164
+ && request.resource.data.players == resource.data.players;
1165
+ }
649
1166
  `,
650
1167
  "validation": `// @pyric-services cloud.firestore
1168
+ // Costs are production expressions per call, not counting arguments. Calls
1169
+ // are not memoized: every call pays its full cost again, and a let inside a
1170
+ // function is paid on every call.
1171
+ //
651
1172
  // Validation module for document field shape and value checks.
652
1173
  //
653
1174
  // Usage:
@@ -657,17 +1178,21 @@ export function turnFlipped() {
657
1178
  // && validString('title', 1, 100)
658
1179
  // && isOneOf('status', ['draft', 'published']);
659
1180
 
1181
+ // cost 7 to 7 expressions per call
660
1182
  export function hasRequired(fields) {
661
1183
  return request.resource.data.keys().hasAll(fields);
662
1184
  }
663
1185
 
1186
+ // cost 7 to 7 expressions per call
664
1187
  export function hasOnly(fields) {
665
1188
  return request.resource.data.keys().hasOnly(fields);
666
1189
  }
667
1190
 
668
1191
  // Incoming field is a string with size in [min, max] (inclusive).
669
- // Uses dynamic access, so a MISSING field reads as null (not an
670
- // error) and fails the \`is string\` check — safe on optional fields.
1192
+ // A missing field is an error under dynamic access, so the call denies.
1193
+ // For an optional field, guard it:
1194
+ // \`!('title' in request.resource.data) || validString('title', 1, 80)\`.
1195
+ // cost 10 to 28 expressions per call
671
1196
  export function validString(field, min, max) {
672
1197
  return request.resource.data[field] is string
673
1198
  && request.resource.data[field].size() >= min
@@ -676,6 +1201,7 @@ export function validString(field, min, max) {
676
1201
 
677
1202
  // Enum check: the incoming field value is one of the allowed values.
678
1203
  // (\`in\` on a list — NOT \`.includes()\`, which does not exist in rules.)
1204
+ // cost 8 to 8 expressions per call
679
1205
  export function isOneOf(field, values) {
680
1206
  return request.resource.data[field] in values;
681
1207
  }