import { Gateway } from '../config'; export interface GraphQLFetchOptions { /** Gateway to target */ gateway: Gateway; /** GraphQL query / mutation string */ query: string; /** Variables for the operation */ variables?: Record; /** Operation name (optional, helps with debugging) */ operationName?: string; /** Override auth token (if not provided, reads from profile storage) */ authToken?: string; /** * Include workspace token in X-Workspace-Authorization header. * For `gateway: "workspace"`, this defaults to `true` (auto-attach) unless explicitly set to `false`. * Pass `true` to auto-read from profile storage, or pass the token string directly. */ workspaceToken?: boolean | string; /** * Include workspace ID in x-workspace-id header. * Pass `true` to auto-read from profile context storage, or pass the workspace ID string directly. * This is the "context workspace" - the user's current working context. * For "target workspace" (e.g., viewing a specific workspace), use GraphQL arguments instead. */ workspaceId?: boolean | string; /** * Include organization ID in x-org-id header. * Pass `true` to auto-read from profile context storage, or pass the org ID string directly. */ organizationId?: boolean | string; /** * Include tenant ID in x-tenant-id header. * Pass `true` to auto-read from profile context storage, or pass the tenant ID string directly. */ tenantId?: boolean | string; /** * Include project ID in x-project-id header. * Pass `true` to auto-read from profile context storage, or pass the project ID string directly. */ projectId?: boolean | string; /** Override locale (if not provided, reads from profile storage) */ locale?: string; /** Override base URL (if not provided, reads from GATEWAYS config) */ baseUrl?: string; /** Additional headers to merge (overrides auto-detected values) */ extraHeaders?: Record; /** AbortSignal for cancellation */ signal?: AbortSignal; /** * Skip the global backend-error event (the "[Burdenoff backend error]" * console log + the user-facing error toast/banner) for this call. Use for * fire-and-forget / non-critical telemetry that handles its own errors and * whose failure is not actionable for the user (e.g. recordProductVisit) — * such ops can fail transiently (cold subgraph) or race a not-yet-attached * token during bootstrap, and surfacing that as a backend error is pure noise. * The returned `errors` are still available to the caller. */ suppressGlobalErrorEvent?: boolean; /** * Skip the automatic UNAUTHENTICATED → refresh-token → retry-once cycle for * this call. Set internally on (a) the refresh mutation itself and (b) the * one post-refresh retry, so the recovery path can never recurse. Callers * implementing their own refresh handling (the Apollo error link) may also * set it to opt out. */ skipAuthRetry?: boolean; } /** * Fired when the session is definitively expired: an authenticated request got * UNAUTHENTICATED and the refresh-token attempt failed for a non-transient * reason. AppShellProvider listens and performs the forced logout + redirect * to login (with `reason=session-expired`), so the user is told the session * ended instead of watching data silently disappear. */ export declare const SESSION_EXPIRED_EVENT: "burdenoff:session-expired"; export interface SessionExpiredDetail { operationName?: string; gateway?: Gateway; } export interface GraphQLResponse { data: T | null; errors?: Array<{ message: string; locations?: Array<{ line: number; column: number; }>; path?: Array; extensions?: Record; }>; } /** Read the active profile's access token from profile-scoped storage */ export declare function getStoredAuthToken(): string | null; /** Read the active profile's workspace token from profile-scoped storage */ export declare function getStoredWorkspaceToken(): string | null; /** Read the active profile's geography from profile-scoped storage */ export declare function getStoredGeography(): { country?: string; currency?: string; timezone?: string; } | null; /** Read the active profile's locale from profile-scoped storage */ export declare function getStoredLocale(): string; /** Read the active profile's context (workspaceId, organizationId, tenantId, projectId) from profile-scoped storage */ export declare function getStoredContext(): { workspaceId?: string; organizationId?: string; tenantId?: string; projectId?: string; } | null; /** Read the active profile's workspace ID. * Reads from profile-scoped context (bf-p-{profileId}-context) which * ActiveContextProvider now writes to on every setWorkspace() call and on init. * Falls back to the ?workspace= URL param for page loads where the context * hasn't been hydrated yet (mirrors MultiGatewayProvider.getWorkspaceId). */ export declare function getStoredWorkspaceId(): string | null; /** Read the active profile's organization ID from profile context storage */ export declare function getStoredOrganizationId(): string | null; /** Read the active profile's tenant ID from profile context storage */ export declare function getStoredTenantId(): string | null; /** Read the active profile's project ID from profile context storage */ export declare function getStoredProjectId(): string | null; export declare function ensureWorkspaceToken(options: { url: string; authToken: string | null; workspaceId?: string; organizationId?: string; projectId?: string; locale?: string; signal?: AbortSignal; currentQuery: string; }): Promise; /** Resolve full gateway GraphQL URL */ export declare function resolveGatewayUrl(gateway: Gateway, baseUrl?: string): string; export interface EnqueueGraphQLFetchOptions { batchMax?: number; batchInterval?: number; } /** * Drop the short-lived GraphQL read caches so the next read of any operation * hits the network. * * `enqueueGraphQLFetch` keeps two read-side maps so a page-load burst of * identical reads coalesces into one request: * - `__graphqlFetchResponseCache` — RESOLVED responses, kept for * `RECENT_QUERY_CACHE_TTL_MS`. * - `__graphqlFetchPendingResponses` — IN-FLIGHT promises, deduped by key. * * Both would otherwise serve a STALE result to a refetch issued right after a * mutation (same operationName + variables): the resolved cache returns the * pre-mutation response directly, and the pending map can coalesce the refetch * onto a read that was already on the wire before the write committed. Either * one makes created/updated/deleted rows invisible until a full page reload. * Callers that perform a write clear both so every follow-up read is fresh. * * Clearing `__graphqlFetchPendingResponses` only stops FUTURE callers from * coalescing onto those in-flight requests — it does not abort them. The * original awaiters still hold their promise references and resolve normally, * and the `.finally` cleanup deletes a key that is already gone (a safe no-op). */ export declare function clearGraphqlFetchResponseCache(): void; export declare function enqueueGraphQLFetch(url: string, headers: Record, body: Record, signal?: AbortSignal, options?: EnqueueGraphQLFetchOptions): Promise; /** * Make a GraphQL request with automatic auth + locale headers. * * @example Basic query (global gateway) * ```ts * const result = await graphqlFetch<{ myWorkspaces: Workspace[] }>({ * gateway: 'global', * query: `query { myWorkspaces { id name } }`, * }); * ``` * * @example Workspace query with context headers (auto-read from storage) * ```ts * const result = await graphqlFetch<{ workspaceResources: Resource[] }>({ * gateway: 'workspace', * query: WORKSPACE_RESOURCES_QUERY, * workspaceId: true, // auto-reads from profile context storage -> x-workspace-id header * }); * ``` * * @example Workspace query with explicit workspace ID * ```ts * const result = await graphqlFetch<{ workspaceMembers: MemberList }>({ * gateway: 'workspace', * query: WORKSPACE_MEMBERS_QUERY, * variables: { workspaceId: targetWorkspaceId }, // Target workspace in arguments * workspaceId: contextWorkspaceId, // Context workspace in header (for RBAC) * }); * ``` * * @example With explicit tokens (e.g. right after login, before storage is updated) * ```ts * const result = await graphqlFetch({ * gateway: 'global', * query: MY_WORKSPACES_QUERY, * authToken: freshAccessToken, * }); * ``` */ export declare function graphqlFetch(options: GraphQLFetchOptions): Promise>; //# sourceMappingURL=fetch.d.ts.map