@pyric/cli 0.1.0-alpha.25 → 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.
@@ -2,27 +2,79 @@
2
2
  <link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.Da5VLhW1.css">
3
3
  <style>:root{--rhythm-para: .875rem;--rhythm-group: 1.5rem;--rhythm-subsection: 2.25rem;--rhythm-section: 3.25rem;--rhythm-list: calc(var(--rhythm-para) * .75)}.prose>*,.prose blockquote>*,.prose li>*,.prose .compat-stat>*{margin-block:0}.prose>*+*{margin-block-start:var(--rhythm-group)}.prose>*+h2{margin-block-start:var(--rhythm-section)}.prose>*+h3,.prose>*+h4{margin-block-start:var(--rhythm-subsection)}.prose>h1+*,.prose>h2+*,.prose>h3+*,.prose>h4+*{margin-block-start:var(--rhythm-para)}.prose>p+p{margin-block-start:var(--rhythm-para)}.prose>p+ul,.prose>p+ol,.prose>p+blockquote{margin-block-start:var(--rhythm-para)}.prose li+li{margin-block-start:var(--rhythm-list)}.prose li>ul,.prose li>ol{margin-block-start:var(--rhythm-list)}.prose li>*+*,.prose blockquote>*+*{margin-block-start:var(--rhythm-para)}
4
4
  html{scrollbar-gutter:stable}
5
- </style></head> <body> <header class="studio__chrome"> <div class="studio__bar"> <div class="studio__chrome-inner"> <nav class="studio__nav" aria-label="Site"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric">pyric</a> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a><a class="studio__nav-tab" href="/__pyric/ui/studio"> Studio </a> </nav> </div> </div> </header> <div class="docs-shell" data-astro-cid-mw7aashj> <details class="docs-nav-drawer" data-astro-cid-mw7aashj> <summary data-astro-cid-mw7aashj>Navigate</summary> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <script type="module">let i=null;function d(t){return i||(i=fetch(t).then(e=>e.json())),i}function l(t,e){return t.title.toLowerCase().includes(e)||t.excerpt.toLowerCase().includes(e)?!0:t.headings.some(r=>r.text.toLowerCase().includes(e))}function u(t,e,r){if(e.innerHTML="",t.length===0){e.hidden=!1;{const n=document.createElement("li");n.className="docs-search-empty",n.textContent="No matches",e.appendChild(n)}return}e.hidden=!1;for(const n of t.slice(0,8)){const s=document.createElement("li"),c=document.createElement("a");c.href=n.path;const o=document.createElement("span");o.className="docs-search-result-title",o.textContent=n.title;const a=document.createElement("span");a.className="docs-search-result-meta",a.textContent=[n.group,n.section].filter(Boolean).join(" / "),c.append(o,a),s.appendChild(c),e.appendChild(s)}}document.querySelectorAll(".docs-search").forEach(t=>{const e=t.dataset.indexUrl,r=t.querySelector(".docs-search-input"),n=t.querySelector(".docs-search-results");r.addEventListener("input",async()=>{const s=r.value.trim().toLowerCase();if(!s){n.hidden=!0,n.innerHTML="";return}const{pages:c}=await d(e);r.value.trim().toLowerCase()===s&&u(c.filter(o=>l(o,s)),n)}),r.addEventListener("focus",()=>{d(e),n.childElementCount>0&&(n.hidden=!1)}),r.addEventListener("keydown",s=>{s.key==="Escape"&&(r.value="",n.hidden=!0,n.innerHTML="",r.blur())}),r.addEventListener("blur",()=>{window.setTimeout(()=>{n.hidden=!0},150)})});document.addEventListener("keydown",t=>{if(!(t.metaKey||t.ctrlKey)||t.key.toLowerCase()!=="k")return;const e=[...document.querySelectorAll(".docs-search-input")].find(r=>r.offsetParent!==null);e&&(t.preventDefault(),e.focus(),e.select())});</script> <details class="docs-nav-group"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/vite/"> Vite </a> </li><li> <a href="/__pyric/ui/docs/get-started/node-host/"> Node host </a> </li><li> <a href="/__pyric/ui/docs/get-started/nextjs/"> Next.js </a> </li><li> <a href="/__pyric/ui/docs/get-started/backend-bundlers/"> Backend bundlers </a> </li><li> <a href="/__pyric/ui/docs/get-started/flutter/"> Flutter </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/default-avatars/"> Default avatars </a> </li><li> <a href="/__pyric/ui/docs/build/inspect-activity/"> Activity on the page </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-standard-library/"> RTDB rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/switch-and-impersonate-identities/"> Impersonate &amp; tenants </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/firestore-flutter-compat/"> Firestore · Flutter </a> </li><li> <a href="/__pyric/ui/docs/firestore-kotlin-compat/"> Firestore · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/firestore-swift-compat/"> Firestore · Swift </a> </li><li> <a href="/__pyric/ui/docs/auth-flutter-compat/"> Auth · Flutter </a> </li><li> <a href="/__pyric/ui/docs/auth-kotlin-compat/"> Auth · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/auth-swift-compat/"> FirebaseAuth Swift </a> </li><li> <a href="/__pyric/ui/docs/rtdb-flutter-compat/"> Realtime Database · Flutter </a> </li><li> <a href="/__pyric/ui/docs/rtdb-kotlin-compat/"> Realtime Database · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/rtdb-swift-compat/"> Realtime Database · Swift </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" open> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-lite-reference-api/"> pyric/firestore/lite </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/" aria-current="page"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-branches-store-reference-api/"> pyric/sandbox/branches/store </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-checkpoints-reference-api/"> pyric/sandbox/checkpoints </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-checkpoints-directory-reference-api/"> pyric/sandbox/checkpoints/directory </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-check-reference-api/"> pyric/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-functions-reference-api/"> pyric/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-analytics-reference-api/"> pyric/analytics </a> </li><li> <a href="/__pyric/ui/docs/pyric-performance-reference-api/"> pyric/performance </a> </li><li> <a href="/__pyric/ui/docs/pyric-remote-config-reference-api/"> pyric/remote-config </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-reference-api/"> pyric-admin </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-check-reference-api/"> pyric-admin/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-data-connect-reference-api/"> pyric-admin/data-connect </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-eventarc-reference-api/"> pyric-admin/eventarc </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-extensions-reference-api/"> pyric-admin/extensions </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-functions-reference-api/"> pyric-admin/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-installations-reference-api/"> pyric-admin/installations </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-instance-id-reference-api/"> pyric-admin/instance-id </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-machine-learning-reference-api/"> pyric-admin/machine-learning </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-phone-number-verification-reference-api/"> pyric-admin/phone-number-verification </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-project-management-reference-api/"> pyric-admin/project-management </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-remote-config-reference-api/"> pyric-admin/remote-config </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-security-rules-reference-api/"> pyric-admin/security-rules </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-repro-reference-api/"> @pyric/cli/repro </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-ssr-loader-reference-api/"> @pyric/cli/vite/ssr-loader </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-next-reference-api/"> @pyric/cli/next </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bundler-reference-api/"> @pyric/cli/bundler </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-app-bridge-reference-api/"> @pyric/cli/register/app-bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-app-reference-api/"> @pyric/cli/register/client/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-app-bridge-reference-api/"> @pyric/cli/register/client/app-bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-auth-reference-api/"> @pyric/cli/register/client/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-database-reference-api/"> @pyric/cli/register/client/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-firestore-reference-api/"> @pyric/cli/register/client/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-storage-reference-api/"> @pyric/cli/register/client/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-flow-reference-api/"> @pyric/cli/flow </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-listener-owner-reference-api/"> @pyric/ui/listener-owner </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </a> </li> </ul> </div> </div> </details> </nav> </details> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <details class="docs-nav-group" id="nav-group-overview"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-get-started"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/vite/"> Vite </a> </li><li> <a href="/__pyric/ui/docs/get-started/node-host/"> Node host </a> </li><li> <a href="/__pyric/ui/docs/get-started/nextjs/"> Next.js </a> </li><li> <a href="/__pyric/ui/docs/get-started/backend-bundlers/"> Backend bundlers </a> </li><li> <a href="/__pyric/ui/docs/get-started/flutter/"> Flutter </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-build"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/default-avatars/"> Default avatars </a> </li><li> <a href="/__pyric/ui/docs/build/inspect-activity/"> Activity on the page </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-secure-debug"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-standard-library/"> RTDB rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-secure-debug-examples"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-observe-shape"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/switch-and-impersonate-identities/"> Impersonate &amp; tenants </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-work-with-an-agent"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-trust"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/firestore-flutter-compat/"> Firestore · Flutter </a> </li><li> <a href="/__pyric/ui/docs/firestore-kotlin-compat/"> Firestore · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/firestore-swift-compat/"> Firestore · Swift </a> </li><li> <a href="/__pyric/ui/docs/auth-flutter-compat/"> Auth · Flutter </a> </li><li> <a href="/__pyric/ui/docs/auth-kotlin-compat/"> Auth · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/auth-swift-compat/"> FirebaseAuth Swift </a> </li><li> <a href="/__pyric/ui/docs/rtdb-flutter-compat/"> Realtime Database · Flutter </a> </li><li> <a href="/__pyric/ui/docs/rtdb-kotlin-compat/"> Realtime Database · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/rtdb-swift-compat/"> Realtime Database · Swift </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference" open> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-lite-reference-api/"> pyric/firestore/lite </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/" aria-current="page"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-branches-store-reference-api/"> pyric/sandbox/branches/store </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-checkpoints-reference-api/"> pyric/sandbox/checkpoints </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-checkpoints-directory-reference-api/"> pyric/sandbox/checkpoints/directory </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-check-reference-api/"> pyric/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-functions-reference-api/"> pyric/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-analytics-reference-api/"> pyric/analytics </a> </li><li> <a href="/__pyric/ui/docs/pyric-performance-reference-api/"> pyric/performance </a> </li><li> <a href="/__pyric/ui/docs/pyric-remote-config-reference-api/"> pyric/remote-config </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-reference-api/"> pyric-admin </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-check-reference-api/"> pyric-admin/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-data-connect-reference-api/"> pyric-admin/data-connect </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-eventarc-reference-api/"> pyric-admin/eventarc </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-extensions-reference-api/"> pyric-admin/extensions </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-functions-reference-api/"> pyric-admin/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-installations-reference-api/"> pyric-admin/installations </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-instance-id-reference-api/"> pyric-admin/instance-id </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-machine-learning-reference-api/"> pyric-admin/machine-learning </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-phone-number-verification-reference-api/"> pyric-admin/phone-number-verification </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-project-management-reference-api/"> pyric-admin/project-management </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-remote-config-reference-api/"> pyric-admin/remote-config </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-security-rules-reference-api/"> pyric-admin/security-rules </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-repro-reference-api/"> @pyric/cli/repro </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-ssr-loader-reference-api/"> @pyric/cli/vite/ssr-loader </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-next-reference-api/"> @pyric/cli/next </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bundler-reference-api/"> @pyric/cli/bundler </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-app-bridge-reference-api/"> @pyric/cli/register/app-bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-app-reference-api/"> @pyric/cli/register/client/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-app-bridge-reference-api/"> @pyric/cli/register/client/app-bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-auth-reference-api/"> @pyric/cli/register/client/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-database-reference-api/"> @pyric/cli/register/client/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-firestore-reference-api/"> @pyric/cli/register/client/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-storage-reference-api/"> @pyric/cli/register/client/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-flow-reference-api/"> @pyric/cli/flow </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-listener-owner-reference-api/"> @pyric/ui/listener-owner </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main" data-astro-cid-mw7aashj> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/api-reference/">API reference</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span>pyric</span> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">pyric/rules</span> </li> </ol> </nav> <header class="api-reference-header" data-astro-cid-mw7aashj> <p class="api-reference-kicker" data-astro-cid-mw7aashj>API reference</p> <h1 data-astro-cid-mw7aashj><code data-astro-cid-mw7aashj>pyric/rules</code></h1> <p class="api-reference-meta" data-astro-cid-mw7aashj> 120 published symbols from <code data-astro-cid-mw7aashj>pyric</code> </p> <p class="api-reference-source" data-astro-cid-mw7aashj>
5
+ </style></head> <body> <header class="studio__chrome"> <div class="studio__bar"> <div class="studio__chrome-inner"> <nav class="studio__nav" aria-label="Site"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric">pyric</a> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a><a class="studio__nav-tab" href="/__pyric/ui/studio"> Studio </a> </nav> </div> </div> </header> <div class="docs-shell" data-astro-cid-mw7aashj> <details class="docs-nav-drawer" data-astro-cid-mw7aashj> <summary data-astro-cid-mw7aashj>Navigate</summary> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <script type="module">let i=null;function d(t){return i||(i=fetch(t).then(e=>e.json())),i}function l(t,e){return t.title.toLowerCase().includes(e)||t.excerpt.toLowerCase().includes(e)?!0:t.headings.some(r=>r.text.toLowerCase().includes(e))}function u(t,e,r){if(e.innerHTML="",t.length===0){e.hidden=!1;{const n=document.createElement("li");n.className="docs-search-empty",n.textContent="No matches",e.appendChild(n)}return}e.hidden=!1;for(const n of t.slice(0,8)){const s=document.createElement("li"),c=document.createElement("a");c.href=n.path;const o=document.createElement("span");o.className="docs-search-result-title",o.textContent=n.title;const a=document.createElement("span");a.className="docs-search-result-meta",a.textContent=[n.group,n.section].filter(Boolean).join(" / "),c.append(o,a),s.appendChild(c),e.appendChild(s)}}document.querySelectorAll(".docs-search").forEach(t=>{const e=t.dataset.indexUrl,r=t.querySelector(".docs-search-input"),n=t.querySelector(".docs-search-results");r.addEventListener("input",async()=>{const s=r.value.trim().toLowerCase();if(!s){n.hidden=!0,n.innerHTML="";return}const{pages:c}=await d(e);r.value.trim().toLowerCase()===s&&u(c.filter(o=>l(o,s)),n)}),r.addEventListener("focus",()=>{d(e),n.childElementCount>0&&(n.hidden=!1)}),r.addEventListener("keydown",s=>{s.key==="Escape"&&(r.value="",n.hidden=!0,n.innerHTML="",r.blur())}),r.addEventListener("blur",()=>{window.setTimeout(()=>{n.hidden=!0},150)})});document.addEventListener("keydown",t=>{if(!(t.metaKey||t.ctrlKey)||t.key.toLowerCase()!=="k")return;const e=[...document.querySelectorAll(".docs-search-input")].find(r=>r.offsetParent!==null);e&&(t.preventDefault(),e.focus(),e.select())});</script> <details class="docs-nav-group"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/vite/"> Vite </a> </li><li> <a href="/__pyric/ui/docs/get-started/node-host/"> Node host </a> </li><li> <a href="/__pyric/ui/docs/get-started/nextjs/"> Next.js </a> </li><li> <a href="/__pyric/ui/docs/get-started/backend-bundlers/"> Backend bundlers </a> </li><li> <a href="/__pyric/ui/docs/get-started/flutter/"> Flutter </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/default-avatars/"> Default avatars </a> </li><li> <a href="/__pyric/ui/docs/build/inspect-activity/"> Activity on the page </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-standard-library/"> RTDB rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/switch-and-impersonate-identities/"> Impersonate &amp; tenants </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/firestore-flutter-compat/"> Firestore · Flutter </a> </li><li> <a href="/__pyric/ui/docs/firestore-kotlin-compat/"> Firestore · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/firestore-swift-compat/"> Firestore · Swift </a> </li><li> <a href="/__pyric/ui/docs/auth-flutter-compat/"> Auth · Flutter </a> </li><li> <a href="/__pyric/ui/docs/auth-kotlin-compat/"> Auth · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/auth-swift-compat/"> FirebaseAuth Swift </a> </li><li> <a href="/__pyric/ui/docs/rtdb-flutter-compat/"> Realtime Database · Flutter </a> </li><li> <a href="/__pyric/ui/docs/rtdb-kotlin-compat/"> Realtime Database · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/rtdb-swift-compat/"> Realtime Database · Swift </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" open> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-lite-reference-api/"> pyric/firestore/lite </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/" aria-current="page"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-branches-store-reference-api/"> pyric/sandbox/branches/store </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-checkpoints-reference-api/"> pyric/sandbox/checkpoints </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-checkpoints-directory-reference-api/"> pyric/sandbox/checkpoints/directory </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-check-reference-api/"> pyric/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-functions-reference-api/"> pyric/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-analytics-reference-api/"> pyric/analytics </a> </li><li> <a href="/__pyric/ui/docs/pyric-performance-reference-api/"> pyric/performance </a> </li><li> <a href="/__pyric/ui/docs/pyric-remote-config-reference-api/"> pyric/remote-config </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-reference-api/"> pyric-admin </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-check-reference-api/"> pyric-admin/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-data-connect-reference-api/"> pyric-admin/data-connect </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-eventarc-reference-api/"> pyric-admin/eventarc </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-extensions-reference-api/"> pyric-admin/extensions </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-functions-reference-api/"> pyric-admin/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-installations-reference-api/"> pyric-admin/installations </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-instance-id-reference-api/"> pyric-admin/instance-id </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-machine-learning-reference-api/"> pyric-admin/machine-learning </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-phone-number-verification-reference-api/"> pyric-admin/phone-number-verification </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-project-management-reference-api/"> pyric-admin/project-management </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-remote-config-reference-api/"> pyric-admin/remote-config </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-security-rules-reference-api/"> pyric-admin/security-rules </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-repro-reference-api/"> @pyric/cli/repro </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-ssr-loader-reference-api/"> @pyric/cli/vite/ssr-loader </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-next-reference-api/"> @pyric/cli/next </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bundler-reference-api/"> @pyric/cli/bundler </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-app-bridge-reference-api/"> @pyric/cli/register/app-bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-app-reference-api/"> @pyric/cli/register/client/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-app-bridge-reference-api/"> @pyric/cli/register/client/app-bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-auth-reference-api/"> @pyric/cli/register/client/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-database-reference-api/"> @pyric/cli/register/client/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-firestore-reference-api/"> @pyric/cli/register/client/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-storage-reference-api/"> @pyric/cli/register/client/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-flow-reference-api/"> @pyric/cli/flow </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-listener-owner-reference-api/"> @pyric/ui/listener-owner </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </a> </li> </ul> </div> </div> </details> </nav> </details> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <details class="docs-nav-group" id="nav-group-overview"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-get-started"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/vite/"> Vite </a> </li><li> <a href="/__pyric/ui/docs/get-started/node-host/"> Node host </a> </li><li> <a href="/__pyric/ui/docs/get-started/nextjs/"> Next.js </a> </li><li> <a href="/__pyric/ui/docs/get-started/backend-bundlers/"> Backend bundlers </a> </li><li> <a href="/__pyric/ui/docs/get-started/flutter/"> Flutter </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-build"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/default-avatars/"> Default avatars </a> </li><li> <a href="/__pyric/ui/docs/build/inspect-activity/"> Activity on the page </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-secure-debug"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-standard-library/"> RTDB rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-secure-debug-examples"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-observe-shape"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/switch-and-impersonate-identities/"> Impersonate &amp; tenants </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-work-with-an-agent"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-trust"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/firestore-flutter-compat/"> Firestore · Flutter </a> </li><li> <a href="/__pyric/ui/docs/firestore-kotlin-compat/"> Firestore · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/firestore-swift-compat/"> Firestore · Swift </a> </li><li> <a href="/__pyric/ui/docs/auth-flutter-compat/"> Auth · Flutter </a> </li><li> <a href="/__pyric/ui/docs/auth-kotlin-compat/"> Auth · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/auth-swift-compat/"> FirebaseAuth Swift </a> </li><li> <a href="/__pyric/ui/docs/rtdb-flutter-compat/"> Realtime Database · Flutter </a> </li><li> <a href="/__pyric/ui/docs/rtdb-kotlin-compat/"> Realtime Database · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/rtdb-swift-compat/"> Realtime Database · Swift </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference" open> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-lite-reference-api/"> pyric/firestore/lite </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/" aria-current="page"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-branches-store-reference-api/"> pyric/sandbox/branches/store </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-checkpoints-reference-api/"> pyric/sandbox/checkpoints </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-checkpoints-directory-reference-api/"> pyric/sandbox/checkpoints/directory </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-check-reference-api/"> pyric/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-functions-reference-api/"> pyric/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-analytics-reference-api/"> pyric/analytics </a> </li><li> <a href="/__pyric/ui/docs/pyric-performance-reference-api/"> pyric/performance </a> </li><li> <a href="/__pyric/ui/docs/pyric-remote-config-reference-api/"> pyric/remote-config </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-reference-api/"> pyric-admin </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-check-reference-api/"> pyric-admin/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-data-connect-reference-api/"> pyric-admin/data-connect </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-eventarc-reference-api/"> pyric-admin/eventarc </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-extensions-reference-api/"> pyric-admin/extensions </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-functions-reference-api/"> pyric-admin/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-installations-reference-api/"> pyric-admin/installations </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-instance-id-reference-api/"> pyric-admin/instance-id </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-machine-learning-reference-api/"> pyric-admin/machine-learning </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-phone-number-verification-reference-api/"> pyric-admin/phone-number-verification </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-project-management-reference-api/"> pyric-admin/project-management </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-remote-config-reference-api/"> pyric-admin/remote-config </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-security-rules-reference-api/"> pyric-admin/security-rules </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-repro-reference-api/"> @pyric/cli/repro </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-ssr-loader-reference-api/"> @pyric/cli/vite/ssr-loader </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-next-reference-api/"> @pyric/cli/next </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bundler-reference-api/"> @pyric/cli/bundler </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-app-bridge-reference-api/"> @pyric/cli/register/app-bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-app-reference-api/"> @pyric/cli/register/client/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-app-bridge-reference-api/"> @pyric/cli/register/client/app-bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-auth-reference-api/"> @pyric/cli/register/client/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-database-reference-api/"> @pyric/cli/register/client/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-firestore-reference-api/"> @pyric/cli/register/client/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-client-storage-reference-api/"> @pyric/cli/register/client/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-flow-reference-api/"> @pyric/cli/flow </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-listener-owner-reference-api/"> @pyric/ui/listener-owner </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main" data-astro-cid-mw7aashj> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/api-reference/">API reference</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span>pyric</span> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">pyric/rules</span> </li> </ol> </nav> <header class="api-reference-header" data-astro-cid-mw7aashj> <p class="api-reference-kicker" data-astro-cid-mw7aashj>API reference</p> <h1 data-astro-cid-mw7aashj><code data-astro-cid-mw7aashj>pyric/rules</code></h1> <p class="api-reference-meta" data-astro-cid-mw7aashj> 126 published symbols from <code data-astro-cid-mw7aashj>pyric</code> </p> <p class="api-reference-source" data-astro-cid-mw7aashj>
6
6
  Generated from the TypeScript declarations shipped at this import path.
7
7
  </p> <a class="api-reference-evidence" href="/__pyric/ui/docs/rules-compat/" data-astro-cid-mw7aashj>
8
8
  Check behavioral conformance
9
9
  </a> </header> <article class="prose api-reference-body" data-astro-cid-mw7aashj> <!-- Generated from published package declarations via TypeDoc. Rendered by the api-reference content loader. -->
10
10
  <h2 id="classes">Classes</h2>
