@pyric/cli 0.1.0-alpha.16 → 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/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.js +9 -7
- 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 +1 -0
- 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.CnoxIle5.js → chess-showcase.kC8dXLKY.js} +1 -1
- package/dist/serve/site-ui/_astro/{example-runtime.R1d96L6-.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.EyI3VYEu.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 +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/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 +9 -7
- package/src/serve/entries/auth.ts +1 -0
- 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.4HeLP_FA.js +0 -109
- package/dist/serve/site-ui/_astro/app.BgSnCR5G.js +0 -1
- package/dist/serve/site-ui/_astro/index.BJiOemMX.js +0 -1
- package/dist/serve/site-ui/_astro/reads.BrKNdKAa.js +0 -1
- package/dist/serve/site-ui/_astro/sandbox-controls.BTb3EbQp.js +0 -1153
|
@@ -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
|
}
|
package/src/serve/vite-plugin.ts
CHANGED
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
* to the in-page sandbox (single-tab, ephemeral).
|
|
40
40
|
*/
|
|
41
41
|
import type { Plugin, UserConfig } from 'vite';
|
|
42
|
+
import { existsSync } from 'node:fs';
|
|
43
|
+
import { dirname, join, resolve } from 'node:path';
|
|
42
44
|
import { createViteWorkerRuntime } from './vite-worker-runtime.js';
|
|
43
45
|
import type { PyricAiOptions } from './vite-ai-config.js';
|
|
44
46
|
import type { PyricRuntimeChipOption } from './runtime/chip-config.js';
|
|
@@ -157,6 +159,29 @@ function resolveFunctionsOptions(
|
|
|
157
159
|
return {};
|
|
158
160
|
}
|
|
159
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Resolves the Firebase project root directory from Vite's server root. In
|
|
164
|
+
* split-directory or full-stack monorepo layouts where Vite operates inside a
|
|
165
|
+
* subdirectory (e.g. `/web` or `/frontend`) while hosting and security rules
|
|
166
|
+
* configuration (`firebase.json`) resides in an ancestor workspace directory,
|
|
167
|
+
* this ascends to locate the authoritative configuration root.
|
|
168
|
+
*/
|
|
169
|
+
function resolveFirebaseProjectDir(defaultRoot: string, explicitRoot?: string): string {
|
|
170
|
+
const hasExplicitRoot = explicitRoot !== undefined && explicitRoot.length > 0;
|
|
171
|
+
if (hasExplicitRoot) return explicitRoot as string;
|
|
172
|
+
let current = resolve(defaultRoot);
|
|
173
|
+
while (true) {
|
|
174
|
+
const candidateConfig = join(current, 'firebase.json');
|
|
175
|
+
const configExists = existsSync(candidateConfig);
|
|
176
|
+
if (configExists) return current;
|
|
177
|
+
const parent = dirname(current);
|
|
178
|
+
const isRootOfFilesystem = parent === current;
|
|
179
|
+
if (isRootOfFilesystem) break;
|
|
180
|
+
current = parent;
|
|
181
|
+
}
|
|
182
|
+
return defaultRoot;
|
|
183
|
+
}
|
|
184
|
+
|
|
160
185
|
/**
|
|
161
186
|
* The dev-only Vite plugin. Add to `vite.config`:
|
|
162
187
|
*
|
|
@@ -165,7 +190,6 @@ function resolveFunctionsOptions(
|
|
|
165
190
|
*/
|
|
166
191
|
export function pyric(options: PyricOptions = {}): Plugin {
|
|
167
192
|
const moduleContext = createViteModuleContext();
|
|
168
|
-
const moduleSwap = createViteModuleSwap(moduleContext);
|
|
169
193
|
const { entries, cliRoot } = moduleContext;
|
|
170
194
|
const workerRuntime = createViteWorkerRuntime();
|
|
171
195
|
const studioEnabled = options.ui !== false;
|
|
@@ -176,6 +200,9 @@ export function pyric(options: PyricOptions = {}): Plugin {
|
|
|
176
200
|
workerRuntime,
|
|
177
201
|
};
|
|
178
202
|
const pageRuntime = createVitePageRuntime(pageRuntimeInput);
|
|
203
|
+
const moduleSwap = createViteModuleSwap(moduleContext, {
|
|
204
|
+
getAiMode: () => pageRuntime.ai().mode,
|
|
205
|
+
});
|
|
179
206
|
|
|
180
207
|
// Normalize the public bridge shorthand once. The active generation owns the
|
|
181
208
|
// bridge/session attachment and routes the peer through the SharedWorker.
|
|
@@ -197,10 +224,21 @@ export function pyric(options: PyricOptions = {}): Plugin {
|
|
|
197
224
|
enforce: 'pre',
|
|
198
225
|
|
|
199
226
|
config(config, env) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
227
|
+
const moduleConfig = moduleSwap.config();
|
|
228
|
+
const pageConfig = pageRuntime.config(config, env);
|
|
229
|
+
const serverWatchConfig: UserConfig = {
|
|
230
|
+
server: {
|
|
231
|
+
watch: {
|
|
232
|
+
ignored: ['**/.pyric/**'],
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
const finalizedConfig: UserConfig = {
|
|
237
|
+
...moduleConfig,
|
|
238
|
+
...pageConfig,
|
|
239
|
+
...serverWatchConfig,
|
|
240
|
+
};
|
|
241
|
+
return finalizedConfig;
|
|
204
242
|
},
|
|
205
243
|
|
|
206
244
|
configResolved(resolved) {
|
|
@@ -220,7 +258,7 @@ export function pyric(options: PyricOptions = {}): Plugin {
|
|
|
220
258
|
activeGeneration = null;
|
|
221
259
|
await priorGeneration?.close();
|
|
222
260
|
|
|
223
|
-
const projectDir =
|
|
261
|
+
const projectDir = resolveFirebaseProjectDir(server.config.root, options.root);
|
|
224
262
|
const uiEnabled = options.ui ?? true;
|
|
225
263
|
const functionsOptions = resolveFunctionsOptions(options.functions);
|
|
226
264
|
const ai = pageRuntime.ai();
|
|
@@ -134,7 +134,7 @@ export async function createViteSandboxGeneration(
|
|
|
134
134
|
const rulesConfig = dependencies.resolveRulesConfig(cwd, options.rules, firebaseConfig);
|
|
135
135
|
|
|
136
136
|
try {
|
|
137
|
-
const epochSalt = viteWorkerEpochSalt(cwd, ai.engineWire);
|
|
137
|
+
const epochSalt = viteWorkerEpochSalt(cwd, ai.engineWire, ai.mode);
|
|
138
138
|
await dependencies.prepareWorker(workerRuntime, epochSalt);
|
|
139
139
|
} catch (error) {
|
|
140
140
|
server.config.logger.warn(
|