import type { DeviceKey } from "./with-assertion.js"; /** Result shape shared by all PostgREST builder executions. */ type PgResult = { data: unknown; error: { message: string; } | null; }; /** * Structural subset of `SupabaseClient` used by the adapter. Any real * `@supabase/supabase-js` client satisfies this — the dependency itself * is deliberately never imported. * * The builder-returning methods are typed `unknown` on purpose: comparing * structurally against supabase-js's deeply generic PostgrestFilterBuilder * blows TypeScript's instantiation depth (TS2589). The implementation * casts to the internal {@linkcode QueryChain} shape instead. */ export interface SupabaseLikeClient { from(table: string): { insert(row: Record): PromiseLike; upsert(row: Record): PromiseLike; delete(): unknown; select(columns?: string): unknown; update(values: Record): unknown; }; } /** Options for {@linkcode createSupabaseAdapter}. */ export type SupabaseAdapterOptions = { /** Device-keys table name. Default `"app_attest_devices"`. */ devicesTable?: string; /** Challenges table name. Default `"app_attest_challenges"`. */ challengesTable?: string; /** Challenge time-to-live in seconds. Default `60`. */ challengeTtlSeconds?: number; }; /** Storage callbacks + challenge lifecycle returned by {@linkcode createSupabaseAdapter}. */ export type SupabaseAdapter = { issueChallenge(purpose: "attestation" | "assertion"): Promise<{ challenge: Uint8Array; challengeBase64: string; expiresAt: Date; }>; /** * Atomically consume a challenge (single-use `DELETE ... RETURNING`). * * `purpose` defaults to `"attestation"` — the shape `withAttestation` * expects when the adapter is spread into its options. A challenge whose * stored purpose differs from the requested one is NOT consumed and this * resolves `false`, exactly like an unknown or expired challenge. Pass * `"assertion"` explicitly to consume assertion-freshness challenges. */ consumeChallenge(challenge: Uint8Array, purpose?: "attestation" | "assertion"): Promise; storeDeviceKey(row: { deviceId: string; publicKeyPem: string; signCount: number; receipt: Uint8Array; }): Promise; getDeviceKey(deviceId: string): Promise; commitSignCount(deviceId: string, newSignCount: number): Promise; }; /** * Create ready-made Supabase-backed callbacks for the * {@linkcode withAttestation} / {@linkcode withAssertion} middleware. * * Spread into the middleware options: * `withAttestation({ appId, ...adapter }, handler)` and * `withAssertion({ appId, ...adapter }, handler)`. * * Schema: see `sql/app_attest.sql` in this package. */ export declare function createSupabaseAdapter(client: SupabaseLikeClient, options?: SupabaseAdapterOptions): SupabaseAdapter; export {};