11
+ <p><a id="rtdbexpressionsyntaxerror"></a></p>
12
+ <h3 id="rtdbexpressionsyntaxerror">RtdbExpressionSyntaxError</h3>
13
+ <p>Why <a href="#canonicalrtdbexpression">canonicalRtdbExpression</a> could not read its input.</p>
14
+ <h4 id="extends">Extends</h4>
15
+ <ul>
16
+ <li><code>Error</code></li>
17
+ </ul>
18
+ <h4 id="constructors">Constructors</h4>
19
+ <p><a id="constructor"></a></p>
20
+ <h5 id="constructor">Constructor</h5>
21
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">new</span><span style="color:#61AFEF"> RtdbExpressionSyntaxError</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">raw</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">string</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">message</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">string</span><span style="color:#ABB2BF">): </span><span style="color:#E06C75">RtdbExpressionSyntaxError</span><span style="color:#ABB2BF">;</span></span></code></pre>
22
+ <h6 id="parameters">Parameters</h6>
23
+ <div class="table-scroll">
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+ <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>raw</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><code>message</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
41
+ <h6 id="returns">Returns</h6>
42
+ <p><a href="#rtdbexpressionsyntaxerror"><code>RtdbExpressionSyntaxError</code></a></p>
43
+ <h6 id="overrides">Overrides</h6>
44
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#E5C07B">Error</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">constructor</span></span></code></pre>
45
+ <h4 id="properties">Properties</h4>
46
+ <div class="table-scroll">
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+ <table><thead><tr><th align="left">Property</th><th align="left">Modifier</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><a id="raw"></a> <code>raw</code></td><td align="left"><code>readonly</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
62
+ <hr>
11
63
  <p><a id="rulesassertionerror"></a></p>
12
64
  <h3 id="rulesassertionerror">RulesAssertionError</h3>
13
65
  <p>Thrown by <code>assertCase</code> / a runner case’s <code>run()</code> when the simulated
14
66
  decision did not match the case’s expectation. The message is the
15
67
  rendered trace from <code>explainCase</code>, so a test runner surfaces the “why”
16
68
  without extra wiring.</p>
17
- <h4 id="extends">Extends</h4>
69
+ <h4 id="extends-1">Extends</h4>
18
70
  <ul>
19
71
  <li><code>Error</code></li>
20
72
  </ul>
21
- <h4 id="constructors">Constructors</h4>
22
- <p><a id="constructor"></a></p>
23
- <h5 id="constructor">Constructor</h5>
73
+ <h4 id="constructors-1">Constructors</h4>
74
+ <p><a id="constructor-1"></a></p>
75
+ <h5 id="constructor-1">Constructor</h5>
24
76
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">new</span><span style="color:#61AFEF"> RulesAssertionError</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">message</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">string</span><span style="color:#ABB2BF">): </span><span style="color:#E06C75">RulesAssertionError</span><span style="color:#ABB2BF">;</span></span></code></pre>
25
- <h6 id="parameters">Parameters</h6>
77
+ <h6 id="parameters-1">Parameters</h6>
26
78
  <div class="table-scroll">
27
79
 
28
80
 
@@ -37,9 +89,9 @@ without extra wiring.</p>
37
89
 
38
90
 
39
91
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>message</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
40
- <h6 id="returns">Returns</h6>
92
+ <h6 id="returns-1">Returns</h6>
41
93
  <p><a href="#rulesassertionerror"><code>RulesAssertionError</code></a></p>
42
- <h6 id="overrides">Overrides</h6>
94
+ <h6 id="overrides-1">Overrides</h6>
43
95
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#E5C07B">Error</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">constructor</span></span></code></pre>
44
96
  <hr>
45
97
  <p><a id="rulescompileerror"></a></p>
@@ -47,15 +99,15 @@ without extra wiring.</p>
47
99
  <p>Thrown by <code>firestoreRules(source)</code> / <code>rtdbRules(...)</code> when the source
48
100
  cannot compile. Carries the compile-blocking issues on <code>.issues</code> so a
49
101
  caller can surface them without re-parsing.</p>
50
- <h4 id="extends-1">Extends</h4>
102
+ <h4 id="extends-2">Extends</h4>
51
103
  <ul>
52
104
  <li><code>Error</code></li>
53
105
  </ul>
54
- <h4 id="constructors-1">Constructors</h4>
55
- <p><a id="constructor-1"></a></p>
56
- <h5 id="constructor-1">Constructor</h5>
106
+ <h4 id="constructors-2">Constructors</h4>
107
+ <p><a id="constructor-2"></a></p>
108
+ <h5 id="constructor-2">Constructor</h5>
57
109
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">new</span><span style="color:#61AFEF"> RulesCompileError</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">message</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">string</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">issues</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">RuleIssue</span><span style="color:#ABB2BF">[]): </span><span style="color:#E06C75">RulesCompileError</span><span style="color:#ABB2BF">;</span></span></code></pre>
58
- <h6 id="parameters-1">Parameters</h6>
110
+ <h6 id="parameters-2">Parameters</h6>
59
111
  <div class="table-scroll">
60
112
 
61
113
 
@@ -74,11 +126,11 @@ caller can surface them without re-parsing.</p>
74
126
 
75
127
 
76
128
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>message</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><code>issues</code></td><td align="left"><a href="#ruleissue"><code>RuleIssue</code></a>[]</td></tr></tbody></table></div>
77
- <h6 id="returns-1">Returns</h6>
129
+ <h6 id="returns-2">Returns</h6>
78
130
  <p><a href="#rulescompileerror"><code>RulesCompileError</code></a></p>
79
- <h6 id="overrides-1">Overrides</h6>
131
+ <h6 id="overrides-2">Overrides</h6>
80
132
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#E5C07B">Error</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">constructor</span></span></code></pre>
81
- <h4 id="properties">Properties</h4>
133
+ <h4 id="properties-1">Properties</h4>
82
134
  <div class="table-scroll">
83
135
 
84
136
 
@@ -103,15 +155,15 @@ abstained — it hit a feature it does not implement, so neither a pass nor
103
155
  a genuine failure can be asserted. Distinct from
104
156
  <a href="#rulesassertionerror">RulesAssertionError</a> so a runner can choose to skip rather than
105
157
  fail on a known simulator gap.</p>
106
- <h4 id="extends-2">Extends</h4>
158
+ <h4 id="extends-3">Extends</h4>
107
159
  <ul>
108
160
  <li><code>Error</code></li>
109
161
  </ul>
110
- <h4 id="constructors-2">Constructors</h4>
111
- <p><a id="constructor-2"></a></p>
112
- <h5 id="constructor-2">Constructor</h5>
162
+ <h4 id="constructors-3">Constructors</h4>
163
+ <p><a id="constructor-3"></a></p>
164
+ <h5 id="constructor-3">Constructor</h5>
113
165
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">new</span><span style="color:#61AFEF"> RulesUnsupportedError</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">message</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">string</span><span style="color:#ABB2BF">): </span><span style="color:#E06C75">RulesUnsupportedError</span><span style="color:#ABB2BF">;</span></span></code></pre>
114
- <h6 id="parameters-2">Parameters</h6>
166
+ <h6 id="parameters-3">Parameters</h6>
115
167
  <div class="table-scroll">
116
168
 
117
169
 
@@ -126,16 +178,16 @@ fail on a known simulator gap.</p>
126
178
 
127
179
 
128
180
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>message</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
129
- <h6 id="returns-2">Returns</h6>
181
+ <h6 id="returns-3">Returns</h6>
130
182
  <p><a href="#rulesunsupportederror"><code>RulesUnsupportedError</code></a></p>
131
- <h6 id="overrides-2">Overrides</h6>
183
+ <h6 id="overrides-3">Overrides</h6>
132
184
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#E5C07B">Error</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">constructor</span></span></code></pre>
133
185
  <h2 id="interfaces">Interfaces</h2>
134
186
  <p><a id="caseresult"></a></p>
135
187
  <h3 id="caseresult">CaseResult</h3>
136
188
  <p>The outcome of running one Firestore case through <code>simulate</code>. Never a
137
189
  thrown error — a denied or abstained case is data, not an exception.</p>
138
- <h4 id="properties-1">Properties</h4>
190
+ <h4 id="properties-2">Properties</h4>
139
191
  <div class="table-scroll">
140
192
 
141
193
 
@@ -208,6 +260,26 @@ thrown error — a denied or abstained case is data, not an exception.</p>
208
260
 
