/** * Realtime subscribe-token mint endpoint. * * `GET /_agent-native/realtime-token` — the one Netlify request per page load * that the hosted Realtime Gateway path needs. The SSR HTML/`.data` shell is a * single impersonal, CDN-cached document (`guard:ssr-cache-shell`), so a * per-visitor token cannot be baked into the page; the client mints it here * after load. Same-origin + session-gated; sessionless requests get 401. * * The signed token binds this app's Builder project id (the gateway channel) * and carries the app's own end-user identity (`owner` = session email, `orgId` * = framework org) — the exact tuple `recordChange` stamps onto `sync_events` * and the gateway feeds to `canSeeChangeForUser`. It is signed with the app's * per-project HMAC secret, injected as a reserved env var at provision time. */ export declare const REALTIME_HMAC_SECRET_ENV = "AGENT_NATIVE_REALTIME_HMAC_SECRET"; export declare function getRealtimeSigningSecret(): string | undefined; /** * The channel this app actually mints against: the pipeline's injected pair, * or the one it registered for itself. * * The discriminator is the whole point and it has exactly one correct form: * self-register only when NEITHER half of the injected pair is present. Either * half alone means the hosting pipeline owns this app and already gave the * gateway its database, so the fix for the missing half is a redeploy, not a * second `rt_` channel tailing a database Builder already holds. Gating on the * project id alone is not enough — `resolveBuilderBranchProjectId()` returns * `""` for an UNREADABLE settings row as well as an absent one * (builder-browser.ts), so one Neon blip would register a genuine pipeline * app's database under a duplicate channel. * * This lives here because the mint is not the only caller: the public * `/_agent-native/health` probe resolves it too (and registers on a miss), and * a probe that used HALF the discriminator would do exactly that on one * anonymous curl. `gateway-access-check.ts` applies the same rule against the * SYNC, env-only project id — it runs without request context — so it spells * it out rather than calling this. * * Callers must supply request context where they have it: the scoped-secret * fallback inside `resolveBuilderBranchProjectId` reads the request-context * ALS, and without it only env vars resolve. * * Rejects rather than swallowing: "no channel" and "could not find out" are * different answers, and `/_agent-native/health` reports them as different * fields. Callers that owe a client a status code catch it themselves. */ export declare function resolveActiveRealtimeChannel(): Promise<{ projectId: string; secret: string; } | null>; export declare function createRealtimeTokenHandler(): import("h3").EventHandlerWithFetch>;