@pyric/cli 0.1.0-alpha.15 → 0.1.0-alpha.17
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/README.md +13 -9
- package/dist/assurance/.generated/conformance-verdicts.d.ts +80 -72
- package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
- package/dist/assurance/.generated/conformance-verdicts.js +80 -72
- package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
- package/dist/bridge/client/dispatch.js +1 -1
- package/dist/bridge/client/dispatch.js.map +1 -1
- package/dist/cli/database-rules.d.ts.map +1 -1
- package/dist/cli/database-rules.js +6 -4
- package/dist/cli/database-rules.js.map +1 -1
- package/dist/cli/dev-runner.d.ts +9 -0
- package/dist/cli/dev-runner.d.ts.map +1 -1
- package/dist/cli/dev-runner.js +18 -0
- package/dist/cli/dev-runner.js.map +1 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +61 -6
- package/dist/cli/serve.js.map +1 -1
- package/dist/cli/verify.js +2 -2
- package/dist/cli/verify.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/next/client-aliases.d.ts +11 -0
- package/dist/next/client-aliases.d.ts.map +1 -0
- package/dist/next/client-aliases.js +38 -0
- package/dist/next/client-aliases.js.map +1 -0
- package/dist/next/dev-rewrites.d.ts +9 -0
- package/dist/next/dev-rewrites.d.ts.map +1 -0
- package/dist/next/dev-rewrites.js +53 -0
- package/dist/next/dev-rewrites.js.map +1 -0
- package/dist/next/guard.d.ts +15 -0
- package/dist/next/guard.d.ts.map +1 -0
- package/dist/next/guard.js +52 -0
- package/dist/next/guard.js.map +1 -0
- package/dist/next/index.d.ts +12 -0
- package/dist/next/index.d.ts.map +1 -0
- package/dist/next/index.js +11 -0
- package/dist/next/index.js.map +1 -0
- package/dist/next/runtime-env.d.ts +7 -0
- package/dist/next/runtime-env.d.ts.map +1 -0
- package/dist/next/runtime-env.js +13 -0
- package/dist/next/runtime-env.js.map +1 -0
- package/dist/next/server-external-packages.d.ts +10 -0
- package/dist/next/server-external-packages.d.ts.map +1 -0
- package/dist/next/server-external-packages.js +34 -0
- package/dist/next/server-external-packages.js.map +1 -0
- package/dist/next/target-url.d.ts +11 -0
- package/dist/next/target-url.d.ts.map +1 -0
- package/dist/next/target-url.js +36 -0
- package/dist/next/target-url.js.map +1 -0
- package/dist/next/turbopack-config.d.ts +9 -0
- package/dist/next/turbopack-config.d.ts.map +1 -0
- package/dist/next/turbopack-config.js +39 -0
- package/dist/next/turbopack-config.js.map +1 -0
- package/dist/next/types.d.ts +40 -0
- package/dist/next/types.d.ts.map +1 -0
- package/dist/next/types.js +5 -0
- package/dist/next/types.js.map +1 -0
- package/dist/next/webpack-config.d.ts +11 -0
- package/dist/next/webpack-config.d.ts.map +1 -0
- package/dist/next/webpack-config.js +51 -0
- package/dist/next/webpack-config.js.map +1 -0
- package/dist/next/with-pyric.d.ts +22 -0
- package/dist/next/with-pyric.d.ts.map +1 -0
- package/dist/next/with-pyric.js +49 -0
- package/dist/next/with-pyric.js.map +1 -0
- package/dist/register/app-bridge.d.ts +9 -0
- package/dist/register/app-bridge.d.ts.map +1 -0
- package/dist/register/app-bridge.js +56 -0
- package/dist/register/app-bridge.js.map +1 -0
- package/dist/register/hooks.d.ts.map +1 -1
- package/dist/register/hooks.js +6 -1
- package/dist/register/hooks.js.map +1 -1
- package/dist/register/index.js +1 -1
- package/dist/register/index.js.map +1 -1
- package/dist/register/mapping.d.ts +3 -1
- package/dist/register/mapping.d.ts.map +1 -1
- package/dist/register/mapping.js +41 -5
- package/dist/register/mapping.js.map +1 -1
- package/dist/rtdb/rules-json.d.ts +12 -0
- package/dist/rtdb/rules-json.d.ts.map +1 -1
- package/dist/rtdb/rules-json.js +98 -0
- package/dist/rtdb/rules-json.js.map +1 -1
- package/dist/serve/bundler.d.ts.map +1 -1
- package/dist/serve/bundler.js +2 -0
- package/dist/serve/bundler.js.map +1 -1
- package/dist/serve/discovery.d.ts +4 -4
- package/dist/serve/discovery.d.ts.map +1 -1
- package/dist/serve/discovery.js +59 -38
- package/dist/serve/discovery.js.map +1 -1
- package/dist/serve/entries/app-ai-passthrough.d.ts +8 -0
- package/dist/serve/entries/app-ai-passthrough.d.ts.map +1 -0
- package/dist/serve/entries/app-ai-passthrough.js +59 -0
- package/dist/serve/entries/app-ai-passthrough.js.map +1 -0
- package/dist/serve/entries/auth-helper-core.d.ts +9 -0
- package/dist/serve/entries/auth-helper-core.d.ts.map +1 -1
- package/dist/serve/entries/auth-helper-core.js +37 -8
- package/dist/serve/entries/auth-helper-core.js.map +1 -1
- package/dist/serve/entries/auth.d.ts +1 -0
- package/dist/serve/entries/auth.d.ts.map +1 -1
- package/dist/serve/entries/auth.js +7 -4
- package/dist/serve/entries/auth.js.map +1 -1
- package/dist/serve/entries/bridge-url.d.ts.map +1 -1
- package/dist/serve/entries/bridge-url.js +7 -2
- package/dist/serve/entries/bridge-url.js.map +1 -1
- package/dist/serve/entries/database.d.ts +1 -0
- package/dist/serve/entries/database.d.ts.map +1 -1
- package/dist/serve/entries/database.js +1 -0
- package/dist/serve/entries/database.js.map +1 -1
- package/dist/serve/entries/firestore.d.ts +1 -0
- package/dist/serve/entries/firestore.d.ts.map +1 -1
- package/dist/serve/entries/firestore.js +1 -0
- package/dist/serve/entries/firestore.js.map +1 -1
- package/dist/serve/entries/init.d.ts.map +1 -1
- package/dist/serve/entries/init.js +4 -2
- package/dist/serve/entries/init.js.map +1 -1
- package/dist/serve/entries/runtime.js +23 -0
- package/dist/serve/entries/runtime.js.map +1 -1
- package/dist/serve/entries/storage.d.ts +2 -0
- package/dist/serve/entries/storage.d.ts.map +1 -1
- package/dist/serve/entries/storage.js +9 -2
- package/dist/serve/entries/storage.js.map +1 -1
- package/dist/serve/html-injection.d.ts +3 -1
- package/dist/serve/html-injection.d.ts.map +1 -1
- package/dist/serve/html-injection.js +27 -1
- package/dist/serve/html-injection.js.map +1 -1
- package/dist/serve/rules.js +2 -2
- package/dist/serve/rules.js.map +1 -1
- package/dist/serve/runtime/chip-config.d.ts +1 -1
- package/dist/serve/runtime/chip-config.d.ts.map +1 -1
- package/dist/serve/runtime/chip-config.js +16 -8
- package/dist/serve/runtime/chip-config.js.map +1 -1
- package/dist/serve/sandbox-session.d.ts +1 -0
- package/dist/serve/sandbox-session.d.ts.map +1 -1
- package/dist/serve/sandbox-session.js +30 -2
- package/dist/serve/sandbox-session.js.map +1 -1
- package/dist/serve/site-ui/_astro/_studio_.B6b_G1ev.css +1 -0
- package/dist/serve/site-ui/_astro/app.bnmVTkIY.js +11 -0
- package/dist/serve/site-ui/_astro/app.t6u-adB_.js +1 -0
- package/dist/serve/site-ui/_astro/{chess-showcase.DzPO6kz0.js → chess-showcase.kC8dXLKY.js} +1 -1
- package/dist/serve/site-ui/_astro/{example-runtime.CM0H02rx.js → example-runtime.D79PnoSk.js} +1 -1
- package/dist/serve/site-ui/_astro/index.DzVde04M.js +1 -0
- package/dist/serve/site-ui/_astro/reads.BYBRLbsE.js +1 -0
- package/dist/serve/site-ui/_astro/sandbox-controls.C9Aaazt8.js +1252 -0
- package/dist/serve/site-ui/_astro/{seed.BCn5DhHS.js → seed.DANAIyRw.js} +1 -1
- package/dist/serve/site-ui/auth/index.html +2 -2
- package/dist/serve/site-ui/docs/_rhythm/index.html +1 -1
- package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +1 -1
- package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +1 -1
- package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +1 -1
- package/dist/serve/site-ui/docs/ai-compat/index.html +85 -85
- package/dist/serve/site-ui/docs/ai-compat.md +84 -84
- package/dist/serve/site-ui/docs/api-reference/index.html +3 -1
- package/dist/serve/site-ui/docs/api-reference.md +2 -0
- package/dist/serve/site-ui/docs/app-compat/index.html +28 -28
- package/dist/serve/site-ui/docs/app-compat.md +27 -27
- package/dist/serve/site-ui/docs/auth-compat/index.html +122 -122
- package/dist/serve/site-ui/docs/auth-compat.md +121 -121
- package/dist/serve/site-ui/docs/build/ai-logic/index.html +1 -1
- package/dist/serve/site-ui/docs/build/authentication/index.html +1 -1
- package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +1 -1
- package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +1 -1
- package/dist/serve/site-ui/docs/build/cloud-storage/index.html +1 -1
- package/dist/serve/site-ui/docs/build/realtime-database/index.html +1 -1
- package/dist/serve/site-ui/docs/conformance-scores/index.html +4 -4
- package/dist/serve/site-ui/docs/conformance-scores.md +3 -3
- package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +6 -6
- package/dist/serve/site-ui/docs/create-pyric-reference-api.md +5 -5
- package/dist/serve/site-ui/docs/database-compat/index.html +200 -448
- package/dist/serve/site-ui/docs/database-compat.md +198 -461
- package/dist/serve/site-ui/docs/examples/chess/index.html +2 -2
- package/dist/serve/site-ui/docs/examples/index.html +1 -1
- package/dist/serve/site-ui/docs/firestore-compat/index.html +186 -195
- package/dist/serve/site-ui/docs/firestore-compat.md +184 -195
- package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +15 -15
- package/dist/serve/site-ui/docs/functions-rtdb-compat.md +14 -14
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +1 -1
- package/dist/serve/site-ui/docs/get-started/nextjs/index.html +57 -0
- package/dist/serve/site-ui/docs/get-started/nextjs.md +86 -0
- package/dist/serve/site-ui/docs/get-started/start-building/index.html +25 -8
- package/dist/serve/site-ui/docs/get-started/start-building.md +34 -5
- package/dist/serve/site-ui/docs/get-started/vite/index.html +26 -0
- package/dist/serve/site-ui/docs/get-started/vite.md +45 -0
- package/dist/serve/site-ui/docs/index.json +668 -103
- package/dist/serve/site-ui/docs/messaging-compat/index.html +56 -56
- package/dist/serve/site-ui/docs/messaging-compat.md +55 -55
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +1 -1
- package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +1 -1
- package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +1 -1
- package/dist/serve/site-ui/docs/overview/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +39 -13
- package/dist/serve/site-ui/docs/pyric-admin-app-reference-api.md +28 -2
- package/dist/serve/site-ui/docs/pyric-admin-auth-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-database-reference-api/index.html +38 -6
- package/dist/serve/site-ui/docs/pyric-admin-database-reference-api.md +43 -0
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +9 -1
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api.md +8 -0
- package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +27 -4
- package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api.md +23 -0
- package/dist/serve/site-ui/docs/pyric-ai-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +2 -2
- package/dist/serve/site-ui/docs/pyric-auth-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-assurance-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-discover-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +123 -0
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +99 -0
- package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api/index.html +127 -0
- package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api.md +174 -0
- package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +570 -326
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +198 -6
- package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-firestore-reference-api/index.html +2971 -627
- package/dist/serve/site-ui/docs/pyric-firestore-reference-api.md +2873 -517
- package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +43 -3
- package/dist/serve/site-ui/docs/pyric-rules-reference-api.md +8 -0
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +26 -2
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api.md +24 -0
- package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-sandbox-reference-api/index.html +77 -9
- package/dist/serve/site-ui/docs/pyric-sandbox-reference-api.md +28 -13
- package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +240 -63
- package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +164 -5
- package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-events-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-rtdb-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api/index.html +2 -1
- package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api.md +1 -0
- package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-traffic-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/rules-compat/index.html +87 -79
- package/dist/serve/site-ui/docs/rules-compat.md +86 -78
- package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +1 -1
- package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +1 -1
- package/dist/serve/site-ui/docs/ship/test-in-node/index.html +1 -1
- package/dist/serve/site-ui/docs/storage-compat/index.html +119 -125
- package/dist/serve/site-ui/docs/storage-compat.md +118 -124
- package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +1 -1
- package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +1 -1
- package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +1 -1
- package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +1 -1
- package/dist/serve/site-ui/docs/tutorial/index.html +1 -1
- package/dist/serve/site-ui/examples/chess/index.html +1 -1
- package/dist/serve/site-ui/examples/firestore-first-write/index.html +1 -1
- package/dist/serve/site-ui/firestore/index.html +2 -2
- package/dist/serve/site-ui/index.html +2 -2
- package/dist/serve/site-ui/llms.txt +6 -2
- package/dist/serve/site-ui/rtdb/index.html +2 -2
- package/dist/serve/site-ui/settings/index.html +2 -2
- package/dist/serve/site-ui/storage/index.html +2 -2
- package/dist/serve/site-ui/traffic/index.html +2 -2
- package/dist/serve/vite-ai-config.d.ts +4 -1
- package/dist/serve/vite-ai-config.d.ts.map +1 -1
- package/dist/serve/vite-ai-config.js +83 -19
- package/dist/serve/vite-ai-config.js.map +1 -1
- package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -1
- package/dist/serve/vite-generation-rules-watch.js +61 -14
- package/dist/serve/vite-generation-rules-watch.js.map +1 -1
- package/dist/serve/vite-module-swap.d.ts +4 -1
- package/dist/serve/vite-module-swap.d.ts.map +1 -1
- package/dist/serve/vite-module-swap.js +106 -21
- package/dist/serve/vite-module-swap.js.map +1 -1
- package/dist/serve/vite-plugin.d.ts.map +1 -1
- package/dist/serve/vite-plugin.js +45 -5
- package/dist/serve/vite-plugin.js.map +1 -1
- package/dist/serve/vite-sandbox-generation.js +1 -1
- package/dist/serve/vite-sandbox-generation.js.map +1 -1
- package/dist/serve/worker/client/resumable.d.ts +30 -0
- package/dist/serve/worker/client/resumable.d.ts.map +1 -0
- package/dist/serve/worker/client/resumable.js +416 -0
- package/dist/serve/worker/client/resumable.js.map +1 -0
- package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -1
- package/dist/serve/worker/client/rtdb-references.js +4 -1
- package/dist/serve/worker/client/rtdb-references.js.map +1 -1
- package/dist/serve/worker/client/storage.d.ts +16 -2
- package/dist/serve/worker/client/storage.d.ts.map +1 -1
- package/dist/serve/worker/client/storage.js +57 -6
- package/dist/serve/worker/client/storage.js.map +1 -1
- package/dist/serve/worker/host/rules.d.ts.map +1 -1
- package/dist/serve/worker/host/rules.js +2 -1
- package/dist/serve/worker/host/rules.js.map +1 -1
- package/dist/serve/worker/index.d.ts +1 -1
- package/dist/serve/worker/index.d.ts.map +1 -1
- package/dist/serve/worker/index.js +1 -1
- package/dist/serve/worker/index.js.map +1 -1
- package/dist/serve/worker/serve-init.d.ts.map +1 -1
- package/dist/serve/worker/serve-init.js +31 -0
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/package.json +15 -4
- package/src/assurance/.generated/conformance-verdicts.ts +80 -72
- package/src/bridge/client/dispatch.ts +1 -1
- package/src/cli/cli.test.ts +14 -0
- package/src/cli/database-rules.ts +6 -4
- package/src/cli/dev-runner.ts +21 -0
- package/src/cli/serve.ts +62 -5
- package/src/cli/verify.ts +2 -2
- 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/next/client-aliases.ts +39 -0
- package/src/next/dev-rewrites.ts +77 -0
- package/src/next/guard.ts +61 -0
- package/src/next/index.ts +16 -0
- package/src/next/runtime-env.ts +18 -0
- package/src/next/server-external-packages.ts +43 -0
- package/src/next/target-url.ts +46 -0
- package/src/next/turbopack-config.ts +54 -0
- package/src/next/types.ts +47 -0
- package/src/next/webpack-config.ts +71 -0
- package/src/next/with-pyric.ts +58 -0
- package/src/register/app-bridge.ts +79 -0
- package/src/register/hooks.ts +6 -1
- package/src/register/index.ts +1 -1
- package/src/register/mapping.ts +50 -4
- package/src/rtdb/rules-json.ts +110 -0
- package/src/serve/bundler.ts +2 -0
- package/src/serve/discovery.ts +65 -44
- package/src/serve/entries/app-ai-passthrough.ts +83 -0
- package/src/serve/entries/auth-helper-core.ts +44 -8
- package/src/serve/entries/auth.ts +9 -4
- package/src/serve/entries/bridge-url.ts +9 -2
- package/src/serve/entries/database.ts +1 -0
- package/src/serve/entries/firestore.ts +1 -0
- package/src/serve/entries/init.ts +5 -2
- package/src/serve/entries/runtime.ts +25 -0
- package/src/serve/entries/storage.ts +12 -1
- package/src/serve/html-injection.ts +26 -1
- package/src/serve/rules.ts +2 -2
- package/src/serve/runtime/chip-config.ts +19 -6
- package/src/serve/sandbox-session.ts +31 -2
- package/src/serve/vite-ai-config.ts +86 -19
- package/src/serve/vite-generation-rules-watch.ts +67 -15
- package/src/serve/vite-module-swap.ts +121 -21
- package/src/serve/vite-plugin.ts +44 -6
- package/src/serve/vite-sandbox-generation.ts +1 -1
- package/src/serve/worker/client/resumable.ts +506 -0
- package/src/serve/worker/client/rtdb-references.ts +4 -1
- package/src/serve/worker/client/storage.ts +77 -7
- package/src/serve/worker/host/rules.ts +2 -1
- package/src/serve/worker/index.ts +4 -0
- package/src/serve/worker/serve-init.ts +30 -0
- package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +0 -1
- package/dist/serve/site-ui/_astro/app.BnMC0ywl.js +0 -109
- package/dist/serve/site-ui/_astro/app.DVXXR-WI.js +0 -1
- package/dist/serve/site-ui/_astro/index.B4Kh80he.js +0 -1
- package/dist/serve/site-ui/_astro/reads.D1exkX1-.js +0 -1
- package/dist/serve/site-ui/_astro/sandbox-controls.BqMePr5V.js +0 -1153
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
import { SANDBOX_BUILD_MARKER } from './sandbox-marker.js';
|
|
2
2
|
|
|
3
3
|
/** The import-map targets. Spec → served URL. */
|
|
4
|
-
export function sdkImportMap(): Record<string, string> {
|
|
4
|
+
export function sdkImportMap(options?: { aiMode?: 'sandbox' | 'production' }): Record<string, string> {
|
|
5
|
+
const explicitMode = options?.aiMode;
|
|
6
|
+
let mode: 'sandbox' | 'production' = 'sandbox';
|
|
7
|
+
const hasExplicitMode = explicitMode !== undefined;
|
|
8
|
+
if (hasExplicitMode) {
|
|
9
|
+
mode = explicitMode;
|
|
10
|
+
} else {
|
|
11
|
+
const isEnvProductionMode = process.env.PYRIC_AI_MODE === 'production';
|
|
12
|
+
const isEnvPassthroughFlag = process.env.PYRIC_AI_PASSTHROUGH === '1';
|
|
13
|
+
const isProductionEnv = isEnvProductionMode || isEnvPassthroughFlag;
|
|
14
|
+
if (isProductionEnv) {
|
|
15
|
+
mode = 'production';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const isProductionMode = mode === 'production';
|
|
19
|
+
if (isProductionMode) {
|
|
20
|
+
return {
|
|
21
|
+
'firebase/app': '/__pyric/sdk/app-ai-passthrough.js',
|
|
22
|
+
'firebase/auth': '/__pyric/sdk/auth.js',
|
|
23
|
+
'firebase/database': '/__pyric/sdk/database.js',
|
|
24
|
+
'firebase/firestore': '/__pyric/sdk/firestore.js',
|
|
25
|
+
'firebase/messaging': '/__pyric/sdk/messaging.js',
|
|
26
|
+
'firebase/messaging/sw': '/__pyric/sdk/messaging-sw.js',
|
|
27
|
+
'firebase/storage': '/__pyric/sdk/storage.js',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
5
30
|
return {
|
|
6
31
|
'firebase/ai': '/__pyric/sdk/ai.js',
|
|
7
32
|
'firebase/app': '/__pyric/sdk/app.js',
|
package/src/serve/rules.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { isAbsolute, join } from 'node:path';
|
|
|
16
16
|
import { lintFirestoreRules, resolveModulesBrowser } from 'pyric/rules/internal';
|
|
17
17
|
import { parseStorageRules } from 'pyric/storage';
|
|
18
18
|
import type { FirebaseJson } from '../cli/firebase-json.js';
|
|
19
|
-
import { parseRtdbRulesJson } from '../rtdb/rules-json.js';
|
|
19
|
+
import { parseRtdbRulesJson, stripJsonComments } from '../rtdb/rules-json.js';
|
|
20
20
|
|
|
21
21
|
export interface LoadedRules {
|
|
22
22
|
/** Plain-v2 source ready for the sandbox, or null when the project has no
|
|
@@ -186,7 +186,7 @@ export async function loadProjectDatabaseRules(
|
|
|
186
186
|
|
|
187
187
|
let parsed: unknown;
|
|
188
188
|
try {
|
|
189
|
-
parsed = JSON.parse(raw);
|
|
189
|
+
parsed = JSON.parse(stripJsonComments(raw));
|
|
190
190
|
} catch (e) {
|
|
191
191
|
throw new Error(`pyric dev: ${path} failed to parse as RTDB rules JSON: ${e instanceof Error ? e.message : String(e)}`);
|
|
192
192
|
}
|
|
@@ -17,14 +17,27 @@ interface RuntimeChipDocument {
|
|
|
17
17
|
querySelector(selector: string): { getAttribute(name: string): string | null } | null;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
function hasBundlerRuntimeChipConfig(): boolean {
|
|
21
|
+
return typeof process !== 'undefined' && typeof process.env !== 'undefined' && typeof process.env.PYRIC_RUNTIME_CHIP === 'string';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Read plugin-authored values from DOM metadata or bundler environment variables, defaulting to collapsed UI when omitted. */
|
|
21
25
|
export function readPyricRuntimeChipConfig(
|
|
22
26
|
documentLike: RuntimeChipDocument,
|
|
23
27
|
): PyricRuntimeChipConfig | null {
|
|
24
28
|
const meta = documentLike.querySelector(`meta[name="${PYRIC_RUNTIME_CHIP_META}"]`);
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
const hasMetaTag = meta !== null;
|
|
30
|
+
let value = hasMetaTag ? meta.getAttribute('content') : null;
|
|
31
|
+
|
|
32
|
+
const shouldFallbackToEnv = !hasMetaTag && hasBundlerRuntimeChipConfig();
|
|
33
|
+
if (shouldFallbackToEnv) {
|
|
34
|
+
value = process.env.PYRIC_RUNTIME_CHIP as string;
|
|
35
|
+
}
|
|
36
|
+
if (value === 'off') {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const studioEnabled = !hasMetaTag || meta.getAttribute('data-studio') !== 'off';
|
|
41
|
+
const initiallyOpen = value === 'expanded';
|
|
42
|
+
return { initiallyOpen, studioEnabled };
|
|
30
43
|
}
|
|
@@ -63,6 +63,7 @@ export interface SandboxSession {
|
|
|
63
63
|
payload(): InitPayload;
|
|
64
64
|
handle(req: IncomingMessage, res: ServerResponse, url: URL): boolean | Promise<boolean>;
|
|
65
65
|
reloadFirestoreRules(): Promise<RulesReloadResult>;
|
|
66
|
+
reloadDatabaseRules(): Promise<RulesReloadResult>;
|
|
66
67
|
close(): Promise<void>;
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -93,6 +94,8 @@ export async function createSandboxSession(
|
|
|
93
94
|
const live = {
|
|
94
95
|
rules: firestore.rules,
|
|
95
96
|
rulesHash: firestore.rulesHash,
|
|
97
|
+
databaseRules: database.rules,
|
|
98
|
+
databaseRulesHash: database.rulesHash,
|
|
96
99
|
};
|
|
97
100
|
const events = createEventHub();
|
|
98
101
|
const capture: CaptureStore | undefined = (options.capture ?? true)
|
|
@@ -145,8 +148,8 @@ export async function createSandboxSession(
|
|
|
145
148
|
const payload = (): InitPayload => ({
|
|
146
149
|
rules: live.rules,
|
|
147
150
|
rulesHash: live.rulesHash,
|
|
148
|
-
databaseRules:
|
|
149
|
-
databaseRulesHash:
|
|
151
|
+
databaseRules: live.databaseRules,
|
|
152
|
+
databaseRulesHash: live.databaseRulesHash,
|
|
150
153
|
databaseUrl: database.databaseUrl,
|
|
151
154
|
storageRules: storage.rules,
|
|
152
155
|
storageRulesHash: storage.rulesHash,
|
|
@@ -217,6 +220,31 @@ export async function createSandboxSession(
|
|
|
217
220
|
return { kind: 'rejected', error: error instanceof Error ? error : new Error(String(error)) };
|
|
218
221
|
}
|
|
219
222
|
};
|
|
223
|
+
const reloadDatabaseRules = async (): Promise<RulesReloadResult> => {
|
|
224
|
+
const isMissingDatabaseRules = database.sourcePath === null;
|
|
225
|
+
if (isMissingDatabaseRules) {
|
|
226
|
+
return { kind: 'not-configured' };
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
const updated = await loadProjectDatabaseRules(options.projectDir, options.firebaseConfig);
|
|
230
|
+
const isMissingUpdatedRules = updated.rules === null || updated.rulesHash === null;
|
|
231
|
+
if (isMissingUpdatedRules) {
|
|
232
|
+
return { kind: 'not-configured' };
|
|
233
|
+
}
|
|
234
|
+
live.databaseRules = updated.rules;
|
|
235
|
+
live.databaseRulesHash = updated.rulesHash;
|
|
236
|
+
events.broadcast('rtdb-rules-update', { rules: updated.rules, rulesHash: updated.rulesHash });
|
|
237
|
+
return { kind: 'reloaded', rulesHash: updated.rulesHash as string, clients: events.clientCount() };
|
|
238
|
+
} catch (error) {
|
|
239
|
+
const isErrorInstance = error instanceof Error;
|
|
240
|
+
let errorResult: Error = new Error(String(error));
|
|
241
|
+
if (isErrorInstance) {
|
|
242
|
+
errorResult = error as Error;
|
|
243
|
+
}
|
|
244
|
+
return { kind: 'rejected', error: errorResult };
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
220
248
|
let closePromise: Promise<void> | null = null;
|
|
221
249
|
const close = (): Promise<void> => {
|
|
222
250
|
closePromise ??= Promise.resolve().then(() => events.close());
|
|
@@ -228,6 +256,7 @@ export async function createSandboxSession(
|
|
|
228
256
|
payload,
|
|
229
257
|
handle: namespace,
|
|
230
258
|
reloadFirestoreRules,
|
|
259
|
+
reloadDatabaseRules,
|
|
231
260
|
close,
|
|
232
261
|
};
|
|
233
262
|
}
|
|
@@ -9,6 +9,8 @@ const AI_PROXY_PATH = '/__pyric/ai-proxy';
|
|
|
9
9
|
export type PyricAiEngineConfig = Extract<NonNullable<AIOptions['engine']>, { kind: string }>;
|
|
10
10
|
|
|
11
11
|
export interface PyricAiOptions {
|
|
12
|
+
/** Mode for AI Logic: 'sandbox' (local mirrors) or 'production' (pass-through to Google AI / Vertex AI). */
|
|
13
|
+
mode?: 'sandbox' | 'production';
|
|
12
14
|
/** Simple OpenAI-compatible model selection through Pyric's same-origin proxy. */
|
|
13
15
|
model?: string;
|
|
14
16
|
/** Advanced declarative engine configuration. */
|
|
@@ -18,6 +20,7 @@ export interface PyricAiOptions {
|
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
export interface ResolvedViteAiConfig {
|
|
23
|
+
mode: 'sandbox' | 'production';
|
|
21
24
|
engineWire: AiEngineConfigWire | undefined;
|
|
22
25
|
proxyUpstream: string | undefined;
|
|
23
26
|
}
|
|
@@ -26,8 +29,9 @@ export interface ResolvedViteAiConfig {
|
|
|
26
29
|
export function viteWorkerEpochSalt(
|
|
27
30
|
projectKey: string,
|
|
28
31
|
engineWire: AiEngineConfigWire | undefined,
|
|
32
|
+
mode: 'sandbox' | 'production' = 'sandbox',
|
|
29
33
|
): string {
|
|
30
|
-
return JSON.stringify({ projectKey, aiEngine: engineWire ?? null });
|
|
34
|
+
return JSON.stringify({ projectKey, aiEngine: engineWire ?? null, aiMode: mode });
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
/** Load env using Vite's `envDir`-relative-to-root convention. */
|
|
@@ -45,20 +49,30 @@ export function loadViteAiEnv(
|
|
|
45
49
|
|
|
46
50
|
/** Convert a public declarative engine into the JSON-safe worker wire shape. */
|
|
47
51
|
export function engineConfigToWire(engine: PyricAiEngineConfig): AiEngineConfigWire {
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
const isOpenAiEngine = engine.kind === 'openai';
|
|
53
|
+
if (isOpenAiEngine) {
|
|
54
|
+
const result: Record<string, unknown> = {
|
|
50
55
|
kind: 'openai',
|
|
51
|
-
baseUrl: engine.baseUrl
|
|
52
|
-
...(engine.model !== undefined ? { model: engine.model } : {}),
|
|
53
|
-
...(engine.modelMap !== undefined ? { modelMap: engine.modelMap } : {}),
|
|
56
|
+
baseUrl: engine.baseUrl !== undefined && engine.baseUrl !== null ? engine.baseUrl : AI_PROXY_PATH,
|
|
54
57
|
};
|
|
58
|
+
const hasModel = engine.model !== undefined;
|
|
59
|
+
if (hasModel) {
|
|
60
|
+
result.model = engine.model;
|
|
61
|
+
}
|
|
62
|
+
const hasModelMap = engine.modelMap !== undefined;
|
|
63
|
+
if (hasModelMap) {
|
|
64
|
+
result.modelMap = engine.modelMap;
|
|
65
|
+
}
|
|
66
|
+
return result as AiEngineConfigWire;
|
|
55
67
|
}
|
|
56
|
-
|
|
68
|
+
const result: Record<string, unknown> = {
|
|
57
69
|
kind: 'scripted',
|
|
58
|
-
...(engine.script !== undefined
|
|
59
|
-
? { script: engine.script as unknown as Array<Record<string, unknown>> }
|
|
60
|
-
: {}),
|
|
61
70
|
};
|
|
71
|
+
const hasScript = engine.script !== undefined;
|
|
72
|
+
if (hasScript) {
|
|
73
|
+
result.script = engine.script as unknown as Array<Record<string, unknown>>;
|
|
74
|
+
}
|
|
75
|
+
return result as AiEngineConfigWire;
|
|
62
76
|
}
|
|
63
77
|
|
|
64
78
|
/** Resolve the plugin's explicit-options-over-Vite-env AI convention. */
|
|
@@ -66,20 +80,73 @@ export function resolveViteAiConfig(
|
|
|
66
80
|
options: PyricAiOptions | undefined,
|
|
67
81
|
env: Record<string, string | undefined>,
|
|
68
82
|
): ResolvedViteAiConfig {
|
|
69
|
-
|
|
83
|
+
const explicitModel = options?.model;
|
|
84
|
+
const explicitEngine = options?.engine;
|
|
85
|
+
const hasModelOption = explicitModel !== undefined;
|
|
86
|
+
const hasEngineOption = explicitEngine !== undefined;
|
|
87
|
+
const hasBothModelAndEngine = hasModelOption && hasEngineOption;
|
|
88
|
+
if (hasBothModelAndEngine) {
|
|
70
89
|
throw new Error('@pyric/cli/vite: Choose either ai.model or ai.engine, not both.');
|
|
71
90
|
}
|
|
72
91
|
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
92
|
+
let mode: 'sandbox' | 'production' = 'sandbox';
|
|
93
|
+
const explicitMode = options?.mode;
|
|
94
|
+
const hasExplicitMode = explicitMode !== undefined;
|
|
95
|
+
if (hasExplicitMode) {
|
|
96
|
+
mode = explicitMode;
|
|
97
|
+
} else {
|
|
98
|
+
const isEnvProductionMode = env.PYRIC_AI_MODE === 'production';
|
|
99
|
+
const isEnvPassthroughFlag = env.PYRIC_AI_PASSTHROUGH === '1';
|
|
100
|
+
const isProductionEnv = isEnvProductionMode || isEnvPassthroughFlag;
|
|
101
|
+
if (isProductionEnv) {
|
|
102
|
+
mode = 'production';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const isProductionMode = mode === 'production';
|
|
107
|
+
const hasAnyEngineConfig = hasModelOption || hasEngineOption;
|
|
108
|
+
const isInvalidProductionConfig = isProductionMode && hasAnyEngineConfig;
|
|
109
|
+
if (isInvalidProductionConfig) {
|
|
110
|
+
throw new Error('@pyric/cli/vite: Cannot configure ai.model or ai.engine when ai.mode is set to "production".');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let model: string | undefined = undefined;
|
|
114
|
+
const envModel = env.PYRIC_AI_MODEL;
|
|
115
|
+
if (explicitModel !== undefined) {
|
|
116
|
+
model = explicitModel.trim();
|
|
117
|
+
} else if (envModel !== undefined) {
|
|
118
|
+
model = envModel.trim();
|
|
119
|
+
}
|
|
120
|
+
const hasNonEmptyModel = model !== undefined && model !== '';
|
|
121
|
+
if (!hasNonEmptyModel) {
|
|
122
|
+
model = undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let engineWire: AiEngineConfigWire | undefined = undefined;
|
|
126
|
+
if (!isProductionMode) {
|
|
127
|
+
if (explicitEngine !== undefined) {
|
|
128
|
+
engineWire = engineConfigToWire(explicitEngine);
|
|
129
|
+
} else if (model !== undefined) {
|
|
130
|
+
engineWire = engineConfigToWire({ kind: 'openai', baseUrl: AI_PROXY_PATH, model });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let proxyUpstream: string | undefined = undefined;
|
|
135
|
+
const explicitProxyUpstream = options?.proxyUpstream;
|
|
136
|
+
const envProxyUpstream = env.PYRIC_AI_PROXY_UPSTREAM;
|
|
137
|
+
if (explicitProxyUpstream !== undefined) {
|
|
138
|
+
proxyUpstream = explicitProxyUpstream.trim();
|
|
139
|
+
} else if (envProxyUpstream !== undefined) {
|
|
140
|
+
proxyUpstream = envProxyUpstream.trim();
|
|
141
|
+
}
|
|
142
|
+
const hasNonEmptyProxyUpstream = proxyUpstream !== undefined && proxyUpstream !== '';
|
|
143
|
+
if (!hasNonEmptyProxyUpstream) {
|
|
144
|
+
proxyUpstream = undefined;
|
|
145
|
+
}
|
|
79
146
|
|
|
80
147
|
return {
|
|
148
|
+
mode,
|
|
81
149
|
engineWire,
|
|
82
|
-
proxyUpstream
|
|
83
|
-
options?.proxyUpstream?.trim() || env.PYRIC_AI_PROXY_UPSTREAM?.trim() || undefined,
|
|
150
|
+
proxyUpstream,
|
|
84
151
|
};
|
|
85
152
|
}
|
|
@@ -8,30 +8,82 @@ export function watchViteGenerationRules(input: {
|
|
|
8
8
|
session: SandboxSession;
|
|
9
9
|
}): (() => void) | null {
|
|
10
10
|
const { server, session } = input;
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const firestoreFile = session.summary.rules.firestore.sourcePath;
|
|
12
|
+
const databaseFile = session.summary.rules.database.sourcePath;
|
|
13
|
+
const hasFirestoreFile = firestoreFile !== null;
|
|
14
|
+
const hasDatabaseFile = databaseFile !== null;
|
|
15
|
+
const hasNeitherFile = !hasFirestoreFile && !hasDatabaseFile;
|
|
16
|
+
if (hasNeitherFile) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
13
19
|
|
|
14
20
|
let debounce: ReturnType<typeof setTimeout> | null = null;
|
|
15
21
|
const onRulesChange = (file: string): void => {
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
const resolvedFile = path.resolve(file);
|
|
23
|
+
let isFirestoreMatch = false;
|
|
24
|
+
if (hasFirestoreFile) {
|
|
25
|
+
const firestoreResolved = path.resolve(firestoreFile);
|
|
26
|
+
isFirestoreMatch = resolvedFile === firestoreResolved;
|
|
27
|
+
}
|
|
28
|
+
let isDatabaseMatch = false;
|
|
29
|
+
if (hasDatabaseFile) {
|
|
30
|
+
const databaseResolved = path.resolve(databaseFile);
|
|
31
|
+
isDatabaseMatch = resolvedFile === databaseResolved;
|
|
32
|
+
}
|
|
33
|
+
const isNeitherMatch = !isFirestoreMatch && !isDatabaseMatch;
|
|
34
|
+
if (isNeitherMatch) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const hasDebounce = debounce !== null;
|
|
38
|
+
if (hasDebounce) {
|
|
39
|
+
clearTimeout(debounce as ReturnType<typeof setTimeout>);
|
|
40
|
+
}
|
|
18
41
|
debounce = setTimeout(() => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
42
|
+
if (isFirestoreMatch) {
|
|
43
|
+
void session.reloadFirestoreRules().then((result) => {
|
|
44
|
+
const isReloaded = result.kind === 'reloaded';
|
|
45
|
+
if (isReloaded) {
|
|
46
|
+
server.config.logger.info(` ↻ [pyric] rules reloaded (${result.rulesHash})`);
|
|
47
|
+
} else {
|
|
48
|
+
const isRejected = result.kind === 'rejected';
|
|
49
|
+
if (isRejected) {
|
|
50
|
+
server.config.logger.warn(
|
|
51
|
+
` ⚠ [pyric] rules NOT reloaded (last-good stays live): ${result.error.message}`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (isDatabaseMatch) {
|
|
58
|
+
void session.reloadDatabaseRules().then((result) => {
|
|
59
|
+
const isReloaded = result.kind === 'reloaded';
|
|
60
|
+
if (isReloaded) {
|
|
61
|
+
server.config.logger.info(` ↻ [pyric] rtdb rules reloaded (${result.rulesHash})`);
|
|
62
|
+
} else {
|
|
63
|
+
const isRejected = result.kind === 'rejected';
|
|
64
|
+
if (isRejected) {
|
|
65
|
+
server.config.logger.warn(
|
|
66
|
+
` ⚠ [pyric] rtdb rules NOT reloaded (last-good stays live): ${result.error.message}`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
28
72
|
}, 150);
|
|
29
73
|
};
|
|
30
74
|
|
|
31
|
-
|
|
75
|
+
if (hasFirestoreFile) {
|
|
76
|
+
server.watcher.add(firestoreFile);
|
|
77
|
+
}
|
|
78
|
+
if (hasDatabaseFile) {
|
|
79
|
+
server.watcher.add(databaseFile);
|
|
80
|
+
}
|
|
32
81
|
server.watcher.on('change', onRulesChange);
|
|
33
82
|
return () => {
|
|
34
|
-
|
|
83
|
+
const hasDebounce = debounce !== null;
|
|
84
|
+
if (hasDebounce) {
|
|
85
|
+
clearTimeout(debounce as ReturnType<typeof setTimeout>);
|
|
86
|
+
}
|
|
35
87
|
server.watcher.off('change', onRulesChange);
|
|
36
88
|
};
|
|
37
89
|
}
|
|
@@ -45,10 +45,18 @@ export function createViteModuleContext(): ViteModuleContext {
|
|
|
45
45
|
return { entries, cliRoot: packageRootOf(entries.init) };
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
export interface ViteModuleSwapOptions {
|
|
49
|
+
getAiMode?: () => 'sandbox' | 'production';
|
|
50
|
+
}
|
|
51
|
+
|
|
48
52
|
/** Own the Vite and optimizer forms of the Firebase-module swap. */
|
|
49
|
-
export function createViteModuleSwap(
|
|
53
|
+
export function createViteModuleSwap(
|
|
54
|
+
context: ViteModuleContext,
|
|
55
|
+
options?: ViteModuleSwapOptions,
|
|
56
|
+
): ViteModuleSwap {
|
|
50
57
|
const { entries, cliRoot } = context;
|
|
51
58
|
const pyricRoot = pyricPackageRoot();
|
|
59
|
+
const aiMode = () => options?.getAiMode?.() ?? 'sandbox';
|
|
52
60
|
|
|
53
61
|
const isPyricImporter = (importer: string | undefined): boolean => {
|
|
54
62
|
if (!importer) return false;
|
|
@@ -68,28 +76,72 @@ export function createViteModuleSwap(context: ViteModuleContext): ViteModuleSwap
|
|
|
68
76
|
name: 'pyric-sandbox-optimizer',
|
|
69
77
|
setup(build) {
|
|
70
78
|
build.onResolve({ filter: FIREBASE_SPECIFIER }, (args) => {
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
const isShadowBridgeImporter = args.importer !== undefined && args.importer !== '' &&
|
|
80
|
+
(args.importer.includes('app-ai-passthrough') || args.importer.includes('app-bridge'));
|
|
81
|
+
const isFirebaseAppSpecifier = args.path === 'firebase/app';
|
|
82
|
+
const isBypassedBridgeImport = isShadowBridgeImporter && isFirebaseAppSpecifier;
|
|
83
|
+
if (isBypassedBridgeImport) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const match = FIREBASE_SPECIFIER.exec(args.path);
|
|
88
|
+
const subpath = match !== null && match[1] !== undefined ? match[1] : '';
|
|
89
|
+
const isProductionAiMode = aiMode() === 'production';
|
|
90
|
+
if (isProductionAiMode) {
|
|
91
|
+
const isAiSubpath = subpath === 'ai';
|
|
92
|
+
if (isAiSubpath) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const isAppSubpath = subpath === 'app';
|
|
96
|
+
const passthroughEntry = entries['app-ai-passthrough'];
|
|
97
|
+
const hasPassthroughEntry = passthroughEntry !== undefined;
|
|
98
|
+
const shouldUsePassthroughBridge = isAppSubpath && hasPassthroughEntry;
|
|
99
|
+
if (shouldUsePassthroughBridge) {
|
|
100
|
+
return { path: passthroughEntry };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const isServedSubpath = SERVED_FIREBASE_SUBPATHS.has(subpath);
|
|
105
|
+
if (isServedSubpath) {
|
|
106
|
+
const key = entryKey(subpath);
|
|
107
|
+
const entryPath = entries[key];
|
|
108
|
+
if (entryPath !== undefined) {
|
|
109
|
+
return { path: entryPath };
|
|
110
|
+
}
|
|
74
111
|
}
|
|
75
112
|
return null;
|
|
76
113
|
});
|
|
77
114
|
build.onResolve({ filter: NODE_BUILTIN_RE }, (args) => {
|
|
78
|
-
|
|
79
|
-
|
|
115
|
+
const isOwnedImporter = isOurCode(args.importer);
|
|
116
|
+
if (!isOwnedImporter) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const shimPath = args.path.replace(/^node:/, '');
|
|
120
|
+
return { path: shimPath, namespace: 'pyric-node-shim' };
|
|
121
|
+
});
|
|
122
|
+
build.onLoad({ filter: /.*/, namespace: 'pyric-node-shim' }, (args) => {
|
|
123
|
+
const content = NODE_BUILTIN_SHIMS[args.path];
|
|
124
|
+
if (content !== undefined) {
|
|
125
|
+
return { contents: content, loader: 'js' };
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
80
128
|
});
|
|
81
|
-
build.onLoad({ filter: /.*/, namespace: 'pyric-node-shim' }, (args) => ({
|
|
82
|
-
contents: NODE_BUILTIN_SHIMS[args.path]!,
|
|
83
|
-
loader: 'js',
|
|
84
|
-
}));
|
|
85
129
|
},
|
|
86
130
|
};
|
|
87
131
|
|
|
88
132
|
return {
|
|
89
133
|
config() {
|
|
134
|
+
const excludedModules = [
|
|
135
|
+
...SDK_MODULES,
|
|
136
|
+
'@firebase/app',
|
|
137
|
+
'@firebase/component',
|
|
138
|
+
'@firebase/ai',
|
|
139
|
+
'@firebase/util',
|
|
140
|
+
'@firebase/logger',
|
|
141
|
+
];
|
|
90
142
|
return {
|
|
91
143
|
optimizeDeps: {
|
|
92
|
-
exclude:
|
|
144
|
+
exclude: excludedModules,
|
|
93
145
|
include: ['js-md5', 'js-sha256'],
|
|
94
146
|
esbuildOptions: { plugins: [optimizerMirror] },
|
|
95
147
|
},
|
|
@@ -97,23 +149,71 @@ export function createViteModuleSwap(context: ViteModuleContext): ViteModuleSwap
|
|
|
97
149
|
},
|
|
98
150
|
configResolved(config) {
|
|
99
151
|
const allow = config.server?.fs?.allow;
|
|
100
|
-
|
|
152
|
+
const hasAllowList = allow !== undefined && Array.isArray(allow);
|
|
153
|
+
if (!hasAllowList) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
101
156
|
for (const dir of [pyricRoot, cliRoot]) {
|
|
102
|
-
|
|
157
|
+
const isAlreadyAllowed = allow.includes(dir);
|
|
158
|
+
if (!isAlreadyAllowed) {
|
|
159
|
+
allow.push(dir);
|
|
160
|
+
}
|
|
103
161
|
}
|
|
104
162
|
},
|
|
105
163
|
resolveId(source, importer) {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
164
|
+
const isShadowBridgeImporter = importer !== undefined &&
|
|
165
|
+
(importer.includes('app-ai-passthrough') || importer.includes('app-bridge'));
|
|
166
|
+
const isFirebaseAppSpecifier = source === 'firebase/app';
|
|
167
|
+
const isBypassedBridgeImport = isShadowBridgeImporter && isFirebaseAppSpecifier;
|
|
168
|
+
if (isBypassedBridgeImport) {
|
|
169
|
+
return null;
|
|
110
170
|
}
|
|
111
|
-
|
|
112
|
-
|
|
171
|
+
|
|
172
|
+
const firebaseMatch = FIREBASE_SPECIFIER.exec(source);
|
|
173
|
+
const isFirebaseSpecifier = firebaseMatch !== null;
|
|
174
|
+
if (isFirebaseSpecifier) {
|
|
175
|
+
const subpath = firebaseMatch[1] !== undefined ? firebaseMatch[1] : '';
|
|
176
|
+
const isProductionAiMode = aiMode() === 'production';
|
|
177
|
+
if (isProductionAiMode) {
|
|
178
|
+
const isAiSubpath = subpath === 'ai';
|
|
179
|
+
if (isAiSubpath) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
const isAppSubpath = subpath === 'app';
|
|
183
|
+
const passthroughEntry = entries['app-ai-passthrough'];
|
|
184
|
+
const hasPassthroughEntry = passthroughEntry !== undefined;
|
|
185
|
+
const shouldUsePassthroughBridge = isAppSubpath && hasPassthroughEntry;
|
|
186
|
+
if (shouldUsePassthroughBridge) {
|
|
187
|
+
return passthroughEntry;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const isServedSubpath = SERVED_FIREBASE_SUBPATHS.has(subpath);
|
|
191
|
+
if (isServedSubpath) {
|
|
192
|
+
const key = entryKey(subpath);
|
|
193
|
+
const entryPath = entries[key];
|
|
194
|
+
if (entryPath !== undefined) {
|
|
195
|
+
return entryPath;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const nodeMatch = NODE_BUILTIN_RE.exec(source);
|
|
202
|
+
const isNodeBuiltin = nodeMatch !== null && nodeMatch[2] !== undefined;
|
|
203
|
+
const isOwnedImporter = isOurCode(importer);
|
|
204
|
+
const shouldShimNodeBuiltin = isNodeBuiltin && isOwnedImporter;
|
|
205
|
+
if (shouldShimNodeBuiltin) {
|
|
206
|
+
return NODE_SHIM_PREFIX + nodeMatch[2];
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
113
209
|
},
|
|
114
210
|
load(id) {
|
|
115
|
-
|
|
116
|
-
|
|
211
|
+
const isNodeShim = id.startsWith(NODE_SHIM_PREFIX);
|
|
212
|
+
if (!isNodeShim) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
const specifier = id.slice(NODE_SHIM_PREFIX.length);
|
|
216
|
+
return shimFor(specifier);
|
|
117
217
|
},
|
|
118
218
|
};
|
|
119
219
|
}
|