209
261
  <table><thead><tr><th align="left">Property</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><a id="case"></a> <code>case</code></td><td align="left"><a href="#firestorecase"><code>FirestoreCase</code></a></td><td align="left">The case that produced this result.</td></tr><tr><td align="left"><a id="decision"></a> <code>decision</code></td><td align="left"><code>"UNSUPPORTED"</code> | <code>"ALLOW"</code> | <code>"DENY"</code></td><td align="left">The engine’s absolute verdict, independent of expectation.</td></tr><tr><td align="left"><a id="description"></a> <code>description</code></td><td align="left"><code>string</code></td><td align="left">-</td></tr><tr><td align="left"><a id="evaluatedexpressions"></a> <code>evaluatedExpressions</code></td><td align="left"><code>number</code></td><td align="left">Expressions the request evaluated, in the unit of production’s per-request limit of 1000, across every allow rule and match block it reached. <code>1000 - evaluatedExpressions</code> is the request’s margin. See <code>TestResult.evaluatedExpressions</code> for the unit.</td></tr><tr><td align="left"><a id="expectation"></a> <code>expectation</code></td><td align="left"><code>"ALLOW"</code> | <code>"DENY"</code></td><td align="left">-</td></tr><tr><td align="left"><a id="notes"></a> <code>notes</code></td><td align="left"><code>string</code>[]</td><td align="left">Top-level diagnostic strings.</td></tr><tr><td align="left"><a id="passed"></a> <code>passed</code></td><td align="left"><code>boolean</code></td><td align="left"><code>true</code> when <code>decision</code> matched <code>expectation</code>.</td></tr><tr><td align="left"><a id="pathresolution"></a> <code>pathResolution?</code></td><td align="left"><a href="#pathresolutiontrace"><code>PathResolutionTrace</code></a></td><td align="left">Which match blocks the resolver considered and where each fell apart.</td></tr><tr><td align="left"><a id="queryproof"></a> <code>queryProof?</code></td><td align="left"><a href="#listqueryproofreport"><code>ListQueryProofReport</code></a></td><td align="left">Static list-query proof verdict for <code>list</code> cases, separate from per-document <code>decision</code> (#371).</td></tr><tr><td align="left"><a id="resourcelimit"></a> <code>resourceLimit?</code></td><td align="left"><a href="#rulesresourcelimit"><code>RulesResourceLimit</code></a></td><td align="left">The per-request limit that stopped the request, when one did. A request past 1000 expressions is DENY with <code>kind: 'expressions'</code> and production’s message.</td></tr><tr><td align="left"><a id="trace"></a> <code>trace</code></td><td align="left"><a href="#ruleevaluation"><code>RuleEvaluation</code></a>[]</td><td align="left">Per-rule evaluation entries in source order.</td></tr><tr><td align="left"><a id="unsupported"></a> <code>unsupported</code></td><td align="left"><code>boolean</code></td><td align="left"><code>true</code> when the simulator abstained on a feature it does not implement — neither a pass nor a genuine failure.</td></tr></tbody></table></div>
210
262
  <hr>
263
+ <p><a id="diffrtdbrulesoptions"></a></p>
264
+ <h3 id="diffrtdbrulesoptions">DiffRtdbRulesOptions</h3>
265
+ <h4 id="properties-3">Properties</h4>
266
+ <div class="table-scroll">
267
+
268
+
269
+
270
+
271
+
272
+
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+
281
+ <table><thead><tr><th align="left">Property</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><a id="ignoreequivalent"></a> <code>ignoreEquivalent?</code></td><td align="left"><code>boolean</code></td><td align="left">Treat two <code>.read</code>, <code>.write</code> or <code>.validate</code> expressions as the same rule when their <a href="#canonicalrtdbexpression">canonicalRtdbExpression</a> texts are equal: spellings that cannot change any decision, such as <code>===</code> for <code>==</code> or <code>child('a/' + $id)</code> for <code>child('a').child($id)</code>. A changed entry still reports both expressions as written. An expression that does not parse is compared as written. Default <code>false</code>: expressions compare as text.</td></tr></tbody></table></div>
282
+ <hr>
211
283
  <p><a id="evaluatedruleinfo"></a></p>
212
284
  <h3 id="evaluatedruleinfo">EvaluatedRuleInfo</h3>
213
285
  <p>The DECIDING rule’s source position + sub-expression trace, projected from a
@@ -218,7 +290,7 @@ strings (dropping <code>line</code> and <code>expressionTrace</code>); this pres
218
290
  structured detail a UI needs to point at the exact source line and step
219
291
  through the evaluation (“show the work”). Position/trace fields are optional
220
292
  so a partial trace projects honestly.</p>
221
- <h4 id="properties-2">Properties</h4>
293
+ <h4 id="properties-4">Properties</h4>
222
294
  <div class="table-scroll">
223
295
 
224
296
 
@@ -274,7 +346,7 @@ so a partial trace projects honestly.</p>
274
346
  <p><a id="explanation"></a></p>
275
347
  <h3 id="explanation">Explanation</h3>
276
348
  <p>The structured account of why one Firestore case resolved as it did.</p>
277
- <h4 id="properties-3">Properties</h4>
349
+ <h4 id="properties-5">Properties</h4>
278
350
  <div class="table-scroll">
279
351
 
280
352
 
@@ -345,7 +417,7 @@ so a partial trace projects honestly.</p>
345
417
  <p><a id="exprtraceentry"></a></p>
346
418
  <h3 id="exprtraceentry">ExprTraceEntry</h3>
347
419
  <p>One entry in a per-rule expression trace, emitted in evaluation order.</p>
348
- <h4 id="properties-4">Properties</h4>
420
+ <h4 id="properties-6">Properties</h4>
349
421
  <div class="table-scroll">
350
422
 
351
423
 
@@ -406,7 +478,7 @@ so a partial trace projects honestly.</p>
406
478
  <p>One Firestore rules case: a single request plus the outcome it should
407
479
  produce. Structurally identical to the engine’s <code>TestCase</code> — re-exported
408
480
  here under the public name so callers never reach into the engine seam.</p>
409
- <h4 id="properties-5">Properties</h4>
481
+ <h4 id="properties-7">Properties</h4>
410
482
  <div class="table-scroll">
411
483
 
412
484
 
@@ -511,7 +583,7 @@ here under the public name so callers never reach into the engine seam.</p>
511
583
  <h5 id="explain">explain()</h5>
512
584
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#61AFEF">explain</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">oneCase</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">FirestoreCase</span><span style="color:#ABB2BF">): </span><span style="color:#E06C75">Explanation</span><span style="color:#ABB2BF">;</span></span></code></pre>
513
585
  <p>The structured account of why one case resolved as it did.</p>
514
- <h6 id="parameters-3">Parameters</h6>
586
+ <h6 id="parameters-4">Parameters</h6>
515
587
  <div class="table-scroll">
516
588
 
517
589
 
@@ -526,21 +598,21 @@ here under the public name so callers never reach into the engine seam.</p>
526
598
 
527
599
 
528
600
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>oneCase</code></td><td align="left"><a href="#firestorecase"><code>FirestoreCase</code></a></td></tr></tbody></table></div>
529
- <h6 id="returns-3">Returns</h6>
601
+ <h6 id="returns-4">Returns</h6>
530
602
  <p><a href="#explanation"><code>Explanation</code></a></p>
531
603
  <p><a id="lint"></a></p>
532
604
  <h5 id="lint">lint()</h5>
533
605
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#61AFEF">lint</span><span style="color:#ABB2BF">(): </span><span style="color:#E06C75">RuleIssue</span><span style="color:#ABB2BF">[];</span></span></code></pre>
534
606
  <p>Structural, security, and budget findings on the compiled ruleset.
535
607
  No parse errors — the source already compiled.</p>
536
- <h6 id="returns-4">Returns</h6>
608
+ <h6 id="returns-5">Returns</h6>
537
609
  <p><a href="#ruleissue"><code>RuleIssue</code></a>[]</p>
538
610
  <p><a id="simulate"></a></p>
539
611
  <h5 id="simulate">simulate()</h5>
540
612
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#61AFEF">simulate</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">cases</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">FirestoreCase</span><span style="color:#ABB2BF">[]): </span><span style="color:#E06C75">SimulationSummary</span><span style="color:#ABB2BF">;</span></span></code></pre>
541
613
  <p>Run every case. Never throws on a rule outcome: a denied or abstained
542
614
  case is reported in the returned summary.</p>
543
- <h6 id="parameters-4">Parameters</h6>
615
+ <h6 id="parameters-5">Parameters</h6>
544
616
  <div class="table-scroll">
545
617
 
546
618
 
@@ -555,20 +627,20 @@ case is reported in the returned summary.</p>
555
627
 
556
628
 
557
629
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>cases</code></td><td align="left"><a href="#firestorecase"><code>FirestoreCase</code></a>[]</td></tr></tbody></table></div>
558
- <h6 id="returns-5">Returns</h6>
630
+ <h6 id="returns-6">Returns</h6>
559
631
  <p><a href="#simulationsummary"><code>SimulationSummary</code></a></p>
560
632
  <p><a id="tojson"></a></p>
561
633
  <h5 id="tojson">toJSON()</h5>
562
634
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#61AFEF">toJSON</span><span style="color:#ABB2BF">(): </span><span style="color:#E06C75">FirestoreRules</span><span style="color:#ABB2BF">;</span></span></code></pre>
563
635
  <p>The parsed ruleset as plain data (the AST).</p>
564
- <h6 id="returns-6">Returns</h6>
636
+ <h6 id="returns-7">Returns</h6>
565
637
  <p><code>FirestoreRules</code></p>
566
638
  <hr>
567
639
  <p><a id="listqueryproofreport"></a></p>
568
640
  <h3 id="listqueryproofreport">ListQueryProofReport</h3>
569
641
  <p>Separate static list-query proof verdict reported alongside per-document
570
642
  evaluation on <code>TestResult</code> / <code>CaseResult</code> / <code>Explanation</code> (#371).</p>
571
- <h4 id="properties-6">Properties</h4>
643
+ <h4 id="properties-8">Properties</h4>
572
644
  <div class="table-scroll">
573
645
 
574
646
 
@@ -624,7 +696,7 @@ evaluation on <code>TestResult</code> / <code>CaseResult</code> / <code>Explanat
624
696
  <p><a id="pathdef"></a></p>
625
697
  <h3 id="pathdef">PathDef</h3>
626
698
  <p>Definition of rules for a single database path.</p>
627
- <h4 id="properties-7">Properties</h4>
699
+ <h4 id="properties-9">Properties</h4>
628
700
  <div class="table-scroll">
629
701
 
630
702
 
@@ -681,7 +753,7 @@ each attempt fall apart?” — useful for the agent when a request
681
753
  lands in the default-deny path because no block matched.</p>
682
754
  <p>Recorded only by the local simulator; the production Test API
683
755
  client doesn’t expose path-resolution internals.</p>
684
- <h4 id="properties-8">Properties</h4>
756
+ <h4 id="properties-10">Properties</h4>
685
757
  <div class="table-scroll">
686
758
 
687
759
 
@@ -731,7 +803,7 @@ client doesn’t expose path-resolution internals.</p>
731
803
  <hr>
732
804
  <p><a id="pathresolutiontrace"></a></p>
733
805
  <h3 id="pathresolutiontrace">PathResolutionTrace</h3>
734
- <h4 id="properties-9">Properties</h4>
806
+ <h4 id="properties-11">Properties</h4>
735
807
  <div class="table-scroll">
736
808
 
737
809
 
@@ -757,7 +829,7 @@ client doesn’t expose path-resolution internals.</p>
757
829
  <p><a id="queryprooffailure"></a></p>
758
830
  <h3 id="queryprooffailure">QueryProofFailure</h3>
759
831
  <p>Local proof evidence. These categories do not claim a Firebase decision.</p>
760
- <h4 id="properties-10">Properties</h4>
832
+ <h4 id="properties-12">Properties</h4>
761
833
  <div class="table-scroll">
762
834
 
763
835
 
@@ -864,7 +936,7 @@ client doesn’t expose path-resolution internals.</p>
864
936
  shape equality analysis can’t discharge (disjunction / range / <code>in</code> / nested
865
937
  path), so no query constraint could prove it — no suggestion is possible.</li>
866
938
  </ul>
867
- <h4 id="properties-11">Properties</h4>
939
+ <h4 id="properties-13">Properties</h4>
868
940
  <div class="table-scroll">
869
941
 
870
942
 
@@ -905,7 +977,7 @@ path), so no query constraint could prove it — no suggestion is possible.</li>
905
977
  <p><a id="queryrepro"></a></p>
906
978
  <h3 id="queryrepro">QueryRepro</h3>
907
979
  <p>Ready-to-run repro for a rejected list query (#371).</p>
908
- <h4 id="properties-12">Properties</h4>
980
+ <h4 id="properties-14">Properties</h4>
909
981
  <div class="table-scroll">
910
982
 
911
983
 
@@ -994,7 +1066,7 @@ path), so no query constraint could prove it — no suggestion is possible.</li>
994
1066
  run can partition cases into passed/failed the same way Firestore does —
995
1067
  the RTDB simulator otherwise returns only a raw allow/deny with no notion
996
1068
  of an expectation.</p>
997
- <h4 id="properties-13">Properties</h4>
1069
+ <h4 id="properties-15">Properties</h4>
998
1070
  <div class="table-scroll">
999
1071
 
1000
1072
 
@@ -1067,7 +1139,7 @@ of an expectation.</p>
1067
1139
  <p>The query a Realtime Database read carries, in the members rules read as
1068
1140
  <code>query.*</code>. At most one <code>orderBy*</code> member and at most one limit may be set,
1069
1141
  as in the SDK.</p>
1070
- <h4 id="properties-14">Properties</h4>
1142
+ <h4 id="properties-16">Properties</h4>
1071
1143
  <div class="table-scroll">
1072
1144
 
1073
1145
 
@@ -1114,7 +1186,7 @@ as in the SDK.</p>
1114
1186
  <p><a id="rtdbcaseresult"></a></p>
1115
1187
  <h3 id="rtdbcaseresult">RtdbCaseResult</h3>
1116
1188
  <p>The outcome of running one RTDB case through <code>simulate</code>.</p>
1117
- <h4 id="properties-15">Properties</h4>
1189
+ <h4 id="properties-17">Properties</h4>
1118
1190
  <div class="table-scroll">
1119
1191
 
1120
1192
 
@@ -1184,7 +1256,7 @@ as in the SDK.</p>
1184
1256
  <hr>
1185
1257
  <p><a id="rtdbcoverageoptions"></a></p>
1186
1258
  <h3 id="rtdbcoverageoptions">RtdbCoverageOptions</h3>
1187
- <h4 id="properties-16">Properties</h4>
1259
+ <h4 id="properties-18">Properties</h4>
1188
1260
  <div class="table-scroll">
1189
1261
 
1190
1262
 
@@ -1209,7 +1281,7 @@ as in the SDK.</p>
1209
1281
  <hr>
1210
1282
  <p><a id="rtdbcoveragesummary"></a></p>
1211
1283
  <h3 id="rtdbcoveragesummary">RtdbCoverageSummary</h3>
1212
- <h4 id="properties-17">Properties</h4>
1284
+ <h4 id="properties-19">Properties</h4>
1213
1285
  <div class="table-scroll">
1214
1286
 
1215
1287
 
@@ -1244,7 +1316,7 @@ as in the SDK.</p>
1244
1316
  <hr>
1245
1317
  <p><a id="rtdbexplanation"></a></p>
1246
1318
  <h3 id="rtdbexplanation">RtdbExplanation</h3>
1247
- <h4 id="properties-18">Properties</h4>
1319
+ <h4 id="properties-20">Properties</h4>
1248
1320
  <div class="table-scroll">
1249
1321
 
1250
1322
 
@@ -1304,7 +1376,7 @@ as in the SDK.</p>
1304
1376
  <hr>
1305
1377
  <p><a id="rtdbfilecoverage"></a></p>
1306
1378
  <h3 id="rtdbfilecoverage">RtdbFileCoverage</h3>
1307
- <h4 id="properties-19">Properties</h4>
1379
+ <h4 id="properties-21">Properties</h4>
1308
1380
  <div class="table-scroll">
1309
1381
 
1310
1382
 
@@ -1355,7 +1427,7 @@ each instance, for <code>rtdbRules.fromFirebaseJson</code>.</p>
1355
1427
  browser graphs, so <code>node:fs</code> and <code>node:path</code> are acquired lazily through
1356
1428
  <code>process.getBuiltinModule</code>; in a browser the loader throws saying it needs
1357
1429
  a file system.</p>
1358
- <h4 id="properties-20">Properties</h4>
1430
+ <h4 id="properties-22">Properties</h4>
1359
1431
  <div class="table-scroll">
1360
1432
 
1361
1433
 
@@ -1373,9 +1445,46 @@ a file system.</p>
1373
1445
 
1374
1446
  <table><thead><tr><th align="left">Property</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><a id="projectid"></a> <code>projectId?</code></td><td align="left"><code>string</code></td><td align="left">The project id, which names the default instance <code>&#x3C;projectId>-default-rtdb</code> and selects the <code>.firebaserc</code> deploy-target mappings. Defaults to <code>projects.default</code> in the <code>.firebaserc</code> beside <code>firebase.json</code>.</td></tr></tbody></table></div>
1375
1447
  <hr>
1448
+ <p><a id="rtdbrulechange"></a></p>
1449
+ <h3 id="rtdbrulechange">RtdbRuleChange</h3>
1450
+ <p>One rule expression that differs. <code>deployed</code> is absent for <code>added</code> and
1451
+ <code>local</code> is absent for <code>removed</code>: the change is what deploying the local
1452
+ ruleset would do to the deployed one.</p>
1453
+ <h4 id="properties-23">Properties</h4>
1454
+ <div class="table-scroll">
1455
+
1456
+
1457
+
1458
+
1459
+
1460
+
1461
+
1462
+
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+
1482
+
1483
+ <table><thead><tr><th align="left">Property</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><a id="change"></a> <code>change</code></td><td align="left"><code>"added"</code> | <code>"removed"</code> | <code>"changed"</code></td></tr><tr><td align="left"><a id="deployed"></a> <code>deployed?</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><a id="kind-3"></a> <code>kind</code></td><td align="left"><a href="#rtdbrulekind"><code>RtdbRuleKind</code></a></td></tr><tr><td align="left"><a id="local"></a> <code>local?</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><a id="path-2"></a> <code>path</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
1484
+ <hr>
1376
1485
  <p><a id="rtdbrulecoverage"></a></p>
1377
1486
  <h3 id="rtdbrulecoverage">RtdbRuleCoverage</h3>
1378
- <h4 id="properties-21">Properties</h4>
1487
+ <h4 id="properties-24">Properties</h4>
1379
1488
  <div class="table-scroll">
1380
1489
 
1381
1490
 
@@ -1441,11 +1550,11 @@ a file system.</p>
1441
1550
 
1442
1551
 
1443
1552
 
1444
- <table><thead><tr><th align="left">Property</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><a id="allow"></a> <code>allow</code></td><td align="left"><code>number</code></td><td align="left">-</td></tr><tr><td align="left"><a id="deny"></a> <code>deny</code></td><td align="left"><code>number</code></td><td align="left">-</td></tr><tr><td align="left"><a id="error-1"></a> <code>error</code></td><td align="left"><code>number</code></td><td align="left">-</td></tr><tr><td align="left"><a id="evaluated"></a> <code>evaluated</code></td><td align="left"><code>number</code></td><td align="left">Evaluations that produced a verdict: <code>allow + deny + error</code>.</td></tr><tr><td align="left"><a id="expression-1"></a> <code>expression</code></td><td align="left"><code>string</code></td><td align="left">The rule expression, or the declared index list for <code>indexOn</code>.</td></tr><tr><td align="left"><a id="file-3"></a> <code>file?</code></td><td align="left"><code>string</code></td><td align="left">The rules file holding the node, when the summary covers several files.</td></tr><tr><td align="left"><a id="kind-3"></a> <code>kind</code></td><td align="left"><a href="#rtdbcoveragekind"><code>RtdbCoverageKind</code></a></td><td align="left">-</td></tr><tr><td align="left"><a id="line-2"></a> <code>line?</code></td><td align="left"><code>number</code></td><td align="left">1-indexed line in the rules file, when a line lookup was supplied.</td></tr><tr><td align="left"><a id="path-2"></a> <code>path</code></td><td align="left"><code>string</code></td><td align="left">The rule node’s path, such as <code>/rooms/$roomId</code>.</td></tr><tr><td align="left"><a id="status"></a> <code>status</code></td><td align="left"><a href="#rtdbcoveragestatus"><code>RtdbCoverageStatus</code></a></td><td align="left">-</td></tr><tr><td align="left"><a id="unsupported-5"></a> <code>unsupported</code></td><td align="left"><code>number</code></td><td align="left">-</td></tr></tbody></table></div>
1553
+ <table><thead><tr><th align="left">Property</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><a id="allow"></a> <code>allow</code></td><td align="left"><code>number</code></td><td align="left">-</td></tr><tr><td align="left"><a id="deny"></a> <code>deny</code></td><td align="left"><code>number</code></td><td align="left">-</td></tr><tr><td align="left"><a id="error-1"></a> <code>error</code></td><td align="left"><code>number</code></td><td align="left">-</td></tr><tr><td align="left"><a id="evaluated"></a> <code>evaluated</code></td><td align="left"><code>number</code></td><td align="left">Evaluations that produced a verdict: <code>allow + deny + error</code>.</td></tr><tr><td align="left"><a id="expression-1"></a> <code>expression</code></td><td align="left"><code>string</code></td><td align="left">The rule expression, or the declared index list for <code>indexOn</code>.</td></tr><tr><td align="left"><a id="file-3"></a> <code>file?</code></td><td align="left"><code>string</code></td><td align="left">The rules file holding the node, when the summary covers several files.</td></tr><tr><td align="left"><a id="kind-4"></a> <code>kind</code></td><td align="left"><a href="#rtdbcoveragekind"><code>RtdbCoverageKind</code></a></td><td align="left">-</td></tr><tr><td align="left"><a id="line-2"></a> <code>line?</code></td><td align="left"><code>number</code></td><td align="left">1-indexed line in the rules file, when a line lookup was supplied.</td></tr><tr><td align="left"><a id="path-3"></a> <code>path</code></td><td align="left"><code>string</code></td><td align="left">The rule node’s path, such as <code>/rooms/$roomId</code>.</td></tr><tr><td align="left"><a id="status"></a> <code>status</code></td><td align="left"><a href="#rtdbcoveragestatus"><code>RtdbCoverageStatus</code></a></td><td align="left">-</td></tr><tr><td align="left"><a id="unsupported-5"></a> <code>unsupported</code></td><td align="left"><code>number</code></td><td align="left">-</td></tr></tbody></table></div>
1445
1554
  <hr>
1446
1555
  <p><a id="rtdbrulescheckresult"></a></p>
1447
1556
  <h3 id="rtdbrulescheckresult">RtdbRulesCheckResult</h3>
1448
- <h4 id="properties-22">Properties</h4>
1557
+ <h4 id="properties-25">Properties</h4>
1449
1558
  <div class="table-scroll">
1450
1559
 
1451
1560
 
@@ -1478,7 +1587,7 @@ instance.</p>
1478
1587
  <p>Build a deep handle on a Realtime Database ruleset from the text of a
1479
1588
  <code>database.rules.json</code> file, a definition, a compiled document, or compiled
1480
1589
  <code>{ rules }</code> JSON.</p>
1481
- <h4 id="parameters-5">Parameters</h4>
1590
+ <h4 id="parameters-6">Parameters</h4>
1482
1591
  <div class="table-scroll">
1483
1592
 
1484
1593
 
@@ -1493,7 +1602,7 @@ instance.</p>
1493
1602
 
1494
1603
 
1495
1604
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>input</code></td><td align="left"><code>string</code> | <code>RtdbRulesInput</code></td></tr></tbody></table></div>
1496
- <h4 id="returns-7">Returns</h4>
1605
+ <h4 id="returns-8">Returns</h4>
1497
1606
  <p><a href="#rtdbruleset"><code>RtdbRuleset</code></a></p>
1498
1607
  <h4 id="throws">Throws</h4>
1499
1608
  <p>when rules text is not JSON (after comments
@@ -1515,7 +1624,7 @@ beside <code>firebase.json</code>. A case that
1515
1624
  names an instance <code>firebase.json</code> deploys no rules to is UNSUPPORTED, with
1516
1625
  a reason naming the instances it does.</p>
1517
1626
  <p>Node-only: it reads files.</p>
1518
- <h6 id="parameters-6">Parameters</h6>
1627
+ <h6 id="parameters-7">Parameters</h6>
1519
1628
  <div class="table-scroll">
1520
1629
 
1521
1630
 
@@ -1534,7 +1643,7 @@ a reason naming the instances it does.</p>
1534
1643
 
1535
1644
 
1536
1645
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>firebaseJsonPath</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><code>options?</code></td><td align="left"><a href="#rtdbfirebasejsonoptions"><code>RtdbFirebaseJsonOptions</code></a></td></tr></tbody></table></div>
1537
- <h6 id="returns-8">Returns</h6>
1646
+ <h6 id="returns-9">Returns</h6>
1538
1647
  <p><a href="#rtdbruleset"><code>RtdbRuleset</code></a></p>
1539
1648
  <h6 id="throws-1">Throws</h6>
1540
1649
  <p>when a rules file is not rules text.</p>
@@ -1544,7 +1653,7 @@ Realtime Database rules, or a deploy target maps to no instance.</p>
1544
1653
  <hr>
1545
1654
  <p><a id="rtdbrulesdefinition"></a></p>
1546
1655
  <h3 id="rtdbrulesdefinition">RtdbRulesDefinition</h3>
1547
- <h4 id="properties-23">Properties</h4>
1656
+ <h4 id="properties-26">Properties</h4>
1548
1657
  <div class="table-scroll">
1549
1658
 
1550
1659
 
@@ -1567,7 +1676,7 @@ Realtime Database rules, or a deploy target maps to no instance.</p>
1567
1676
  value you author and hand to <code>rtdbRules()</code>, which is the one analysis
1568
1677
  surface (<code>lint</code> / <code>simulate</code> / <code>explain</code> / <code>toJSON</code>). The brand is
1569
1678
  type-level only; nothing exists at runtime.</p>
1570
- <h4 id="properties-24">Properties</h4>
1679
+ <h4 id="properties-27">Properties</h4>
1571
1680
  <div class="table-scroll">
1572
1681
 
1573
1682
 
@@ -1597,7 +1706,7 @@ for its own cases; call it to merge several runs or to attach a file name
1597
1706
  and line numbers. A ruleset from <a href="#fromfirebasejson">rtdbRules.fromFirebaseJson</a>
1598
1707
  reports each rules file under the name <code>firebase.json</code> gives it, with
1599
1708
  lines located in its text, and takes no options.</p>
1600
- <h6 id="parameters-7">Parameters</h6>
1709
+ <h6 id="parameters-8">Parameters</h6>
1601
1710
  <div class="table-scroll">
1602
1711
 
1603
1712
 
@@ -1616,13 +1725,13 @@ lines located in its text, and takes no options.</p>
1616
1725
 
1617
1726
 
1618
1727
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>results</code></td><td align="left">readonly <a href="#rtdbcaseresult"><code>RtdbCaseResult</code></a>[]</td></tr><tr><td align="left"><code>options?</code></td><td align="left"><a href="#rtdbcoverageoptions"><code>RtdbCoverageOptions</code></a></td></tr></tbody></table></div>
1619
- <h6 id="returns-9">Returns</h6>
1728
+ <h6 id="returns-10">Returns</h6>
1620
1729
  <p><a href="#rtdbcoveragesummary"><code>RtdbCoverageSummary</code></a></p>
1621
1730
  <p><a id="explain-2"></a></p>
1622
1731
  <h5 id="explain-1">explain()</h5>
1623
1732
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#61AFEF">explain</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">oneCase</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">RtdbCase</span><span style="color:#ABB2BF">): </span><span style="color:#E06C75">RtdbExplanation</span><span style="color:#ABB2BF">;</span></span></code></pre>
1624
1733
  <p>The structured account of why one case resolved as it did.</p>
1625
- <h6 id="parameters-8">Parameters</h6>
1734
+ <h6 id="parameters-9">Parameters</h6>
1626
1735
  <div class="table-scroll">
1627
1736
 
1628
1737
 
@@ -1637,7 +1746,7 @@ lines located in its text, and takes no options.</p>
1637
1746
 
1638
1747
 
1639
1748
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>oneCase</code></td><td align="left"><a href="#rtdbcase"><code>RtdbCase</code></a></td></tr></tbody></table></div>
1640
- <h6 id="returns-10">Returns</h6>
1749
+ <h6 id="returns-11">Returns</h6>
1641
1750
  <p><a href="#rtdbexplanation"><code>RtdbExplanation</code></a></p>
1642
1751
  <p><a id="lint-2"></a></p>
1643
1752
  <h5 id="lint-1">lint()</h5>
@@ -1645,13 +1754,13 @@ lines located in its text, and takes no options.</p>
1645
1754
  <p>Structural findings on the compiled ruleset (from <code>check()</code>). On a
1646
1755
  ruleset from <a href="#fromfirebasejson">rtdbRules.fromFirebaseJson</a>, each rules file’s
1647
1756
  findings, once per file, with its <code>file</code>.</p>
1648
- <h6 id="returns-11">Returns</h6>
1757
+ <h6 id="returns-12">Returns</h6>
1649
1758
  <p><a href="#ruleissue"><code>RuleIssue</code></a>[]</p>
1650
1759
  <p><a id="simulate-2"></a></p>
1651
1760
  <h5 id="simulate-1">simulate()</h5>
1652
1761
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#61AFEF">simulate</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">cases</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">RtdbCase</span><span style="color:#ABB2BF">[]): </span><span style="color:#E06C75">RtdbSimulationSummary</span><span style="color:#ABB2BF">;</span></span></code></pre>
1653
1762
  <p>Run every case. Never throws on a rule outcome.</p>
1654
- <h6 id="parameters-9">Parameters</h6>
1763
+ <h6 id="parameters-10">Parameters</h6>
1655
1764
  <div class="table-scroll">
1656
1765
 
1657
1766
 
@@ -1666,7 +1775,7 @@ findings, once per file, with its <code>file</code>.</p>
1666
1775
 
1667
1776
 
1668
1777
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>cases</code></td><td align="left"><a href="#rtdbcase"><code>RtdbCase</code></a>[]</td></tr></tbody></table></div>
1669
- <h6 id="returns-12">Returns</h6>
1778
+ <h6 id="returns-13">Returns</h6>
1670
1779
  <p><a href="#rtdbsimulationsummary"><code>RtdbSimulationSummary</code></a></p>
1671
1780
  <p><a id="tojson-2"></a></p>
1672
1781
  <h5 id="tojson-1">toJSON()</h5>
@@ -1674,12 +1783,12 @@ findings, once per file, with its <code>file</code>.</p>
1674
1783
  <p>The compiled <code>rules.json</code>. On a ruleset from
1675
1784
  <a href="#fromfirebasejson">rtdbRules.fromFirebaseJson</a>, the default instance’s rules; it
1676
1785
  throws when <code>firebase.json</code> deploys none to the default instance.</p>
1677
- <h6 id="returns-13">Returns</h6>
1786
+ <h6 id="returns-14">Returns</h6>
1678
1787
  <p><a href="#rtdbrulesjson"><code>RtdbRulesJson</code></a></p>
1679
1788
  <hr>
1680
1789
  <p><a id="rtdbrulesfinding"></a></p>
1681
1790
  <h3 id="rtdbrulesfinding">RtdbRulesFinding</h3>
1682
- <h4 id="properties-25">Properties</h4>
1791
+ <h4 id="properties-28">Properties</h4>
1683
1792
  <div class="table-scroll">
1684
1793
 
1685
1794
 
@@ -1705,11 +1814,11 @@ throws when <code>firebase.json</code> deploys none to the default instance.</p>
1705
1814
 
1706
1815
 
1707
1816
 
1708
- <table><thead><tr><th align="left">Property</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><a id="code"></a> <code>code</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><a id="message"></a> <code>message</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><a id="path-3"></a> <code>path</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><a id="rule-2"></a> <code>rule</code></td><td align="left"><a href="#rtdbrulesfindingrule-1"><code>RtdbRulesFindingRule</code></a></td></tr></tbody></table></div>
1817
+ <table><thead><tr><th align="left">Property</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><a id="code"></a> <code>code</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><a id="message"></a> <code>message</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><a id="path-4"></a> <code>path</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><a id="rule-2"></a> <code>rule</code></td><td align="left"><a href="#rtdbrulesfindingrule-1"><code>RtdbRulesFindingRule</code></a></td></tr></tbody></table></div>
1709
1818
  <hr>
1710
1819
  <p><a id="rtdbsimulationsummary"></a></p>
1711
1820
  <h3 id="rtdbsimulationsummary">RtdbSimulationSummary</h3>
1712
- <h4 id="properties-26">Properties</h4>
1821
+ <h4 id="properties-29">Properties</h4>
1713
1822
  <div class="table-scroll">
1714
1823
 
1715
1824
 
@@ -1755,7 +1864,7 @@ source order.</p>
1755
1864
  <p>Populated only by the internal simulator (which has the parsed
1756
1865
  AST in hand); the production Test API client (<code>TestFirestoreRulesHandler</code>)
1757
1866
  returns an empty <code>trace</code> and surfaces the wire text on <code>TestResult.notes</code>.</p>
1758
- <h4 id="properties-27">Properties</h4>
1867
+ <h4 id="properties-30">Properties</h4>
1759
1868
  <div class="table-scroll">
1760
1869
 
1761
1870
 
@@ -1835,7 +1944,7 @@ returns an empty <code>trace</code> and surfaces the wire text on <code>TestResu
1835
1944
  <hr>
1836
1945
  <p><a id="ruleissue"></a></p>
1837
1946
  <h3 id="ruleissue">RuleIssue</h3>
1838
- <h4 id="properties-28">Properties</h4>
1947
+ <h4 id="properties-31">Properties</h4>
1839
1948
  <div class="table-scroll">
1840
1949
 
1841
1950
 
@@ -1891,12 +2000,12 @@ returns an empty <code>trace</code> and surfaces the wire text on <code>TestResu
1891
2000
 
1892
2001
 
1893
2002
 
1894
- <table><thead><tr><th align="left">Property</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><a id="code-1"></a> <code>code</code></td><td align="left"><code>string</code></td><td align="left">Stable machine code, e.g. <code>'PARSE_ERROR'</code>, <code>'SEC-4'</code>, <code>'GET_BUDGET'</code>.</td></tr><tr><td align="left"><a id="file-5"></a> <code>file?</code></td><td align="left"><code>string</code></td><td align="left">The Realtime Database rules file the issue is in, as <code>firebase.json</code> names it, for a ruleset read with <code>rtdbRules.fromFirebaseJson</code>.</td></tr><tr><td align="left"><a id="fix"></a> <code>fix?</code></td><td align="left"><code>string</code></td><td align="left">Suggested remediation, verbatim, when the producing stage offers one.</td></tr><tr><td align="left"><a id="line-4"></a> <code>line?</code></td><td align="left"><code>number</code></td><td align="left">1-indexed source line, when known.</td></tr><tr><td align="left"><a id="message-2"></a> <code>message</code></td><td align="left"><code>string</code></td><td align="left">Human-readable description.</td></tr><tr><td align="left"><a id="origin"></a> <code>origin</code></td><td align="left"><a href="#ruleissueorigin-1"><code>RuleIssueOrigin</code></a></td><td align="left">-</td></tr><tr><td align="left"><a id="path-4"></a> <code>path?</code></td><td align="left"><code>string</code></td><td align="left">Rules path the issue applies to, when known (e.g. <code>'/users/{uid}'</code>).</td></tr><tr><td align="left"><a id="rule-3"></a> <code>rule?</code></td><td align="left"><code>".read"</code> | <code>".write"</code> | <code>".validate"</code></td><td align="left">The Realtime Database rule at <code>path</code> the issue applies to. Absent for Firestore issues and for an RTDB issue about the whole ruleset.</td></tr><tr><td align="left"><a id="severity"></a> <code>severity</code></td><td align="left"><a href="#ruleissueseverity-1"><code>RuleIssueSeverity</code></a></td><td align="left">-</td></tr></tbody></table></div>
2003
+ <table><thead><tr><th align="left">Property</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><a id="code-1"></a> <code>code</code></td><td align="left"><code>string</code></td><td align="left">Stable machine code, e.g. <code>'PARSE_ERROR'</code>, <code>'SEC-4'</code>, <code>'GET_BUDGET'</code>.</td></tr><tr><td align="left"><a id="file-5"></a> <code>file?</code></td><td align="left"><code>string</code></td><td align="left">The Realtime Database rules file the issue is in, as <code>firebase.json</code> names it, for a ruleset read with <code>rtdbRules.fromFirebaseJson</code>.</td></tr><tr><td align="left"><a id="fix"></a> <code>fix?</code></td><td align="left"><code>string</code></td><td align="left">Suggested remediation, verbatim, when the producing stage offers one.</td></tr><tr><td align="left"><a id="line-4"></a> <code>line?</code></td><td align="left"><code>number</code></td><td align="left">1-indexed source line, when known.</td></tr><tr><td align="left"><a id="message-2"></a> <code>message</code></td><td align="left"><code>string</code></td><td align="left">Human-readable description.</td></tr><tr><td align="left"><a id="origin"></a> <code>origin</code></td><td align="left"><a href="#ruleissueorigin-1"><code>RuleIssueOrigin</code></a></td><td align="left">-</td></tr><tr><td align="left"><a id="path-5"></a> <code>path?</code></td><td align="left"><code>string</code></td><td align="left">Rules path the issue applies to, when known (e.g. <code>'/users/{uid}'</code>).</td></tr><tr><td align="left"><a id="rule-3"></a> <code>rule?</code></td><td align="left"><code>".read"</code> | <code>".write"</code> | <code>".validate"</code></td><td align="left">The Realtime Database rule at <code>path</code> the issue applies to. Absent for Firestore issues and for an RTDB issue about the whole ruleset.</td></tr><tr><td align="left"><a id="severity"></a> <code>severity</code></td><td align="left"><a href="#ruleissueseverity-1"><code>RuleIssueSeverity</code></a></td><td align="left">-</td></tr></tbody></table></div>
1895
2004
  <hr>
1896
2005
  <p><a id="rulesetcontext"></a></p>
1897
2006
  <h3 id="rulesetcontext">RulesetContext</h3>
1898
2007
  <p>Context passed to the callback overload of ruleset().</p>
1899
- <h4 id="properties-29">Properties</h4>
2008
+ <h4 id="properties-32">Properties</h4>
1900
2009
  <div class="table-scroll">
1901
2010
 
1902
2011
 
@@ -1910,7 +2019,7 @@ returns an empty <code>trace</code> and surfaces the wire text on <code>TestResu
1910
2019
 
1911
2020
 
1912
2021
 
1913
- <table><thead><tr><th align="left">Property</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><a id="path-5"></a> <code>path</code></td><td align="left">(<code>path</code>: <code>string</code>, <code>def</code>: <a href="#pathdef"><code>PathDef</code></a>) => <code>void</code></td></tr></tbody></table></div>
2022
+ <table><thead><tr><th align="left">Property</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><a id="path-6"></a> <code>path</code></td><td align="left">(<code>path</code>: <code>string</code>, <code>def</code>: <a href="#pathdef"><code>PathDef</code></a>) => <code>void</code></td></tr></tbody></table></div>
1914
2023
  <hr>
1915
2024
  <p><a id="rulesresourcelimit"></a></p>
1916
2025
  <h3 id="rulesresourcelimit">RulesResourceLimit</h3>
@@ -1926,7 +2035,7 @@ existsAfter() document accesses.</li>
1926
2035
  <p><code>line</code> and <code>column</code> place an <code>expressions</code> limit where production reports
1927
2036
  it: the 1-based line and column, in the evaluated source, of the
1928
2037
  expression the request was evaluating when the budget ran out.</p>
1929
- <h4 id="properties-30">Properties</h4>
2038
+ <h4 id="properties-33">Properties</h4>
1930
2039
  <div class="table-scroll">
1931
2040
 
1932
2041
 
@@ -1956,11 +2065,11 @@ expression the request was evaluating when the budget ran out.</p>
1956
2065
 
1957
2066
 
1958
2067
 
1959
- <table><thead><tr><th align="left">Property</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><a id="column-2"></a> <code>column?</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><a id="kind-4"></a> <code>kind</code></td><td align="left"><code>"expressions"</code> | <code>"document-lookups"</code></td></tr><tr><td align="left"><a id="limit"></a> <code>limit</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><a id="line-5"></a> <code>line?</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><a id="message-3"></a> <code>message</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2068
+ <table><thead><tr><th align="left">Property</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><a id="column-2"></a> <code>column?</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><a id="kind-5"></a> <code>kind</code></td><td align="left"><code>"expressions"</code> | <code>"document-lookups"</code></td></tr><tr><td align="left"><a id="limit"></a> <code>limit</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><a id="line-5"></a> <code>line?</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><a id="message-3"></a> <code>message</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
1960
2069
  <hr>
1961
2070
  <p><a id="schemarulesresult"></a></p>
1962
2071
  <h3 id="schemarulesresult">SchemaRulesResult</h3>
1963
- <h4 id="properties-31">Properties</h4>
2072
+ <h4 id="properties-34">Properties</h4>
1964
2073
  <div class="table-scroll">
1965
2074
 
1966
2075
 
@@ -1982,7 +2091,7 @@ expression the request was evaluating when the budget ran out.</p>
1982
2091
  <hr>
1983
2092
  <p><a id="shapeoptions"></a></p>
1984
2093
  <h3 id="shapeoptions">ShapeOptions</h3>
1985
- <h4 id="properties-32">Properties</h4>
2094
+ <h4 id="properties-35">Properties</h4>
1986
2095
  <div class="table-scroll">
1987
2096
 
1988
2097
 
@@ -2007,7 +2116,7 @@ expression the request was evaluating when the budget ran out.</p>
2007
2116
  <hr>
2008
2117
  <p><a id="shaperesult"></a></p>
2009
2118
  <h3 id="shaperesult">ShapeResult</h3>
2010
- <h4 id="properties-33">Properties</h4>
2119
+ <h4 id="properties-36">Properties</h4>
2011
2120
  <div class="table-scroll">
2012
2121
 
2013
2122
 
@@ -2031,7 +2140,7 @@ expression the request was evaluating when the budget ran out.</p>
2031
2140
  <h3 id="simulationsummary">SimulationSummary</h3>
2032
2141
  <p>Aggregate of a <code>simulate(cases)</code> run. Counts partition the cases:
2033
2142
  <code>passed + failed + unsupported === cases.length</code>.</p>
2034
- <h4 id="properties-34">Properties</h4>
2143
+ <h4 id="properties-37">Properties</h4>
2035
2144
  <div class="table-scroll">
2036
2145
 
2037
2146
 
@@ -2101,7 +2210,7 @@ expression the request was evaluating when the budget ran out.</p>
2101
2210
  <span class="line"><span style="color:#E06C75"> instances</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Record</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">Record</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">unknown</span><span style="color:#ABB2BF">>>;</span></span>
2102
2211
  <span class="line"><span style="color:#ABB2BF">};</span></span></code></pre>
2103
2212
  <p>A case’s data as one tree per database instance, keyed by instance name.</p>
2104
- <h4 id="properties-35">Properties</h4>
2213
+ <h4 id="properties-38">Properties</h4>
2105
2214
  <div class="table-scroll">
2106
2215
 
2107
2216
 
@@ -2121,6 +2230,10 @@ expression the request was evaluating when the budget ran out.</p>
2121
2230
  <h3 id="rtdbruleevaluation">RtdbRuleEvaluation</h3>
2122
2231
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">type</span><span style="color:#E5C07B"> RtdbRuleEvaluation</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> z</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">infer</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#C678DD">typeof</span><span style="color:#E06C75"> RtdbRuleEvaluationSchema</span><span style="color:#ABB2BF">>;</span></span></code></pre>
2123
2232
  <hr>
2233
+ <p><a id="rtdbrulekind"></a></p>
2234
+ <h3 id="rtdbrulekind">RtdbRuleKind</h3>
2235
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">type</span><span style="color:#E5C07B"> RtdbRuleKind</span><span style="color:#56B6C2"> =</span><span style="color:#98C379"> ".read"</span><span style="color:#ABB2BF"> | </span><span style="color:#98C379">".write"</span><span style="color:#ABB2BF"> | </span><span style="color:#98C379">".validate"</span><span style="color:#ABB2BF"> | </span><span style="color:#98C379">".indexOn"</span><span style="color:#ABB2BF">;</span></span></code></pre>
2236
+ <hr>
2124
2237
  <p><a id="rtdbrulesfindingrule-1"></a></p>
2125
2238
  <h3 id="rtdbrulesfindingrule">RtdbRulesFindingRule</h3>
2126
2239
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">type</span><span style="color:#E5C07B"> RtdbRulesFindingRule</span><span style="color:#56B6C2"> =</span><span style="color:#98C379"> ".read"</span><span style="color:#ABB2BF"> | </span><span style="color:#98C379">".write"</span><span style="color:#ABB2BF"> | </span><span style="color:#98C379">".validate"</span><span style="color:#ABB2BF"> | </span><span style="color:#98C379">"ruleset"</span><span style="color:#ABB2BF">;</span></span></code></pre>
@@ -2130,7 +2243,7 @@ expression the request was evaluating when the budget ran out.</p>
2130
2243
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">type</span><span style="color:#E5C07B"> RtdbRulesJson</span><span style="color:#56B6C2"> =</span><span style="color:#ABB2BF"> {</span></span>
2131
2244
  <span class="line"><span style="color:#E06C75"> rules</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Record</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">unknown</span><span style="color:#ABB2BF">>;</span></span>
2132
2245
  <span class="line"><span style="color:#ABB2BF">};</span></span></code></pre>
