@pyric/cli 0.1.0-alpha.11 → 0.1.0-alpha.13
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/cli/serve.js +4 -4
- package/dist/cli/serve.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 +2 -2
- package/dist/conformance/.generated/can-i-use.js.map +1 -1
- package/dist/serve/bundler.d.ts +13 -8
- package/dist/serve/bundler.d.ts.map +1 -1
- package/dist/serve/bundler.js +31 -36
- package/dist/serve/bundler.js.map +1 -1
- package/dist/serve/docs-ui/docs/_rhythm/index.html +1 -1
- package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +1 -1
- package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +1 -1
- package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +1 -1
- package/dist/serve/docs-ui/docs/ai-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/api-reference/index.html +2 -2
- package/dist/serve/docs-ui/docs/api-reference.md +1 -1
- package/dist/serve/docs-ui/docs/app-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/auth-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/ai-logic/index.html +44 -22
- package/dist/serve/docs-ui/docs/build/ai-logic.md +69 -21
- package/dist/serve/docs-ui/docs/build/authentication/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/realtime-database/index.html +1 -1
- package/dist/serve/docs-ui/docs/conformance-scores/index.html +1 -1
- package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/database-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/firestore-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +2 -1
- package/dist/serve/docs-ui/docs/get-started/how-the-swap-works.md +2 -0
- package/dist/serve/docs-ui/docs/get-started/start-building/index.html +3 -2
- package/dist/serve/docs-ui/docs/get-started/start-building.md +3 -1
- package/dist/serve/docs-ui/docs/index.json +349 -29
- package/dist/serve/docs-ui/docs/messaging-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/observe/resolve-runtime-status/index.html +28 -0
- package/dist/serve/docs-ui/docs/observe/resolve-runtime-status.md +47 -0
- package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +1 -1
- package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +1 -1
- package/dist/serve/docs-ui/docs/overview/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-messaging-reference-api/index.html +916 -0
- package/dist/serve/docs-ui/docs/pyric-admin-messaging-reference-api.md +706 -0
- package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ai-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-auth-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api/index.html +168 -76
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api.md +156 -73
- package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +11 -8
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api.md +17 -4
- package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-rules-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api/index.html +37 -14
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api.md +28 -8
- package/dist/serve/docs-ui/docs/pyric-storage-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/rules-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +1 -1
- package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +1 -1
- package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +1 -1
- package/dist/serve/docs-ui/docs/storage-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +1 -1
- package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +1 -1
- package/dist/serve/docs-ui/docs/tutorial/index.html +429 -0
- package/dist/serve/docs-ui/docs/tutorial.md +701 -0
- package/dist/serve/docs-ui/llms.txt +3 -1
- package/dist/serve/entries/init.d.ts.map +1 -1
- package/dist/serve/entries/init.js +3 -0
- package/dist/serve/entries/init.js.map +1 -1
- package/dist/serve/entries/runtime.d.ts.map +1 -1
- package/dist/serve/entries/runtime.js +20 -5
- package/dist/serve/entries/runtime.js.map +1 -1
- package/dist/serve/entries/worker-runtime.d.ts +2 -2
- package/dist/serve/entries/worker-runtime.d.ts.map +1 -1
- package/dist/serve/entries/worker-runtime.js +45 -10
- package/dist/serve/entries/worker-runtime.js.map +1 -1
- package/dist/serve/runtime/chip-config.d.ts +19 -0
- package/dist/serve/runtime/chip-config.d.ts.map +1 -0
- package/dist/serve/runtime/chip-config.js +19 -0
- package/dist/serve/runtime/chip-config.js.map +1 -0
- package/dist/serve/runtime/chip-install.d.ts +10 -0
- package/dist/serve/runtime/chip-install.d.ts.map +1 -0
- package/dist/serve/runtime/chip-install.js +15 -0
- package/dist/serve/runtime/chip-install.js.map +1 -0
- package/dist/serve/runtime/chip.d.ts +17 -0
- package/dist/serve/runtime/chip.d.ts.map +1 -0
- package/dist/serve/runtime/chip.js +257 -0
- package/dist/serve/runtime/chip.js.map +1 -0
- package/dist/serve/runtime/manifest.d.ts +22 -0
- package/dist/serve/runtime/manifest.d.ts.map +1 -0
- package/dist/serve/runtime/manifest.js +20 -0
- package/dist/serve/runtime/manifest.js.map +1 -0
- package/dist/serve/runtime/status.d.ts +49 -0
- package/dist/serve/runtime/status.d.ts.map +1 -0
- package/dist/serve/runtime/status.js +164 -0
- package/dist/serve/runtime/status.js.map +1 -0
- package/dist/serve/runtime/worker-connection.d.ts +4 -0
- package/dist/serve/runtime/worker-connection.d.ts.map +1 -0
- package/dist/serve/runtime/worker-connection.js +11 -0
- package/dist/serve/runtime/worker-connection.js.map +1 -0
- package/dist/serve/runtime/worker-generation.d.ts +14 -0
- package/dist/serve/runtime/worker-generation.d.ts.map +1 -0
- package/dist/serve/runtime/worker-generation.js +56 -0
- package/dist/serve/runtime/worker-generation.js.map +1 -0
- package/dist/serve/runtime/worker-replacement.d.ts +18 -0
- package/dist/serve/runtime/worker-replacement.d.ts.map +1 -0
- package/dist/serve/runtime/worker-replacement.js +29 -0
- package/dist/serve/runtime/worker-replacement.js.map +1 -0
- package/dist/serve/standalone-assets.d.ts +2 -2
- package/dist/serve/standalone-assets.d.ts.map +1 -1
- package/dist/serve/standalone-assets.js +1 -1
- package/dist/serve/standalone-assets.js.map +1 -1
- package/dist/serve/studio-ui/assets/{RulesCodeEditor-CxVYcZXw.js → RulesCodeEditor-BDlH-5lp.js} +1 -1
- package/dist/serve/studio-ui/assets/{index-cpSfgQ7H.js → index-Bf9SSE8L.js} +5 -5
- package/dist/serve/studio-ui/assets/{seed-DeuFKi4J.js → seed-D_UjxfOU.js} +1 -1
- package/dist/serve/studio-ui/index.html +1 -1
- package/dist/serve/vite-ai-config.d.ts +25 -0
- package/dist/serve/vite-ai-config.d.ts.map +1 -0
- package/dist/serve/vite-ai-config.js +45 -0
- package/dist/serve/vite-ai-config.js.map +1 -0
- package/dist/serve/vite-plugin.d.ts +17 -36
- package/dist/serve/vite-plugin.d.ts.map +1 -1
- package/dist/serve/vite-plugin.js +38 -57
- package/dist/serve/vite-plugin.js.map +1 -1
- package/dist/serve/vite-rules-source.d.ts +8 -0
- package/dist/serve/vite-rules-source.d.ts.map +1 -0
- package/dist/serve/vite-rules-source.js +23 -0
- package/dist/serve/vite-rules-source.js.map +1 -0
- package/dist/serve/vite-worker-runtime.d.ts +20 -0
- package/dist/serve/vite-worker-runtime.d.ts.map +1 -0
- package/dist/serve/vite-worker-runtime.js +25 -0
- package/dist/serve/vite-worker-runtime.js.map +1 -0
- package/dist/serve/worker/client/connection.d.ts +7 -2
- package/dist/serve/worker/client/connection.d.ts.map +1 -1
- package/dist/serve/worker/client/connection.js +13 -16
- package/dist/serve/worker/client/connection.js.map +1 -1
- package/dist/serve/worker/client/core.d.ts +7 -0
- package/dist/serve/worker/client/core.d.ts.map +1 -1
- package/dist/serve/worker/client/core.js +28 -0
- package/dist/serve/worker/client/core.js.map +1 -1
- package/dist/serve/worker/client/runtime-control.d.ts +8 -0
- package/dist/serve/worker/client/runtime-control.d.ts.map +1 -0
- package/dist/serve/worker/client/runtime-control.js +11 -0
- package/dist/serve/worker/client/runtime-control.js.map +1 -0
- package/dist/serve/worker/entry.js +44 -2
- package/dist/serve/worker/entry.js.map +1 -1
- package/dist/serve/worker/host/core.js +1 -1
- package/dist/serve/worker/host/core.js.map +1 -1
- package/dist/serve/worker/host/firestore-writes.d.ts.map +1 -1
- package/dist/serve/worker/host/firestore-writes.js +3 -2
- package/dist/serve/worker/host/firestore-writes.js.map +1 -1
- package/dist/serve/worker/host/studio.js +1 -1
- package/dist/serve/worker/host/studio.js.map +1 -1
- package/dist/serve/worker/host-context.d.ts +1 -1
- package/dist/serve/worker/host-context.d.ts.map +1 -1
- package/dist/serve/worker/index.d.ts +2 -1
- package/dist/serve/worker/index.d.ts.map +1 -1
- package/dist/serve/worker/index.js +2 -1
- package/dist/serve/worker/index.js.map +1 -1
- package/dist/serve/worker/protocol.d.ts +15 -1
- package/dist/serve/worker/protocol.d.ts.map +1 -1
- package/dist/serve/worker/protocol.js +2 -2
- package/dist/serve/worker/protocol.js.map +1 -1
- package/dist/serve/worker/retirement.d.ts +21 -0
- package/dist/serve/worker/retirement.d.ts.map +1 -0
- package/dist/serve/worker/retirement.js +97 -0
- package/dist/serve/worker/retirement.js.map +1 -0
- package/dist/serve/worker/serve-init.d.ts.map +1 -1
- package/dist/serve/worker/serve-init.js +5 -6
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/dist/vite.d.ts +1 -0
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js.map +1 -1
- package/package.json +6 -4
- package/src/assurance/.generated/conformance-verdicts.ts +1090 -0
- package/src/assurance/attachment.ts +211 -0
- package/src/assurance/browser.ts +80 -0
- package/src/assurance/campaign.ts +496 -0
- package/src/assurance/capabilities.ts +446 -0
- package/src/assurance/cases.ts +43 -0
- package/src/assurance/index.ts +75 -0
- package/src/assurance/runner.ts +885 -0
- package/src/assurance/tool-names.ts +15 -0
- package/src/assurance/tools.ts +830 -0
- package/src/assurance/types.ts +352 -0
- package/src/assurance/validation.ts +434 -0
- package/src/bridge/client/bridge.ts +550 -0
- package/src/bridge/client/dispatch.ts +137 -0
- package/src/bridge/client.ts +45 -0
- package/src/bridge/protocol.ts +351 -0
- package/src/bridge/server/audit.ts +53 -0
- package/src/bridge/server/bridge.ts +597 -0
- package/src/bridge/server/headless.ts +160 -0
- package/src/bridge/server/json-schema-to-zod.ts +108 -0
- package/src/bridge/server/local-bridge.ts +66 -0
- package/src/bridge/server/logger.ts +50 -0
- package/src/bridge/server/mcp-contract.ts +93 -0
- package/src/bridge/server/mcp.ts +129 -0
- package/src/bridge/server/peer.ts +232 -0
- package/src/bridge/server/standalone.ts +347 -0
- package/src/bridge/server/tool-metadata.ts +99 -0
- package/src/bridge/server.ts +28 -0
- package/src/cli/can-i-use.ts +50 -0
- package/src/cli/cli.test.ts +493 -0
- package/src/cli/database-rules.ts +329 -0
- package/src/cli/dev-runner.ts +282 -0
- package/src/cli/firebase-json.ts +100 -0
- package/src/cli/firestore-indexes.ts +70 -0
- package/src/cli/index.ts +425 -0
- package/src/cli/init.ts +260 -0
- package/src/cli/mcp-proxy.ts +196 -0
- package/src/cli/parse-args.ts +80 -0
- package/src/cli/rules.ts +259 -0
- package/src/cli/scope.ts +67 -0
- package/src/cli/serve.ts +996 -0
- package/src/cli/service-commands.ts +73 -0
- package/src/cli/snapshot.ts +164 -0
- package/src/cli/storage-rules.ts +172 -0
- package/src/cli/verify.ts +416 -0
- package/src/conformance/.generated/can-i-use-browser.ts +113 -0
- package/src/conformance/.generated/can-i-use.ts +117 -0
- package/src/conformance/.generated/conformance-docs.ts +14 -0
- package/src/conformance/browser.ts +24 -0
- package/src/conformance/can-i-use-tool.ts +51 -0
- package/src/conformance/can-i-use.ts +18 -0
- package/src/conformance/docs.ts +8 -0
- package/src/conformance/index.ts +20 -0
- package/src/conformance/tools.ts +16 -0
- package/src/credentials/core/memoize-ttl.ts +142 -0
- package/src/credentials/core/types.ts +10 -0
- package/src/credentials/node/from-adc.ts +96 -0
- package/src/credentials/node/from-service-account.ts +133 -0
- package/src/credentials/node/index.ts +6 -0
- package/src/discover/concurrency.ts +127 -0
- package/src/discover/crawler-adapter.ts +142 -0
- package/src/discover/crawler.ts +1127 -0
- package/src/discover/credential-free.ts +27 -0
- package/src/discover/findCollectionGroup.ts +131 -0
- package/src/discover/firestore-source.ts +59 -0
- package/src/discover/index.ts +5 -0
- package/src/discover/merge.ts +523 -0
- package/src/discover/session.ts +402 -0
- package/src/discover/tools.ts +201 -0
- package/src/discover/types.ts +187 -0
- package/src/discover/wire.ts +324 -0
- package/src/functions-rtdb/child.ts +382 -0
- package/src/functions-rtdb/delivery.ts +7 -0
- package/src/functions-rtdb/discovery.ts +136 -0
- package/src/functions-rtdb/event.ts +64 -0
- package/src/functions-rtdb/execution.ts +111 -0
- package/src/functions-rtdb/in-memory-delivery.ts +40 -0
- package/src/functions-rtdb/project.ts +74 -0
- package/src/functions-rtdb/projection.ts +104 -0
- package/src/functions-rtdb/reference-pattern.ts +20 -0
- package/src/functions-rtdb/remote-delivery.ts +23 -0
- package/src/pkg-version.ts +49 -0
- package/src/register/esm-exports.ts +63 -0
- package/src/register/hooks.ts +30 -0
- package/src/register/index.ts +150 -0
- package/src/register/mapping.ts +33 -0
- package/src/remote/index.ts +1050 -0
- package/src/rtdb/crawl-snapshot.ts +118 -0
- package/src/rtdb/inspection.ts +137 -0
- package/src/rtdb/load-rules-document.ts +56 -0
- package/src/rtdb/rules-generation-tool.ts +38 -0
- package/src/rtdb/rules-json.ts +29 -0
- package/src/serve/activity-guard.ts +29 -0
- package/src/serve/activity-route.ts +164 -0
- package/src/serve/activity-warning.ts +26 -0
- package/src/serve/bridge-mount.ts +200 -0
- package/src/serve/bundler.ts +519 -0
- package/src/serve/capture-store.ts +65 -0
- package/src/serve/discovery.ts +199 -0
- package/src/serve/entries/ai.ts +292 -0
- package/src/serve/entries/app-backend.ts +4 -0
- package/src/serve/entries/app-client.ts +26 -0
- package/src/serve/entries/app-session-store.ts +47 -0
- package/src/serve/entries/app.ts +11 -0
- package/src/serve/entries/auth-helper-core.ts +181 -0
- package/src/serve/entries/auth-helper-dom.ts +134 -0
- package/src/serve/entries/auth-helper-runtime.ts +20 -0
- package/src/serve/entries/auth.ts +255 -0
- package/src/serve/entries/bridge-url.ts +31 -0
- package/src/serve/entries/database.ts +129 -0
- package/src/serve/entries/firestore.ts +232 -0
- package/src/serve/entries/init.ts +49 -0
- package/src/serve/entries/keepalive.ts +46 -0
- package/src/serve/entries/messaging-sw.ts +75 -0
- package/src/serve/entries/messaging.ts +96 -0
- package/src/serve/entries/runtime.ts +556 -0
- package/src/serve/entries/session-store.ts +97 -0
- package/src/serve/entries/storage.ts +92 -0
- package/src/serve/entries/tab-sync-wiring.ts +274 -0
- package/src/serve/entries/worker-runtime.ts +135 -0
- package/src/serve/init-payload.ts +42 -0
- package/src/serve/namespace.ts +675 -0
- package/src/serve/open-browser.ts +68 -0
- package/src/serve/rules.ts +272 -0
- package/src/serve/runtime/chip-config.ts +30 -0
- package/src/serve/runtime/chip-install.ts +27 -0
- package/src/serve/runtime/chip.ts +282 -0
- package/src/serve/runtime/manifest.ts +37 -0
- package/src/serve/runtime/status.ts +216 -0
- package/src/serve/runtime/worker-connection.ts +14 -0
- package/src/serve/runtime/worker-generation.ts +75 -0
- package/src/serve/runtime/worker-replacement.ts +42 -0
- package/src/serve/sandbox-marker.ts +31 -0
- package/src/serve/server.ts +428 -0
- package/src/serve/standalone-assets.ts +180 -0
- package/src/serve/state-store.ts +166 -0
- package/src/serve/studio/disk-project-store.ts +185 -0
- package/src/serve/studio/disk-workspace.ts +162 -0
- package/src/serve/studio/index.ts +20 -0
- package/src/serve/studio/routes.ts +237 -0
- package/src/serve/studio/store-types.ts +48 -0
- package/src/serve/studio/studio-storage.test.ts +289 -0
- package/src/serve/vite-ai-config.ts +77 -0
- package/src/serve/vite-plugin.ts +1075 -0
- package/src/serve/vite-rules-source.ts +28 -0
- package/src/serve/vite-worker-runtime.ts +51 -0
- package/src/serve/worker/activity-bootstrap.ts +24 -0
- package/src/serve/worker/client/admin-firestore.ts +38 -0
- package/src/serve/worker/client/ai.ts +124 -0
- package/src/serve/worker/client/auth.ts +489 -0
- package/src/serve/worker/client/connection.ts +227 -0
- package/src/serve/worker/client/core.ts +384 -0
- package/src/serve/worker/client/disconnect.ts +45 -0
- package/src/serve/worker/client/firestore-reads.ts +181 -0
- package/src/serve/worker/client/firestore-refs.ts +226 -0
- package/src/serve/worker/client/firestore-writes.ts +232 -0
- package/src/serve/worker/client/handles.ts +91 -0
- package/src/serve/worker/client/messaging.ts +119 -0
- package/src/serve/worker/client/presence.ts +174 -0
- package/src/serve/worker/client/rtdb.ts +311 -0
- package/src/serve/worker/client/rules.ts +63 -0
- package/src/serve/worker/client/runtime-control.ts +22 -0
- package/src/serve/worker/client/service-worker-connection.ts +59 -0
- package/src/serve/worker/client/snapshots.ts +86 -0
- package/src/serve/worker/client/storage.ts +195 -0
- package/src/serve/worker/client/studio.ts +88 -0
- package/src/serve/worker/client.ts +57 -0
- package/src/serve/worker/durable-persistence.ts +137 -0
- package/src/serve/worker/entry.ts +223 -0
- package/src/serve/worker/host/admin-firestore.ts +88 -0
- package/src/serve/worker/host/connection.ts +179 -0
- package/src/serve/worker/host/core.ts +387 -0
- package/src/serve/worker/host/dispatch.ts +316 -0
- package/src/serve/worker/host/firestore-reads.ts +117 -0
- package/src/serve/worker/host/firestore-writes.ts +456 -0
- package/src/serve/worker/host/presence.ts +312 -0
- package/src/serve/worker/host/rtdb.ts +136 -0
- package/src/serve/worker/host/rules.ts +128 -0
- package/src/serve/worker/host/storage.ts +312 -0
- package/src/serve/worker/host/studio.ts +75 -0
- package/src/serve/worker/host/subscriptions.ts +238 -0
- package/src/serve/worker/host-ai.ts +165 -0
- package/src/serve/worker/host-auth.ts +469 -0
- package/src/serve/worker/host-context.ts +273 -0
- package/src/serve/worker/host-events.ts +94 -0
- package/src/serve/worker/host-messaging.ts +240 -0
- package/src/serve/worker/host.ts +47 -0
- package/src/serve/worker/index.ts +196 -0
- package/src/serve/worker/presence-timing.ts +15 -0
- package/src/serve/worker/protocol.ts +1124 -0
- package/src/serve/worker/retirement.ts +125 -0
- package/src/serve/worker/serve-init.ts +605 -0
- package/src/serve/worker/service-worker-channel.ts +33 -0
- package/src/serve/worker/service-worker-relay.ts +86 -0
- package/src/serve/writer-lock.ts +53 -0
- package/src/verify/cases.ts +233 -0
- package/src/verify/fixture.ts +258 -0
- package/src/verify/index.ts +519 -0
- package/src/verify/tools.ts +108 -0
- package/src/version/compat-target.ts +17 -0
- package/src/vite.ts +18 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api/index.html +0 -31
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api.md +0 -29
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import { lint } from "pyric/rules";
|
|
2
|
+
// Internal engine seams, both on the browser-safe `pyric/rules/internal` entry
|
|
3
|
+
// (this runtime ships to the browser, so the Node-only `internal/rtdb` entry is
|
|
4
|
+
// not reachable from here):
|
|
5
|
+
//
|
|
6
|
+
// parseToASTOrError / MatchBlock / PathSegment — the public API exposes
|
|
7
|
+
// lint/simulate but no parsed AST, and the overlapping-match analysis below
|
|
8
|
+
// must walk the match tree to detect production OR composition.
|
|
9
|
+
//
|
|
10
|
+
// parseRtdbExpression — a target carries COMPILED RTDB `{ rules }` JSON, and
|
|
11
|
+
// `rtdbRules(compiledJson).lint()` returns nothing (a compiled document has
|
|
12
|
+
// no IR to lint against). The per-expression parse check below therefore
|
|
13
|
+
// reaches the expression parser directly.
|
|
14
|
+
import {
|
|
15
|
+
parseToASTOrError,
|
|
16
|
+
parseRtdbExpression,
|
|
17
|
+
type MatchBlock,
|
|
18
|
+
type PathSegment,
|
|
19
|
+
} from "pyric/rules/internal";
|
|
20
|
+
import { parseStorageRules } from "pyric/storage";
|
|
21
|
+
import {
|
|
22
|
+
CONFORMANCE_VERDICTS,
|
|
23
|
+
type ConformanceVerdict,
|
|
24
|
+
} from "./.generated/conformance-verdicts.js";
|
|
25
|
+
import type {
|
|
26
|
+
AssuranceProbe,
|
|
27
|
+
CapabilityDependency,
|
|
28
|
+
CapabilityRequirement,
|
|
29
|
+
EngineQualification,
|
|
30
|
+
LocalFirebaseTarget,
|
|
31
|
+
} from "./types.js";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A probe's `requires` names graph nodes (constructs, registry rows) directly,
|
|
35
|
+
* and the engine resolves each against the node's derived verdict. The lookup
|
|
36
|
+
* contains every addressable graph node and is regenerated before compilation;
|
|
37
|
+
* it is not an authored or committed capability catalog.
|
|
38
|
+
*/
|
|
39
|
+
export function verdictOf(nodeId: string): ConformanceVerdict | undefined {
|
|
40
|
+
return Object.prototype.hasOwnProperty.call(CONFORMANCE_VERDICTS, nodeId)
|
|
41
|
+
? CONFORMANCE_VERDICTS[nodeId as keyof typeof CONFORMANCE_VERDICTS]
|
|
42
|
+
: undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Resolve one `requires` node against the derived graph verdict, appending a
|
|
47
|
+
* requirement. A `supported` node passes; a `qualified`/`unsupported` node
|
|
48
|
+
* abstains (engine-gap); a node the graph does not model is an authoring error
|
|
49
|
+
* (invalid-probe).
|
|
50
|
+
*/
|
|
51
|
+
function resolveRequiredNode(
|
|
52
|
+
dependency: CapabilityDependency,
|
|
53
|
+
requirements: CapabilityRequirement[],
|
|
54
|
+
): EngineQualification["classification"] | undefined {
|
|
55
|
+
const verdict = verdictOf(dependency.id);
|
|
56
|
+
if (!verdict) {
|
|
57
|
+
requirements.push(
|
|
58
|
+
requirement(
|
|
59
|
+
dependency.id,
|
|
60
|
+
false,
|
|
61
|
+
`The probe requires ${dependency.kind} '${dependency.id}', which the conformance graph does not model.`,
|
|
62
|
+
),
|
|
63
|
+
);
|
|
64
|
+
return "invalid-probe";
|
|
65
|
+
}
|
|
66
|
+
if (verdict !== "supported") {
|
|
67
|
+
requirements.push(
|
|
68
|
+
requirement(
|
|
69
|
+
dependency.id,
|
|
70
|
+
false,
|
|
71
|
+
`The ${dependency.kind} '${dependency.id}' is derived '${verdict}', not 'supported'; the engine abstains.`,
|
|
72
|
+
),
|
|
73
|
+
);
|
|
74
|
+
return "engine-gap";
|
|
75
|
+
}
|
|
76
|
+
requirements.push(
|
|
77
|
+
requirement(dependency.id, true, `The ${dependency.kind} '${dependency.id}' is derived 'supported'.`),
|
|
78
|
+
);
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function requirement(
|
|
83
|
+
id: string,
|
|
84
|
+
supported: boolean,
|
|
85
|
+
reason: string,
|
|
86
|
+
): CapabilityRequirement {
|
|
87
|
+
return { id, supported, reason };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface FirestoreMatchPattern {
|
|
91
|
+
segments: PathSegment[];
|
|
92
|
+
operations: Set<string>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function collectFirestoreMatchPatterns(
|
|
96
|
+
block: MatchBlock,
|
|
97
|
+
prefix: PathSegment[] = [],
|
|
98
|
+
): FirestoreMatchPattern[] {
|
|
99
|
+
const segments = [...prefix, ...block.path.segments];
|
|
100
|
+
const current = block.allows.length
|
|
101
|
+
? [
|
|
102
|
+
{
|
|
103
|
+
segments,
|
|
104
|
+
operations: new Set(
|
|
105
|
+
block.allows.flatMap((allow) => allow.operations),
|
|
106
|
+
),
|
|
107
|
+
},
|
|
108
|
+
]
|
|
109
|
+
: [];
|
|
110
|
+
return [
|
|
111
|
+
...current,
|
|
112
|
+
...block.children.flatMap((child) =>
|
|
113
|
+
collectFirestoreMatchPatterns(child, segments),
|
|
114
|
+
),
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function patternMatchesPath(pattern: PathSegment[], path: string[]): boolean {
|
|
119
|
+
const visit = (patternIndex: number, pathIndex: number): boolean => {
|
|
120
|
+
if (patternIndex === pattern.length) return pathIndex === path.length;
|
|
121
|
+
const segment = pattern[patternIndex]!;
|
|
122
|
+
if (segment.type === "recursive") {
|
|
123
|
+
if (patternIndex === pattern.length - 1) return true;
|
|
124
|
+
for (let next = pathIndex; next <= path.length; next++) {
|
|
125
|
+
if (visit(patternIndex + 1, next)) return true;
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
if (pathIndex === path.length) return false;
|
|
130
|
+
if (segment.type === "literal" && segment.value !== path[pathIndex])
|
|
131
|
+
return false;
|
|
132
|
+
return visit(patternIndex + 1, pathIndex + 1);
|
|
133
|
+
};
|
|
134
|
+
return visit(0, 0);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function firestoreOperationNames(method: string): string[] {
|
|
138
|
+
if (method === "get") return ["get", "read"];
|
|
139
|
+
if (method === "list") return ["list", "read"];
|
|
140
|
+
if (method === "create") return ["create", "write"];
|
|
141
|
+
if (method === "delete") return ["delete", "write"];
|
|
142
|
+
return ["update", "write"];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function hasOverlappingFirestoreMatch(
|
|
146
|
+
root: MatchBlock,
|
|
147
|
+
operation: AssuranceProbe["control"],
|
|
148
|
+
): boolean {
|
|
149
|
+
if (operation.service !== "firestore") return false;
|
|
150
|
+
const path = operation.path.split("/").filter(Boolean);
|
|
151
|
+
if (operation.method === "list") path.push("__hypothetical_doc__");
|
|
152
|
+
const operationNames = firestoreOperationNames(operation.method);
|
|
153
|
+
return (
|
|
154
|
+
root.children
|
|
155
|
+
.flatMap((child) => collectFirestoreMatchPatterns(child))
|
|
156
|
+
.filter((pattern) => patternMatchesPath(pattern.segments, path))
|
|
157
|
+
.filter((pattern) =>
|
|
158
|
+
operationNames.some((name) => pattern.operations.has(name)),
|
|
159
|
+
).length > 1
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
interface RtdbRuleSource {
|
|
164
|
+
path: string;
|
|
165
|
+
source: string;
|
|
166
|
+
kind: ".read" | ".write" | ".validate";
|
|
167
|
+
segments: string[];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function collectRtdbRuleSources(
|
|
171
|
+
value: unknown,
|
|
172
|
+
path = "rules",
|
|
173
|
+
segments: string[] = [],
|
|
174
|
+
): RtdbRuleSource[] {
|
|
175
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return [];
|
|
176
|
+
const sources: RtdbRuleSource[] = [];
|
|
177
|
+
for (const [key, child] of Object.entries(value as Record<string, unknown>)) {
|
|
178
|
+
const childPath = `${path}/${key}`;
|
|
179
|
+
if (key === ".read" || key === ".write" || key === ".validate") {
|
|
180
|
+
if (typeof child === "string" || typeof child === "boolean") {
|
|
181
|
+
sources.push({
|
|
182
|
+
path: childPath,
|
|
183
|
+
source: String(child),
|
|
184
|
+
kind: key,
|
|
185
|
+
segments,
|
|
186
|
+
});
|
|
187
|
+
} else {
|
|
188
|
+
sources.push({ path: childPath, source: "", kind: key, segments });
|
|
189
|
+
}
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
sources.push(
|
|
193
|
+
...collectRtdbRuleSources(child, childPath, [...segments, key]),
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
return sources;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function compatibleRtdbPrefix(
|
|
200
|
+
ruleSegments: string[],
|
|
201
|
+
operationSegments: string[],
|
|
202
|
+
length: number,
|
|
203
|
+
): boolean {
|
|
204
|
+
for (let index = 0; index < length; index++) {
|
|
205
|
+
const ruleSegment = ruleSegments[index]!;
|
|
206
|
+
const operationSegment = operationSegments[index]!;
|
|
207
|
+
if (!ruleSegment.startsWith("$") && ruleSegment !== operationSegment) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function rtdbRuleAppliesToOperation(
|
|
215
|
+
rule: RtdbRuleSource,
|
|
216
|
+
operation: AssuranceProbe["control"],
|
|
217
|
+
): boolean {
|
|
218
|
+
if (operation.service !== "rtdb") return false;
|
|
219
|
+
const segments = operation.path.split("/").filter(Boolean);
|
|
220
|
+
const isRead = operation.method === "get";
|
|
221
|
+
if (rule.kind === ".read") {
|
|
222
|
+
return (
|
|
223
|
+
isRead &&
|
|
224
|
+
rule.segments.length <= segments.length &&
|
|
225
|
+
compatibleRtdbPrefix(rule.segments, segments, rule.segments.length)
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
if (rule.kind === ".write") {
|
|
229
|
+
return (
|
|
230
|
+
!isRead &&
|
|
231
|
+
rule.segments.length <= segments.length &&
|
|
232
|
+
compatibleRtdbPrefix(rule.segments, segments, rule.segments.length)
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
if (isRead) return false;
|
|
236
|
+
|
|
237
|
+
const overlapLength = Math.min(rule.segments.length, segments.length);
|
|
238
|
+
return compatibleRtdbPrefix(rule.segments, segments, overlapLength);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function firestoreRequirements(
|
|
242
|
+
target: LocalFirebaseTarget,
|
|
243
|
+
probe: AssuranceProbe,
|
|
244
|
+
): CapabilityRequirement[] {
|
|
245
|
+
const rules = target.rules.firestore;
|
|
246
|
+
const requirements = [
|
|
247
|
+
requirement(
|
|
248
|
+
"firestore.rules-present",
|
|
249
|
+
typeof rules === "string" && rules.trim().length > 0,
|
|
250
|
+
"Firestore probes require an explicit rules source.",
|
|
251
|
+
),
|
|
252
|
+
];
|
|
253
|
+
if (!rules) return requirements;
|
|
254
|
+
|
|
255
|
+
// Parse gate via the public tolerant front door: a parse blocker surfaces as
|
|
256
|
+
// a `RuleIssue` with `origin === "parse"`.
|
|
257
|
+
const parseIssue = lint(rules).find((issue) => issue.origin === "parse");
|
|
258
|
+
requirements.push(
|
|
259
|
+
requirement(
|
|
260
|
+
"firestore.rules-parse",
|
|
261
|
+
!parseIssue,
|
|
262
|
+
parseIssue
|
|
263
|
+
? `The Firestore rules source did not parse: ${parseIssue.message}`
|
|
264
|
+
: "The Firestore rules source parsed successfully.",
|
|
265
|
+
),
|
|
266
|
+
);
|
|
267
|
+
if (parseIssue) return requirements;
|
|
268
|
+
|
|
269
|
+
// The AST walk needs the parsed match tree (no public accessor exists).
|
|
270
|
+
const parsed = parseToASTOrError(rules);
|
|
271
|
+
if (!parsed.ok) return requirements;
|
|
272
|
+
|
|
273
|
+
const operations = [probe.control, probe.mutation.operation];
|
|
274
|
+
const overlapping = operations.some((operation) =>
|
|
275
|
+
hasOverlappingFirestoreMatch(parsed.ast.service.match, operation),
|
|
276
|
+
);
|
|
277
|
+
requirements.push(
|
|
278
|
+
requirement(
|
|
279
|
+
"firestore.match-resolution",
|
|
280
|
+
!overlapping,
|
|
281
|
+
overlapping
|
|
282
|
+
? "This probe matches multiple allow-bearing blocks; the current sandbox resolves only the first block instead of production OR composition."
|
|
283
|
+
: "Each operation resolves to at most one applicable allow-bearing match block.",
|
|
284
|
+
),
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
for (const operation of operations) {
|
|
288
|
+
if (operation.service !== "firestore" || operation.method !== "list")
|
|
289
|
+
continue;
|
|
290
|
+
const equalityOnly = (operation.query?.where ?? []).every(
|
|
291
|
+
(item) => item.op === "==",
|
|
292
|
+
);
|
|
293
|
+
requirements.push(
|
|
294
|
+
requirement(
|
|
295
|
+
"firestore.query-proof-equality",
|
|
296
|
+
equalityOnly,
|
|
297
|
+
equalityOnly
|
|
298
|
+
? "The query uses the supported equality-proof subset."
|
|
299
|
+
: "Inequality, membership, and disjunctive query proof is conservative in the current simulator.",
|
|
300
|
+
),
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
return requirements;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function rtdbRequirements(
|
|
307
|
+
target: LocalFirebaseTarget,
|
|
308
|
+
probe: AssuranceProbe,
|
|
309
|
+
): CapabilityRequirement[] {
|
|
310
|
+
const rules = target.rules.rtdb;
|
|
311
|
+
const operations = [probe.control, probe.mutation.operation];
|
|
312
|
+
const ruleSources = rules
|
|
313
|
+
? collectRtdbRuleSources(rules.rules).filter((rule) =>
|
|
314
|
+
operations.some((operation) =>
|
|
315
|
+
rtdbRuleAppliesToOperation(rule, operation),
|
|
316
|
+
),
|
|
317
|
+
)
|
|
318
|
+
: [];
|
|
319
|
+
const serialized = ruleSources.map((item) => item.source).join("\n");
|
|
320
|
+
const invalidExpressions = ruleSources
|
|
321
|
+
.filter((item) => !item.source || !parseRtdbExpression(item.source).valid)
|
|
322
|
+
.map((item) => item.path);
|
|
323
|
+
const queryDependent = /\bquery\b/.test(serialized);
|
|
324
|
+
const requirements = [
|
|
325
|
+
requirement(
|
|
326
|
+
"rtdb.rules-present",
|
|
327
|
+
!!rules,
|
|
328
|
+
"RTDB probes require an explicit rules JSON document.",
|
|
329
|
+
),
|
|
330
|
+
requirement(
|
|
331
|
+
"rtdb.rules-parse",
|
|
332
|
+
invalidExpressions.length === 0,
|
|
333
|
+
invalidExpressions.length === 0
|
|
334
|
+
? "All RTDB expressions relevant to the probed paths parsed successfully."
|
|
335
|
+
: `RTDB rule expressions did not parse at: ${invalidExpressions.join(", ")}.`,
|
|
336
|
+
),
|
|
337
|
+
requirement(
|
|
338
|
+
"rtdb.query-rules",
|
|
339
|
+
!queryDependent,
|
|
340
|
+
queryDependent
|
|
341
|
+
? "The current RTDB evaluator does not expose query constraints to rule expressions."
|
|
342
|
+
: "The rules used by this probe do not authorize from query constraints.",
|
|
343
|
+
),
|
|
344
|
+
requirement(
|
|
345
|
+
"rtdb.rule-location-data",
|
|
346
|
+
!/\b(?:data|newData)\b/.test(serialized),
|
|
347
|
+
/\b(?:data|newData)\b/.test(serialized)
|
|
348
|
+
? "The current evaluator cannot prove ancestor rule-location data/newData merged-tree semantics."
|
|
349
|
+
: "The rules used by this probe do not depend on data/newData.",
|
|
350
|
+
),
|
|
351
|
+
];
|
|
352
|
+
|
|
353
|
+
for (const operation of operations) {
|
|
354
|
+
if (operation.service !== "rtdb" || operation.method !== "update") continue;
|
|
355
|
+
const keys =
|
|
356
|
+
operation.data &&
|
|
357
|
+
typeof operation.data === "object" &&
|
|
358
|
+
!Array.isArray(operation.data)
|
|
359
|
+
? Object.keys(operation.data as Record<string, unknown>)
|
|
360
|
+
: [];
|
|
361
|
+
requirements.push(
|
|
362
|
+
requirement(
|
|
363
|
+
"rtdb.atomic-multipath",
|
|
364
|
+
keys.length <= 1,
|
|
365
|
+
keys.length <= 1
|
|
366
|
+
? "The update changes at most one child."
|
|
367
|
+
: "The current local backend checks multi-child updates per leaf instead of one projected future tree.",
|
|
368
|
+
),
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
return requirements;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function storageRequirements(
|
|
375
|
+
target: LocalFirebaseTarget,
|
|
376
|
+
): CapabilityRequirement[] {
|
|
377
|
+
const rules = target.rules.storage;
|
|
378
|
+
const requirements = [
|
|
379
|
+
requirement(
|
|
380
|
+
"storage.rules-present",
|
|
381
|
+
typeof rules === "string" && rules.trim().length > 0,
|
|
382
|
+
"Storage probes require an explicit rules source.",
|
|
383
|
+
),
|
|
384
|
+
requirement(
|
|
385
|
+
"storage.indexeddb",
|
|
386
|
+
typeof globalThis.indexedDB !== "undefined",
|
|
387
|
+
typeof globalThis.indexedDB !== "undefined"
|
|
388
|
+
? "IndexedDB is available for the local Storage sandbox."
|
|
389
|
+
: "The local Storage sandbox requires IndexedDB.",
|
|
390
|
+
),
|
|
391
|
+
];
|
|
392
|
+
if (!rules) return requirements;
|
|
393
|
+
try {
|
|
394
|
+
parseStorageRules(rules);
|
|
395
|
+
requirements.push(
|
|
396
|
+
requirement(
|
|
397
|
+
"storage.rules-subset",
|
|
398
|
+
true,
|
|
399
|
+
"The rules parse within the local coarse read/write evaluator subset.",
|
|
400
|
+
),
|
|
401
|
+
);
|
|
402
|
+
} catch (error) {
|
|
403
|
+
requirements.push(
|
|
404
|
+
requirement(
|
|
405
|
+
"storage.rules-subset",
|
|
406
|
+
false,
|
|
407
|
+
`The Storage rules require unsupported local semantics: ${error instanceof Error ? error.message : String(error)}`,
|
|
408
|
+
),
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
return requirements;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export function qualifyProbe(
|
|
415
|
+
target: LocalFirebaseTarget,
|
|
416
|
+
probe: AssuranceProbe,
|
|
417
|
+
): EngineQualification {
|
|
418
|
+
const service = probe.control.service;
|
|
419
|
+
const requirements =
|
|
420
|
+
service === "firestore"
|
|
421
|
+
? firestoreRequirements(target, probe)
|
|
422
|
+
: service === "rtdb"
|
|
423
|
+
? rtdbRequirements(target, probe)
|
|
424
|
+
: storageRequirements(target);
|
|
425
|
+
|
|
426
|
+
// A probe names the graph nodes its verdict depends on, and each resolves
|
|
427
|
+
// against the node's DERIVED verdict in the same pass as the structural
|
|
428
|
+
// checks above. Only `supported` proceeds; `qualified`/`unsupported` abstains
|
|
429
|
+
// (engine-gap); a node the graph does not model is a campaign authoring error
|
|
430
|
+
// (invalid-probe), which outranks engine-gap for the single classification.
|
|
431
|
+
let abstention: EngineQualification["classification"];
|
|
432
|
+
for (const dependency of probe.requires ?? []) {
|
|
433
|
+
const nodeAbstention = resolveRequiredNode(dependency, requirements);
|
|
434
|
+
if (nodeAbstention === "invalid-probe") abstention = "invalid-probe";
|
|
435
|
+
else if (nodeAbstention === "engine-gap" && abstention !== "invalid-probe") {
|
|
436
|
+
abstention = "engine-gap";
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return {
|
|
441
|
+
engine: "pyric-local-sandboxes",
|
|
442
|
+
supported: requirements.every((item) => item.supported),
|
|
443
|
+
requirements,
|
|
444
|
+
...(abstention ? { classification: abstention } : {}),
|
|
445
|
+
};
|
|
446
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { runAuthorizationCampaign } from "./runner.js";
|
|
2
|
+
import {
|
|
3
|
+
ASSURANCE_CAMPAIGN_SCHEMA,
|
|
4
|
+
type AssuranceActor,
|
|
5
|
+
type AuthorizationCampaignReport,
|
|
6
|
+
type LocalFirebaseTarget,
|
|
7
|
+
type SecurityCase,
|
|
8
|
+
type SecurityInvariant,
|
|
9
|
+
} from "./types.js";
|
|
10
|
+
|
|
11
|
+
export interface RunSecurityCasesInput {
|
|
12
|
+
campaignId: string;
|
|
13
|
+
target: LocalFirebaseTarget;
|
|
14
|
+
actors: AssuranceActor[];
|
|
15
|
+
cases: SecurityCase[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Re-run exported expectations against a candidate local target. Each case
|
|
20
|
+
* keeps its known-good control and explicit negative expectation, so a rules
|
|
21
|
+
* change must preserve the application workflow and reject the boundary case.
|
|
22
|
+
*/
|
|
23
|
+
export function runSecurityCases(
|
|
24
|
+
input: RunSecurityCasesInput,
|
|
25
|
+
): Promise<AuthorizationCampaignReport> {
|
|
26
|
+
const invariants = new Map<string, SecurityInvariant>();
|
|
27
|
+
for (const item of input.cases)
|
|
28
|
+
invariants.set(item.invariant.id, item.invariant);
|
|
29
|
+
return runAuthorizationCampaign({
|
|
30
|
+
schema: ASSURANCE_CAMPAIGN_SCHEMA,
|
|
31
|
+
id: input.campaignId,
|
|
32
|
+
target: input.target,
|
|
33
|
+
actors: input.actors,
|
|
34
|
+
invariants: [...invariants.values()],
|
|
35
|
+
probes: input.cases.map((item) => ({
|
|
36
|
+
id: item.id,
|
|
37
|
+
actorId: item.actorId,
|
|
38
|
+
invariantId: item.invariant.id,
|
|
39
|
+
control: item.control,
|
|
40
|
+
mutation: item.mutation,
|
|
41
|
+
})),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export {
|
|
2
|
+
createSandboxAttachmentProvider,
|
|
3
|
+
type AssuranceAttachment,
|
|
4
|
+
type AssuranceAttachmentInput,
|
|
5
|
+
type AssuranceAttachmentProvider,
|
|
6
|
+
type SandboxAttachmentProviderOptions,
|
|
7
|
+
} from "./attachment.js";
|
|
8
|
+
export {
|
|
9
|
+
qualifyProbe,
|
|
10
|
+
} from "./capabilities.js";
|
|
11
|
+
export { runSecurityCases, type RunSecurityCasesInput } from "./cases.js";
|
|
12
|
+
export {
|
|
13
|
+
AuthorizationCampaign,
|
|
14
|
+
createAuthorizationCampaign,
|
|
15
|
+
type CreateAuthorizationCampaignOptions,
|
|
16
|
+
} from "./campaign.js";
|
|
17
|
+
export { runAuthorizationCampaign } from "./runner.js";
|
|
18
|
+
export {
|
|
19
|
+
ASSURANCE_BROADCAST_CHANNEL,
|
|
20
|
+
ASSURANCE_BROWSER_EVENT,
|
|
21
|
+
publishAssuranceVisualization,
|
|
22
|
+
subscribeAssuranceVisualizations,
|
|
23
|
+
} from "./browser.js";
|
|
24
|
+
export {
|
|
25
|
+
AssuranceCampaignStore,
|
|
26
|
+
createAssuranceTools,
|
|
27
|
+
defaultAssuranceCampaignStore,
|
|
28
|
+
type AssuranceToolDeps,
|
|
29
|
+
} from "./tools.js";
|
|
30
|
+
export {
|
|
31
|
+
ASSURANCE_CAMPAIGN_SCHEMA,
|
|
32
|
+
ASSURANCE_REPORT_SCHEMA,
|
|
33
|
+
ASSURANCE_TARGET_SCHEMA,
|
|
34
|
+
AssuranceInputError,
|
|
35
|
+
} from "./types.js";
|
|
36
|
+
export type {
|
|
37
|
+
ActorAcquisition,
|
|
38
|
+
ActorEvidence,
|
|
39
|
+
AssuranceActor,
|
|
40
|
+
AssuranceAttachmentInventory,
|
|
41
|
+
AssuranceAttachmentSource,
|
|
42
|
+
AssuranceCampaignContext,
|
|
43
|
+
AssuranceCoverageGap,
|
|
44
|
+
AssuranceDecision,
|
|
45
|
+
AssuranceEventEvidence,
|
|
46
|
+
AssuranceVisualizationSnapshot,
|
|
47
|
+
AssuranceObservation,
|
|
48
|
+
AssuranceProbe,
|
|
49
|
+
AssuranceProbeResult,
|
|
50
|
+
AssuranceReportSummary,
|
|
51
|
+
AssuranceService,
|
|
52
|
+
AuthFixtureUser,
|
|
53
|
+
AuthorizationCampaignReport,
|
|
54
|
+
AuthorizationCampaignSpec,
|
|
55
|
+
CampaignExport,
|
|
56
|
+
CapabilityRequirement,
|
|
57
|
+
EngineQualification,
|
|
58
|
+
FirebaseOperation,
|
|
59
|
+
FirestoreOperation,
|
|
60
|
+
FirestoreQueryConstraint,
|
|
61
|
+
LocalFirebaseTarget,
|
|
62
|
+
MinimizationResult,
|
|
63
|
+
MutationDimension,
|
|
64
|
+
MutationCandidate,
|
|
65
|
+
OperationEvidence,
|
|
66
|
+
ProbeClassification,
|
|
67
|
+
ProbeMutation,
|
|
68
|
+
ProposalInput,
|
|
69
|
+
RtdbOperation,
|
|
70
|
+
SecurityCase,
|
|
71
|
+
SecurityInvariant,
|
|
72
|
+
StateDiff,
|
|
73
|
+
StorageObjectFixture,
|
|
74
|
+
StorageOperation,
|
|
75
|
+
} from "./types.js";
|