@pyric/cli 0.1.0-alpha.11 → 0.1.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use-browser.js +1 -1
- package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
- package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use.js +2 -2
- package/dist/conformance/.generated/can-i-use.js.map +1 -1
- package/dist/serve/docs-ui/docs/_rhythm/index.html +1 -1
- package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +1 -1
- package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +1 -1
- package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +1 -1
- package/dist/serve/docs-ui/docs/ai-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/api-reference/index.html +2 -2
- package/dist/serve/docs-ui/docs/api-reference.md +1 -1
- package/dist/serve/docs-ui/docs/app-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/auth-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/ai-logic/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/authentication/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +1 -1
- package/dist/serve/docs-ui/docs/build/realtime-database/index.html +1 -1
- package/dist/serve/docs-ui/docs/conformance-scores/index.html +1 -1
- package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/database-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/firestore-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +1 -1
- package/dist/serve/docs-ui/docs/get-started/start-building/index.html +1 -1
- package/dist/serve/docs-ui/docs/index.json +200 -25
- package/dist/serve/docs-ui/docs/messaging-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +1 -1
- package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +1 -1
- package/dist/serve/docs-ui/docs/overview/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-admin-messaging-reference-api/index.html +916 -0
- package/dist/serve/docs-ui/docs/pyric-admin-messaging-reference-api.md +706 -0
- package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ai-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-auth-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api/index.html +131 -66
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api.md +130 -65
- package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-rules-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api/index.html +37 -14
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api.md +28 -8
- package/dist/serve/docs-ui/docs/pyric-storage-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api/index.html +1 -1
- package/dist/serve/docs-ui/docs/rules-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +1 -1
- package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +1 -1
- package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +1 -1
- package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +1 -1
- package/dist/serve/docs-ui/docs/storage-compat/index.html +1 -1
- package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +1 -1
- package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +1 -1
- package/dist/serve/docs-ui/llms.txt +1 -1
- package/dist/serve/worker/host/core.js +1 -1
- package/dist/serve/worker/host/core.js.map +1 -1
- package/dist/serve/worker/host/firestore-writes.d.ts.map +1 -1
- package/dist/serve/worker/host/firestore-writes.js +3 -2
- package/dist/serve/worker/host/firestore-writes.js.map +1 -1
- package/dist/serve/worker/index.d.ts +2 -1
- package/dist/serve/worker/index.d.ts.map +1 -1
- package/dist/serve/worker/index.js +2 -1
- package/dist/serve/worker/index.js.map +1 -1
- package/dist/serve/worker/protocol.js +2 -2
- package/dist/serve/worker/protocol.js.map +1 -1
- package/package.json +5 -4
- package/src/assurance/.generated/conformance-verdicts.ts +1090 -0
- package/src/assurance/attachment.ts +211 -0
- package/src/assurance/browser.ts +80 -0
- package/src/assurance/campaign.ts +496 -0
- package/src/assurance/capabilities.ts +446 -0
- package/src/assurance/cases.ts +43 -0
- package/src/assurance/index.ts +75 -0
- package/src/assurance/runner.ts +885 -0
- package/src/assurance/tool-names.ts +15 -0
- package/src/assurance/tools.ts +830 -0
- package/src/assurance/types.ts +352 -0
- package/src/assurance/validation.ts +434 -0
- package/src/bridge/client/bridge.ts +550 -0
- package/src/bridge/client/dispatch.ts +137 -0
- package/src/bridge/client.ts +45 -0
- package/src/bridge/protocol.ts +351 -0
- package/src/bridge/server/audit.ts +53 -0
- package/src/bridge/server/bridge.ts +597 -0
- package/src/bridge/server/headless.ts +160 -0
- package/src/bridge/server/json-schema-to-zod.ts +108 -0
- package/src/bridge/server/local-bridge.ts +66 -0
- package/src/bridge/server/logger.ts +50 -0
- package/src/bridge/server/mcp-contract.ts +93 -0
- package/src/bridge/server/mcp.ts +129 -0
- package/src/bridge/server/peer.ts +232 -0
- package/src/bridge/server/standalone.ts +347 -0
- package/src/bridge/server/tool-metadata.ts +99 -0
- package/src/bridge/server.ts +28 -0
- package/src/cli/can-i-use.ts +50 -0
- package/src/cli/cli.test.ts +493 -0
- package/src/cli/database-rules.ts +329 -0
- package/src/cli/dev-runner.ts +282 -0
- package/src/cli/firebase-json.ts +100 -0
- package/src/cli/firestore-indexes.ts +70 -0
- package/src/cli/index.ts +425 -0
- package/src/cli/init.ts +260 -0
- package/src/cli/mcp-proxy.ts +196 -0
- package/src/cli/parse-args.ts +80 -0
- package/src/cli/rules.ts +259 -0
- package/src/cli/scope.ts +67 -0
- package/src/cli/serve.ts +996 -0
- package/src/cli/service-commands.ts +73 -0
- package/src/cli/snapshot.ts +164 -0
- package/src/cli/storage-rules.ts +172 -0
- package/src/cli/verify.ts +416 -0
- package/src/conformance/.generated/can-i-use-browser.ts +113 -0
- package/src/conformance/.generated/can-i-use.ts +117 -0
- package/src/conformance/.generated/conformance-docs.ts +14 -0
- package/src/conformance/browser.ts +24 -0
- package/src/conformance/can-i-use-tool.ts +51 -0
- package/src/conformance/can-i-use.ts +18 -0
- package/src/conformance/docs.ts +8 -0
- package/src/conformance/index.ts +20 -0
- package/src/conformance/tools.ts +16 -0
- package/src/credentials/core/memoize-ttl.ts +142 -0
- package/src/credentials/core/types.ts +10 -0
- package/src/credentials/node/from-adc.ts +96 -0
- package/src/credentials/node/from-service-account.ts +133 -0
- package/src/credentials/node/index.ts +6 -0
- package/src/discover/concurrency.ts +127 -0
- package/src/discover/crawler-adapter.ts +142 -0
- package/src/discover/crawler.ts +1127 -0
- package/src/discover/credential-free.ts +27 -0
- package/src/discover/findCollectionGroup.ts +131 -0
- package/src/discover/firestore-source.ts +59 -0
- package/src/discover/index.ts +5 -0
- package/src/discover/merge.ts +523 -0
- package/src/discover/session.ts +402 -0
- package/src/discover/tools.ts +201 -0
- package/src/discover/types.ts +187 -0
- package/src/discover/wire.ts +324 -0
- package/src/functions-rtdb/child.ts +382 -0
- package/src/functions-rtdb/delivery.ts +7 -0
- package/src/functions-rtdb/discovery.ts +136 -0
- package/src/functions-rtdb/event.ts +64 -0
- package/src/functions-rtdb/execution.ts +111 -0
- package/src/functions-rtdb/in-memory-delivery.ts +40 -0
- package/src/functions-rtdb/project.ts +74 -0
- package/src/functions-rtdb/projection.ts +104 -0
- package/src/functions-rtdb/reference-pattern.ts +20 -0
- package/src/functions-rtdb/remote-delivery.ts +23 -0
- package/src/pkg-version.ts +49 -0
- package/src/register/esm-exports.ts +63 -0
- package/src/register/hooks.ts +30 -0
- package/src/register/index.ts +150 -0
- package/src/register/mapping.ts +33 -0
- package/src/remote/index.ts +1050 -0
- package/src/rtdb/crawl-snapshot.ts +118 -0
- package/src/rtdb/inspection.ts +137 -0
- package/src/rtdb/load-rules-document.ts +56 -0
- package/src/rtdb/rules-generation-tool.ts +38 -0
- package/src/rtdb/rules-json.ts +29 -0
- package/src/serve/activity-guard.ts +29 -0
- package/src/serve/activity-route.ts +164 -0
- package/src/serve/activity-warning.ts +26 -0
- package/src/serve/bridge-mount.ts +200 -0
- package/src/serve/bundler.ts +493 -0
- package/src/serve/capture-store.ts +65 -0
- package/src/serve/discovery.ts +199 -0
- package/src/serve/entries/ai.ts +292 -0
- package/src/serve/entries/app-backend.ts +4 -0
- package/src/serve/entries/app-client.ts +26 -0
- package/src/serve/entries/app-session-store.ts +47 -0
- package/src/serve/entries/app.ts +11 -0
- package/src/serve/entries/auth-helper-core.ts +181 -0
- package/src/serve/entries/auth-helper-dom.ts +134 -0
- package/src/serve/entries/auth-helper-runtime.ts +20 -0
- package/src/serve/entries/auth.ts +255 -0
- package/src/serve/entries/bridge-url.ts +31 -0
- package/src/serve/entries/database.ts +129 -0
- package/src/serve/entries/firestore.ts +232 -0
- package/src/serve/entries/init.ts +46 -0
- package/src/serve/entries/keepalive.ts +46 -0
- package/src/serve/entries/messaging-sw.ts +75 -0
- package/src/serve/entries/messaging.ts +96 -0
- package/src/serve/entries/runtime.ts +540 -0
- package/src/serve/entries/session-store.ts +97 -0
- package/src/serve/entries/storage.ts +92 -0
- package/src/serve/entries/tab-sync-wiring.ts +274 -0
- package/src/serve/entries/worker-runtime.ts +75 -0
- package/src/serve/init-payload.ts +42 -0
- package/src/serve/namespace.ts +675 -0
- package/src/serve/open-browser.ts +68 -0
- package/src/serve/rules.ts +272 -0
- package/src/serve/sandbox-marker.ts +31 -0
- package/src/serve/server.ts +428 -0
- package/src/serve/standalone-assets.ts +180 -0
- package/src/serve/state-store.ts +166 -0
- package/src/serve/studio/disk-project-store.ts +185 -0
- package/src/serve/studio/disk-workspace.ts +162 -0
- package/src/serve/studio/index.ts +20 -0
- package/src/serve/studio/routes.ts +237 -0
- package/src/serve/studio/store-types.ts +48 -0
- package/src/serve/studio/studio-storage.test.ts +289 -0
- package/src/serve/vite-plugin.ts +1102 -0
- package/src/serve/worker/activity-bootstrap.ts +24 -0
- package/src/serve/worker/client/admin-firestore.ts +38 -0
- package/src/serve/worker/client/ai.ts +124 -0
- package/src/serve/worker/client/auth.ts +489 -0
- package/src/serve/worker/client/connection.ts +202 -0
- package/src/serve/worker/client/core.ts +350 -0
- package/src/serve/worker/client/disconnect.ts +45 -0
- package/src/serve/worker/client/firestore-reads.ts +181 -0
- package/src/serve/worker/client/firestore-refs.ts +226 -0
- package/src/serve/worker/client/firestore-writes.ts +232 -0
- package/src/serve/worker/client/handles.ts +91 -0
- package/src/serve/worker/client/messaging.ts +119 -0
- package/src/serve/worker/client/presence.ts +174 -0
- package/src/serve/worker/client/rtdb.ts +311 -0
- package/src/serve/worker/client/rules.ts +63 -0
- package/src/serve/worker/client/service-worker-connection.ts +59 -0
- package/src/serve/worker/client/snapshots.ts +86 -0
- package/src/serve/worker/client/storage.ts +195 -0
- package/src/serve/worker/client/studio.ts +88 -0
- package/src/serve/worker/client.ts +57 -0
- package/src/serve/worker/durable-persistence.ts +137 -0
- package/src/serve/worker/entry.ts +179 -0
- package/src/serve/worker/host/admin-firestore.ts +88 -0
- package/src/serve/worker/host/connection.ts +179 -0
- package/src/serve/worker/host/core.ts +387 -0
- package/src/serve/worker/host/dispatch.ts +316 -0
- package/src/serve/worker/host/firestore-reads.ts +117 -0
- package/src/serve/worker/host/firestore-writes.ts +456 -0
- package/src/serve/worker/host/presence.ts +312 -0
- package/src/serve/worker/host/rtdb.ts +136 -0
- package/src/serve/worker/host/rules.ts +128 -0
- package/src/serve/worker/host/storage.ts +312 -0
- package/src/serve/worker/host/studio.ts +75 -0
- package/src/serve/worker/host/subscriptions.ts +238 -0
- package/src/serve/worker/host-ai.ts +165 -0
- package/src/serve/worker/host-auth.ts +469 -0
- package/src/serve/worker/host-context.ts +273 -0
- package/src/serve/worker/host-events.ts +94 -0
- package/src/serve/worker/host-messaging.ts +240 -0
- package/src/serve/worker/host.ts +47 -0
- package/src/serve/worker/index.ts +196 -0
- package/src/serve/worker/presence-timing.ts +15 -0
- package/src/serve/worker/protocol.ts +1112 -0
- package/src/serve/worker/serve-init.ts +606 -0
- package/src/serve/worker/service-worker-channel.ts +33 -0
- package/src/serve/worker/service-worker-relay.ts +86 -0
- package/src/serve/writer-lock.ts +53 -0
- package/src/verify/cases.ts +233 -0
- package/src/verify/fixture.ts +258 -0
- package/src/verify/index.ts +519 -0
- package/src/verify/tools.ts +108 -0
- package/src/version/compat-target.ts +17 -0
- package/src/vite.ts +17 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api/index.html +0 -31
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api.md +0 -29
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { getAuth, sandbox as authSandbox } from "pyric/auth";
|
|
2
|
+
import {
|
|
3
|
+
getAdminDatabase,
|
|
4
|
+
sandbox as rtdbSandbox,
|
|
5
|
+
} from "pyric/database";
|
|
6
|
+
import type { Sandbox } from "pyric/sandbox";
|
|
7
|
+
import {
|
|
8
|
+
ASSURANCE_TARGET_SCHEMA,
|
|
9
|
+
AssuranceInputError,
|
|
10
|
+
type AssuranceAttachmentInventory,
|
|
11
|
+
type AssuranceAttachmentSource,
|
|
12
|
+
type AssuranceCoverageGap,
|
|
13
|
+
type LocalFirebaseTarget,
|
|
14
|
+
} from "./types.js";
|
|
15
|
+
|
|
16
|
+
export interface AssuranceAttachmentInput {
|
|
17
|
+
url: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface AssuranceAttachment {
|
|
21
|
+
target: LocalFirebaseTarget;
|
|
22
|
+
source: AssuranceAttachmentSource;
|
|
23
|
+
inventory: AssuranceAttachmentInventory;
|
|
24
|
+
coverageGaps: AssuranceCoverageGap[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type AssuranceAttachmentProvider = (
|
|
28
|
+
input: AssuranceAttachmentInput,
|
|
29
|
+
) => Promise<AssuranceAttachment>;
|
|
30
|
+
|
|
31
|
+
export interface SandboxAttachmentProviderOptions {
|
|
32
|
+
origin?: string;
|
|
33
|
+
fetchImpl?: typeof fetch;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type {
|
|
37
|
+
AssuranceAttachmentInventory,
|
|
38
|
+
AssuranceAttachmentSource,
|
|
39
|
+
AssuranceCoverageGap,
|
|
40
|
+
} from "./types.js";
|
|
41
|
+
|
|
42
|
+
interface PyricInitPayload {
|
|
43
|
+
rules?: string | null;
|
|
44
|
+
databaseRules?: { rules: Record<string, unknown> } | null;
|
|
45
|
+
bridgeUrl?: string | null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function isLoopbackHostname(hostname: string): boolean {
|
|
49
|
+
const normalized = hostname.toLowerCase().replace(/\.$/, "");
|
|
50
|
+
if (
|
|
51
|
+
normalized === "localhost" ||
|
|
52
|
+
normalized === "[::1]" ||
|
|
53
|
+
normalized === "::1"
|
|
54
|
+
)
|
|
55
|
+
return true;
|
|
56
|
+
const parts = normalized.split(".");
|
|
57
|
+
return (
|
|
58
|
+
parts.length === 4 &&
|
|
59
|
+
parts[0] === "127" &&
|
|
60
|
+
parts.every((part) => /^\d{1,3}$/.test(part) && Number(part) <= 255)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function parseLocalOrigin(rawUrl: string, runtimeOrigin: string): URL {
|
|
65
|
+
let requested: URL;
|
|
66
|
+
let current: URL;
|
|
67
|
+
try {
|
|
68
|
+
requested = new URL(rawUrl);
|
|
69
|
+
current = new URL(runtimeOrigin);
|
|
70
|
+
} catch {
|
|
71
|
+
throw new AssuranceInputError(
|
|
72
|
+
`'${rawUrl}' is not a valid absolute Pyric URL.`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (
|
|
76
|
+
(requested.protocol !== "http:" && requested.protocol !== "https:") ||
|
|
77
|
+
!isLoopbackHostname(requested.hostname) ||
|
|
78
|
+
requested.username ||
|
|
79
|
+
requested.password
|
|
80
|
+
) {
|
|
81
|
+
throw new AssuranceInputError(
|
|
82
|
+
"firebase_assurance_attach accepts only credential-free HTTP(S) loopback URLs.",
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
if (requested.origin !== current.origin) {
|
|
86
|
+
throw new AssuranceInputError(
|
|
87
|
+
`attachment URL origin '${requested.origin}' does not match the connected Pyric sandbox origin '${current.origin}'.`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
return requested;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function hasRtdbState(value: unknown): boolean {
|
|
94
|
+
if (value === null || value === undefined) return false;
|
|
95
|
+
if (typeof value !== "object") return true;
|
|
96
|
+
return Object.keys(value as Record<string, unknown>).length > 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Clone the sandbox currently hosting the connected bridge peer. The URL is an
|
|
101
|
+
* origin assertion and source for explicit rules metadata; no arbitrary host is
|
|
102
|
+
* contacted and the returned campaign target itself keeps networking forbidden.
|
|
103
|
+
*/
|
|
104
|
+
export function createSandboxAttachmentProvider(
|
|
105
|
+
sandbox: Sandbox,
|
|
106
|
+
options: SandboxAttachmentProviderOptions = {},
|
|
107
|
+
): AssuranceAttachmentProvider {
|
|
108
|
+
return async ({ url }) => {
|
|
109
|
+
const runtimeOrigin =
|
|
110
|
+
options.origin ??
|
|
111
|
+
(typeof globalThis.location !== "undefined"
|
|
112
|
+
? globalThis.location.origin
|
|
113
|
+
: "");
|
|
114
|
+
if (!runtimeOrigin) {
|
|
115
|
+
throw new AssuranceInputError(
|
|
116
|
+
"localhost attachment is available only inside a served Pyric sandbox peer.",
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
const requested = parseLocalOrigin(url, runtimeOrigin);
|
|
120
|
+
const origin = requested.origin;
|
|
121
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
122
|
+
if (!fetchImpl) {
|
|
123
|
+
throw new AssuranceInputError(
|
|
124
|
+
"localhost attachment requires the Fetch API.",
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const response = await fetchImpl(`${origin}/__pyric/init.json`, {
|
|
129
|
+
redirect: "error",
|
|
130
|
+
});
|
|
131
|
+
if (!response.ok) {
|
|
132
|
+
throw new AssuranceInputError(
|
|
133
|
+
`Pyric initialization metadata returned HTTP ${response.status} at '${origin}'.`,
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
const payload = (await response.json()) as PyricInitPayload;
|
|
137
|
+
if (!payload || typeof payload !== "object" || !payload.bridgeUrl) {
|
|
138
|
+
throw new AssuranceInputError(
|
|
139
|
+
`No active Pyric bridge was advertised by '${origin}/__pyric/init.json'.`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const snapshot = sandbox.snapshot();
|
|
144
|
+
const rtdbState = rtdbSandbox.snapshotState(getAdminDatabase(sandbox));
|
|
145
|
+
const authUsers = authSandbox.exportUsers(getAuth(sandbox));
|
|
146
|
+
const rules: LocalFirebaseTarget["rules"] = {};
|
|
147
|
+
if (typeof payload.rules === "string" && payload.rules.trim()) {
|
|
148
|
+
rules.firestore = payload.rules;
|
|
149
|
+
}
|
|
150
|
+
if (payload.databaseRules?.rules) rules.rtdb = payload.databaseRules;
|
|
151
|
+
|
|
152
|
+
const coverageGaps: AssuranceCoverageGap[] = [
|
|
153
|
+
{
|
|
154
|
+
service: "storage",
|
|
155
|
+
code: "storage-attachment-unavailable",
|
|
156
|
+
reason:
|
|
157
|
+
"The served runtime does not yet expose Storage rules or complete object enumeration; provide explicit Storage rules and objects in a fixture campaign.",
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
if (!rules.firestore && Object.keys(snapshot.firestore).length > 0) {
|
|
161
|
+
coverageGaps.push({
|
|
162
|
+
service: "firestore",
|
|
163
|
+
code: "firestore-rules-unavailable",
|
|
164
|
+
reason:
|
|
165
|
+
"The running sandbox has Firestore data but no explicit project rules source.",
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (!rules.rtdb && hasRtdbState(rtdbState)) {
|
|
169
|
+
coverageGaps.push({
|
|
170
|
+
service: "rtdb",
|
|
171
|
+
code: "rtdb-rules-unavailable",
|
|
172
|
+
reason:
|
|
173
|
+
"The running sandbox has RTDB data but no explicit database rules source.",
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
target: {
|
|
179
|
+
schema: ASSURANCE_TARGET_SCHEMA,
|
|
180
|
+
network: "forbid",
|
|
181
|
+
rules,
|
|
182
|
+
state: {
|
|
183
|
+
firestore: snapshot.firestore,
|
|
184
|
+
...(rules.rtdb || hasRtdbState(rtdbState) ? { rtdb: rtdbState } : {}),
|
|
185
|
+
auth: {
|
|
186
|
+
users: authUsers.map((user) => ({
|
|
187
|
+
uid: user.uid,
|
|
188
|
+
email: user.email,
|
|
189
|
+
password: user.password,
|
|
190
|
+
...(user.customClaims ? { customClaims: user.customClaims } : {}),
|
|
191
|
+
})),
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
source: {
|
|
196
|
+
requestedUrl: url,
|
|
197
|
+
origin,
|
|
198
|
+
transport: "same-origin-shared-worker",
|
|
199
|
+
readOnly: true,
|
|
200
|
+
studioUrl: `${origin}/__pyric/ui/assurance`,
|
|
201
|
+
},
|
|
202
|
+
inventory: {
|
|
203
|
+
firestoreDocuments: Object.keys(snapshot.firestore).length,
|
|
204
|
+
rtdbPresent: hasRtdbState(rtdbState),
|
|
205
|
+
authUsers: authUsers.length,
|
|
206
|
+
storageObjects: 0,
|
|
207
|
+
},
|
|
208
|
+
coverageGaps,
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { AssuranceVisualizationSnapshot } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export const ASSURANCE_BROWSER_EVENT = "pyric:assurance-campaign";
|
|
4
|
+
export const ASSURANCE_BROADCAST_CHANNEL = "pyric-assurance-v1";
|
|
5
|
+
|
|
6
|
+
const listeners = new Set<(snapshot: AssuranceVisualizationSnapshot) => void>();
|
|
7
|
+
let installed = false;
|
|
8
|
+
let channel: BroadcastChannel | undefined;
|
|
9
|
+
|
|
10
|
+
function receive(snapshot: AssuranceVisualizationSnapshot): void {
|
|
11
|
+
for (const listener of listeners) listener(snapshot);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isSnapshot(value: unknown): value is AssuranceVisualizationSnapshot {
|
|
15
|
+
return (
|
|
16
|
+
!!value &&
|
|
17
|
+
typeof value === "object" &&
|
|
18
|
+
(value as { schema?: unknown }).schema ===
|
|
19
|
+
"pyric.assurance.visualization.v1" &&
|
|
20
|
+
typeof (value as { campaignId?: unknown }).campaignId === "string"
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function installBrowserReceivers(): void {
|
|
25
|
+
if (installed || typeof document === "undefined") return;
|
|
26
|
+
installed = true;
|
|
27
|
+
globalThis.addEventListener(ASSURANCE_BROWSER_EVENT, (event) => {
|
|
28
|
+
const detail = (event as CustomEvent<unknown>).detail;
|
|
29
|
+
if (isSnapshot(detail)) receive(detail);
|
|
30
|
+
});
|
|
31
|
+
try {
|
|
32
|
+
channel = new BroadcastChannel(ASSURANCE_BROADCAST_CHANNEL);
|
|
33
|
+
channel.onmessage = (event) => {
|
|
34
|
+
if (isSnapshot(event.data)) receive(event.data);
|
|
35
|
+
};
|
|
36
|
+
} catch {
|
|
37
|
+
// BroadcastChannel is optional in constrained browser contexts.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function subscribeAssuranceVisualizations(
|
|
42
|
+
listener: (snapshot: AssuranceVisualizationSnapshot) => void,
|
|
43
|
+
): () => void {
|
|
44
|
+
installBrowserReceivers();
|
|
45
|
+
listeners.add(listener);
|
|
46
|
+
return () => listeners.delete(listener);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function publishAssuranceVisualization(
|
|
50
|
+
snapshot: AssuranceVisualizationSnapshot,
|
|
51
|
+
): void {
|
|
52
|
+
receive(snapshot);
|
|
53
|
+
const globalKind =
|
|
54
|
+
(globalThis as { constructor?: { name?: string } }).constructor?.name ?? "";
|
|
55
|
+
const isBrowserWorker = globalKind.endsWith("WorkerGlobalScope");
|
|
56
|
+
if (typeof document !== "undefined") {
|
|
57
|
+
try {
|
|
58
|
+
globalThis.dispatchEvent(
|
|
59
|
+
new CustomEvent<AssuranceVisualizationSnapshot>(
|
|
60
|
+
ASSURANCE_BROWSER_EVENT,
|
|
61
|
+
{
|
|
62
|
+
detail: snapshot,
|
|
63
|
+
},
|
|
64
|
+
),
|
|
65
|
+
);
|
|
66
|
+
} catch {
|
|
67
|
+
// Visualization delivery is observational; campaign execution already succeeded.
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (typeof document === "undefined" && !isBrowserWorker) return;
|
|
71
|
+
try {
|
|
72
|
+
const target = channel ?? new BroadcastChannel(ASSURANCE_BROADCAST_CHANNEL);
|
|
73
|
+
target.postMessage(snapshot);
|
|
74
|
+
if (target !== channel) target.close();
|
|
75
|
+
} catch {
|
|
76
|
+
// BroadcastChannel is optional (SSR and constrained browser contexts).
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export type { AssuranceVisualizationSnapshot } from "./types.js";
|