2133
- <h4 id="properties-36">Properties</h4>
2246
+ <h4 id="properties-39">Properties</h4>
2134
2247
  <div class="table-scroll">
2135
2248
 
2136
2249
 
@@ -2205,14 +2318,14 @@ limit; nothing downstream ran.</li>
2205
2318
  <h3 id="allow">allow()</h3>
2206
2319
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> allow</span><span style="color:#ABB2BF">: () </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2207
2320
  <p>Always allow (true). Readable alias for always().</p>
2208
- <h4 id="returns-14">Returns</h4>
2321
+ <h4 id="returns-15">Returns</h4>
2209
2322
  <p><a href="#expr"><code>Expr</code></a></p>
2210
2323
  <hr>
2211
2324
  <p><a id="always"></a></p>
2212
2325
  <h3 id="always">always()</h3>
2213
2326
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> always</span><span style="color:#ABB2BF">: () </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2214
2327
  <p>Always allow (true).</p>
2215
- <h4 id="returns-15">Returns</h4>
2328
+ <h4 id="returns-16">Returns</h4>
2216
2329
  <p><a href="#expr"><code>Expr</code></a></p>
2217
2330
  <hr>
2218
2331
  <p><a id="auth_uid"></a></p>
@@ -2223,14 +2336,14 @@ limit; nothing downstream ran.</li>
2223
2336
  <p><a id="authenticated"></a></p>
2224
2337
  <h3 id="authenticated">authenticated()</h3>
2225
2338
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> authenticated</span><span style="color:#ABB2BF">: () </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2226
- <h4 id="returns-16">Returns</h4>
2339
+ <h4 id="returns-17">Returns</h4>
2227
2340
  <p><a href="#expr"><code>Expr</code></a></p>
2228
2341
  <hr>
2229
2342
  <p><a id="dataexists"></a></p>
2230
2343
  <h3 id="dataexists">dataExists()</h3>
2231
2344
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> dataExists</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">path</span><span style="color:#C678DD">?</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2232
2345
  <p>Check if data exists at current node or a child path</p>
2233
- <h4 id="parameters-10">Parameters</h4>
2346
+ <h4 id="parameters-11">Parameters</h4>
2234
2347
  <div class="table-scroll">
2235
2348
 
2236
2349
 
@@ -2245,14 +2358,14 @@ limit; nothing downstream ran.</li>
2245
2358
 
2246
2359
 
2247
2360
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>path?</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2248
- <h4 id="returns-17">Returns</h4>
2361
+ <h4 id="returns-18">Returns</h4>
2249
2362
  <p><a href="#expr"><code>Expr</code></a></p>
2250
2363
  <hr>
2251
2364
  <p><a id="dataparentval"></a></p>
2252
2365
  <h3 id="dataparentval">dataParentVal()</h3>
2253
2366
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> dataParentVal</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">depth</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">number</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2254
2367
  <p>Navigate up from data snapshot, then read a child field’s value</p>
2255
- <h4 id="parameters-11">Parameters</h4>
2368
+ <h4 id="parameters-12">Parameters</h4>
2256
2369
  <div class="table-scroll">
2257
2370
 
2258
2371
 
@@ -2271,14 +2384,14 @@ limit; nothing downstream ran.</li>
2271
2384
 
2272
2385
 
2273
2386
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>depth</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2274
- <h4 id="returns-18">Returns</h4>
2387
+ <h4 id="returns-19">Returns</h4>
2275
2388
  <p><a href="#expr"><code>Expr</code></a></p>
2276
2389
  <hr>
2277
2390
  <p><a id="dataval"></a></p>
2278
2391
  <h3 id="dataval">dataVal()</h3>
2279
2392
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> dataVal</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">path</span><span style="color:#C678DD">?</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2280
2393
  <p>Read data value at current node or a child path (pre-write state)</p>
2281
- <h4 id="parameters-12">Parameters</h4>
2394
+ <h4 id="parameters-13">Parameters</h4>
2282
2395
  <div class="table-scroll">
2283
2396
 
2284
2397
 
@@ -2293,21 +2406,21 @@ limit; nothing downstream ran.</li>
2293
2406
 
2294
2407
 
2295
2408
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>path?</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2296
- <h4 id="returns-19">Returns</h4>
2409
+ <h4 id="returns-20">Returns</h4>
2297
2410
  <p><a href="#expr"><code>Expr</code></a></p>
2298
2411
  <hr>
2299
2412
  <p><a id="deny-1"></a></p>
2300
2413
  <h3 id="deny">deny()</h3>
2301
2414
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> deny</span><span style="color:#ABB2BF">: () </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2302
2415
  <p>Always deny (false).</p>
2303
- <h4 id="returns-20">Returns</h4>
2416
+ <h4 id="returns-21">Returns</h4>
2304
2417
  <p><a href="#expr"><code>Expr</code></a></p>
2305
2418
  <hr>
2306
2419
  <p><a id="eq"></a></p>
2307
2420
  <h3 id="eq">eq()</h3>
2308
2421
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> eq</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">left</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Expr</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">right</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">CompareValue</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2309
2422
  <p>Equality: left == right (right is a literal value or runtime ref)</p>
2310
- <h4 id="parameters-13">Parameters</h4>
2423
+ <h4 id="parameters-14">Parameters</h4>
2311
2424
  <div class="table-scroll">
2312
2425
 
2313
2426
 
@@ -2326,14 +2439,14 @@ limit; nothing downstream ran.</li>
2326
2439
 
2327
2440
 
2328
2441
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>left</code></td><td align="left"><a href="#expr"><code>Expr</code></a></td></tr><tr><td align="left"><code>right</code></td><td align="left"><code>CompareValue</code></td></tr></tbody></table></div>
2329
- <h4 id="returns-21">Returns</h4>
2442
+ <h4 id="returns-22">Returns</h4>
2330
2443
  <p><a href="#expr"><code>Expr</code></a></p>
2331
2444
  <hr>
2332
2445
  <p><a id="expr-1"></a></p>
2333
2446
  <h3 id="expr-1">expr()</h3>
2334
2447
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> expr</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">raw</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2335
2448
  <p>Create an Expr from a raw expression string.</p>
2336
- <h4 id="parameters-14">Parameters</h4>
2449
+ <h4 id="parameters-15">Parameters</h4>
2337
2450
  <div class="table-scroll">
2338
2451
 
2339
2452
 
@@ -2348,14 +2461,14 @@ limit; nothing downstream ran.</li>
2348
2461
 
2349
2462
 
2350
2463
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>raw</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2351
- <h4 id="returns-22">Returns</h4>
2464
+ <h4 id="returns-23">Returns</h4>
2352
2465
  <p><a href="#expr"><code>Expr</code></a></p>
2353
2466
  <hr>
2354
2467
  <p><a id="fieldenum"></a></p>
2355
2468
  <h3 id="fieldenum">fieldEnum()</h3>
2356
2469
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> fieldEnum</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">values</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">[]) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2357
2470
  <p>Field must be one of the allowed string values</p>
2358
- <h4 id="parameters-15">Parameters</h4>
2471
+ <h4 id="parameters-16">Parameters</h4>
2359
2472
  <div class="table-scroll">
2360
2473
 
2361
2474
 
@@ -2374,14 +2487,14 @@ limit; nothing downstream ran.</li>
2374
2487
 
2375
2488
 
2376
2489
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><code>values</code></td><td align="left"><code>string</code>[]</td></tr></tbody></table></div>
2377
- <h4 id="returns-23">Returns</h4>
2490
+ <h4 id="returns-24">Returns</h4>
2378
2491
  <p><a href="#expr"><code>Expr</code></a></p>
2379
2492
  <hr>
2380
2493
  <p><a id="fieldisboolean"></a></p>
2381
2494
  <h3 id="fieldisboolean">fieldIsBoolean()</h3>
2382
2495
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> fieldIsBoolean</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2383
2496
  <p>Field must be a boolean</p>
2384
- <h4 id="parameters-16">Parameters</h4>
2497
+ <h4 id="parameters-17">Parameters</h4>
2385
2498
  <div class="table-scroll">
2386
2499
 
2387
2500
 
@@ -2396,14 +2509,14 @@ limit; nothing downstream ran.</li>
2396
2509
 
2397
2510
 
2398
2511
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2399
- <h4 id="returns-24">Returns</h4>
2512
+ <h4 id="returns-25">Returns</h4>
2400
2513
  <p><a href="#expr"><code>Expr</code></a></p>
2401
2514
  <hr>
2402
2515
  <p><a id="fieldisnumber"></a></p>
2403
2516
  <h3 id="fieldisnumber">fieldIsNumber()</h3>
2404
2517
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> fieldIsNumber</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2405
2518
  <p>Field must be a number</p>
2406
- <h4 id="parameters-17">Parameters</h4>
2519
+ <h4 id="parameters-18">Parameters</h4>
2407
2520
  <div class="table-scroll">
2408
2521
 
2409
2522
 
@@ -2418,14 +2531,14 @@ limit; nothing downstream ran.</li>
2418
2531
 
2419
2532
 
2420
2533
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2421
- <h4 id="returns-25">Returns</h4>
2534
+ <h4 id="returns-26">Returns</h4>
2422
2535
  <p><a href="#expr"><code>Expr</code></a></p>
2423
2536
  <hr>
2424
2537
  <p><a id="fieldisstring"></a></p>
2425
2538
  <h3 id="fieldisstring">fieldIsString()</h3>
2426
2539
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> fieldIsString</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2427
2540
  <p>Field must be a string</p>
2428
- <h4 id="parameters-18">Parameters</h4>
2541
+ <h4 id="parameters-19">Parameters</h4>
2429
2542
  <div class="table-scroll">
2430
2543
 
2431
2544
 
@@ -2440,14 +2553,14 @@ limit; nothing downstream ran.</li>
2440
2553
 
2441
2554
 
2442
2555
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2443
- <h4 id="returns-26">Returns</h4>
2556
+ <h4 id="returns-27">Returns</h4>
2444
2557
  <p><a href="#expr"><code>Expr</code></a></p>
2445
2558
  <hr>
2446
2559
  <p><a id="fieldowneronly"></a></p>
2447
2560
  <h3 id="fieldowneronly">fieldOwnerOnly()</h3>
2448
2561
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> fieldOwnerOnly</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2449
2562
  <p>Only the field owner (auth.uid == data.child(field).val()) can access</p>
2450
- <h4 id="parameters-19">Parameters</h4>
2563
+ <h4 id="parameters-20">Parameters</h4>
2451
2564
  <div class="table-scroll">
2452
2565
 
2453
2566
 
@@ -2462,14 +2575,14 @@ limit; nothing downstream ran.</li>
2462
2575
 
2463
2576
 
2464
2577
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2465
- <h4 id="returns-27">Returns</h4>
2578
+ <h4 id="returns-28">Returns</h4>
2466
2579
  <p><a href="#expr"><code>Expr</code></a></p>
2467
2580
  <hr>
2468
2581
  <p><a id="gt"></a></p>
2469
2582
  <h3 id="gt">gt()</h3>
2470
2583
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> gt</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">left</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Expr</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">right</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">number</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2471
2584
  <p>Greater than: left > right</p>
2472
- <h4 id="parameters-20">Parameters</h4>
2585
+ <h4 id="parameters-21">Parameters</h4>
2473
2586
  <div class="table-scroll">
2474
2587
 
2475
2588
 
@@ -2488,14 +2601,14 @@ limit; nothing downstream ran.</li>
2488
2601
 
2489
2602
 
2490
2603
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>left</code></td><td align="left"><a href="#expr"><code>Expr</code></a></td></tr><tr><td align="left"><code>right</code></td><td align="left"><code>number</code></td></tr></tbody></table></div>
2491
- <h4 id="returns-28">Returns</h4>
2604
+ <h4 id="returns-29">Returns</h4>
2492
2605
  <p><a href="#expr"><code>Expr</code></a></p>
2493
2606
  <hr>
2494
2607
  <p><a id="haschild"></a></p>
2495
2608
  <h3 id="haschild">hasChild()</h3>
2496
2609
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> hasChild</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2497
2610
  <p>Incoming data must have a specific child field</p>
2498
- <h4 id="parameters-21">Parameters</h4>
2611
+ <h4 id="parameters-22">Parameters</h4>
2499
2612
  <div class="table-scroll">
2500
2613
 
2501
2614
 
@@ -2510,21 +2623,21 @@ limit; nothing downstream ran.</li>
2510
2623
 
2511
2624
 
2512
2625
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2513
- <h4 id="returns-29">Returns</h4>
2626
+ <h4 id="returns-30">Returns</h4>
2514
2627
  <p><a href="#expr"><code>Expr</code></a></p>
2515
2628
  <hr>
2516
2629
  <p><a id="haschildren"></a></p>
2517
2630
  <h3 id="haschildren">hasChildren()</h3>
2518
2631
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> hasChildren</span><span style="color:#ABB2BF">: () </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2519
2632
  <p>Incoming data must be an object with at least one child</p>
2520
- <h4 id="returns-30">Returns</h4>
2633
+ <h4 id="returns-31">Returns</h4>
2521
2634
  <p><a href="#expr"><code>Expr</code></a></p>
2522
2635
  <hr>
2523
2636
  <p><a id="hasrole"></a></p>
2524
2637
  <h3 id="hasrole">hasRole()</h3>
2525
2638
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> hasRole</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">segments</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Segment</span><span style="color:#ABB2BF">[], </span><span style="color:#E06C75;font-style:italic">role</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2526
2639
  <p>Cross-path role check via root lookup</p>
2527
- <h4 id="parameters-22">Parameters</h4>
2640
+ <h4 id="parameters-23">Parameters</h4>
2528
2641
  <div class="table-scroll">
2529
2642
 
2530
2643
 
@@ -2543,14 +2656,14 @@ limit; nothing downstream ran.</li>
2543
2656
 
2544
2657
 
2545
2658
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>segments</code></td><td align="left"><a href="#segment"><code>Segment</code></a>[]</td></tr><tr><td align="left"><code>role</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2546
- <h4 id="returns-31">Returns</h4>
2659
+ <h4 id="returns-32">Returns</h4>
2547
2660
  <p><a href="#expr"><code>Expr</code></a></p>
2548
2661
  <hr>
2549
2662
  <p><a id="immutable"></a></p>
2550
2663
  <h3 id="immutable">immutable()</h3>
2551
2664
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> immutable</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2552
2665
  <p>Field can be set on creation but never changed after</p>
2553
- <h4 id="parameters-23">Parameters</h4>
2666
+ <h4 id="parameters-24">Parameters</h4>
2554
2667
  <div class="table-scroll">
2555
2668
 
2556
2669
 
@@ -2565,21 +2678,21 @@ limit; nothing downstream ran.</li>
2565
2678
 
2566
2679
 
2567
2680
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2568
- <h4 id="returns-32">Returns</h4>
2681
+ <h4 id="returns-33">Returns</h4>
2569
2682
  <p><a href="#expr"><code>Expr</code></a></p>
2570
2683
  <hr>
2571
2684
  <p><a id="immutableself"></a></p>
2572
2685
  <h3 id="immutableself">immutableSelf()</h3>
2573
2686
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> immutableSelf</span><span style="color:#ABB2BF">: () </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2574
2687
  <p>This node’s own value can be set on creation but never changed</p>
2575
- <h4 id="returns-33">Returns</h4>
2688
+ <h4 id="returns-34">Returns</h4>
2576
2689
  <p><a href="#expr"><code>Expr</code></a></p>
2577
2690
  <hr>
2578
2691
  <p><a id="ismember"></a></p>
2579
2692
  <h3 id="ismember">isMember()</h3>
2580
2693
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> isMember</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">listName</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">pathVarName</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2581
2694
  <p>Cross-path membership check: root.child(list).child($var).child(auth.uid).exists()</p>
