@pyric/cli 0.1.0-alpha.13 → 0.1.0-alpha.15
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.
- package/dist/assurance/.generated/conformance-verdicts.d.ts +120 -75
- package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
- package/dist/assurance/.generated/conformance-verdicts.js +120 -75
- package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
- package/dist/cli/serve.d.ts +1 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +208 -285
- package/dist/cli/serve.js.map +1 -1
- package/dist/cli/service-command-records/database-rules-generate.d.ts +4 -0
- package/dist/cli/service-command-records/database-rules-generate.d.ts.map +1 -0
- package/dist/cli/service-command-records/database-rules-generate.js +3 -0
- package/dist/cli/service-command-records/database-rules-generate.js.map +1 -0
- package/dist/cli/service-command-records/database-rules-lint.d.ts +4 -0
- package/dist/cli/service-command-records/database-rules-lint.d.ts.map +1 -0
- package/dist/cli/service-command-records/database-rules-lint.js +3 -0
- package/dist/cli/service-command-records/database-rules-lint.js.map +1 -0
- package/dist/cli/service-command-records/database-rules-simulate.d.ts +4 -0
- package/dist/cli/service-command-records/database-rules-simulate.d.ts.map +1 -0
- package/dist/cli/service-command-records/database-rules-simulate.js +3 -0
- package/dist/cli/service-command-records/database-rules-simulate.js.map +1 -0
- package/dist/cli/service-command-records/database-rules-validate.d.ts +4 -0
- package/dist/cli/service-command-records/database-rules-validate.d.ts.map +1 -0
- package/dist/cli/service-command-records/database-rules-validate.js +3 -0
- package/dist/cli/service-command-records/database-rules-validate.js.map +1 -0
- package/dist/cli/service-command-records/firestore-indexes-generate.d.ts +4 -0
- package/dist/cli/service-command-records/firestore-indexes-generate.d.ts.map +1 -0
- package/dist/cli/service-command-records/firestore-indexes-generate.js +3 -0
- package/dist/cli/service-command-records/firestore-indexes-generate.js.map +1 -0
- package/dist/cli/service-command-records/firestore-rules-lint.d.ts +4 -0
- package/dist/cli/service-command-records/firestore-rules-lint.d.ts.map +1 -0
- package/dist/cli/service-command-records/firestore-rules-lint.js +3 -0
- package/dist/cli/service-command-records/firestore-rules-lint.js.map +1 -0
- package/dist/cli/service-command-records/firestore-rules-resolve.d.ts +4 -0
- package/dist/cli/service-command-records/firestore-rules-resolve.d.ts.map +1 -0
- package/dist/cli/service-command-records/firestore-rules-resolve.js +3 -0
- package/dist/cli/service-command-records/firestore-rules-resolve.js.map +1 -0
- package/dist/cli/service-command-records/firestore-rules-simulate.d.ts +4 -0
- package/dist/cli/service-command-records/firestore-rules-simulate.d.ts.map +1 -0
- package/dist/cli/service-command-records/firestore-rules-simulate.js +3 -0
- package/dist/cli/service-command-records/firestore-rules-simulate.js.map +1 -0
- package/dist/cli/service-command-records/firestore-rules-validate.d.ts +4 -0
- package/dist/cli/service-command-records/firestore-rules-validate.d.ts.map +1 -0
- package/dist/cli/service-command-records/firestore-rules-validate.js +3 -0
- package/dist/cli/service-command-records/firestore-rules-validate.js.map +1 -0
- package/dist/cli/service-command-records/storage-rules-lint.d.ts +4 -0
- package/dist/cli/service-command-records/storage-rules-lint.d.ts.map +1 -0
- package/dist/cli/service-command-records/storage-rules-lint.js +3 -0
- package/dist/cli/service-command-records/storage-rules-lint.js.map +1 -0
- package/dist/cli/service-command-records/storage-rules-simulate.d.ts +4 -0
- package/dist/cli/service-command-records/storage-rules-simulate.d.ts.map +1 -0
- package/dist/cli/service-command-records/storage-rules-simulate.js +3 -0
- package/dist/cli/service-command-records/storage-rules-simulate.js.map +1 -0
- package/dist/cli/service-commands.d.ts +7 -0
- package/dist/cli/service-commands.d.ts.map +1 -1
- package/dist/cli/service-commands.generated.d.ts +35 -0
- package/dist/cli/service-commands.generated.d.ts.map +1 -0
- package/dist/cli/service-commands.generated.js +25 -0
- package/dist/cli/service-commands.generated.js.map +1 -0
- package/dist/cli/service-commands.js +23 -40
- package/dist/cli/service-commands.js.map +1 -1
- package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use-browser.js +1 -1
- package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
- package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use.js +1 -1
- package/dist/conformance/.generated/can-i-use.js.map +1 -1
- package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
- package/dist/conformance/.generated/conformance-docs.js +1 -1
- package/dist/conformance/.generated/conformance-docs.js.map +1 -1
- package/dist/functions-rtdb/development-runtime.d.ts +63 -0
- package/dist/functions-rtdb/development-runtime.d.ts.map +1 -0
- package/dist/functions-rtdb/development-runtime.js +244 -0
- package/dist/functions-rtdb/development-runtime.js.map +1 -0
- package/dist/serve/bridge-mount.d.ts +32 -2
- package/dist/serve/bridge-mount.d.ts.map +1 -1
- package/dist/serve/bridge-mount.js +232 -18
- package/dist/serve/bridge-mount.js.map +1 -1
- package/dist/serve/bundler.d.ts +4 -18
- package/dist/serve/bundler.d.ts.map +1 -1
- package/dist/serve/bundler.js +15 -37
- package/dist/serve/bundler.js.map +1 -1
- package/dist/serve/entries/app-client.d.ts.map +1 -1
- package/dist/serve/entries/app-client.js +5 -5
- package/dist/serve/entries/app-client.js.map +1 -1
- package/dist/serve/entries/auth-helper-core.d.ts +23 -6
- package/dist/serve/entries/auth-helper-core.d.ts.map +1 -1
- package/dist/serve/entries/auth-helper-core.js +55 -24
- package/dist/serve/entries/auth-helper-core.js.map +1 -1
- package/dist/serve/entries/database.d.ts +28 -0
- package/dist/serve/entries/database.d.ts.map +1 -1
- package/dist/serve/entries/database.js +95 -26
- package/dist/serve/entries/database.js.map +1 -1
- package/dist/serve/entries/init.d.ts.map +1 -1
- package/dist/serve/entries/init.js +21 -12
- package/dist/serve/entries/init.js.map +1 -1
- package/dist/serve/html-injection.d.ts +5 -0
- package/dist/serve/html-injection.d.ts.map +1 -0
- package/dist/serve/html-injection.js +59 -0
- package/dist/serve/html-injection.js.map +1 -0
- package/dist/serve/namespace.d.ts +6 -22
- package/dist/serve/namespace.d.ts.map +1 -1
- package/dist/serve/namespace.js +23 -145
- package/dist/serve/namespace.js.map +1 -1
- package/dist/serve/runtime/worker-generation.d.ts +10 -2
- package/dist/serve/runtime/worker-generation.d.ts.map +1 -1
- package/dist/serve/runtime/worker-generation.js +29 -8
- package/dist/serve/runtime/worker-generation.js.map +1 -1
- package/dist/serve/runtime/worker-replacement.d.ts +1 -2
- package/dist/serve/runtime/worker-replacement.d.ts.map +1 -1
- package/dist/serve/sandbox-session.d.ts +78 -0
- package/dist/serve/sandbox-session.d.ts.map +1 -0
- package/dist/serve/sandbox-session.js +171 -0
- package/dist/serve/sandbox-session.js.map +1 -0
- package/dist/serve/server.d.ts +5 -2
- package/dist/serve/server.d.ts.map +1 -1
- package/dist/serve/server.js +21 -5
- package/dist/serve/server.js.map +1 -1
- package/dist/serve/site-tree.d.ts +8 -0
- package/dist/serve/site-tree.d.ts.map +1 -0
- package/dist/serve/site-tree.js +113 -0
- package/dist/serve/site-tree.js.map +1 -0
- package/dist/serve/site-ui/_astro/RulesCodeEditor.CzwHdCi9.js +23 -0
- package/dist/serve/site-ui/_astro/_example_.jevZ7OdV.css +1 -0
- package/dist/serve/site-ui/_astro/_slug_.BoKXYrnu.css +1 -0
- package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +1 -0
- package/dist/serve/site-ui/_astro/app.BnMC0ywl.js +109 -0
- package/dist/serve/site-ui/_astro/app.BsFsMjn0.css +1 -0
- package/dist/serve/site-ui/_astro/app.DVXXR-WI.js +1 -0
- package/dist/serve/site-ui/_astro/chess-showcase.DzPO6kz0.js +1 -0
- package/dist/serve/site-ui/_astro/chess-source-explorer.C5k9c5yK.js +1 -0
- package/dist/serve/site-ui/_astro/chess-v2.CFHmd3UL.js +354 -0
- package/dist/serve/site-ui/_astro/client.D2ORs4B-.js +25 -0
- package/dist/serve/site-ui/_astro/example-runtime.CM0H02rx.js +291 -0
- package/dist/serve/site-ui/_astro/index.B4Kh80he.js +1 -0
- package/dist/serve/site-ui/_astro/index.DBy5LfQW.js +9 -0
- package/dist/serve/site-ui/_astro/index.DNyk7q8W.js +9 -0
- package/dist/serve/site-ui/_astro/jsx-runtime.D_zvdyIk.js +9 -0
- package/dist/serve/site-ui/_astro/reads.D1exkX1-.js +1 -0
- package/dist/serve/site-ui/_astro/sandbox-controls.BqMePr5V.js +1153 -0
- package/dist/serve/site-ui/_astro/seed.BCn5DhHS.js +20 -0
- package/dist/serve/site-ui/auth/index.html +11 -0
- package/dist/serve/site-ui/docs/_rhythm/index.html +100 -0
- package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +43 -0
- package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +26 -0
- package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +70 -0
- package/dist/serve/{docs-ui → site-ui}/docs/ai-compat/index.html +3 -3
- package/dist/serve/site-ui/docs/api-reference/index.html +68 -0
- package/dist/serve/{docs-ui → site-ui}/docs/app-compat/index.html +3 -3
- package/dist/serve/{docs-ui → site-ui}/docs/auth-compat/index.html +3 -3
- package/dist/serve/site-ui/docs/build/ai-logic/index.html +64 -0
- package/dist/serve/site-ui/docs/build/authentication/index.html +66 -0
- package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +84 -0
- package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +71 -0
- package/dist/serve/site-ui/docs/build/cloud-storage/index.html +66 -0
- package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-storage.md +2 -2
- package/dist/serve/site-ui/docs/build/realtime-database/index.html +67 -0
- package/dist/serve/site-ui/docs/conformance-scores/index.html +50 -0
- package/dist/serve/{docs-ui → site-ui}/docs/conformance-scores.md +3 -3
- package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +531 -0
- package/dist/serve/{docs-ui → site-ui}/docs/database-compat/index.html +211 -168
- package/dist/serve/{docs-ui → site-ui}/docs/database-compat.md +208 -170
- package/dist/serve/site-ui/docs/examples/chess/index.html +384 -0
- package/dist/serve/site-ui/docs/examples/chess.md +57 -0
- package/dist/serve/site-ui/docs/examples/index.html +3 -0
- package/dist/serve/site-ui/docs/examples.md +4 -0
- package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat/index.html +55 -91
- package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat.md +52 -88
- package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +73 -0
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +29 -0
- package/dist/serve/site-ui/docs/get-started/start-building/index.html +33 -0
- package/dist/serve/{docs-ui → site-ui}/docs/index.json +595 -26
- package/dist/serve/site-ui/docs/messaging-compat/index.html +324 -0
- package/dist/serve/{docs-ui → site-ui}/docs/messaging-compat.md +71 -1
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +28 -0
- package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +74 -0
- package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +45 -0
- package/dist/serve/site-ui/docs/overview/index.html +17 -0
- package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +186 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api/index.html +4 -4
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api/index.html +4 -4
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api/index.html +318 -202
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api.md +154 -27
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api/index.html +5 -5
- package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +318 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api/index.html +5 -5
- package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +160 -0
- package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +425 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api/index.html +5 -5
- package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +60 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api/index.html +4 -4
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api/index.html +4 -4
- package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +507 -0
- package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +258 -0
- package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +51 -0
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +308 -0
- package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +68 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api/index.html +4 -4
- package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +11 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api/index.html +4 -4
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api/index.html +1186 -1384
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api.md +817 -1291
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api/index.html +4 -4
- package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +126 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-vite-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +2641 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-database-reference-api.md +1055 -158
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api/index.html +311 -249
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api.md +72 -54
- package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +509 -0
- package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +182 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api/index.html +7 -26
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api.md +13 -23
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +121 -0
- package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +203 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api/index.html +26 -5
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api.md +22 -22
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api/index.html +5 -15
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api.md +0 -13
- package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +639 -0
- package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +100 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api/index.html +4 -4
- package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +24 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api/index.html +4 -4
- package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +136 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api/index.html +7 -7
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api.md +4 -4
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api/index.html +4 -4
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api/index.html +4 -4
- package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +16 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api/index.html +4 -4
- package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +176 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api/index.html +10 -11
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api.md +7 -8
- package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +188 -0
- package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api/index.html +4 -4
- package/dist/serve/{docs-ui → site-ui}/docs/rules-compat/index.html +87 -57
- package/dist/serve/{docs-ui → site-ui}/docs/rules-compat.md +84 -54
- package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +51 -0
- package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +106 -0
- package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +41 -0
- package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +67 -0
- package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +159 -0
- package/dist/serve/{docs-ui → site-ui}/docs/secure/rules-standard-library.md +2 -2
- package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +47 -0
- package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +95 -0
- package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +82 -0
- package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +37 -0
- package/dist/serve/site-ui/docs/ship/test-in-node/index.html +75 -0
- package/dist/serve/{docs-ui → site-ui}/docs/storage-compat/index.html +8 -8
- package/dist/serve/{docs-ui → site-ui}/docs/storage-compat.md +5 -5
- package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +132 -0
- package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +861 -0
- package/dist/serve/site-ui/docs/trust/rules-standard-library.md +344 -0
- package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +582 -0
- package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research.md +448 -0
- package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +14 -0
- package/dist/serve/{docs-ui → site-ui}/docs/tutorial/index.html +4 -4
- package/dist/serve/{docs-ui → site-ui}/docs/tutorial.md +1 -1
- package/dist/serve/site-ui/examples/chess/index.html +2 -0
- package/dist/serve/site-ui/examples/firestore-first-write/index.html +2 -0
- package/dist/serve/site-ui/firestore/index.html +11 -0
- package/dist/serve/site-ui/index.html +11 -0
- package/dist/serve/{docs-ui → site-ui}/llms.txt +6 -2
- package/dist/serve/site-ui/rtdb/index.html +11 -0
- package/dist/serve/site-ui/settings/index.html +11 -0
- package/dist/serve/site-ui/storage/index.html +11 -0
- package/dist/serve/site-ui/studio-routes.json +1 -0
- package/dist/serve/site-ui/traffic/index.html +11 -0
- package/dist/serve/standalone-assets.d.ts +4 -10
- package/dist/serve/standalone-assets.d.ts.map +1 -1
- package/dist/serve/standalone-assets.js +8 -21
- package/dist/serve/standalone-assets.js.map +1 -1
- package/dist/serve/vite-ai-config.d.ts +2 -0
- package/dist/serve/vite-ai-config.d.ts.map +1 -1
- package/dist/serve/vite-ai-config.js +4 -0
- package/dist/serve/vite-ai-config.js.map +1 -1
- package/dist/serve/vite-functions-development.d.ts +29 -0
- package/dist/serve/vite-functions-development.d.ts.map +1 -0
- package/dist/serve/vite-functions-development.js +150 -0
- package/dist/serve/vite-functions-development.js.map +1 -0
- package/dist/serve/vite-generation-bridge.d.ts +17 -0
- package/dist/serve/vite-generation-bridge.d.ts.map +1 -0
- package/dist/serve/vite-generation-bridge.js +47 -0
- package/dist/serve/vite-generation-bridge.js.map +1 -0
- package/dist/serve/vite-generation-functions.d.ts +35 -0
- package/dist/serve/vite-generation-functions.d.ts.map +1 -0
- package/dist/serve/vite-generation-functions.js +46 -0
- package/dist/serve/vite-generation-functions.js.map +1 -0
- package/dist/serve/vite-generation-middleware.d.ts +10 -0
- package/dist/serve/vite-generation-middleware.d.ts.map +1 -0
- package/dist/serve/vite-generation-middleware.js +40 -0
- package/dist/serve/vite-generation-middleware.js.map +1 -0
- package/dist/serve/vite-generation-rules-watch.d.ts +8 -0
- package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -0
- package/dist/serve/vite-generation-rules-watch.js +33 -0
- package/dist/serve/vite-generation-rules-watch.js.map +1 -0
- package/dist/serve/vite-module-swap.d.ts +16 -0
- package/dist/serve/vite-module-swap.d.ts.map +1 -0
- package/dist/serve/vite-module-swap.js +96 -0
- package/dist/serve/vite-module-swap.js.map +1 -0
- package/dist/serve/vite-page-runtime.d.ts +29 -0
- package/dist/serve/vite-page-runtime.d.ts.map +1 -0
- package/dist/serve/vite-page-runtime.js +71 -0
- package/dist/serve/vite-page-runtime.js.map +1 -0
- package/dist/serve/vite-plugin.d.ts +44 -4
- package/dist/serve/vite-plugin.d.ts.map +1 -1
- package/dist/serve/vite-plugin.js +62 -864
- package/dist/serve/vite-plugin.js.map +1 -1
- package/dist/serve/vite-sandbox-generation.d.ts +57 -0
- package/dist/serve/vite-sandbox-generation.d.ts.map +1 -0
- package/dist/serve/vite-sandbox-generation.js +178 -0
- package/dist/serve/vite-sandbox-generation.js.map +1 -0
- package/dist/serve/vite-worker-runtime.d.ts +1 -1
- package/dist/serve/vite-worker-runtime.d.ts.map +1 -1
- package/dist/serve/vite-worker-runtime.js +8 -4
- package/dist/serve/vite-worker-runtime.js.map +1 -1
- package/dist/serve/worker/client/disconnect.d.ts.map +1 -1
- package/dist/serve/worker/client/disconnect.js +2 -0
- package/dist/serve/worker/client/disconnect.js.map +1 -1
- package/dist/serve/worker/client/handles.d.ts +5 -0
- package/dist/serve/worker/client/handles.d.ts.map +1 -1
- package/dist/serve/worker/client/handles.js.map +1 -1
- package/dist/serve/worker/client/pagehide.d.ts +13 -0
- package/dist/serve/worker/client/pagehide.d.ts.map +1 -0
- package/dist/serve/worker/client/pagehide.js +19 -0
- package/dist/serve/worker/client/pagehide.js.map +1 -0
- package/dist/serve/worker/client/rtdb-admin.d.ts +8 -0
- package/dist/serve/worker/client/rtdb-admin.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-admin.js +39 -0
- package/dist/serve/worker/client/rtdb-admin.js.map +1 -0
- package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts +15 -0
- package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-connection-lifecycle.js +45 -0
- package/dist/serve/worker/client/rtdb-connection-lifecycle.js.map +1 -0
- package/dist/serve/worker/client/rtdb-controls.d.ts +6 -0
- package/dist/serve/worker/client/rtdb-controls.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-controls.js +8 -0
- package/dist/serve/worker/client/rtdb-controls.js.map +1 -0
- package/dist/serve/worker/client/rtdb-listeners.d.ts +24 -0
- package/dist/serve/worker/client/rtdb-listeners.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-listeners.js +262 -0
- package/dist/serve/worker/client/rtdb-listeners.js.map +1 -0
- package/dist/serve/worker/client/rtdb-reads.d.ts +4 -0
- package/dist/serve/worker/client/rtdb-reads.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-reads.js +11 -0
- package/dist/serve/worker/client/rtdb-reads.js.map +1 -0
- package/dist/serve/worker/client/rtdb-references.d.ts +19 -0
- package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-references.js +63 -0
- package/dist/serve/worker/client/rtdb-references.js.map +1 -0
- package/dist/serve/worker/client/rtdb-snapshots.d.ts +20 -0
- package/dist/serve/worker/client/rtdb-snapshots.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-snapshots.js +64 -0
- package/dist/serve/worker/client/rtdb-snapshots.js.map +1 -0
- package/dist/serve/worker/client/rtdb-transactions.d.ts +14 -0
- package/dist/serve/worker/client/rtdb-transactions.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-transactions.js +34 -0
- package/dist/serve/worker/client/rtdb-transactions.js.map +1 -0
- package/dist/serve/worker/client/rtdb-writes.d.ts +8 -0
- package/dist/serve/worker/client/rtdb-writes.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-writes.js +65 -0
- package/dist/serve/worker/client/rtdb-writes.js.map +1 -0
- package/dist/serve/worker/client.d.ts +0 -2
- package/dist/serve/worker/client.d.ts.map +1 -1
- package/dist/serve/worker/client.js +0 -2
- package/dist/serve/worker/client.js.map +1 -1
- package/dist/serve/worker/entry.js +2 -2
- package/dist/serve/worker/entry.js.map +1 -1
- package/dist/serve/worker/host/dispatch.d.ts +2 -0
- package/dist/serve/worker/host/dispatch.d.ts.map +1 -1
- package/dist/serve/worker/host/dispatch.js +24 -2
- package/dist/serve/worker/host/dispatch.js.map +1 -1
- package/dist/serve/worker/host/rtdb.d.ts +6 -2
- package/dist/serve/worker/host/rtdb.d.ts.map +1 -1
- package/dist/serve/worker/host/rtdb.js +224 -2
- package/dist/serve/worker/host/rtdb.js.map +1 -1
- package/dist/serve/worker/host/studio.d.ts.map +1 -1
- package/dist/serve/worker/host/studio.js +2 -0
- package/dist/serve/worker/host/studio.js.map +1 -1
- package/dist/serve/worker/host/subscriptions.d.ts.map +1 -1
- package/dist/serve/worker/host/subscriptions.js +3 -3
- package/dist/serve/worker/host/subscriptions.js.map +1 -1
- package/dist/serve/worker/host.d.ts +1 -1
- package/dist/serve/worker/host.d.ts.map +1 -1
- package/dist/serve/worker/host.js +1 -1
- package/dist/serve/worker/host.js.map +1 -1
- package/dist/serve/worker/index.d.ts +16 -1
- package/dist/serve/worker/index.d.ts.map +1 -1
- package/dist/serve/worker/index.js +17 -4
- package/dist/serve/worker/index.js.map +1 -1
- package/dist/serve/worker/protocol.d.ts +57 -0
- package/dist/serve/worker/protocol.d.ts.map +1 -1
- package/dist/serve/worker/protocol.js.map +1 -1
- package/dist/serve/worker/rtdb-value-equality.d.ts +3 -0
- package/dist/serve/worker/rtdb-value-equality.d.ts.map +1 -0
- package/dist/serve/worker/rtdb-value-equality.js +18 -0
- package/dist/serve/worker/rtdb-value-equality.js.map +1 -0
- package/dist/serve/worker/serve-init.js +2 -2
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/dist/serve/worker/service-worker-relay.js +2 -2
- package/dist/serve/worker/service-worker-relay.js.map +1 -1
- package/package.json +7 -5
- package/src/assurance/.generated/conformance-verdicts.ts +120 -75
- package/src/cli/serve.ts +216 -308
- package/src/cli/service-command-records/database-rules-generate.ts +3 -0
- package/src/cli/service-command-records/database-rules-lint.ts +3 -0
- package/src/cli/service-command-records/database-rules-simulate.ts +3 -0
- package/src/cli/service-command-records/database-rules-validate.ts +3 -0
- package/src/cli/service-command-records/firestore-indexes-generate.ts +3 -0
- package/src/cli/service-command-records/firestore-rules-lint.ts +3 -0
- package/src/cli/service-command-records/firestore-rules-resolve.ts +3 -0
- package/src/cli/service-command-records/firestore-rules-simulate.ts +3 -0
- package/src/cli/service-command-records/firestore-rules-validate.ts +3 -0
- package/src/cli/service-command-records/storage-rules-lint.ts +3 -0
- package/src/cli/service-command-records/storage-rules-simulate.ts +3 -0
- package/src/cli/service-commands.generated.ts +27 -0
- package/src/cli/service-commands.test.ts +43 -0
- package/src/cli/service-commands.ts +36 -51
- package/src/conformance/.generated/can-i-use-browser.ts +1 -1
- package/src/conformance/.generated/can-i-use.ts +1 -1
- package/src/conformance/.generated/conformance-docs.ts +1 -1
- package/src/functions-rtdb/development-runtime.ts +299 -0
- package/src/serve/bridge-mount.ts +253 -19
- package/src/serve/bundler.ts +17 -36
- package/src/serve/entries/app-client.ts +5 -4
- package/src/serve/entries/auth-helper-core.ts +83 -30
- package/src/serve/entries/database.ts +180 -57
- package/src/serve/entries/init.ts +30 -20
- package/src/serve/html-injection.ts +65 -0
- package/src/serve/namespace.ts +26 -169
- package/src/serve/runtime/worker-generation.ts +29 -7
- package/src/serve/runtime/worker-replacement.ts +1 -1
- package/src/serve/sandbox-session.ts +233 -0
- package/src/serve/server.ts +20 -5
- package/src/serve/site-tree.ts +146 -0
- package/src/serve/standalone-assets.ts +9 -26
- package/src/serve/vite-ai-config.ts +8 -0
- package/src/serve/vite-functions-development.ts +201 -0
- package/src/serve/vite-generation-bridge.ts +66 -0
- package/src/serve/vite-generation-functions.ts +78 -0
- package/src/serve/vite-generation-middleware.ts +56 -0
- package/src/serve/vite-generation-rules-watch.ts +37 -0
- package/src/serve/vite-module-swap.ts +119 -0
- package/src/serve/vite-page-runtime.ts +100 -0
- package/src/serve/vite-plugin.ts +78 -882
- package/src/serve/vite-sandbox-generation.ts +255 -0
- package/src/serve/vite-worker-runtime.ts +12 -5
- package/src/serve/worker/client/disconnect.ts +3 -1
- package/src/serve/worker/client/handles.ts +5 -0
- package/src/serve/worker/client/pagehide.ts +31 -0
- package/src/serve/worker/client/rtdb-admin.ts +74 -0
- package/src/serve/worker/client/rtdb-connection-lifecycle.ts +52 -0
- package/src/serve/worker/client/rtdb-controls.ts +8 -0
- package/src/serve/worker/client/rtdb-listeners.ts +337 -0
- package/src/serve/worker/client/rtdb-reads.ts +12 -0
- package/src/serve/worker/client/rtdb-references.ts +85 -0
- package/src/serve/worker/client/rtdb-snapshots.ts +118 -0
- package/src/serve/worker/client/rtdb-transactions.ts +51 -0
- package/src/serve/worker/client/rtdb-writes.ts +74 -0
- package/src/serve/worker/client.ts +0 -2
- package/src/serve/worker/entry.ts +2 -2
- package/src/serve/worker/host/dispatch.ts +22 -2
- package/src/serve/worker/host/rtdb.ts +243 -2
- package/src/serve/worker/host/studio.ts +2 -0
- package/src/serve/worker/host/subscriptions.ts +8 -4
- package/src/serve/worker/host.ts +1 -1
- package/src/serve/worker/index.ts +58 -10
- package/src/serve/worker/protocol.ts +23 -2
- package/src/serve/worker/rtdb-value-equality.ts +17 -0
- package/src/serve/worker/serve-init.ts +2 -2
- package/src/serve/worker/service-worker-relay.ts +2 -2
- package/dist/serve/docs-ui/_astro/_slug_.DUci-duz.css +0 -1
- package/dist/serve/docs-ui/docs/_rhythm/index.html +0 -100
- package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +0 -43
- package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +0 -26
- package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +0 -70
- package/dist/serve/docs-ui/docs/api-reference/index.html +0 -68
- package/dist/serve/docs-ui/docs/build/ai-logic/index.html +0 -64
- package/dist/serve/docs-ui/docs/build/authentication/index.html +0 -66
- package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +0 -70
- package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +0 -71
- package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +0 -66
- package/dist/serve/docs-ui/docs/build/realtime-database/index.html +0 -67
- package/dist/serve/docs-ui/docs/conformance-scores/index.html +0 -50
- package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +0 -531
- package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +0 -73
- package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +0 -29
- package/dist/serve/docs-ui/docs/get-started/start-building/index.html +0 -33
- package/dist/serve/docs-ui/docs/messaging-compat/index.html +0 -265
- package/dist/serve/docs-ui/docs/observe/resolve-runtime-status/index.html +0 -28
- package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +0 -74
- package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +0 -45
- package/dist/serve/docs-ui/docs/overview/index.html +0 -17
- package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +0 -186
- package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +0 -318
- package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +0 -160
- package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +0 -425
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +0 -60
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +0 -507
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +0 -258
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +0 -51
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +0 -308
- package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +0 -68
- package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +0 -11
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +0 -126
- package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +0 -1852
- package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +0 -509
- package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +0 -182
- package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +0 -121
- package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +0 -203
- package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +0 -639
- package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +0 -100
- package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +0 -24
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +0 -136
- package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +0 -16
- package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +0 -176
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +0 -188
- package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +0 -51
- package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +0 -106
- package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +0 -41
- package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +0 -67
- package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +0 -159
- package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +0 -47
- package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +0 -95
- package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +0 -82
- package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +0 -37
- package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +0 -75
- package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +0 -132
- package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +0 -14
- package/dist/serve/docs-ui/index.html +0 -1
- package/dist/serve/studio-ui/assets/RulesCodeEditor-BDlH-5lp.js +0 -23
- package/dist/serve/studio-ui/assets/index-Bf9SSE8L.js +0 -1218
- package/dist/serve/studio-ui/assets/index-BlSGru_r.css +0 -1
- package/dist/serve/studio-ui/assets/seed-D_UjxfOU.js +0 -20
- package/dist/serve/studio-ui/index.html +0 -32
- package/dist/serve/worker/client/rtdb.d.ts +0 -36
- package/dist/serve/worker/client/rtdb.d.ts.map +0 -1
- package/dist/serve/worker/client/rtdb.js +0 -241
- package/dist/serve/worker/client/rtdb.js.map +0 -1
- package/src/serve/worker/client/rtdb.ts +0 -311
- /package/dist/serve/{docs-ui → site-ui}/404.html +0 -0
- /package/dist/serve/{docs-ui → site-ui}/_astro/_slug_.CXh9yTP1.css +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/_rhythm.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/agent/set-up-your-agent.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/agent/watch-and-review.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/agent/work-with-an-agent.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/ai-compat.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/api-reference.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/app-compat.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/auth-compat.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/build/ai-logic.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/build/authentication.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-firestore.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-messaging.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/build/realtime-database.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/create-pyric-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/functions-rtdb-compat.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/get-started/how-the-swap-works.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/get-started/start-building.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/index.html +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/observe/resolve-runtime-status.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/observe/see-whats-happening.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/observe/shape-your-data.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/overview.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-app-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-storage-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-scripting-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-app-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-browser-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-browser-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-docs-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-credentials-node-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-register-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-sw-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-database-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-firestore-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-agents-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-hooks-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-hooks-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-hooks-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-hooks-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-hooks-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-hooks-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/secure/audit-your-rules.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/secure/firestore-rules-limits.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/secure/read-a-denial.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/secure/rtdb-rules-in-typescript.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/secure/secure-it-with-rules.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/secure/simulate-and-lint.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/secure/write-a-rules-test-suite.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/ship/ship-to-production.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/ship/test-in-node.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/trust/how-we-know-it-matches-firebase.md +0 -0
- /package/dist/serve/{docs-ui → site-ui}/docs/trust/versioning-and-compatibility.md +0 -0
- /package/dist/serve/{studio-ui → site-ui}/pyric-logo.svg +0 -0
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Write Realtime Database rules in TypeScript · Pyric Studio</title><meta name="description" content="Compose RTDB rules from typed constraints, prove them in-process, and deploy the compiled JSON."><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CXh9yTP1.css">
|
|
2
|
-
<link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.DUci-duz.css"></head> <body> <header class="studio__bar"> <div class="studio__bar-inner"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio">Pyric</a> <nav class="studio__nav" aria-label="Studio tabs"> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore"> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth"> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb"> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage"> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic"> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings"> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a> </nav> </div> </header> <div class="docs-shell"> <details class="docs-nav-drawer"> <summary>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> </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/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/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" open> <summary>Secure & 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/" aria-current="page"> RTDB rules in TypeScript </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> </details><details class="docs-nav-group"> <summary>Observe & 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 & 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/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship & 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><a class="docs-nav-toplink" href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Trust </a><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/"> Public API coverage </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> </ul> </div> </div> </details> <details class="docs-nav-group"> <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-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/"> 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-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </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-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> </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-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-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> </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-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> </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> </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/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/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" open> <summary>Secure & 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/" aria-current="page"> RTDB rules in TypeScript </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> </details><details class="docs-nav-group" id="nav-group-observe-shape"> <summary>Observe & 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 & 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/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship & 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><a class="docs-nav-toplink" href="/__pyric/ui/docs/trust/versioning-and-compatibility/" id="nav-group-trust"> Trust </a><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/"> Public API coverage </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> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <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-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/"> 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-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </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-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> </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-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-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> </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-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> </details> </nav> <main class="doc-main"> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/">Secure & debug</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">RTDB rules in TypeScript</span> </li> </ol> </nav> <article class="prose"> <h1 id="write-realtime-database-rules-in-typescript">Write Realtime Database rules in TypeScript</h1>
|
|
3
|
-
<p>Realtime Database support is still incomplete. Check the generated conformance reference for the exact supported surface before depending on it.</p>
|
|
4
|
-
<p>Realtime Database rules are strings inside a JSON tree. Pyric lets you write them as TypeScript instead: typed builders compose into expressions, the expressions assemble into a ruleset, and the ruleset checks itself, simulates requests, and compiles to the exact JSON Firebase deploys. A typo becomes a compile error instead of a production surprise.</p>
|
|
5
|
-
<h2 id="define-the-rules-in-code">Define the rules in code</h2>
|
|
6
|
-
<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">import</span><span style="color:#ABB2BF"> {</span></span>
|
|
7
|
-
<span class="line"><span style="color:#E06C75"> defineRtdbRules</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">all</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">authenticated</span><span style="color:#ABB2BF">,</span></span>
|
|
8
|
-
<span class="line"><span style="color:#E06C75"> fieldOwnerOnly</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">ownerOrNew</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">immutable</span><span style="color:#ABB2BF">,</span></span>
|
|
9
|
-
<span class="line"><span style="color:#ABB2BF">} </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'pyric/rules/rtdb/constraints'</span><span style="color:#ABB2BF">;</span></span>
|
|
10
|
-
<span class="line"></span>
|
|
11
|
-
<span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> rules</span><span style="color:#56B6C2"> =</span><span style="color:#61AFEF"> defineRtdbRules</span><span style="color:#ABB2BF">({</span></span>
|
|
12
|
-
<span class="line"><span style="color:#E06C75"> paths</span><span style="color:#ABB2BF">: {</span></span>
|
|
13
|
-
<span class="line"><span style="color:#98C379"> '/notes/$noteId'</span><span style="color:#ABB2BF">: {</span></span>
|
|
14
|
-
<span class="line"><span style="color:#E06C75"> read</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">authenticated</span><span style="color:#ABB2BF">(),</span></span>
|
|
15
|
-
<span class="line"><span style="color:#E06C75"> write</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">ownerOrNew</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">'ownerId'</span><span style="color:#ABB2BF">),</span></span>
|
|
16
|
-
<span class="line"><span style="color:#E06C75"> validate</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">immutable</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">'createdAt'</span><span style="color:#ABB2BF">),</span></span>
|
|
17
|
-
<span class="line"><span style="color:#ABB2BF"> },</span></span>
|
|
18
|
-
<span class="line"><span style="color:#ABB2BF"> },</span></span>
|
|
19
|
-
<span class="line"><span style="color:#ABB2BF">});</span></span></code></pre>
|
|
20
|
-
<p><code>$noteId</code> is a real wildcard. <code>ownerOrNew('ownerId')</code> compiles to the signed-in-and-owner-or-new expression you would have written by hand, and <code>immutable('createdAt')</code> pins a field after creation. Every builder’s output is pinned by tests, so what you compose is what deploys.</p>
|
|
21
|
-
<h2 id="check-it-before-anything-runs">Check it before anything runs</h2>
|
|
22
|
-
<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:#E5C07B"> result</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> rules</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">check</span><span style="color:#ABB2BF">();</span></span>
|
|
23
|
-
<span class="line"><span style="color:#7F848E;font-style:italic">// { ok: true, errors: [], warnings: [] }</span></span></code></pre>
|
|
24
|
-
<p><code>check()</code> parses, validates, and lints every expression in the tree. A <code>==</code> where you meant <code>===</code> comes back as a <code>LOOSE_EQUALITY</code> warning with its path and rule. An unsupported schema type is a <code>COMPILE_ERROR</code>. No deploy, no network.</p>
|
|
25
|
-
<h2 id="simulate-a-request">Simulate a request</h2>
|
|
26
|
-
<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:#E5C07B"> verdict</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> rules</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">simulate</span><span style="color:#ABB2BF">({</span></span>
|
|
27
|
-
<span class="line"><span style="color:#E06C75"> operation</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'write'</span><span style="color:#ABB2BF">,</span></span>
|
|
28
|
-
<span class="line"><span style="color:#E06C75"> path</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'/notes/n1'</span><span style="color:#ABB2BF">,</span></span>
|
|
29
|
-
<span class="line"><span style="color:#E06C75"> auth</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'alice'</span><span style="color:#ABB2BF">,</span></span>
|
|
30
|
-
<span class="line"><span style="color:#E06C75"> data</span><span style="color:#ABB2BF">: { </span><span style="color:#E06C75">ownerId</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'alice'</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">createdAt</span><span style="color:#ABB2BF">: </span><span style="color:#D19A66">1</span><span style="color:#ABB2BF"> },</span></span>
|
|
31
|
-
<span class="line"><span style="color:#E06C75"> newData</span><span style="color:#ABB2BF">: { </span><span style="color:#E06C75">ownerId</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'alice'</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">createdAt</span><span style="color:#ABB2BF">: </span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">title</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'edited'</span><span style="color:#ABB2BF"> },</span></span>
|
|
32
|
-
<span class="line"><span style="color:#ABB2BF">});</span></span></code></pre>
|
|
33
|
-
<p>The simulator runs in-process against the same grammar the sandbox enforces. <code>auth: 'alice'</code> is shorthand for <code>{ uid: 'alice', token: {} }</code>. Ask the denial question the same way: change <code>auth</code> to <code>'mallory'</code> and read the verdict.</p>
|
|
34
|
-
<h2 id="ship-the-json">Ship the JSON</h2>
|
|
35
|
-
<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">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">writeFileSync</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'node:fs'</span><span style="color:#ABB2BF">;</span></span>
|
|
36
|
-
<span class="line"><span style="color:#61AFEF">writeFileSync</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">'database.rules.json'</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">JSON</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">stringify</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">rules</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">toJSON</span><span style="color:#ABB2BF">(), </span><span style="color:#D19A66">null</span><span style="color:#ABB2BF">, </span><span style="color:#D19A66">2</span><span style="color:#ABB2BF">));</span></span>
|
|
37
|
-
<span class="line"><span style="color:#98C379">``````</span><span style="color:#E06C75">bash</span></span>
|
|
38
|
-
<span class="line"><span style="color:#E06C75">pyric</span><span style="color:#E06C75"> database</span><span style="color:#E06C75"> rules</span><span style="color:#E06C75"> lint</span><span style="color:#E5C07B"> database</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">rules</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">json</span></span>
|
|
39
|
-
<span class="line"><span style="color:#ABB2BF"># </span><span style="color:#E06C75">or</span><span style="color:#ABB2BF">: </span><span style="color:#E06C75">pyric</span><span style="color:#E06C75"> database</span><span style="color:#E06C75"> rules</span><span style="color:#E06C75"> generate</span></span>
|
|
40
|
-
<span class="line"><span style="color:#E06C75">firebase</span><span style="color:#E06C75"> deploy</span><span style="color:#56B6C2"> --</span><span style="color:#E06C75">only</span><span style="color:#E06C75"> database</span></span></code></pre>
|
|
41
|
-
<p><code>toJSON()</code> emits the <code>{ rules: ... }</code> document Firebase expects. Generate or write that file locally (<code>pyric database rules generate</code>), then ship it with <code>firebase-tools</code> (or the Console) using the path your <code>firebase.json</code> points at. The CLI’s <code>database rules lint</code>, <code>database rules validate</code>, and <code>database rules simulate</code> operations run the same checks against the JSON file, so CI can gate on them without TypeScript in the loop.</p>
|
|
42
|
-
<h2 id="turn-enforcement-from-a-deployed-game">Turn enforcement, from a deployed game</h2>
|
|
43
|
-
<p>This turn-enforcement example is built from the same parts:</p>
|
|
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:#C678DD">import</span><span style="color:#ABB2BF"> {</span></span>
|
|
45
|
-
<span class="line"><span style="color:#E06C75"> ruleset</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">deny</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">any</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">isNew</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">authenticated</span><span style="color:#ABB2BF">,</span></span>
|
|
46
|
-
<span class="line"><span style="color:#E06C75"> turnGuard</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">flip</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">winCheckHelper</span><span style="color:#ABB2BF">,</span></span>
|
|
47
|
-
<span class="line"><span style="color:#ABB2BF">} </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'pyric/rules'</span><span style="color:#ABB2BF">;</span></span>
|
|
48
|
-
<span class="line"></span>
|
|
49
|
-
<span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> LINES</span><span style="color:#56B6C2"> =</span><span style="color:#ABB2BF"> [[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">2</span><span style="color:#ABB2BF">],[</span><span style="color:#D19A66">3</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">4</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">5</span><span style="color:#ABB2BF">],[</span><span style="color:#D19A66">6</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">7</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">8</span><span style="color:#ABB2BF">],[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">3</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">6</span><span style="color:#ABB2BF">],[</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">4</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">7</span><span style="color:#ABB2BF">],[</span><span style="color:#D19A66">2</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">5</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">8</span><span style="color:#ABB2BF">],[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">4</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">8</span><span style="color:#ABB2BF">],[</span><span style="color:#D19A66">2</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">4</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">6</span><span style="color:#ABB2BF">]];</span></span>
|
|
50
|
-
<span class="line"></span>
|
|
51
|
-
<span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> game</span><span style="color:#56B6C2"> =</span><span style="color:#61AFEF"> ruleset</span><span style="color:#ABB2BF">({</span></span>
|
|
52
|
-
<span class="line"><span style="color:#98C379"> '/'</span><span style="color:#ABB2BF">: { </span><span style="color:#E06C75">read</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">deny</span><span style="color:#ABB2BF">(), </span><span style="color:#E06C75">write</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">deny</span><span style="color:#ABB2BF">() },</span></span>
|
|
53
|
-
<span class="line"><span style="color:#98C379"> '/games/$gameId'</span><span style="color:#ABB2BF">: {</span></span>
|
|
54
|
-
<span class="line"><span style="color:#E06C75"> read</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">authenticated</span><span style="color:#ABB2BF">(),</span></span>
|
|
55
|
-
<span class="line"><span style="color:#E06C75"> write</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">any</span><span style="color:#ABB2BF">(</span><span style="color:#61AFEF">isNew</span><span style="color:#ABB2BF">(), </span><span style="color:#61AFEF">turnGuard</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">'currentTurn'</span><span style="color:#ABB2BF">, { </span><span style="color:#E06C75">X</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'playerX'</span><span style="color:#ABB2BF">, </span><span style="color:#E06C75">O</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'playerO'</span><span style="color:#ABB2BF"> }, </span><span style="color:#98C379">'status'</span><span style="color:#ABB2BF">, </span><span style="color:#98C379">'playing'</span><span style="color:#ABB2BF">)),</span></span>
|
|
56
|
-
<span class="line"><span style="color:#E06C75"> children</span><span style="color:#ABB2BF">: {</span></span>
|
|
57
|
-
<span class="line"><span style="color:#98C379"> '/currentTurn'</span><span style="color:#ABB2BF">: { </span><span style="color:#E06C75">validate</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">flip</span><span style="color:#ABB2BF">([</span><span style="color:#98C379">'X'</span><span style="color:#ABB2BF">, </span><span style="color:#98C379">'O'</span><span style="color:#ABB2BF">]) },</span></span>
|
|
58
|
-
<span class="line"><span style="color:#98C379"> '/xWins'</span><span style="color:#ABB2BF">: { </span><span style="color:#E06C75">validate</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">winCheckHelper</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">'X'</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">LINES</span><span style="color:#ABB2BF">) },</span></span>
|
|
59
|
-
<span class="line"><span style="color:#98C379"> '/oWins'</span><span style="color:#ABB2BF">: { </span><span style="color:#E06C75">validate</span><span style="color:#ABB2BF">: </span><span style="color:#61AFEF">winCheckHelper</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">'O'</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">LINES</span><span style="color:#ABB2BF">) },</span></span>
|
|
60
|
-
<span class="line"><span style="color:#ABB2BF"> },</span></span>
|
|
61
|
-
<span class="line"><span style="color:#ABB2BF"> },</span></span>
|
|
62
|
-
<span class="line"><span style="color:#ABB2BF">});</span></span></code></pre>
|
|
63
|
-
<p>Three constraints carry the whole game. <code>turnGuard</code> reads stored state, never the incoming write, so a player cannot hand themselves the turn. <code>flip</code> makes turn order a validation rule. And <code>winCheckHelper</code> verifies a win claim against the actual board, so the winner field only accepts the truth.</p>
|
|
64
|
-
<h2 id="and-from-an-agent">And from an agent</h2>
|
|
65
|
-
<p>An agent authors and checks the same way you do: lint and simulate locally (<code>pyric database rules lint</code>, <code>pyric database rules simulate</code>, or <code>rtdb_simulate_access</code> against the connected sandbox), generate JSON with <code>pyric database rules generate</code>, then ship with <code>firebase-tools</code>. See the RTDB task in <a href="../../agent/work-with-an-agent/">Work with an agent</a>.</p>
|
|
66
|
-
<h2 id="where-to-go-next">Where to go next</h2>
|
|
67
|
-
<p>The full builder catalog, with the exact expression each one produces, is in the <a href="../../pyric-database-reference-api/">constraints reference</a>. For the data side of RTDB, see <a href="../../build/realtime-database/">Sync realtime data</a>.</p> </article> </main> <aside class="doc-toc" aria-label="On this page"> <h2 class="doc-toc-heading">On this page</h2> <ul> <li data-depth="2"> <a href="#define-the-rules-in-code">Define the rules in code</a> </li><li data-depth="2"> <a href="#check-it-before-anything-runs">Check it before anything runs</a> </li><li data-depth="2"> <a href="#simulate-a-request">Simulate a request</a> </li><li data-depth="2"> <a href="#ship-the-json">Ship the JSON</a> </li><li data-depth="2"> <a href="#turn-enforcement-from-a-deployed-game">Turn enforcement, from a deployed game</a> </li><li data-depth="2"> <a href="#and-from-an-agent">And from an agent</a> </li><li data-depth="2"> <a href="#where-to-go-next">Where to go next</a> </li> </ul> </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>
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Use tested modules in Firestore Security Rules · Pyric Studio</title><meta name="description" content="Import a tested rule function, resolve it to ordinary Firebase Rules, then lint and simulate the result."><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CXh9yTP1.css">
|
|
2
|
-
<link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.DUci-duz.css"></head> <body> <header class="studio__bar"> <div class="studio__bar-inner"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio">Pyric</a> <nav class="studio__nav" aria-label="Studio tabs"> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore"> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth"> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb"> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage"> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic"> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings"> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a> </nav> </div> </header> <div class="docs-shell"> <details class="docs-nav-drawer"> <summary>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> </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/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/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" open> <summary>Secure & 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/" aria-current="page"> 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/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> </details><details class="docs-nav-group"> <summary>Observe & 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 & 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/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship & 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><a class="docs-nav-toplink" href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Trust </a><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/"> Public API coverage </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> </ul> </div> </div> </details> <details class="docs-nav-group"> <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-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/"> 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-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </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-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> </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-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-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> </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-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> </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> </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/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/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" open> <summary>Secure & 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/" aria-current="page"> 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/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> </details><details class="docs-nav-group" id="nav-group-observe-shape"> <summary>Observe & 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 & 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/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship & 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><a class="docs-nav-toplink" href="/__pyric/ui/docs/trust/versioning-and-compatibility/" id="nav-group-trust"> Trust </a><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/"> Public API coverage </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> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <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-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/"> 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-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </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-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> </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-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-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> </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-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> </details> </nav> <main class="doc-main"> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/">Secure & debug</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">The rules standard library</span> </li> </ol> </nav> <article class="prose"> <h1 id="use-tested-modules-in-firestore-security-rules">Use tested modules in Firestore Security Rules</h1>
|
|
3
|
-
<p>Pyric’s standard library is a set of tested Firestore Rules functions. The <code>2+modules</code> source format adds imports for local development; the resolver replaces those imports with ordinary <code>rules_version = '2'</code> functions before deployment.</p>
|
|
4
|
-
<p>This example lets an author update a post, prevents changes to <code>authorId</code> and <code>createdAt</code>, and requires a two-second cooldown between edits.</p>
|
|
5
|
-
<h2 id="import-the-functions-you-need">Import the functions you need</h2>
|
|
6
|
-
<p>Create <code>firestore.modules.rules</code>:</p>
|
|
7
|
-
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="rules"><code><span class="line"><span style="color:#C678DD">rules_version</span><span style="color:#ABB2BF"> = </span><span style="color:#98C379">'2+modules'</span><span style="color:#ABB2BF">;</span></span>
|
|
8
|
-
<span class="line"></span>
|
|
9
|
-
<span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { isAuthor } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'content'</span><span style="color:#ABB2BF">;</span></span>
|
|
10
|
-
<span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { onlyFieldsChanged, isServerTimestamp } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'lifecycle'</span><span style="color:#ABB2BF">;</span></span>
|
|
11
|
-
<span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { cooldownElapsed } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'timing'</span><span style="color:#ABB2BF">;</span></span>
|
|
12
|
-
<span class="line"></span>
|
|
13
|
-
<span class="line"><span style="color:#C678DD">service</span><span style="color:#ABB2BF"> cloud.firestore {</span></span>
|
|
14
|
-
<span class="line"><span style="color:#C678DD"> match</span><span style="color:#ABB2BF"> /databases/</span><span style="color:#E06C75;font-style:italic">{database}</span><span style="color:#ABB2BF">/documents {</span></span>
|
|
15
|
-
<span class="line"><span style="color:#C678DD"> match</span><span style="color:#ABB2BF"> /posts/</span><span style="color:#E06C75;font-style:italic">{postId}</span><span style="color:#ABB2BF"> {</span></span>
|
|
16
|
-
<span class="line"><span style="color:#C678DD"> allow</span><span style="color:#61AFEF"> update</span><span style="color:#ABB2BF">: </span><span style="color:#C678DD">if</span><span style="color:#ABB2BF"> isAuthor(</span><span style="color:#98C379">'authorId'</span><span style="color:#ABB2BF">)</span></span>
|
|
17
|
-
<span class="line"><span style="color:#ABB2BF"> && onlyFieldsChanged([</span><span style="color:#98C379">'title'</span><span style="color:#ABB2BF">, </span><span style="color:#98C379">'body'</span><span style="color:#ABB2BF">, </span><span style="color:#98C379">'updatedAt'</span><span style="color:#ABB2BF">])</span></span>
|
|
18
|
-
<span class="line"><span style="color:#ABB2BF"> && cooldownElapsed(</span><span style="color:#98C379">'updatedAt'</span><span style="color:#ABB2BF">, </span><span style="color:#D19A66">2</span><span style="color:#ABB2BF">)</span></span>
|
|
19
|
-
<span class="line"><span style="color:#ABB2BF"> && isServerTimestamp(</span><span style="color:#98C379">'updatedAt'</span><span style="color:#ABB2BF">);</span></span>
|
|
20
|
-
<span class="line"><span style="color:#ABB2BF"> }</span></span>
|
|
21
|
-
<span class="line"><span style="color:#ABB2BF"> }</span></span>
|
|
22
|
-
<span class="line"><span style="color:#ABB2BF">}</span></span></code></pre>
|
|
23
|
-
<p>Imports are flat: call <code>isAuthor(...)</code>, not <code>content.isAuthor(...)</code>. Resolution fails if an imported name collides with a function already declared in your file.</p>
|
|
24
|
-
<p><code>cooldownElapsed('updatedAt', 2)</code> compares the stored timestamp with <code>request.time</code>. Pairing it with <code>isServerTimestamp('updatedAt')</code> matters: without that second check, a client could submit an old timestamp and bypass the next cooldown. <code>cooldownElapsed</code> is for updates because it reads <code>resource.data</code>.</p>
|
|
25
|
-
<h2 id="resolve-to-deployable-rules">Resolve to deployable Rules</h2>
|
|
26
|
-
<p>Firebase does not understand <code>2+modules</code>, so compile the imports away:</p>
|
|
27
|
-
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">pyric</span><span style="color:#98C379"> firestore</span><span style="color:#98C379"> rules</span><span style="color:#98C379"> resolve</span><span style="color:#98C379"> firestore.modules.rules</span><span style="color:#D19A66"> --out</span><span style="color:#98C379"> firestore.rules</span></span></code></pre>
|
|
28
|
-
<p>The generated <code>firestore.rules</code> contains <code>rules_version = '2'</code> and the imported function bodies. Point <code>firebase.json</code> at that generated file, and commit both the module source and resolved output if production deploys from the repository.</p>
|
|
29
|
-
<h2 id="lint-and-simulate-the-resolved-result">Lint and simulate the resolved result</h2>
|
|
30
|
-
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">pyric</span><span style="color:#98C379"> firestore</span><span style="color:#98C379"> rules</span><span style="color:#98C379"> lint</span><span style="color:#98C379"> firestore.rules</span></span></code></pre>
|
|
31
|
-
<p>You can then exercise the rule through the public API:</p>
|
|
32
|
-
<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">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">readFileSync</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'node:fs'</span><span style="color:#ABB2BF">;</span></span>
|
|
33
|
-
<span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">firestoreRules</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'pyric/rules'</span><span style="color:#ABB2BF">;</span></span>
|
|
34
|
-
<span class="line"></span>
|
|
35
|
-
<span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> source</span><span style="color:#56B6C2"> =</span><span style="color:#61AFEF"> readFileSync</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">'firestore.rules'</span><span style="color:#ABB2BF">, </span><span style="color:#98C379">'utf8'</span><span style="color:#ABB2BF">);</span></span>
|
|
36
|
-
<span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> result</span><span style="color:#56B6C2"> =</span><span style="color:#61AFEF"> firestoreRules</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">source</span><span style="color:#ABB2BF">).</span><span style="color:#61AFEF">simulate</span><span style="color:#ABB2BF">([</span></span>
|
|
37
|
-
<span class="line"><span style="color:#ABB2BF"> {</span></span>
|
|
38
|
-
<span class="line"><span style="color:#E06C75"> description</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'author changes the title after the cooldown'</span><span style="color:#ABB2BF">,</span></span>
|
|
39
|
-
<span class="line"><span style="color:#E06C75"> expectation</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'ALLOW'</span><span style="color:#ABB2BF">,</span></span>
|
|
40
|
-
<span class="line"><span style="color:#E06C75"> method</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'update'</span><span style="color:#ABB2BF">,</span></span>
|
|
41
|
-
<span class="line"><span style="color:#E06C75"> path</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'posts/p1'</span><span style="color:#ABB2BF">,</span></span>
|
|
42
|
-
<span class="line"><span style="color:#E06C75"> auth</span><span style="color:#ABB2BF">: { </span><span style="color:#E06C75">uid</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'alice'</span><span style="color:#ABB2BF"> },</span></span>
|
|
43
|
-
<span class="line"><span style="color:#E06C75"> requestTime</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'2026-07-16T12:00:03.000Z'</span><span style="color:#ABB2BF">,</span></span>
|
|
44
|
-
<span class="line"><span style="color:#E06C75"> resource</span><span style="color:#ABB2BF">: {</span></span>
|
|
45
|
-
<span class="line"><span style="color:#E06C75"> authorId</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'alice'</span><span style="color:#ABB2BF">,</span></span>
|
|
46
|
-
<span class="line"><span style="color:#E06C75"> title</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'Old'</span><span style="color:#ABB2BF">,</span></span>
|
|
47
|
-
<span class="line"><span style="color:#E06C75"> body</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'Text'</span><span style="color:#ABB2BF">,</span></span>
|
|
48
|
-
<span class="line"><span style="color:#E06C75"> updatedAt</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'2026-07-16T12:00:00.000Z'</span><span style="color:#ABB2BF">,</span></span>
|
|
49
|
-
<span class="line"><span style="color:#ABB2BF"> },</span></span>
|
|
50
|
-
<span class="line"><span style="color:#E06C75"> data</span><span style="color:#ABB2BF">: {</span></span>
|
|
51
|
-
<span class="line"><span style="color:#E06C75"> authorId</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'alice'</span><span style="color:#ABB2BF">,</span></span>
|
|
52
|
-
<span class="line"><span style="color:#E06C75"> title</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'New'</span><span style="color:#ABB2BF">,</span></span>
|
|
53
|
-
<span class="line"><span style="color:#E06C75"> body</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'Text'</span><span style="color:#ABB2BF">,</span></span>
|
|
54
|
-
<span class="line"><span style="color:#E06C75"> updatedAt</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'2026-07-16T12:00:03.000Z'</span><span style="color:#ABB2BF">,</span></span>
|
|
55
|
-
<span class="line"><span style="color:#ABB2BF"> },</span></span>
|
|
56
|
-
<span class="line"><span style="color:#ABB2BF"> },</span></span>
|
|
57
|
-
<span class="line"><span style="color:#ABB2BF">]);</span></span>
|
|
58
|
-
<span class="line"></span>
|
|
59
|
-
<span class="line"><span style="color:#C678DD">if</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">result</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">failed</span><span style="color:#56B6C2"> ></span><span style="color:#D19A66"> 0</span><span style="color:#56B6C2"> ||</span><span style="color:#E5C07B"> result</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">unsupported</span><span style="color:#56B6C2"> ></span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">) </span><span style="color:#E5C07B">process</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">exit</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">);</span></span></code></pre>
|
|
60
|
-
<p>Pin <code>requestTime</code> whenever a rule reads <code>request.time</code>, otherwise the test depends on the clock.</p>
|
|
61
|
-
<h2 id="choose-a-module">Choose a module</h2>
|
|
62
|
-
<p>These are the importable modules shipped with Pyric:</p>
|
|
63
|
-
<div class="table-scroll">
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
<table><thead><tr><th>Module</th><th>Use it for</th><th>Main functions</th></tr></thead><tbody><tr><td><code>auth</code></td><td>Authentication and ownership</td><td><code>isAuthenticated</code>, <code>isOwner</code></td></tr><tr><td><code>validation</code></td><td>Required fields, allowed fields, strings, enums</td><td><code>hasRequired</code>, <code>hasOnly</code>, <code>validString</code>, <code>isOneOf</code></td></tr><tr><td><code>lifecycle</code></td><td>Immutable or changed fields and server timestamps</td><td><code>fieldUnchanged</code>, <code>immutableFields</code>, <code>isServerTimestamp</code>, <code>onlyFieldsChanged</code>, <code>nFieldsChanged</code></td></tr><tr><td><code>content</code></td><td>Author-owned documents and published visibility</td><td><code>validAuthorCreate</code>, <code>isAuthor</code>, <code>canReadContent</code>, <code>notDeleted</code></td></tr><tr><td><code>membership</code></td><td>Claims and document membership maps</td><td><code>hasClaim</code>, <code>hasClaimRole</code>, <code>isMemberOf</code>, <code>hasRole</code></td></tr><tr><td><code>spaces</code></td><td>Parent-document membership for child data</td><td><code>isSpaceMember</code>, <code>hasSpaceRole</code>, <code>validMemberCreate</code></td></tr><tr><td><code>joining</code></td><td>Safe self-service join and leave</td><td><code>onlyAddedSelf</code>, <code>onlyRemovedSelf</code></td></tr><tr><td><code>transitions</code></td><td>Allowed state-machine edges</td><td><code>validTransition</code>, <code>statusIs</code>, <code>newStatusIs</code></td></tr><tr><td><code>counters</code></td><td>Bounded values and controlled numeric changes</td><td><code>incrementedBy</code>, <code>changedBy</code>, <code>boundedNumber</code></td></tr><tr><td><code>timing</code></td><td>Update cooldowns</td><td><code>cooldownElapsed</code></td></tr><tr><td><code>atomic</code></td><td>Companion changes in one batch</td><td><code>companionChangedBy</code>, <code>consumedFlag</code></td></tr><tr><td><code>geometry</code></td><td>Config-driven game moves</td><td><code>validSimpleMove</code>, <code>validJumpMove</code></td></tr><tr><td><code>lobby</code></td><td>Two-player session creation and joining</td><td><code>validCreate</code>, <code>validJoin</code>, <code>canCancel</code></td></tr><tr><td><code>turns</code></td><td>Two-player turn enforcement</td><td><code>isMyTurn</code>, <code>turnFlipped</code></td></tr><tr><td><code>state</code></td><td>Game status, move count, and participants</td><td><code>isPlaying</code>, <code>moveIncremented</code>, <code>participantsUnchanged</code></td></tr></tbody></table></div>
|
|
149
|
-
<p>The game-oriented modules assume the field conventions documented by their function descriptions. Prefer the general modules for application data unless your schema matches those conventions.</p>
|
|
150
|
-
<h2 id="look-up-exact-signatures-through-an-agent">Look up exact signatures through an agent</h2>
|
|
151
|
-
<p>Do not ask an agent to guess a helper name. Ask it to inspect the library first:</p>
|
|
152
|
-
<blockquote>
|
|
153
|
-
<p>Find the standard-library functions for an author-owned post with a server-timestamp cooldown. Show the signatures, compose the rule, resolve it, lint it, and simulate one allowed edit and one too-fast edit.</p>
|
|
154
|
-
</blockquote>
|
|
155
|
-
<p>The agent calls <code>firestore_rules_stdlib_list</code>, then <code>firestore_rules_stdlib_get</code> for <code>content</code>, <code>lifecycle</code>, and <code>timing</code>. It resolves the source with <code>firestore_resolve_modules</code>, checks it with <code>firestore_lint_rules</code>, and runs the two cases with <code>firestore_simulate_rules</code>.</p>
|
|
156
|
-
<h2 id="deploy-the-resolved-file">Deploy the resolved file</h2>
|
|
157
|
-
<p>Only deploy the resolved <code>rules_version = '2'</code> file:</p>
|
|
158
|
-
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">firebase</span><span style="color:#98C379"> deploy</span><span style="color:#D19A66"> --only</span><span style="color:#98C379"> firestore:rules</span></span></code></pre>
|
|
159
|
-
<p>For the compiler and evaluator ceilings that can still reject a valid-looking ruleset, see <a href="../firestore-rules-limits/">Firestore Rules limits</a>.</p> </article> </main> <aside class="doc-toc" aria-label="On this page"> <h2 class="doc-toc-heading">On this page</h2> <ul> <li data-depth="2"> <a href="#import-the-functions-you-need">Import the functions you need</a> </li><li data-depth="2"> <a href="#resolve-to-deployable-rules">Resolve to deployable Rules</a> </li><li data-depth="2"> <a href="#lint-and-simulate-the-resolved-result">Lint and simulate the resolved result</a> </li><li data-depth="2"> <a href="#choose-a-module">Choose a module</a> </li><li data-depth="2"> <a href="#look-up-exact-signatures-through-an-agent">Look up exact signatures through an agent</a> </li><li data-depth="2"> <a href="#deploy-the-resolved-file">Deploy the resolved file</a> </li> </ul> </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>
|