2582
- <h4 id="parameters-24">Parameters</h4>
2695
+ <h4 id="parameters-25">Parameters</h4>
2583
2696
  <div class="table-scroll">
2584
2697
 
2585
2698
 
@@ -2598,21 +2711,21 @@ limit; nothing downstream ran.</li>
2598
2711
 
2599
2712
 
2600
2713
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>listName</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><code>pathVarName</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2601
- <h4 id="returns-34">Returns</h4>
2714
+ <h4 id="returns-35">Returns</h4>
2602
2715
  <p><a href="#expr"><code>Expr</code></a></p>
2603
2716
  <hr>
2604
2717
  <p><a id="isnew"></a></p>
2605
2718
  <h3 id="isnew">isNew()</h3>
2606
2719
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> isNew</span><span style="color:#ABB2BF">: () </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2607
2720
  <p>Data at this path doesn’t exist yet (creation check)</p>
2608
- <h4 id="returns-35">Returns</h4>
2721
+ <h4 id="returns-36">Returns</h4>
2609
2722
  <p><a href="#expr"><code>Expr</code></a></p>
2610
2723
  <hr>
2611
2724
  <p><a id="lte"></a></p>
2612
2725
  <h3 id="lte">lte()</h3>
2613
2726
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> lte</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">left</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Expr</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">right</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">number</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2614
2727
  <p>Less than or equal: left &#x3C;= right</p>
2615
- <h4 id="parameters-25">Parameters</h4>
2728
+ <h4 id="parameters-26">Parameters</h4>
2616
2729
  <div class="table-scroll">
2617
2730
 
2618
2731
 
@@ -2631,14 +2744,14 @@ limit; nothing downstream ran.</li>
2631
2744
 
2632
2745
 
2633
2746
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>left</code></td><td align="left"><a href="#expr"><code>Expr</code></a></td></tr><tr><td align="left"><code>right</code></td><td align="left"><code>number</code></td></tr></tbody></table></div>
2634
- <h4 id="returns-36">Returns</h4>
2747
+ <h4 id="returns-37">Returns</h4>
2635
2748
  <p><a href="#expr"><code>Expr</code></a></p>
2636
2749
  <hr>
2637
2750
  <p><a id="neq"></a></p>
2638
2751
  <h3 id="neq">neq()</h3>
2639
2752
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> neq</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">left</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Expr</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">right</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">CompareValue</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2640
2753
  <p>Inequality: left != right</p>
2641
- <h4 id="parameters-26">Parameters</h4>
2754
+ <h4 id="parameters-27">Parameters</h4>
2642
2755
  <div class="table-scroll">
2643
2756
 
2644
2757
 
@@ -2657,14 +2770,14 @@ limit; nothing downstream ran.</li>
2657
2770
 
2658
2771
 
2659
2772
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>left</code></td><td align="left"><a href="#expr"><code>Expr</code></a></td></tr><tr><td align="left"><code>right</code></td><td align="left"><code>CompareValue</code></td></tr></tbody></table></div>
2660
- <h4 id="returns-37">Returns</h4>
2773
+ <h4 id="returns-38">Returns</h4>
2661
2774
  <p><a href="#expr"><code>Expr</code></a></p>
2662
2775
  <hr>
2663
2776
  <p><a id="newdataexists"></a></p>
2664
2777
  <h3 id="newdataexists">newDataExists()</h3>
2665
2778
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> newDataExists</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">path</span><span style="color:#C678DD">?</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2666
2779
  <p>Check if incoming data exists at current node or a child path</p>
2667
- <h4 id="parameters-27">Parameters</h4>
2780
+ <h4 id="parameters-28">Parameters</h4>
2668
2781
  <div class="table-scroll">
2669
2782
 
2670
2783
 
@@ -2679,14 +2792,14 @@ limit; nothing downstream ran.</li>
2679
2792
 
2680
2793
 
2681
2794
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>path?</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2682
- <h4 id="returns-38">Returns</h4>
2795
+ <h4 id="returns-39">Returns</h4>
2683
2796
  <p><a href="#expr"><code>Expr</code></a></p>
2684
2797
  <hr>
2685
2798
  <p><a id="newdatais"></a></p>
2686
2799
  <h3 id="newdatais">newDataIs()</h3>
2687
2800
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> newDataIs</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">type</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">"String"</span><span style="color:#ABB2BF"> | </span><span style="color:#98C379">"Number"</span><span style="color:#ABB2BF"> | </span><span style="color:#98C379">"Boolean"</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2688
2801
  <p>Check incoming data type at current node</p>
2689
- <h4 id="parameters-28">Parameters</h4>
2802
+ <h4 id="parameters-29">Parameters</h4>
2690
2803
  <div class="table-scroll">
2691
2804
 
2692
2805
 
@@ -2701,14 +2814,14 @@ limit; nothing downstream ran.</li>
2701
2814
 
2702
2815
 
2703
2816
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>type</code></td><td align="left"><code>"String"</code> | <code>"Number"</code> | <code>"Boolean"</code></td></tr></tbody></table></div>
2704
- <h4 id="returns-39">Returns</h4>
2817
+ <h4 id="returns-40">Returns</h4>
2705
2818
  <p><a href="#expr"><code>Expr</code></a></p>
2706
2819
  <hr>
2707
2820
  <p><a id="newdataparentexists"></a></p>
2708
2821
  <h3 id="newdataparentexists">newDataParentExists()</h3>
2709
2822
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> newDataParentExists</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">depth</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">number</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2710
2823
  <p>Navigate up from newData snapshot, then check if a child field exists</p>
2711
- <h4 id="parameters-29">Parameters</h4>
2824
+ <h4 id="parameters-30">Parameters</h4>
2712
2825
  <div class="table-scroll">
2713
2826
 
2714
2827
 
@@ -2727,14 +2840,14 @@ limit; nothing downstream ran.</li>
2727
2840
 
2728
2841
 
2729
2842
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>depth</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2730
- <h4 id="returns-40">Returns</h4>
2843
+ <h4 id="returns-41">Returns</h4>
2731
2844
  <p><a href="#expr"><code>Expr</code></a></p>
2732
2845
  <hr>
2733
2846
  <p><a id="newdataparentval"></a></p>
2734
2847
  <h3 id="newdataparentval">newDataParentVal()</h3>
2735
2848
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> newDataParentVal</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">depth</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">number</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2736
2849
  <p>Navigate up from newData snapshot, then read a child field’s value</p>
2737
- <h4 id="parameters-30">Parameters</h4>
2850
+ <h4 id="parameters-31">Parameters</h4>
2738
2851
  <div class="table-scroll">
2739
2852
 
2740
2853
 
@@ -2753,14 +2866,14 @@ limit; nothing downstream ran.</li>
2753
2866
 
2754
2867
 
2755
2868
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>depth</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2756
- <h4 id="returns-41">Returns</h4>
2869
+ <h4 id="returns-42">Returns</h4>
2757
2870
  <p><a href="#expr"><code>Expr</code></a></p>
2758
2871
  <hr>
2759
2872
  <p><a id="newdataval"></a></p>
2760
2873
  <h3 id="newdataval">newDataVal()</h3>
2761
2874
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> newDataVal</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">path</span><span style="color:#C678DD">?</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2762
2875
  <p>Read incoming data value at current node or a child path (post-write state)</p>
2763
- <h4 id="parameters-31">Parameters</h4>
2876
+ <h4 id="parameters-32">Parameters</h4>
2764
2877
  <div class="table-scroll">
2765
2878
 
2766
2879
 
@@ -2775,14 +2888,14 @@ limit; nothing downstream ran.</li>
2775
2888
 
2776
2889
 
2777
2890
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>path?</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2778
- <h4 id="returns-42">Returns</h4>
2891
+ <h4 id="returns-43">Returns</h4>
2779
2892
  <p><a href="#expr"><code>Expr</code></a></p>
2780
2893
  <hr>
2781
2894
  <p><a id="ownerornew"></a></p>
2782
2895
  <h3 id="ownerornew">ownerOrNew()</h3>
2783
2896
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> ownerOrNew</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2784
2897
  <p>Anyone authenticated can create; only the field owner can edit</p>
2785
- <h4 id="parameters-32">Parameters</h4>
2898
+ <h4 id="parameters-33">Parameters</h4>
2786
2899
  <div class="table-scroll">
2787
2900
 
2788
2901
 
@@ -2797,14 +2910,14 @@ limit; nothing downstream ran.</li>
2797
2910
 
2798
2911
 
2799
2912
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2800
- <h4 id="returns-43">Returns</h4>
2913
+ <h4 id="returns-44">Returns</h4>
2801
2914
  <p><a href="#expr"><code>Expr</code></a></p>
2802
2915
  <hr>
2803
2916
  <p><a id="ownfield"></a></p>
2804
2917
  <h3 id="ownfield">ownField()</h3>
2805
2918
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> ownField</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2806
2919
  <p>Field-based ownership: auth.uid matches a value stored in a data field</p>
2807
- <h4 id="parameters-33">Parameters</h4>
2920
+ <h4 id="parameters-34">Parameters</h4>
2808
2921
  <div class="table-scroll">
2809
2922
 
2810
2923
 
@@ -2819,14 +2932,14 @@ limit; nothing downstream ran.</li>
2819
2932
 
2820
2933
 
2821
2934
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2822
- <h4 id="returns-44">Returns</h4>
2935
+ <h4 id="returns-45">Returns</h4>
2823
2936
  <p><a href="#expr"><code>Expr</code></a></p>
2824
2937
  <hr>
2825
2938
  <p><a id="ownpath"></a></p>
2826
2939
  <h3 id="ownpath">ownPath()</h3>
2827
2940
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> ownPath</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">pathVar</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2828
2941
  <p>Path-based ownership: auth.uid matches a URL path variable</p>
2829
- <h4 id="parameters-34">Parameters</h4>
2942
+ <h4 id="parameters-35">Parameters</h4>
2830
2943
  <div class="table-scroll">
2831
2944
 
2832
2945
 
@@ -2841,14 +2954,14 @@ limit; nothing downstream ran.</li>
2841
2954
 
2842
2955
 
2843
2956
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>pathVar</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2844
- <h4 id="returns-45">Returns</h4>
2957
+ <h4 id="returns-46">Returns</h4>
2845
2958
  <p><a href="#expr"><code>Expr</code></a></p>
2846
2959
  <hr>
2847
2960
  <p><a id="pathowneronly"></a></p>
2848
2961
  <h3 id="pathowneronly">pathOwnerOnly()</h3>
2849
2962
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> pathOwnerOnly</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">pathVar</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2850
2963
  <p>Only the path owner (auth.uid == $pathVar) can access</p>
2851
- <h4 id="parameters-35">Parameters</h4>
2964
+ <h4 id="parameters-36">Parameters</h4>
2852
2965
  <div class="table-scroll">
2853
2966
 
2854
2967
 
@@ -2863,14 +2976,14 @@ limit; nothing downstream ran.</li>
2863
2976
 
2864
2977
 
2865
2978
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>pathVar</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2866
- <h4 id="returns-46">Returns</h4>
2979
+ <h4 id="returns-47">Returns</h4>
2867
2980
  <p><a href="#expr"><code>Expr</code></a></p>
2868
2981
  <hr>
2869
2982
  <p><a id="ref"></a></p>
2870
2983
  <h3 id="ref">ref()</h3>
2871
2984
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> ref</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">expression</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Segment</span><span style="color:#ABB2BF">;</span></span></code></pre>
2872
2985
  <p>Wrap a runtime rule expression so comparisons emit it unquoted</p>
2873
- <h4 id="parameters-36">Parameters</h4>
2986
+ <h4 id="parameters-37">Parameters</h4>
2874
2987
  <div class="table-scroll">
2875
2988
 
2876
2989
 
@@ -2885,7 +2998,7 @@ limit; nothing downstream ran.</li>
2885
2998
 
2886
2999
 
2887
3000
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>expression</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2888
- <h4 id="returns-47">Returns</h4>
3001
+ <h4 id="returns-48">Returns</h4>
2889
3002
  <p><a href="#segment"><code>Segment</code></a></p>
2890
3003
  <hr>
2891
3004
  <p><a id="required-1"></a></p>
@@ -2895,7 +3008,7 @@ limit; nothing downstream ran.</li>
2895
3008
  checked together with <code>newData.hasChildren([...])</code>; a nested path such as
2896
3009
  ‘puck/x’ is checked with <code>newData.hasChild('puck/x')</code>, joined with <code>&#x26;&#x26;</code>.
2897
3010
  Every segment of every field must be a valid RTDB key.</p>
2898
- <h4 id="parameters-37">Parameters</h4>
3011
+ <h4 id="parameters-38">Parameters</h4>
2899
3012
  <div class="table-scroll">
2900
3013
 
2901
3014
 
@@ -2910,14 +3023,14 @@ Every segment of every field must be a valid RTDB key.</p>
2910
3023
 
2911
3024
 
2912
3025
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left">…<code>fields</code></td><td align="left"><code>string</code>[]</td></tr></tbody></table></div>
2913
- <h4 id="returns-48">Returns</h4>
3026
+ <h4 id="returns-49">Returns</h4>
2914
3027
  <p><a href="#expr"><code>Expr</code></a></p>
2915
3028
  <hr>
2916
3029
  <p><a id="rootequals"></a></p>
2917
3030
  <h3 id="rootequals">rootEquals()</h3>
2918
3031
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> rootEquals</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">segments</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Segment</span><span style="color:#ABB2BF">[], </span><span style="color:#E06C75;font-style:italic">value</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2919
3032
  <p>Check if a path’s value equals a specific string (via root)</p>
2920
- <h4 id="parameters-38">Parameters</h4>
3033
+ <h4 id="parameters-39">Parameters</h4>
2921
3034
  <div class="table-scroll">
2922
3035
 
2923
3036
 
@@ -2936,14 +3049,14 @@ Every segment of every field must be a valid RTDB key.</p>
2936
3049
 
2937
3050
 
2938
3051
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>segments</code></td><td align="left"><a href="#segment"><code>Segment</code></a>[]</td></tr><tr><td align="left"><code>value</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
2939
- <h4 id="returns-49">Returns</h4>
3052
+ <h4 id="returns-50">Returns</h4>
2940
3053
  <p><a href="#expr"><code>Expr</code></a></p>
2941
3054
  <hr>
2942
3055
  <p><a id="rootexists"></a></p>
2943
3056
  <h3 id="rootexists">rootExists()</h3>
2944
3057
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> rootExists</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">segments</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Segment</span><span style="color:#ABB2BF">[]) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2945
3058
  <p>Check if a path exists in the database (via root)</p>
2946
- <h4 id="parameters-39">Parameters</h4>
3059
+ <h4 id="parameters-40">Parameters</h4>
2947
3060
  <div class="table-scroll">
2948
3061
 
2949
3062
 
@@ -2958,7 +3071,7 @@ Every segment of every field must be a valid RTDB key.</p>
2958
3071
 
2959
3072
 
2960
3073
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>segments</code></td><td align="left"><a href="#segment"><code>Segment</code></a>[]</td></tr></tbody></table></div>
2961
- <h4 id="returns-50">Returns</h4>
3074
+ <h4 id="returns-51">Returns</h4>
2962
3075
  <p><a href="#expr"><code>Expr</code></a></p>
2963
3076
  <hr>
2964
3077
  <p><a id="rtdbrules"></a></p>
@@ -2991,7 +3104,7 @@ and trailing commas) or has no top-level <code>rules</code> object.</p>
2991
3104
  <h3 id="transition">transition()</h3>
2992
3105
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#61AFEF"> transition</span><span style="color:#ABB2BF">: (</span><span style="color:#E06C75;font-style:italic">field</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">allowed</span><span style="color:#ABB2BF">: [</span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">][]) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> Expr</span><span style="color:#ABB2BF">;</span></span></code></pre>
2993
3106
  <p>State machine: only allowed transitions on a field</p>
2994
- <h4 id="parameters-40">Parameters</h4>
3107
+ <h4 id="parameters-41">Parameters</h4>
2995
3108
  <div class="table-scroll">
2996
3109
 
2997
3110
 
@@ -3010,7 +3123,7 @@ and trailing commas) or has no top-level <code>rules</code> object.</p>
3010
3123
 
3011
3124
 
3012
3125
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>field</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><code>allowed</code></td><td align="left">[<code>string</code>, <code>string</code>][]</td></tr></tbody></table></div>
3013
- <h4 id="returns-51">Returns</h4>
3126
+ <h4 id="returns-52">Returns</h4>
3014
3127
  <p><a href="#expr"><code>Expr</code></a></p>
3015
3128
  <h2 id="functions">Functions</h2>
3016
3129
  <p><a id="all"></a></p>
@@ -3020,7 +3133,7 @@ and trailing commas) or has no top-level <code>rules</code> object.</p>
3020
3133
  it holds a top-level <code>||</code> or ternary, which binds looser than <code>&#x26;&#x26;</code>.
3021
3134
  Empty operands are dropped; with none left it throws, since an empty
3022
3135
  conjunction would allow everything. Use <a href="#always">always</a> for that.</p>
3023
- <h4 id="parameters-41">Parameters</h4>
3136
+ <h4 id="parameters-42">Parameters</h4>
3024
3137
  <div class="table-scroll">
3025
3138
 
3026
3139
 
@@ -3035,7 +3148,7 @@ conjunction would allow everything. Use <a href="#always">always</a> for that.</
3035
3148
 
3036
3149
 
3037
3150
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left">…<code>exprs</code></td><td align="left"><code>string</code>[]</td></tr></tbody></table></div>
3038
- <h4 id="returns-52">Returns</h4>
3151
+ <h4 id="returns-53">Returns</h4>
3039
3152
  <p><code>string</code></p>
3040
3153
  <hr>
3041
3154
  <p><a id="any"></a></p>
@@ -3045,7 +3158,7 @@ conjunction would allow everything. Use <a href="#always">always</a> for that.</
3045
3158
  is parenthesized for the reader, and one with a ternary for the parser.
3046
3159
  Empty operands are dropped; with none left it throws, since an empty
3047
3160
  disjunction would deny everything. Use <a href="#deny-1">deny</a> for that.</p>
3048
- <h4 id="parameters-42">Parameters</h4>
3161
+ <h4 id="parameters-43">Parameters</h4>
3049
3162
  <div class="table-scroll">
3050
3163
 
3051
3164
 
@@ -3060,7 +3173,7 @@ disjunction would deny everything. Use <a href="#deny-1">deny</a> for that.</p>
3060
3173
 
3061
3174
 
3062
3175
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left">…<code>exprs</code></td><td align="left"><code>string</code>[]</td></tr></tbody></table></div>
3063
- <h4 id="returns-53">Returns</h4>
3176
+ <h4 id="returns-54">Returns</h4>
3064
3177
  <p><code>string</code></p>
3065
3178
  <hr>
3066
3179
  <p><a id="assertcase"></a></p>
@@ -3071,7 +3184,7 @@ disjunction would deny everything. Use <a href="#deny-1">deny</a> for that.</p>
3071
3184
  <a href="#rulesunsupportederror">RulesUnsupportedError</a>; a genuine expectation mismatch throws
3072
3185
  <a href="#rulesassertionerror">RulesAssertionError</a>. Both carry the <a href="#explaincase">explainCase</a> trace as
3073
3186
  their message. Returns <code>void</code> on a passing result.</p>
3074
- <h5 id="parameters-43">Parameters</h5>
3187
+ <h5 id="parameters-44">Parameters</h5>
3075
3188
  <div class="table-scroll">
3076
3189
 
3077
3190
 
@@ -3086,13 +3199,13 @@ their message. Returns <code>void</code> on a passing result.</p>
3086
3199
 
3087
3200
 
3088
3201
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>result</code></td><td align="left"><a href="#rtdbcaseresult"><code>RtdbCaseResult</code></a> | <a href="#caseresult"><code>CaseResult</code></a></td></tr></tbody></table></div>
3089
- <h5 id="returns-54">Returns</h5>
3202
+ <h5 id="returns-55">Returns</h5>
3090
3203
  <p><code>void</code></p>
3091
3204
  <h4 id="call-signature-1">Call Signature</h4>
3092
3205
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> assertCase</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">ruleset</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">FirestoreRuleset</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">oneCase</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">FirestoreCase</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">void</span><span style="color:#ABB2BF">;</span></span></code></pre>
3093
3206
  <p>Simulate one case against a ruleset and throw on a miss — the runner
3094
3207
  form: <code>for (const c of cases) test(c.description, () => assertCase(ruleset, c))</code>.</p>
3095
- <h5 id="parameters-44">Parameters</h5>
3208
+ <h5 id="parameters-45">Parameters</h5>
3096
3209
  <div class="table-scroll">
3097
3210
 
3098
3211
 
@@ -3111,7 +3224,7 @@ form: <code>for (const c of cases) test(c.description, () => assertCase(ruleset,
3111
3224
 
3112
3225
 
3113
3226
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>ruleset</code></td><td align="left"><a href="#firestoreruleset"><code>FirestoreRuleset</code></a></td></tr><tr><td align="left"><code>oneCase</code></td><td align="left"><a href="#firestorecase"><code>FirestoreCase</code></a></td></tr></tbody></table></div>
3114
- <h5 id="returns-55">Returns</h5>
3227
+ <h5 id="returns-56">Returns</h5>
3115
3228
  <p><code>void</code></p>
3116
3229
  <h4 id="call-signature-2">Call Signature</h4>
3117
3230
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> assertCase</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">ruleset</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">RtdbRuleset</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">oneCase</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">RtdbCase</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">void</span><span style="color:#ABB2BF">;</span></span></code></pre>
@@ -3119,7 +3232,7 @@ form: <code>for (const c of cases) test(c.description, () => assertCase(ruleset,
3119
3232
  <a href="#rulesunsupportederror">RulesUnsupportedError</a>; a genuine expectation mismatch throws
3120
3233
  <a href="#rulesassertionerror">RulesAssertionError</a>. Both carry the <a href="#explaincase">explainCase</a> trace as
3121
3234
  their message. Returns <code>void</code> on a passing result.</p>
3122
- <h5 id="parameters-45">Parameters</h5>
3235
+ <h5 id="parameters-46">Parameters</h5>
3123
3236
  <div class="table-scroll">
3124
3237
 
3125
3238
 
@@ -3138,12 +3251,12 @@ their message. Returns <code>void</code> on a passing result.</p>
3138
3251
 
3139
3252
 
3140
3253
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>ruleset</code></td><td align="left"><a href="#rtdbruleset"><code>RtdbRuleset</code></a></td></tr><tr><td align="left"><code>oneCase</code></td><td align="left"><a href="#rtdbcase"><code>RtdbCase</code></a></td></tr></tbody></table></div>
3141
- <h5 id="returns-56">Returns</h5>
3254
+ <h5 id="returns-57">Returns</h5>
3142
3255
  <p><code>void</code></p>
3143
3256
  <h4 id="call-signature-3">Call Signature</h4>
3144
3257
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> assertCase</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">source</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">oneCase</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">FirestoreCase</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">void</span><span style="color:#ABB2BF">;</span></span></code></pre>
3145
3258
  <p>Convenience: compile Firestore source and assert one case against it.</p>
3146
- <h5 id="parameters-46">Parameters</h5>
3259
+ <h5 id="parameters-47">Parameters</h5>
3147
3260
  <div class="table-scroll">
3148
3261
 
3149
3262
 
@@ -3162,7 +3275,7 @@ their message. Returns <code>void</code> on a passing result.</p>
3162
3275
 
3163
3276
 
3164
3277
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>source</code></td><td align="left"><code>string</code></td></tr><tr><td align="left"><code>oneCase</code></td><td align="left"><a href="#firestorecase"><code>FirestoreCase</code></a></td></tr></tbody></table></div>
3165
- <h5 id="returns-57">Returns</h5>
3278
+ <h5 id="returns-58">Returns</h5>
3166
3279
  <p><code>void</code></p>
3167
3280
  <hr>
3168
3281
  <p><a id="bytes"></a></p>
@@ -3173,7 +3286,7 @@ their message. Returns <code>void</code> on a passing result.</p>
3173
3286
  <li>string → UTF-8 encoded</li>
3174
3287
  <li>Uint8Array → used verbatim</li>
3175
3288
  </ul>
3176
- <h4 id="parameters-47">Parameters</h4>
3289
+ <h4 id="parameters-48">Parameters</h4>
3177
3290
  <div class="table-scroll">
3178
3291
 
3179
3292
 
@@ -3188,13 +3301,38 @@ their message. Returns <code>void</code> on a passing result.</p>
3188
3301
 
3189
3302
 
3190
3303
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>input</code></td><td align="left"><code>string</code> | <code>Uint8Array</code>&#x3C;<code>ArrayBufferLike</code>></td></tr></tbody></table></div>
3191
- <h4 id="returns-58">Returns</h4>
3304
+ <h4 id="returns-59">Returns</h4>
3192
3305
  <p><code>Bytes</code></p>
3193
3306
  <hr>
3307
+ <p><a id="canonicalrtdbexpression"></a></p>
3308
+ <h3 id="canonicalrtdbexpression">canonicalRtdbExpression()</h3>
3309
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> canonicalRtdbExpression</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">raw</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">;</span></span></code></pre>
3310
+ <p>Canonical text of an RTDB rule expression: two expressions with equal
3311
+ canonical texts evaluate identically for every request. Deterministic and
3312
+ idempotent. Throws <a href="#rtdbexpressionsyntaxerror">RtdbExpressionSyntaxError</a> for text that is not a
3313
+ rule expression.</p>
3314
+ <h4 id="parameters-49">Parameters</h4>
3315
+ <div class="table-scroll">
3316
+
3317
+
3318
+
3319
+
3320
+
3321
+
3322
+
3323
+
3324
+
3325
+
3326
+
3327
+
3328
+ <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>raw</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
3329
+ <h4 id="returns-60">Returns</h4>
3330
+ <p><code>string</code></p>
3331
+ <hr>
3194
3332
  <p><a id="definertdbrules"></a></p>
3195
3333
  <h3 id="definertdbrules">defineRtdbRules()</h3>
3196
3334
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> defineRtdbRules</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">definition</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">RtdbRulesDefinition</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">RtdbRulesDocument</span><span style="color:#ABB2BF">;</span></span></code></pre>
3197
- <h4 id="parameters-48">Parameters</h4>
3335
+ <h4 id="parameters-50">Parameters</h4>
3198
3336
  <div class="table-scroll">
3199
3337
 
3200
3338
 
@@ -3209,15 +3347,48 @@ their message. Returns <code>void</code> on a passing result.</p>
3209
3347
 
3210
3348
 
3211
3349
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>definition</code></td><td align="left"><a href="#rtdbrulesdefinition"><code>RtdbRulesDefinition</code></a></td></tr></tbody></table></div>
3212
- <h4 id="returns-59">Returns</h4>
3350
+ <h4 id="returns-61">Returns</h4>
3213
3351
  <p><a href="#rtdbrulesdocument"><code>RtdbRulesDocument</code></a></p>
3214
3352
  <hr>
3353
+ <p><a id="diffrtdbrules"></a></p>
3354
+ <h3 id="diffrtdbrules">diffRtdbRules()</h3>
3355
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> diffRtdbRules</span><span style="color:#ABB2BF">(</span></span>
3356
+ <span class="line"><span style="color:#E06C75;font-style:italic"> deployed</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Record</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">unknown</span><span style="color:#ABB2BF">>,</span></span>
3357
+ <span class="line"><span style="color:#E06C75;font-style:italic"> local</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Record</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">unknown</span><span style="color:#ABB2BF">>,</span></span>
3358
+ <span class="line"><span style="color:#E06C75;font-style:italic"> options</span><span style="color:#C678DD">?</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">DiffRtdbRulesOptions</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">RtdbRuleChange</span><span style="color:#ABB2BF">[];</span></span></code></pre>
3359
+ <p>Node-level diff of two <code>rules</code> trees, ordered by path then rule kind.</p>
3360
+ <h4 id="parameters-51">Parameters</h4>
3361
+ <div class="table-scroll">
3362
+
3363
+
3364
+
3365
+
3366
+
3367
+
3368
+
3369
+
3370
+
3371
+
3372
+
3373
+
3374
+
3375
+
3376
+
3377
+
3378
+
3379
+
3380
+
3381
+
3382
+ <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>deployed</code></td><td align="left"><code>Record</code>&#x3C;<code>string</code>, <code>unknown</code>></td></tr><tr><td align="left"><code>local</code></td><td align="left"><code>Record</code>&#x3C;<code>string</code>, <code>unknown</code>></td></tr><tr><td align="left"><code>options?</code></td><td align="left"><a href="#diffrtdbrulesoptions"><code>DiffRtdbRulesOptions</code></a></td></tr></tbody></table></div>
3383
+ <h4 id="returns-62">Returns</h4>
3384
+ <p><a href="#rtdbrulechange"><code>RtdbRuleChange</code></a>[]</p>
3385
+ <hr>
3215
3386
  <p><a id="duration"></a></p>
3216
3387
  <h3 id="duration">duration()</h3>
3217
3388
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> duration</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">value</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">number</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">unit</span><span style="color:#C678DD">?</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">Duration</span><span style="color:#ABB2BF">;</span></span></code></pre>
3218
3389
  <p>A <code>duration</code> value. <code>unit</code> is one of the Firestore duration units
3219
3390
  (<code>'w' | 'd' | 'h' | 'm' | 's' | 'ms' | 'ns'</code>); defaults to seconds.</p>
3220
- <h4 id="parameters-49">Parameters</h4>
3391
+ <h4 id="parameters-52">Parameters</h4>
3221
3392
  <div class="table-scroll">
3222
3393
 
3223
3394
 
@@ -3236,7 +3407,7 @@ their message. Returns <code>void</code> on a passing result.</p>
3236
3407
 
3237
3408
 
3238
3409
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>value</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><code>unit?</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
3239
- <h4 id="returns-60">Returns</h4>
3410
+ <h4 id="returns-63">Returns</h4>
3240
3411
  <p><code>Duration</code></p>
3241
3412
  <hr>
3242
3413
  <p><a id="explaincase"></a></p>
@@ -3245,7 +3416,7 @@ their message. Returns <code>void</code> on a passing result.</p>
3245
3416
  <p>Render a case result as a human-readable trace. The single sanctioned
3246
3417
  trace renderer — used as the message of the error <code>assertCase</code> throws, and
3247
3418
  available directly for logging a result without asserting.</p>
3248
- <h4 id="parameters-50">Parameters</h4>
3419
+ <h4 id="parameters-53">Parameters</h4>
3249
3420
  <div class="table-scroll">
3250
3421
 
3251
3422
 
@@ -3260,14 +3431,14 @@ available directly for logging a result without asserting.</p>
3260
3431
 
3261
3432
 
3262
3433
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>result</code></td><td align="left"><a href="#rtdbcaseresult"><code>RtdbCaseResult</code></a> | <a href="#caseresult"><code>CaseResult</code></a></td></tr></tbody></table></div>
3263
- <h4 id="returns-61">Returns</h4>
3434
+ <h4 id="returns-64">Returns</h4>
3264
3435
  <p><code>string</code></p>
3265
3436
  <hr>
3266
3437
  <p><a id="firestorerules"></a></p>
3267
3438
  <h3 id="firestorerules">firestoreRules()</h3>
3268
3439
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> firestoreRules</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">source</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">FirestoreRuleset</span><span style="color:#ABB2BF">;</span></span></code></pre>
3269
3440
  <p>Compile Firestore rules source into a deep, safe-by-default handle.</p>
3270
- <h4 id="parameters-51">Parameters</h4>
3441
+ <h4 id="parameters-54">Parameters</h4>
3271
3442
  <div class="table-scroll">
3272
3443
 
3273
3444
 
@@ -3282,7 +3453,7 @@ available directly for logging a result without asserting.</p>
3282
3453
 
3283
3454
 
3284
3455
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>source</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
3285
- <h4 id="returns-62">Returns</h4>
3456
+ <h4 id="returns-65">Returns</h4>
3286
3457
  <p><a href="#firestoreruleset"><code>FirestoreRuleset</code></a></p>
3287
3458
  <h4 id="throws-4">Throws</h4>
3288
3459
  <p>when the source does not parse or breaks one
@@ -3295,7 +3466,7 @@ compile-blocking issues on <code>.issues</code>.</p>
3295
3466
  <p>Turn flip: validates a turn field alternates between marks.
3296
3467
  First mark is the initial value on creation.
3297
3468
  Supports 2+ players with circular rotation.</p>
3298
- <h4 id="parameters-52">Parameters</h4>
3469
+ <h4 id="parameters-55">Parameters</h4>
3299
3470
  <div class="table-scroll">
3300
3471
 
3301
3472
 
@@ -3312,14 +3483,14 @@ Supports 2+ players with circular rotation.</p>
3312
3483
 
3313
3484
 
3314
3485
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code>marks</code></td><td align="left"><code>string</code>[]</td><td align="left">ordered list of marks (e.g., [“X”, “O”])</td></tr></tbody></table></div>
3315
- <h4 id="returns-63">Returns</h4>
3486
+ <h4 id="returns-66">Returns</h4>
3316
3487
  <p><code>string</code></p>
3317
3488
  <hr>
3318
3489
  <p><a id="latlng"></a></p>
3319
3490
  <h3 id="latlng">latlng()</h3>
3320
3491
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> latlng</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">lat</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">number</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75;font-style:italic">lng</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">number</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">LatLng</span><span style="color:#ABB2BF">;</span></span></code></pre>
3321
3492
  <p>A <code>latlng</code> geographic point.</p>
3322
- <h4 id="parameters-53">Parameters</h4>
3493
+ <h4 id="parameters-56">Parameters</h4>
3323
3494
  <div class="table-scroll">
3324
3495
 
3325
3496
 
@@ -3338,7 +3509,7 @@ Supports 2+ players with circular rotation.</p>
3338
3509
 
3339
3510
 
3340
3511
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>lat</code></td><td align="left"><code>number</code></td></tr><tr><td align="left"><code>lng</code></td><td align="left"><code>number</code></td></tr></tbody></table></div>
3341
- <h4 id="returns-64">Returns</h4>
3512
+ <h4 id="returns-67">Returns</h4>
3342
3513
  <p><code>LatLng</code></p>
3343
3514
  <hr>
3344
3515
  <p><a id="lint-4"></a></p>
@@ -3346,7 +3517,7 @@ Supports 2+ players with circular rotation.</p>
3346
3517
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> lint</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">source</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">RuleIssue</span><span style="color:#ABB2BF">[];</span></span></code></pre>
3347
3518
  <p>Lint Firestore rules source. Accepts anything — including empty or
3348
3519
  syntactically broken source — and always returns an issue list.</p>
3349
- <h4 id="parameters-54">Parameters</h4>
3520
+ <h4 id="parameters-57">Parameters</h4>
3350
3521
  <div class="table-scroll">
3351
3522
 
3352
3523
 
@@ -3361,7 +3532,7 @@ syntactically broken source — and always returns an issue list.</p>
3361
3532
 
3362
3533
 
3363
3534
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>source</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
3364
- <h4 id="returns-65">Returns</h4>
3535
+ <h4 id="returns-68">Returns</h4>
3365
3536
  <p><a href="#ruleissue"><code>RuleIssue</code></a>[]</p>
3366
3537
  <hr>
3367
3538
  <p><a id="lit"></a></p>
@@ -3373,7 +3544,7 @@ so compiled rules use one quote style.</p>
3373
3544
  <p>The quote and backslash escapes match Pyric’s rules simulator. A string
3374
3545
  with a newline or another control character is refused: Pyric does not
3375
3546
  model escapes for those, and production behavior for them is not captured.</p>
3376
- <h4 id="parameters-55">Parameters</h4>
3547
+ <h4 id="parameters-58">Parameters</h4>
3377
3548
  <div class="table-scroll">
3378
3549
 
3379
3550
 
@@ -3388,14 +3559,14 @@ model escapes for those, and production behavior for them is not captured.</p>
3388
3559
 
3389
3560
 
3390
3561
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>value</code></td><td align="left"><code>Literal</code></td></tr></tbody></table></div>
3391
- <h4 id="returns-66">Returns</h4>
3562
+ <h4 id="returns-69">Returns</h4>
3392
3563
  <p><code>string</code></p>
3393
3564
  <hr>
3394
3565
  <p><a id="not"></a></p>
3395
3566
  <h3 id="not">not()</h3>
3396
3567
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> not</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">e</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">;</span></span></code></pre>
3397
3568
  <p>Negate a condition. A member chain such as <code>data.child('a').exists()</code> needs no parentheses.</p>
3398
- <h4 id="parameters-56">Parameters</h4>
3569
+ <h4 id="parameters-59">Parameters</h4>
3399
3570
  <div class="table-scroll">
3400
3571
 
3401
3572
 
@@ -3410,14 +3581,14 @@ model escapes for those, and production behavior for them is not captured.</p>
3410
3581
 
3411
3582
 
3412
3583
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>e</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
3413
- <h4 id="returns-67">Returns</h4>
3584
+ <h4 id="returns-70">Returns</h4>
3414
3585
  <p><code>string</code></p>
3415
3586
  <hr>
3416
3587
  <p><a id="reference"></a></p>
3417
3588
  <h3 id="reference">reference()</h3>
3418
3589
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> reference</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">path</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">Reference</span><span style="color:#ABB2BF">;</span></span></code></pre>
3419
3590
  <p>A <code>reference</code> to a document, by its path (e.g. <code>"users/alice"</code>).</p>
3420
- <h4 id="parameters-57">Parameters</h4>
3591
+ <h4 id="parameters-60">Parameters</h4>
3421
3592
  <div class="table-scroll">
3422
3593
 
3423
3594
 
@@ -3432,14 +3603,14 @@ model escapes for those, and production behavior for them is not captured.</p>
3432
3603
 
3433
3604
 
3434
3605
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>path</code></td><td align="left"><code>string</code></td></tr></tbody></table></div>
3435
- <h4 id="returns-68">Returns</h4>
3606
+ <h4 id="returns-71">Returns</h4>
3436
3607
  <p><code>Reference</code></p>
3437
3608
  <hr>
3438
3609
  <p><a id="renderrtdbcoverage"></a></p>
3439
3610
  <h3 id="renderrtdbcoverage">renderRtdbCoverage()</h3>
3440
3611
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> renderRtdbCoverage</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">summary</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">RtdbCoverageSummary</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">;</span></span></code></pre>
3441
3612
  <p>One line per rule node, then the per-file totals and the nodes never evaluated.</p>
3442
- <h4 id="parameters-58">Parameters</h4>
3613
+ <h4 id="parameters-61">Parameters</h4>
3443
3614
  <div class="table-scroll">
3444
3615
 
3445
3616
 
@@ -3454,7 +3625,7 @@ model escapes for those, and production behavior for them is not captured.</p>
3454
3625
 
3455
3626
 
3456
3627
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>summary</code></td><td align="left"><a href="#rtdbcoveragesummary"><code>RtdbCoverageSummary</code></a></td></tr></tbody></table></div>
3457
- <h4 id="returns-69">Returns</h4>
3628
+ <h4 id="returns-72">Returns</h4>
3458
3629
  <p><code>string</code></p>
3459
3630
  <hr>
3460
3631
  <p><a id="ruleset"></a></p>
@@ -3463,7 +3634,7 @@ model escapes for those, and production behavior for them is not captured.</p>
3463
3634
  <span class="line"><span style="color:#ABB2BF"> | </span><span style="color:#E5C07B">Record</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">PathDef</span><span style="color:#ABB2BF">></span></span>
3464
3635
  <span class="line"><span style="color:#ABB2BF"> | (</span><span style="color:#E06C75;font-style:italic">ctx</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">RulesetContext</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> void</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">RtdbNode</span><span style="color:#ABB2BF">;</span></span></code></pre>
3465
3636
  <p>Compile a declarative rules definition into an environment-independent tree.</p>
3466
- <h4 id="parameters-59">Parameters</h4>
3637
+ <h4 id="parameters-62">Parameters</h4>
3467
3638
  <div class="table-scroll">
3468
3639
 
3469
3640
 
@@ -3478,7 +3649,7 @@ model escapes for those, and production behavior for them is not captured.</p>
3478
3649
 
3479
3650
 
3480
3651
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>input</code></td><td align="left">| <code>Record</code>&#x3C;<code>string</code>, <a href="#pathdef"><code>PathDef</code></a>> | (<code>ctx</code>: <a href="#rulesetcontext"><code>RulesetContext</code></a>) => <code>void</code></td></tr></tbody></table></div>
3481
- <h4 id="returns-70">Returns</h4>
3652
+ <h4 id="returns-73">Returns</h4>
3482
3653
  <p><code>RtdbNode</code></p>
3483
3654
  <hr>
3484
3655
  <p><a id="schemarules"></a></p>
@@ -3486,7 +3657,7 @@ model escapes for those, and production behavior for them is not captured.</p>
3486
3657
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> schemaRules</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">schema</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">ZodObject</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E5C07B">any</span><span style="color:#ABB2BF">>, </span><span style="color:#E06C75;font-style:italic">fieldConstraints</span><span style="color:#C678DD">?</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">Record</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">Expr</span><span style="color:#ABB2BF">[]>): </span><span style="color:#E5C07B">SchemaRulesResult</span><span style="color:#ABB2BF">;</span></span></code></pre>
3487
3658
  <p>Generate RTDB validate rules from a Zod object schema.
3488
3659
  Optional fieldConstraints are AND-composed with the schema type check.</p>
3489
- <h4 id="parameters-60">Parameters</h4>
3660
+ <h4 id="parameters-63">Parameters</h4>
3490
3661
  <div class="table-scroll">
3491
3662
 
3492
3663
 
@@ -3505,7 +3676,7 @@ Optional fieldConstraints are AND-composed with the schema type check.</p>
3505
3676
 
3506
3677
 
3507
3678
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>schema</code></td><td align="left"><code>ZodObject</code>&#x3C;<code>any</code>></td></tr><tr><td align="left"><code>fieldConstraints?</code></td><td align="left"><code>Record</code>&#x3C;<code>string</code>, <a href="#expr"><code>Expr</code></a>[]></td></tr></tbody></table></div>
3508
- <h4 id="returns-71">Returns</h4>
3679
+ <h4 id="returns-74">Returns</h4>
3509
3680
  <p><a href="#schemarulesresult"><code>SchemaRulesResult</code></a></p>
3510
3681
  <hr>
3511
3682
  <p><a id="servertimestamp"></a></p>
@@ -3517,7 +3688,7 @@ Optional fieldConstraints are AND-composed with the schema type check.</p>
3517
3688
  resolves it to the request time (<code>request.time</code> in Firestore, <code>now</code> in
3518
3689
  Realtime Database), so a rule comparing a timestamp field to the server
3519
3690
  clock sees a match.</p>
3520
- <h4 id="returns-72">Returns</h4>
3691
+ <h4 id="returns-75">Returns</h4>
3521
3692
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#ABB2BF">{</span></span>
3522
3693
  <span class="line"><span style="color:#ABB2BF">}</span></span></code></pre>
3523
3694
  <hr>
@@ -3536,7 +3707,7 @@ clock sees a match.</p>
3536
3707
  <li>string → ISO-8601</li>
3537
3708
  <li>object → explicit <code>{ seconds, nanos }</code></li>
3538
3709
  </ul>
3539
- <h4 id="parameters-61">Parameters</h4>
3710
+ <h4 id="parameters-64">Parameters</h4>
3540
3711
  <div class="table-scroll">
3541
3712
 
3542
3713
 
@@ -3551,7 +3722,7 @@ clock sees a match.</p>
3551
3722
 
3552
3723
 
3553
3724
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>input</code></td><td align="left">| <code>string</code> | <code>number</code> | { <code>nanos?</code>: <code>number</code>; <code>seconds</code>: <code>number</code>; }</td></tr></tbody></table></div>
3554
- <h4 id="returns-73">Returns</h4>
3725
+ <h4 id="returns-76">Returns</h4>
3555
3726
  <p><code>Timestamp</code></p>
3556
3727
  <hr>
3557
3728
  <p><a id="turnguard"></a></p>
@@ -3563,7 +3734,7 @@ clock sees a match.</p>
3563
3734
  <span class="line"><span style="color:#E06C75;font-style:italic"> playingValue</span><span style="color:#C678DD">?</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">): </span><span style="color:#E5C07B">string</span><span style="color:#ABB2BF">;</span></span></code></pre>
3564
3735
  <p>Turn enforcement: only the current turn’s player can write.
3565
3736
  Uses data (pre-write) for the turn check — NOT newData.</p>
3566
- <h4 id="parameters-62">Parameters</h4>
3737
+ <h4 id="parameters-65">Parameters</h4>
3567
3738
  <div class="table-scroll">
3568
3739
 
3569
3740
 
@@ -3595,14 +3766,14 @@ Uses data (pre-write) for the turn check — NOT newData.</p>
3595
3766
 
3596
3767
 
3597
3768
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code>turnField</code></td><td align="left"><code>string</code></td><td align="left">the field that stores whose turn it is (e.g., “currentTurn”)</td></tr><tr><td align="left"><code>players</code></td><td align="left"><code>Record</code>&#x3C;<code>string</code>, <code>string</code>></td><td align="left">map of mark → player field (e.g., { X: “playerX”, O: “playerO” })</td></tr><tr><td align="left"><code>statusField?</code></td><td align="left"><code>string</code></td><td align="left">optional field that must equal playingValue for moves to be allowed</td></tr><tr><td align="left"><code>playingValue?</code></td><td align="left"><code>string</code></td><td align="left">the value of statusField during active play (e.g., “playing”)</td></tr></tbody></table></div>
3598
- <h4 id="returns-74">Returns</h4>
3769
+ <h4 id="returns-77">Returns</h4>
3599
3770
  <p><code>string</code></p>
3600
3771
  <hr>
3601
3772
  <p><a id="vector"></a></p>
3602
3773
  <h3 id="vector">vector()</h3>
3603
3774
  <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">function</span><span style="color:#61AFEF"> vector</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">values</span><span style="color:#ABB2BF">: </span><span style="color:#C678DD">readonly</span><span style="color:#E5C07B"> number</span><span style="color:#ABB2BF">[]): </span><span style="color:#E5C07B">Vector</span><span style="color:#ABB2BF">;</span></span></code></pre>
3604
3775
  <p>A <code>vector</code> value from its numeric components.</p>
3605
- <h4 id="parameters-63">Parameters</h4>
3776
+ <h4 id="parameters-66">Parameters</h4>
3606
3777
  <div class="table-scroll">
3607
3778
 
3608
3779
 
@@ -3617,7 +3788,7 @@ Uses data (pre-write) for the turn check — NOT newData.</p>
3617
3788
 
3618
3789
 
3619
3790
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th></tr></thead><tbody><tr><td align="left"><code>values</code></td><td align="left">readonly <code>number</code>[]</td></tr></tbody></table></div>
3620
- <h4 id="returns-75">Returns</h4>
3791
+ <h4 id="returns-78">Returns</h4>
3621
3792
  <p><code>Vector</code></p>
3622
3793
  <hr>
3623
3794
  <p><a id="wincheckhelper"></a></p>
@@ -3629,7 +3800,7 @@ Uses data (pre-write) for the turn check — NOT newData.</p>
3629
3800
  <p>Win check helper: validates a boolean field against winning lines on a board.
3630
3801
  If true, at least one winning line must exist. If false, no winning line can exist.
3631
3802
  Uses the “client claims, rules verify” pattern.</p>
3632
- <h4 id="parameters-64">Parameters</h4>
3803
+ <h4 id="parameters-67">Parameters</h4>
3633
3804
  <div class="table-scroll">
3634
3805
 
3635
3806
 
@@ -3656,5 +3827,5 @@ Uses the “client claims, rules verify” pattern.</p>
3656
3827
 
3657
3828
 
3658
3829
  <table><thead><tr><th align="left">Parameter</th><th align="left">Type</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code>mark</code></td><td align="left"><code>string</code></td><td align="left">the player mark to check (e.g., “X”)</td></tr><tr><td align="left"><code>lines</code></td><td align="left"><code>number</code>[][]</td><td align="left">array of winning line coordinates (e.g., [[0,1,2], [3,4,5], …])</td></tr><tr><td align="left"><code>boardPath?</code></td><td align="left"><code>string</code></td><td align="left">the path to the board relative to the parent (default “board”)</td></tr></tbody></table></div>
3659
- <h4 id="returns-76">Returns</h4>
3660
- <p><code>string</code></p> </article> </main> <aside class="doc-toc api-symbols" aria-label="API symbols" data-astro-cid-mw7aashj> <h2 class="doc-toc-heading" data-astro-cid-mw7aashj>Symbols</h2> <input class="api-symbol-filter" type="search" placeholder="Filter symbols" aria-label="Filter API symbols" data-api-symbol-filter data-astro-cid-mw7aashj> <div class="api-symbol-groups" data-api-symbol-groups data-astro-cid-mw7aashj> <section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#classes" data-astro-cid-mw7aashj> Classes </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="rulesassertionerror" data-astro-cid-mw7aashj> <a href="#rulesassertionerror" data-astro-cid-mw7aashj>RulesAssertionError</a> </li><li data-api-symbol="rulescompileerror" data-astro-cid-mw7aashj> <a href="#rulescompileerror" data-astro-cid-mw7aashj>RulesCompileError</a> </li><li data-api-symbol="rulesunsupportederror" data-astro-cid-mw7aashj> <a href="#rulesunsupportederror" data-astro-cid-mw7aashj>RulesUnsupportedError</a> </li> </ul> </section><section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#interfaces" data-astro-cid-mw7aashj> Interfaces </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="caseresult" data-astro-cid-mw7aashj> <a href="#caseresult" data-astro-cid-mw7aashj>CaseResult</a> </li><li data-api-symbol="evaluatedruleinfo" data-astro-cid-mw7aashj> <a href="#evaluatedruleinfo" data-astro-cid-mw7aashj>EvaluatedRuleInfo</a> </li><li data-api-symbol="explanation" data-astro-cid-mw7aashj> <a href="#explanation" data-astro-cid-mw7aashj>Explanation</a> </li><li data-api-symbol="exprtraceentry" data-astro-cid-mw7aashj> <a href="#exprtraceentry" data-astro-cid-mw7aashj>ExprTraceEntry</a> </li><li data-api-symbol="firestorecase" data-astro-cid-mw7aashj> <a href="#firestorecase" data-astro-cid-mw7aashj>FirestoreCase</a> </li><li data-api-symbol="firestoreruleset" data-astro-cid-mw7aashj> <a href="#firestoreruleset" data-astro-cid-mw7aashj>FirestoreRuleset</a> </li><li data-api-symbol="listqueryproofreport" data-astro-cid-mw7aashj> <a href="#listqueryproofreport" data-astro-cid-mw7aashj>ListQueryProofReport</a> </li><li data-api-symbol="pathdef" data-astro-cid-mw7aashj> <a href="#pathdef" data-astro-cid-mw7aashj>PathDef</a> </li><li data-api-symbol="pathresolutionentry" data-astro-cid-mw7aashj> <a href="#pathresolutionentry" data-astro-cid-mw7aashj>PathResolutionEntry</a> </li><li data-api-symbol="pathresolutiontrace" data-astro-cid-mw7aashj> <a href="#pathresolutiontrace" data-astro-cid-mw7aashj>PathResolutionTrace</a> </li><li data-api-symbol="queryprooffailure" data-astro-cid-mw7aashj> <a href="#queryprooffailure" data-astro-cid-mw7aashj>QueryProofFailure</a> </li><li data-api-symbol="queryproofresidual" data-astro-cid-mw7aashj> <a href="#queryproofresidual" data-astro-cid-mw7aashj>QueryProofResidual</a> </li><li data-api-symbol="queryrepro" data-astro-cid-mw7aashj> <a href="#queryrepro" data-astro-cid-mw7aashj>QueryRepro</a> </li><li data-api-symbol="rtdbcase" data-astro-cid-mw7aashj> <a href="#rtdbcase" data-astro-cid-mw7aashj>RtdbCase</a> </li><li data-api-symbol="rtdbcasequery" data-astro-cid-mw7aashj> <a href="#rtdbcasequery" data-astro-cid-mw7aashj>RtdbCaseQuery</a> </li><li data-api-symbol="rtdbcaseresult" data-astro-cid-mw7aashj> <a href="#rtdbcaseresult" data-astro-cid-mw7aashj>RtdbCaseResult</a> </li><li data-api-symbol="rtdbcoverageoptions" data-astro-cid-mw7aashj> <a href="#rtdbcoverageoptions" data-astro-cid-mw7aashj>RtdbCoverageOptions</a> </li><li data-api-symbol="rtdbcoveragesummary" data-astro-cid-mw7aashj> <a href="#rtdbcoveragesummary" data-astro-cid-mw7aashj>RtdbCoverageSummary</a> </li><li data-api-symbol="rtdbexplanation" data-astro-cid-mw7aashj> <a href="#rtdbexplanation" data-astro-cid-mw7aashj>RtdbExplanation</a> </li><li data-api-symbol="rtdbfilecoverage" data-astro-cid-mw7aashj> <a href="#rtdbfilecoverage" data-astro-cid-mw7aashj>RtdbFileCoverage</a> </li><li data-api-symbol="rtdbfirebasejsonoptions" data-astro-cid-mw7aashj> <a href="#rtdbfirebasejsonoptions" data-astro-cid-mw7aashj>RtdbFirebaseJsonOptions</a> </li><li data-api-symbol="rtdbrulecoverage" data-astro-cid-mw7aashj> <a href="#rtdbrulecoverage" data-astro-cid-mw7aashj>RtdbRuleCoverage</a> </li><li data-api-symbol="rtdbrulescheckresult" data-astro-cid-mw7aashj> <a href="#rtdbrulescheckresult" data-astro-cid-mw7aashj>RtdbRulesCheckResult</a> </li><li data-api-symbol="rtdbrulesconstructor()" data-astro-cid-mw7aashj> <a href="#rtdbrulesconstructor" data-astro-cid-mw7aashj>RtdbRulesConstructor()</a> </li><li data-api-symbol="rtdbrulesdefinition" data-astro-cid-mw7aashj> <a href="#rtdbrulesdefinition" data-astro-cid-mw7aashj>RtdbRulesDefinition</a> </li><li data-api-symbol="rtdbrulesdocument" data-astro-cid-mw7aashj> <a href="#rtdbrulesdocument" data-astro-cid-mw7aashj>RtdbRulesDocument</a> </li><li data-api-symbol="rtdbruleset" data-astro-cid-mw7aashj> <a href="#rtdbruleset" data-astro-cid-mw7aashj>RtdbRuleset</a> </li><li data-api-symbol="rtdbrulesfinding" data-astro-cid-mw7aashj> <a href="#rtdbrulesfinding" data-astro-cid-mw7aashj>RtdbRulesFinding</a> </li><li data-api-symbol="rtdbsimulationsummary" data-astro-cid-mw7aashj> <a href="#rtdbsimulationsummary" data-astro-cid-mw7aashj>RtdbSimulationSummary</a> </li><li data-api-symbol="ruleevaluation" data-astro-cid-mw7aashj> <a href="#ruleevaluation" data-astro-cid-mw7aashj>RuleEvaluation</a> </li><li data-api-symbol="ruleissue" data-astro-cid-mw7aashj> <a href="#ruleissue" data-astro-cid-mw7aashj>RuleIssue</a> </li><li data-api-symbol="rulesetcontext" data-astro-cid-mw7aashj> <a href="#rulesetcontext" data-astro-cid-mw7aashj>RulesetContext</a> </li><li data-api-symbol="rulesresourcelimit" data-astro-cid-mw7aashj> <a href="#rulesresourcelimit" data-astro-cid-mw7aashj>RulesResourceLimit</a> </li><li data-api-symbol="schemarulesresult" data-astro-cid-mw7aashj> <a href="#schemarulesresult" data-astro-cid-mw7aashj>SchemaRulesResult</a> </li><li data-api-symbol="shapeoptions" data-astro-cid-mw7aashj> <a href="#shapeoptions" data-astro-cid-mw7aashj>ShapeOptions</a> </li><li data-api-symbol="shaperesult" data-astro-cid-mw7aashj> <a href="#shaperesult" data-astro-cid-mw7aashj>ShapeResult</a> </li><li data-api-symbol="simulationsummary" data-astro-cid-mw7aashj> <a href="#simulationsummary" data-astro-cid-mw7aashj>SimulationSummary</a> </li> </ul> </section><section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#type-aliases" data-astro-cid-mw7aashj> Type Aliases </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="expr" data-astro-cid-mw7aashj> <a href="#expr" data-astro-cid-mw7aashj>Expr</a> </li><li data-api-symbol="fieldrule" data-astro-cid-mw7aashj> <a href="#fieldrule" data-astro-cid-mw7aashj>FieldRule</a> </li><li data-api-symbol="firestoremethod" data-astro-cid-mw7aashj> <a href="#firestoremethod" data-astro-cid-mw7aashj>FirestoreMethod</a> </li><li data-api-symbol="listquery" data-astro-cid-mw7aashj> <a href="#listquery" data-astro-cid-mw7aashj>ListQuery</a> </li><li data-api-symbol="listquerywhereconstraint" data-astro-cid-mw7aashj> <a href="#listquerywhereconstraint" data-astro-cid-mw7aashj>ListQueryWhereConstraint</a> </li><li data-api-symbol="rtdbcoveragekind" data-astro-cid-mw7aashj> <a href="#rtdbcoveragekind" data-astro-cid-mw7aashj>RtdbCoverageKind</a> </li><li data-api-symbol="rtdbcoveragestatus" data-astro-cid-mw7aashj> <a href="#rtdbcoveragestatus" data-astro-cid-mw7aashj>RtdbCoverageStatus</a> </li><li data-api-symbol="rtdbinstancesdata" data-astro-cid-mw7aashj> <a href="#rtdbinstancesdata" data-astro-cid-mw7aashj>RtdbInstancesData</a> </li><li data-api-symbol="rtdbruleevaluation" data-astro-cid-mw7aashj> <a href="#rtdbruleevaluation" data-astro-cid-mw7aashj>RtdbRuleEvaluation</a> </li><li data-api-symbol="rtdbrulesfindingrule" data-astro-cid-mw7aashj> <a href="#rtdbrulesfindingrule" data-astro-cid-mw7aashj>RtdbRulesFindingRule</a> </li><li data-api-symbol="rtdbrulesjson" data-astro-cid-mw7aashj> <a href="#rtdbrulesjson" data-astro-cid-mw7aashj>RtdbRulesJson</a> </li><li data-api-symbol="rtdbrulessimulationauth" data-astro-cid-mw7aashj> <a href="#rtdbrulessimulationauth" data-astro-cid-mw7aashj>RtdbRulesSimulationAuth</a> </li><li data-api-symbol="rtdbrulessimulationinput" data-astro-cid-mw7aashj> <a href="#rtdbrulessimulationinput" data-astro-cid-mw7aashj>RtdbRulesSimulationInput</a> </li><li data-api-symbol="rtdbstdlib" data-astro-cid-mw7aashj> <a href="#rtdbstdlib" data-astro-cid-mw7aashj>RtdbStdlib</a> </li><li data-api-symbol="ruleissueorigin" data-astro-cid-mw7aashj> <a href="#ruleissueorigin" data-astro-cid-mw7aashj>RuleIssueOrigin</a> </li><li data-api-symbol="ruleissueseverity" data-astro-cid-mw7aashj> <a href="#ruleissueseverity" data-astro-cid-mw7aashj>RuleIssueSeverity</a> </li><li data-api-symbol="segment" data-astro-cid-mw7aashj> <a href="#segment" data-astro-cid-mw7aashj>Segment</a> </li> </ul> </section><section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#variables" data-astro-cid-mw7aashj> Variables </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="allow()" data-astro-cid-mw7aashj> <a href="#allow" data-astro-cid-mw7aashj>allow()</a> </li><li data-api-symbol="always()" data-astro-cid-mw7aashj> <a href="#always" data-astro-cid-mw7aashj>always()</a> </li><li data-api-symbol="auth_uid" data-astro-cid-mw7aashj> <a href="#auth_uid" data-astro-cid-mw7aashj>AUTH_UID</a> </li><li data-api-symbol="authenticated()" data-astro-cid-mw7aashj> <a href="#authenticated" data-astro-cid-mw7aashj>authenticated()</a> </li><li data-api-symbol="dataexists()" data-astro-cid-mw7aashj> <a href="#dataexists" data-astro-cid-mw7aashj>dataExists()</a> </li><li data-api-symbol="dataparentval()" data-astro-cid-mw7aashj> <a href="#dataparentval" data-astro-cid-mw7aashj>dataParentVal()</a> </li><li data-api-symbol="dataval()" data-astro-cid-mw7aashj> <a href="#dataval" data-astro-cid-mw7aashj>dataVal()</a> </li><li data-api-symbol="deny()" data-astro-cid-mw7aashj> <a href="#deny" data-astro-cid-mw7aashj>deny()</a> </li><li data-api-symbol="eq()" data-astro-cid-mw7aashj> <a href="#eq" data-astro-cid-mw7aashj>eq()</a> </li><li data-api-symbol="expr()" data-astro-cid-mw7aashj> <a href="#expr-1" data-astro-cid-mw7aashj>expr()</a> </li><li data-api-symbol="fieldenum()" data-astro-cid-mw7aashj> <a href="#fieldenum" data-astro-cid-mw7aashj>fieldEnum()</a> </li><li data-api-symbol="fieldisboolean()" data-astro-cid-mw7aashj> <a href="#fieldisboolean" data-astro-cid-mw7aashj>fieldIsBoolean()</a> </li><li data-api-symbol="fieldisnumber()" data-astro-cid-mw7aashj> <a href="#fieldisnumber" data-astro-cid-mw7aashj>fieldIsNumber()</a> </li><li data-api-symbol="fieldisstring()" data-astro-cid-mw7aashj> <a href="#fieldisstring" data-astro-cid-mw7aashj>fieldIsString()</a> </li><li data-api-symbol="fieldowneronly()" data-astro-cid-mw7aashj> <a href="#fieldowneronly" data-astro-cid-mw7aashj>fieldOwnerOnly()</a> </li><li data-api-symbol="gt()" data-astro-cid-mw7aashj> <a href="#gt" data-astro-cid-mw7aashj>gt()</a> </li><li data-api-symbol="haschild()" data-astro-cid-mw7aashj> <a href="#haschild" data-astro-cid-mw7aashj>hasChild()</a> </li><li data-api-symbol="haschildren()" data-astro-cid-mw7aashj> <a href="#haschildren" data-astro-cid-mw7aashj>hasChildren()</a> </li><li data-api-symbol="hasrole()" data-astro-cid-mw7aashj> <a href="#hasrole" data-astro-cid-mw7aashj>hasRole()</a> </li><li data-api-symbol="immutable()" data-astro-cid-mw7aashj> <a href="#immutable" data-astro-cid-mw7aashj>immutable()</a> </li><li data-api-symbol="immutableself()" data-astro-cid-mw7aashj> <a href="#immutableself" data-astro-cid-mw7aashj>immutableSelf()</a> </li><li data-api-symbol="ismember()" data-astro-cid-mw7aashj> <a href="#ismember" data-astro-cid-mw7aashj>isMember()</a> </li><li data-api-symbol="isnew()" data-astro-cid-mw7aashj> <a href="#isnew" data-astro-cid-mw7aashj>isNew()</a> </li><li data-api-symbol="lte()" data-astro-cid-mw7aashj> <a href="#lte" data-astro-cid-mw7aashj>lte()</a> </li><li data-api-symbol="neq()" data-astro-cid-mw7aashj> <a href="#neq" data-astro-cid-mw7aashj>neq()</a> </li><li data-api-symbol="newdataexists()" data-astro-cid-mw7aashj> <a href="#newdataexists" data-astro-cid-mw7aashj>newDataExists()</a> </li><li data-api-symbol="newdatais()" data-astro-cid-mw7aashj> <a href="#newdatais" data-astro-cid-mw7aashj>newDataIs()</a> </li><li data-api-symbol="newdataparentexists()" data-astro-cid-mw7aashj> <a href="#newdataparentexists" data-astro-cid-mw7aashj>newDataParentExists()</a> </li><li data-api-symbol="newdataparentval()" data-astro-cid-mw7aashj> <a href="#newdataparentval" data-astro-cid-mw7aashj>newDataParentVal()</a> </li><li data-api-symbol="newdataval()" data-astro-cid-mw7aashj> <a href="#newdataval" data-astro-cid-mw7aashj>newDataVal()</a> </li><li data-api-symbol="ownerornew()" data-astro-cid-mw7aashj> <a href="#ownerornew" data-astro-cid-mw7aashj>ownerOrNew()</a> </li><li data-api-symbol="ownfield()" data-astro-cid-mw7aashj> <a href="#ownfield" data-astro-cid-mw7aashj>ownField()</a> </li><li data-api-symbol="ownpath()" data-astro-cid-mw7aashj> <a href="#ownpath" data-astro-cid-mw7aashj>ownPath()</a> </li><li data-api-symbol="pathowneronly()" data-astro-cid-mw7aashj> <a href="#pathowneronly" data-astro-cid-mw7aashj>pathOwnerOnly()</a> </li><li data-api-symbol="ref()" data-astro-cid-mw7aashj> <a href="#ref" data-astro-cid-mw7aashj>ref()</a> </li><li data-api-symbol="required()" data-astro-cid-mw7aashj> <a href="#required" data-astro-cid-mw7aashj>required()</a> </li><li data-api-symbol="rootequals()" data-astro-cid-mw7aashj> <a href="#rootequals" data-astro-cid-mw7aashj>rootEquals()</a> </li><li data-api-symbol="rootexists()" data-astro-cid-mw7aashj> <a href="#rootexists" data-astro-cid-mw7aashj>rootExists()</a> </li><li data-api-symbol="rtdbrules" data-astro-cid-mw7aashj> <a href="#rtdbrules" data-astro-cid-mw7aashj>rtdbRules</a> </li><li data-api-symbol="rtdbstdlib" data-astro-cid-mw7aashj> <a href="#rtdbstdlib-1" data-astro-cid-mw7aashj>rtdbStdlib</a> </li><li data-api-symbol="transition()" data-astro-cid-mw7aashj> <a href="#transition" data-astro-cid-mw7aashj>transition()</a> </li> </ul> </section><section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#functions" data-astro-cid-mw7aashj> Functions </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="all()" data-astro-cid-mw7aashj> <a href="#all" data-astro-cid-mw7aashj>all()</a> </li><li data-api-symbol="any()" data-astro-cid-mw7aashj> <a href="#any" data-astro-cid-mw7aashj>any()</a> </li><li data-api-symbol="assertcase()" data-astro-cid-mw7aashj> <a href="#assertcase" data-astro-cid-mw7aashj>assertCase()</a> </li><li data-api-symbol="bytes()" data-astro-cid-mw7aashj> <a href="#bytes" data-astro-cid-mw7aashj>bytes()</a> </li><li data-api-symbol="definertdbrules()" data-astro-cid-mw7aashj> <a href="#definertdbrules" data-astro-cid-mw7aashj>defineRtdbRules()</a> </li><li data-api-symbol="duration()" data-astro-cid-mw7aashj> <a href="#duration" data-astro-cid-mw7aashj>duration()</a> </li><li data-api-symbol="explaincase()" data-astro-cid-mw7aashj> <a href="#explaincase" data-astro-cid-mw7aashj>explainCase()</a> </li><li data-api-symbol="firestorerules()" data-astro-cid-mw7aashj> <a href="#firestorerules" data-astro-cid-mw7aashj>firestoreRules()</a> </li><li data-api-symbol="flip()" data-astro-cid-mw7aashj> <a href="#flip" data-astro-cid-mw7aashj>flip()</a> </li><li data-api-symbol="latlng()" data-astro-cid-mw7aashj> <a href="#latlng" data-astro-cid-mw7aashj>latlng()</a> </li><li data-api-symbol="lint()" data-astro-cid-mw7aashj> <a href="#lint-2" data-astro-cid-mw7aashj>lint()</a> </li><li data-api-symbol="lit()" data-astro-cid-mw7aashj> <a href="#lit" data-astro-cid-mw7aashj>lit()</a> </li><li data-api-symbol="not()" data-astro-cid-mw7aashj> <a href="#not" data-astro-cid-mw7aashj>not()</a> </li><li data-api-symbol="reference()" data-astro-cid-mw7aashj> <a href="#reference" data-astro-cid-mw7aashj>reference()</a> </li><li data-api-symbol="renderrtdbcoverage()" data-astro-cid-mw7aashj> <a href="#renderrtdbcoverage" data-astro-cid-mw7aashj>renderRtdbCoverage()</a> </li><li data-api-symbol="ruleset()" data-astro-cid-mw7aashj> <a href="#ruleset" data-astro-cid-mw7aashj>ruleset()</a> </li><li data-api-symbol="schemarules()" data-astro-cid-mw7aashj> <a href="#schemarules" data-astro-cid-mw7aashj>schemaRules()</a> </li><li data-api-symbol="servertimestamp()" data-astro-cid-mw7aashj> <a href="#servertimestamp" data-astro-cid-mw7aashj>serverTimestamp()</a> </li><li data-api-symbol="timestamp()" data-astro-cid-mw7aashj> <a href="#timestamp" data-astro-cid-mw7aashj>timestamp()</a> </li><li data-api-symbol="turnguard()" data-astro-cid-mw7aashj> <a href="#turnguard" data-astro-cid-mw7aashj>turnGuard()</a> </li><li data-api-symbol="vector()" data-astro-cid-mw7aashj> <a href="#vector" data-astro-cid-mw7aashj>vector()</a> </li><li data-api-symbol="wincheckhelper()" data-astro-cid-mw7aashj> <a href="#wincheckhelper" data-astro-cid-mw7aashj>winCheckHelper()</a> </li> </ul> </section> <p class="api-symbol-empty" data-api-symbol-empty hidden data-astro-cid-mw7aashj>No matching symbols</p> </div> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body></html>
3830
+ <h4 id="returns-79">Returns</h4>
3831
+ <p><code>string</code></p> </article> </main> <aside class="doc-toc api-symbols" aria-label="API symbols" data-astro-cid-mw7aashj> <h2 class="doc-toc-heading" data-astro-cid-mw7aashj>Symbols</h2> <input class="api-symbol-filter" type="search" placeholder="Filter symbols" aria-label="Filter API symbols" data-api-symbol-filter data-astro-cid-mw7aashj> <div class="api-symbol-groups" data-api-symbol-groups data-astro-cid-mw7aashj> <section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#classes" data-astro-cid-mw7aashj> Classes </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="rtdbexpressionsyntaxerror" data-astro-cid-mw7aashj> <a href="#rtdbexpressionsyntaxerror" data-astro-cid-mw7aashj>RtdbExpressionSyntaxError</a> </li><li data-api-symbol="rulesassertionerror" data-astro-cid-mw7aashj> <a href="#rulesassertionerror" data-astro-cid-mw7aashj>RulesAssertionError</a> </li><li data-api-symbol="rulescompileerror" data-astro-cid-mw7aashj> <a href="#rulescompileerror" data-astro-cid-mw7aashj>RulesCompileError</a> </li><li data-api-symbol="rulesunsupportederror" data-astro-cid-mw7aashj> <a href="#rulesunsupportederror" data-astro-cid-mw7aashj>RulesUnsupportedError</a> </li> </ul> </section><section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#interfaces" data-astro-cid-mw7aashj> Interfaces </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="caseresult" data-astro-cid-mw7aashj> <a href="#caseresult" data-astro-cid-mw7aashj>CaseResult</a> </li><li data-api-symbol="diffrtdbrulesoptions" data-astro-cid-mw7aashj> <a href="#diffrtdbrulesoptions" data-astro-cid-mw7aashj>DiffRtdbRulesOptions</a> </li><li data-api-symbol="evaluatedruleinfo" data-astro-cid-mw7aashj> <a href="#evaluatedruleinfo" data-astro-cid-mw7aashj>EvaluatedRuleInfo</a> </li><li data-api-symbol="explanation" data-astro-cid-mw7aashj> <a href="#explanation" data-astro-cid-mw7aashj>Explanation</a> </li><li data-api-symbol="exprtraceentry" data-astro-cid-mw7aashj> <a href="#exprtraceentry" data-astro-cid-mw7aashj>ExprTraceEntry</a> </li><li data-api-symbol="firestorecase" data-astro-cid-mw7aashj> <a href="#firestorecase" data-astro-cid-mw7aashj>FirestoreCase</a> </li><li data-api-symbol="firestoreruleset" data-astro-cid-mw7aashj> <a href="#firestoreruleset" data-astro-cid-mw7aashj>FirestoreRuleset</a> </li><li data-api-symbol="listqueryproofreport" data-astro-cid-mw7aashj> <a href="#listqueryproofreport" data-astro-cid-mw7aashj>ListQueryProofReport</a> </li><li data-api-symbol="pathdef" data-astro-cid-mw7aashj> <a href="#pathdef" data-astro-cid-mw7aashj>PathDef</a> </li><li data-api-symbol="pathresolutionentry" data-astro-cid-mw7aashj> <a href="#pathresolutionentry" data-astro-cid-mw7aashj>PathResolutionEntry</a> </li><li data-api-symbol="pathresolutiontrace" data-astro-cid-mw7aashj> <a href="#pathresolutiontrace" data-astro-cid-mw7aashj>PathResolutionTrace</a> </li><li data-api-symbol="queryprooffailure" data-astro-cid-mw7aashj> <a href="#queryprooffailure" data-astro-cid-mw7aashj>QueryProofFailure</a> </li><li data-api-symbol="queryproofresidual" data-astro-cid-mw7aashj> <a href="#queryproofresidual" data-astro-cid-mw7aashj>QueryProofResidual</a> </li><li data-api-symbol="queryrepro" data-astro-cid-mw7aashj> <a href="#queryrepro" data-astro-cid-mw7aashj>QueryRepro</a> </li><li data-api-symbol="rtdbcase" data-astro-cid-mw7aashj> <a href="#rtdbcase" data-astro-cid-mw7aashj>RtdbCase</a> </li><li data-api-symbol="rtdbcasequery" data-astro-cid-mw7aashj> <a href="#rtdbcasequery" data-astro-cid-mw7aashj>RtdbCaseQuery</a> </li><li data-api-symbol="rtdbcaseresult" data-astro-cid-mw7aashj> <a href="#rtdbcaseresult" data-astro-cid-mw7aashj>RtdbCaseResult</a> </li><li data-api-symbol="rtdbcoverageoptions" data-astro-cid-mw7aashj> <a href="#rtdbcoverageoptions" data-astro-cid-mw7aashj>RtdbCoverageOptions</a> </li><li data-api-symbol="rtdbcoveragesummary" data-astro-cid-mw7aashj> <a href="#rtdbcoveragesummary" data-astro-cid-mw7aashj>RtdbCoverageSummary</a> </li><li data-api-symbol="rtdbexplanation" data-astro-cid-mw7aashj> <a href="#rtdbexplanation" data-astro-cid-mw7aashj>RtdbExplanation</a> </li><li data-api-symbol="rtdbfilecoverage" data-astro-cid-mw7aashj> <a href="#rtdbfilecoverage" data-astro-cid-mw7aashj>RtdbFileCoverage</a> </li><li data-api-symbol="rtdbfirebasejsonoptions" data-astro-cid-mw7aashj> <a href="#rtdbfirebasejsonoptions" data-astro-cid-mw7aashj>RtdbFirebaseJsonOptions</a> </li><li data-api-symbol="rtdbrulechange" data-astro-cid-mw7aashj> <a href="#rtdbrulechange" data-astro-cid-mw7aashj>RtdbRuleChange</a> </li><li data-api-symbol="rtdbrulecoverage" data-astro-cid-mw7aashj> <a href="#rtdbrulecoverage" data-astro-cid-mw7aashj>RtdbRuleCoverage</a> </li><li data-api-symbol="rtdbrulescheckresult" data-astro-cid-mw7aashj> <a href="#rtdbrulescheckresult" data-astro-cid-mw7aashj>RtdbRulesCheckResult</a> </li><li data-api-symbol="rtdbrulesconstructor()" data-astro-cid-mw7aashj> <a href="#rtdbrulesconstructor" data-astro-cid-mw7aashj>RtdbRulesConstructor()</a> </li><li data-api-symbol="rtdbrulesdefinition" data-astro-cid-mw7aashj> <a href="#rtdbrulesdefinition" data-astro-cid-mw7aashj>RtdbRulesDefinition</a> </li><li data-api-symbol="rtdbrulesdocument" data-astro-cid-mw7aashj> <a href="#rtdbrulesdocument" data-astro-cid-mw7aashj>RtdbRulesDocument</a> </li><li data-api-symbol="rtdbruleset" data-astro-cid-mw7aashj> <a href="#rtdbruleset" data-astro-cid-mw7aashj>RtdbRuleset</a> </li><li data-api-symbol="rtdbrulesfinding" data-astro-cid-mw7aashj> <a href="#rtdbrulesfinding" data-astro-cid-mw7aashj>RtdbRulesFinding</a> </li><li data-api-symbol="rtdbsimulationsummary" data-astro-cid-mw7aashj> <a href="#rtdbsimulationsummary" data-astro-cid-mw7aashj>RtdbSimulationSummary</a> </li><li data-api-symbol="ruleevaluation" data-astro-cid-mw7aashj> <a href="#ruleevaluation" data-astro-cid-mw7aashj>RuleEvaluation</a> </li><li data-api-symbol="ruleissue" data-astro-cid-mw7aashj> <a href="#ruleissue" data-astro-cid-mw7aashj>RuleIssue</a> </li><li data-api-symbol="rulesetcontext" data-astro-cid-mw7aashj> <a href="#rulesetcontext" data-astro-cid-mw7aashj>RulesetContext</a> </li><li data-api-symbol="rulesresourcelimit" data-astro-cid-mw7aashj> <a href="#rulesresourcelimit" data-astro-cid-mw7aashj>RulesResourceLimit</a> </li><li data-api-symbol="schemarulesresult" data-astro-cid-mw7aashj> <a href="#schemarulesresult" data-astro-cid-mw7aashj>SchemaRulesResult</a> </li><li data-api-symbol="shapeoptions" data-astro-cid-mw7aashj> <a href="#shapeoptions" data-astro-cid-mw7aashj>ShapeOptions</a> </li><li data-api-symbol="shaperesult" data-astro-cid-mw7aashj> <a href="#shaperesult" data-astro-cid-mw7aashj>ShapeResult</a> </li><li data-api-symbol="simulationsummary" data-astro-cid-mw7aashj> <a href="#simulationsummary" data-astro-cid-mw7aashj>SimulationSummary</a> </li> </ul> </section><section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#type-aliases" data-astro-cid-mw7aashj> Type Aliases </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="expr" data-astro-cid-mw7aashj> <a href="#expr" data-astro-cid-mw7aashj>Expr</a> </li><li data-api-symbol="fieldrule" data-astro-cid-mw7aashj> <a href="#fieldrule" data-astro-cid-mw7aashj>FieldRule</a> </li><li data-api-symbol="firestoremethod" data-astro-cid-mw7aashj> <a href="#firestoremethod" data-astro-cid-mw7aashj>FirestoreMethod</a> </li><li data-api-symbol="listquery" data-astro-cid-mw7aashj> <a href="#listquery" data-astro-cid-mw7aashj>ListQuery</a> </li><li data-api-symbol="listquerywhereconstraint" data-astro-cid-mw7aashj> <a href="#listquerywhereconstraint" data-astro-cid-mw7aashj>ListQueryWhereConstraint</a> </li><li data-api-symbol="rtdbcoveragekind" data-astro-cid-mw7aashj> <a href="#rtdbcoveragekind" data-astro-cid-mw7aashj>RtdbCoverageKind</a> </li><li data-api-symbol="rtdbcoveragestatus" data-astro-cid-mw7aashj> <a href="#rtdbcoveragestatus" data-astro-cid-mw7aashj>RtdbCoverageStatus</a> </li><li data-api-symbol="rtdbinstancesdata" data-astro-cid-mw7aashj> <a href="#rtdbinstancesdata" data-astro-cid-mw7aashj>RtdbInstancesData</a> </li><li data-api-symbol="rtdbruleevaluation" data-astro-cid-mw7aashj> <a href="#rtdbruleevaluation" data-astro-cid-mw7aashj>RtdbRuleEvaluation</a> </li><li data-api-symbol="rtdbrulekind" data-astro-cid-mw7aashj> <a href="#rtdbrulekind" data-astro-cid-mw7aashj>RtdbRuleKind</a> </li><li data-api-symbol="rtdbrulesfindingrule" data-astro-cid-mw7aashj> <a href="#rtdbrulesfindingrule" data-astro-cid-mw7aashj>RtdbRulesFindingRule</a> </li><li data-api-symbol="rtdbrulesjson" data-astro-cid-mw7aashj> <a href="#rtdbrulesjson" data-astro-cid-mw7aashj>RtdbRulesJson</a> </li><li data-api-symbol="rtdbrulessimulationauth" data-astro-cid-mw7aashj> <a href="#rtdbrulessimulationauth" data-astro-cid-mw7aashj>RtdbRulesSimulationAuth</a> </li><li data-api-symbol="rtdbrulessimulationinput" data-astro-cid-mw7aashj> <a href="#rtdbrulessimulationinput" data-astro-cid-mw7aashj>RtdbRulesSimulationInput</a> </li><li data-api-symbol="rtdbstdlib" data-astro-cid-mw7aashj> <a href="#rtdbstdlib" data-astro-cid-mw7aashj>RtdbStdlib</a> </li><li data-api-symbol="ruleissueorigin" data-astro-cid-mw7aashj> <a href="#ruleissueorigin" data-astro-cid-mw7aashj>RuleIssueOrigin</a> </li><li data-api-symbol="ruleissueseverity" data-astro-cid-mw7aashj> <a href="#ruleissueseverity" data-astro-cid-mw7aashj>RuleIssueSeverity</a> </li><li data-api-symbol="segment" data-astro-cid-mw7aashj> <a href="#segment" data-astro-cid-mw7aashj>Segment</a> </li> </ul> </section><section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#variables" data-astro-cid-mw7aashj> Variables </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="allow()" data-astro-cid-mw7aashj> <a href="#allow" data-astro-cid-mw7aashj>allow()</a> </li><li data-api-symbol="always()" data-astro-cid-mw7aashj> <a href="#always" data-astro-cid-mw7aashj>always()</a> </li><li data-api-symbol="auth_uid" data-astro-cid-mw7aashj> <a href="#auth_uid" data-astro-cid-mw7aashj>AUTH_UID</a> </li><li data-api-symbol="authenticated()" data-astro-cid-mw7aashj> <a href="#authenticated" data-astro-cid-mw7aashj>authenticated()</a> </li><li data-api-symbol="dataexists()" data-astro-cid-mw7aashj> <a href="#dataexists" data-astro-cid-mw7aashj>dataExists()</a> </li><li data-api-symbol="dataparentval()" data-astro-cid-mw7aashj> <a href="#dataparentval" data-astro-cid-mw7aashj>dataParentVal()</a> </li><li data-api-symbol="dataval()" data-astro-cid-mw7aashj> <a href="#dataval" data-astro-cid-mw7aashj>dataVal()</a> </li><li data-api-symbol="deny()" data-astro-cid-mw7aashj> <a href="#deny" data-astro-cid-mw7aashj>deny()</a> </li><li data-api-symbol="eq()" data-astro-cid-mw7aashj> <a href="#eq" data-astro-cid-mw7aashj>eq()</a> </li><li data-api-symbol="expr()" data-astro-cid-mw7aashj> <a href="#expr-1" data-astro-cid-mw7aashj>expr()</a> </li><li data-api-symbol="fieldenum()" data-astro-cid-mw7aashj> <a href="#fieldenum" data-astro-cid-mw7aashj>fieldEnum()</a> </li><li data-api-symbol="fieldisboolean()" data-astro-cid-mw7aashj> <a href="#fieldisboolean" data-astro-cid-mw7aashj>fieldIsBoolean()</a> </li><li data-api-symbol="fieldisnumber()" data-astro-cid-mw7aashj> <a href="#fieldisnumber" data-astro-cid-mw7aashj>fieldIsNumber()</a> </li><li data-api-symbol="fieldisstring()" data-astro-cid-mw7aashj> <a href="#fieldisstring" data-astro-cid-mw7aashj>fieldIsString()</a> </li><li data-api-symbol="fieldowneronly()" data-astro-cid-mw7aashj> <a href="#fieldowneronly" data-astro-cid-mw7aashj>fieldOwnerOnly()</a> </li><li data-api-symbol="gt()" data-astro-cid-mw7aashj> <a href="#gt" data-astro-cid-mw7aashj>gt()</a> </li><li data-api-symbol="haschild()" data-astro-cid-mw7aashj> <a href="#haschild" data-astro-cid-mw7aashj>hasChild()</a> </li><li data-api-symbol="haschildren()" data-astro-cid-mw7aashj> <a href="#haschildren" data-astro-cid-mw7aashj>hasChildren()</a> </li><li data-api-symbol="hasrole()" data-astro-cid-mw7aashj> <a href="#hasrole" data-astro-cid-mw7aashj>hasRole()</a> </li><li data-api-symbol="immutable()" data-astro-cid-mw7aashj> <a href="#immutable" data-astro-cid-mw7aashj>immutable()</a> </li><li data-api-symbol="immutableself()" data-astro-cid-mw7aashj> <a href="#immutableself" data-astro-cid-mw7aashj>immutableSelf()</a> </li><li data-api-symbol="ismember()" data-astro-cid-mw7aashj> <a href="#ismember" data-astro-cid-mw7aashj>isMember()</a> </li><li data-api-symbol="isnew()" data-astro-cid-mw7aashj> <a href="#isnew" data-astro-cid-mw7aashj>isNew()</a> </li><li data-api-symbol="lte()" data-astro-cid-mw7aashj> <a href="#lte" data-astro-cid-mw7aashj>lte()</a> </li><li data-api-symbol="neq()" data-astro-cid-mw7aashj> <a href="#neq" data-astro-cid-mw7aashj>neq()</a> </li><li data-api-symbol="newdataexists()" data-astro-cid-mw7aashj> <a href="#newdataexists" data-astro-cid-mw7aashj>newDataExists()</a> </li><li data-api-symbol="newdatais()" data-astro-cid-mw7aashj> <a href="#newdatais" data-astro-cid-mw7aashj>newDataIs()</a> </li><li data-api-symbol="newdataparentexists()" data-astro-cid-mw7aashj> <a href="#newdataparentexists" data-astro-cid-mw7aashj>newDataParentExists()</a> </li><li data-api-symbol="newdataparentval()" data-astro-cid-mw7aashj> <a href="#newdataparentval" data-astro-cid-mw7aashj>newDataParentVal()</a> </li><li data-api-symbol="newdataval()" data-astro-cid-mw7aashj> <a href="#newdataval" data-astro-cid-mw7aashj>newDataVal()</a> </li><li data-api-symbol="ownerornew()" data-astro-cid-mw7aashj> <a href="#ownerornew" data-astro-cid-mw7aashj>ownerOrNew()</a> </li><li data-api-symbol="ownfield()" data-astro-cid-mw7aashj> <a href="#ownfield" data-astro-cid-mw7aashj>ownField()</a> </li><li data-api-symbol="ownpath()" data-astro-cid-mw7aashj> <a href="#ownpath" data-astro-cid-mw7aashj>ownPath()</a> </li><li data-api-symbol="pathowneronly()" data-astro-cid-mw7aashj> <a href="#pathowneronly" data-astro-cid-mw7aashj>pathOwnerOnly()</a> </li><li data-api-symbol="ref()" data-astro-cid-mw7aashj> <a href="#ref" data-astro-cid-mw7aashj>ref()</a> </li><li data-api-symbol="required()" data-astro-cid-mw7aashj> <a href="#required" data-astro-cid-mw7aashj>required()</a> </li><li data-api-symbol="rootequals()" data-astro-cid-mw7aashj> <a href="#rootequals" data-astro-cid-mw7aashj>rootEquals()</a> </li><li data-api-symbol="rootexists()" data-astro-cid-mw7aashj> <a href="#rootexists" data-astro-cid-mw7aashj>rootExists()</a> </li><li data-api-symbol="rtdbrules" data-astro-cid-mw7aashj> <a href="#rtdbrules" data-astro-cid-mw7aashj>rtdbRules</a> </li><li data-api-symbol="rtdbstdlib" data-astro-cid-mw7aashj> <a href="#rtdbstdlib-1" data-astro-cid-mw7aashj>rtdbStdlib</a> </li><li data-api-symbol="transition()" data-astro-cid-mw7aashj> <a href="#transition" data-astro-cid-mw7aashj>transition()</a> </li> </ul> </section><section class="api-symbol-group" data-api-symbol-group data-astro-cid-mw7aashj> <a class="api-symbol-kind" href="#functions" data-astro-cid-mw7aashj> Functions </a> <ul data-astro-cid-mw7aashj> <li data-api-symbol="all()" data-astro-cid-mw7aashj> <a href="#all" data-astro-cid-mw7aashj>all()</a> </li><li data-api-symbol="any()" data-astro-cid-mw7aashj> <a href="#any" data-astro-cid-mw7aashj>any()</a> </li><li data-api-symbol="assertcase()" data-astro-cid-mw7aashj> <a href="#assertcase" data-astro-cid-mw7aashj>assertCase()</a> </li><li data-api-symbol="bytes()" data-astro-cid-mw7aashj> <a href="#bytes" data-astro-cid-mw7aashj>bytes()</a> </li><li data-api-symbol="canonicalrtdbexpression()" data-astro-cid-mw7aashj> <a href="#canonicalrtdbexpression" data-astro-cid-mw7aashj>canonicalRtdbExpression()</a> </li><li data-api-symbol="definertdbrules()" data-astro-cid-mw7aashj> <a href="#definertdbrules" data-astro-cid-mw7aashj>defineRtdbRules()</a> </li><li data-api-symbol="diffrtdbrules()" data-astro-cid-mw7aashj> <a href="#diffrtdbrules" data-astro-cid-mw7aashj>diffRtdbRules()</a> </li><li data-api-symbol="duration()" data-astro-cid-mw7aashj> <a href="#duration" data-astro-cid-mw7aashj>duration()</a> </li><li data-api-symbol="explaincase()" data-astro-cid-mw7aashj> <a href="#explaincase" data-astro-cid-mw7aashj>explainCase()</a> </li><li data-api-symbol="firestorerules()" data-astro-cid-mw7aashj> <a href="#firestorerules" data-astro-cid-mw7aashj>firestoreRules()</a> </li><li data-api-symbol="flip()" data-astro-cid-mw7aashj> <a href="#flip" data-astro-cid-mw7aashj>flip()</a> </li><li data-api-symbol="latlng()" data-astro-cid-mw7aashj> <a href="#latlng" data-astro-cid-mw7aashj>latlng()</a> </li><li data-api-symbol="lint()" data-astro-cid-mw7aashj> <a href="#lint-2" data-astro-cid-mw7aashj>lint()</a> </li><li data-api-symbol="lit()" data-astro-cid-mw7aashj> <a href="#lit" data-astro-cid-mw7aashj>lit()</a> </li><li data-api-symbol="not()" data-astro-cid-mw7aashj> <a href="#not" data-astro-cid-mw7aashj>not()</a> </li><li data-api-symbol="reference()" data-astro-cid-mw7aashj> <a href="#reference" data-astro-cid-mw7aashj>reference()</a> </li><li data-api-symbol="renderrtdbcoverage()" data-astro-cid-mw7aashj> <a href="#renderrtdbcoverage" data-astro-cid-mw7aashj>renderRtdbCoverage()</a> </li><li data-api-symbol="ruleset()" data-astro-cid-mw7aashj> <a href="#ruleset" data-astro-cid-mw7aashj>ruleset()</a> </li><li data-api-symbol="schemarules()" data-astro-cid-mw7aashj> <a href="#schemarules" data-astro-cid-mw7aashj>schemaRules()</a> </li><li data-api-symbol="servertimestamp()" data-astro-cid-mw7aashj> <a href="#servertimestamp" data-astro-cid-mw7aashj>serverTimestamp()</a> </li><li data-api-symbol="timestamp()" data-astro-cid-mw7aashj> <a href="#timestamp" data-astro-cid-mw7aashj>timestamp()</a> </li><li data-api-symbol="turnguard()" data-astro-cid-mw7aashj> <a href="#turnguard" data-astro-cid-mw7aashj>turnGuard()</a> </li><li data-api-symbol="vector()" data-astro-cid-mw7aashj> <a href="#vector" data-astro-cid-mw7aashj>vector()</a> </li><li data-api-symbol="wincheckhelper()" data-astro-cid-mw7aashj> <a href="#wincheckhelper" data-astro-cid-mw7aashj>winCheckHelper()</a> </li> </ul> </section> <p class="api-symbol-empty" data-api-symbol-empty hidden data-astro-cid-mw7aashj>No matching symbols</p> </div> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body></html>