/** * Interface for API Client configuration. * Includes an optional function to retrieve the access token dynamically. */ export interface ApiClientConfig { /** * Base URL of the Rayfin backend the client targets. Use an absolute URL * (for example, the deployed Fabric item URL) to call a backend directly, or * an empty string (`''`) to keep requests same-origin so a dev-server proxy * can forward them. */ baseUrl: string; /** Publishable key used for service-level authentication. Required. */ publishableKey: string; /** * Optional override for the functions invocation host. When set, function * invocations (`client.functions..invoke(...)`) are routed to * `${functionsBaseUrl}/api/` (Azure Functions Core Tools convention) * instead of the default `${baseUrl}/functions//invoke` path that * goes through the Fabric `InvokeController`. Set this in local-debug * scenarios (e.g. from `import.meta.env.VITE_RAYFIN_FUNCTIONS_URL`) to * point the frontend at a locally-running `func start` process while * data calls continue to hit the deployed Fabric item via `baseUrl`. */ functionsBaseUrl?: string; /** Default headers merged into every request. */ headers?: Record; /** * Explicit `x-ms-workload-resource-moniker` value (typically a resolved * Fabric item ID). Takes precedence over the GUID heuristically extracted * from `baseUrl`, so callers with an authoritative resolved item ID (e.g. * `RayfinClient.fromConfig()`'s resolved `runtimeConfig.itemId`) aren't at * the mercy of URL-shape guessing. */ moniker?: string; /** Default request timeout in milliseconds (defaults to 30000). */ timeout?: number; /** Returns the current access token to attach as a bearer token, or `null`. */ getAccessToken?: () => string | null; /** * @deprecated This option no longer has any effect and will be removed in a * future major release. The client no longer inspects the runtime environment * to rewrite URLs. To route requests through a development proxy, set * `baseUrl` to an empty string (`''`) so requests stay same-origin, and * configure your dev server proxy accordingly. To call a backend directly, * pass its absolute URL as `baseUrl`. */ useProxy?: boolean; /** Callback when retry after refresh also returns 401. */ onAuthExhausted?: () => void; /** Invoked when a `401` response indicates the access token must be refreshed. */ onRefreshNeeded?: () => Promise; } /** * Request options for fetch API. */ export interface RequestOptions { /** HTTP method (defaults to the method implied by the calling helper). */ method?: string; /** Per-request headers, merged over the client's default headers. */ headers?: Record | Headers; /** Raw request body. */ body?: string | null; /** Per-request timeout in milliseconds, overriding the client default. */ timeout?: number; /** * Skip automatic token refresh and retry on 401 Unauthorized. * Used for auth endpoints like signOut and refreshToken where 401 is an expected error. */ skipRetryOn401?: boolean; /** * Controls how the response body is read. * * - `'json'` / `'text'` / omitted — the default behaviour: the body is read * as text and parsed as JSON when the response `Content-Type` indicates * JSON (or when an untyped body looks like JSON). * - `'arraybuffer'` — the caller is willing to receive raw bytes. Combined * with a binary response `Content-Type` (for example an Apache Arrow IPC * stream), the body is returned as an `ArrayBuffer` instead of being read * as text. A JSON response is still parsed as JSON, so callers can safely * request `'arraybuffer'` for endpoints that may return either format. */ responseType?: 'json' | 'text' | 'arraybuffer'; [key: string]: any; } /** * A generic HTTP client to interact with the service API. * Uses isomorphic fetch approach that works in both browser and Node.js environments * without external dependencies when native fetch is available. */ export declare class ApiClient { private baseUrl; private functionsBaseUrl; private publishableKey; private defaultHeaders; private moniker; private defaultTimeout; private getAccessTokenCallback; private onRefreshNeededCallback; private onAuthExhaustedCallback; private fetchImplementation; /** * Creates a new HTTP client. * * @param config - Client configuration. A non-empty `publishableKey` is required. * @throws An {@link SdkError} if `publishableKey` is missing or blank. */ constructor(config: ApiClientConfig); /** * Returns the configured functions invocation host, or `undefined` when * functions should be invoked against the default `baseUrl`. Consumed by * `FunctionClient.invoke()` to switch between the local * `func start`-style path and the Fabric `InvokeController` path. * * @returns The functions base URL, or `undefined` to use `baseUrl`. * @internal */ getFunctionsBaseUrl(): string | undefined; /** * Sets or updates the access token callback function. * This allows attaching a token provider after the ApiClient has been initialized. * @param callback - Function that returns the current access token or null */ setAccessTokenCallback(callback: () => string | null): void; /** * Sets or updates the refresh callback function. * This allows attaching a refresh handler after the ApiClient has been initialized. * @param callback - Function that performs token refresh */ setRefreshCallback(callback: () => Promise): void; /** * Sets the callback invoked when a retry after refresh also returns 401. * @param callback - Function called when auth is exhausted */ setAuthExhaustedCallback(callback: () => void): void; /** * Prepares the request headers, including authorization if available. * @param additionalHeaders - Additional headers to include with the request * @returns Combined headers with authorization if available */ /** * Normalizes request headers into a plain record. A Headers instance cannot * be spread into a plain object (its values are stored internally), so its * entries must be copied explicitly to avoid silently dropping headers. * @param headers - The headers to normalize. * @returns A plain record of header name/value pairs. */ private headersToRecord; private prepareHeaders; /** * Extracts the last GUID from a URL path. This would be projectId. * @param url - The URL to extract from * @returns The last GUID found in the path, or undefined if none found */ private extractLastGuid; /** * Builds a full URL by properly combining base URL and path. * Unlike new URL(path, base), this preserves the base URL's path component. * * Examples: * - buildUrl('/api/auth') with baseUrl 'http://localhost:5168' * → 'http://localhost:5168/api/auth' * * - buildUrl('/api/auth') with baseUrl 'https://host:443/webapi/capacities/123/appbackends/456' * → 'https://host/webapi/capacities/123/appbackends/456/api/auth' * (Preserves the full path, unlike new URL() which would produce 'https://host:443/api/auth') * * - buildUrl('https://example.com/full/url') * → 'https://example.com/full/url' (absolute URLs returned as-is) * * @param path - The relative path to append * @returns The full URL string */ private buildUrl; /** * Handles response errors in a consistent way. * On 401 Unauthorized, attempts automatic token refresh if callback is configured. * @param response - The fetch Response object * @returns The Response if it's ok, otherwise throws an appropriate error */ private handleResponseErrors; /** * Handles 401 errors by attempting token refresh and retrying the request. * @param url - The original request URL * @param options - The original request options * @returns Promise that resolves with the parsed response after retry */ private handleUnauthorizedWithRetry; /** * Handles a 401 on the retry-after-refresh path. * Notifies the auth layer that the fresh token was also rejected. */ private handleRetryUnauthorized; /** * Executes a fetch request with proper error handling and timeout. * Automatically retries on 401 if refresh callback is available. * @param url - The URL to request * @param options - Request options * @returns Promise that resolves with the parsed response */ private fetchWithTimeout; /** * Makes a GET request. * @param path - The API endpoint path. * @param options - Optional fetch request options. * @returns A promise that resolves with the response data. */ get(path: string, options?: RequestOptions): Promise; /** * Makes a POST request. * @param path - The API endpoint path. * @param data - The request body. * @param options - Optional fetch request options. * @returns A promise that resolves with the response data. */ post(path: string, data?: any, options?: RequestOptions): Promise; /** * Makes a PUT request. * @param path - The API endpoint path. * @param data - The request body. * @param options - Optional fetch request options. * @returns A promise that resolves with the response data. */ put(path: string, data?: any, options?: RequestOptions): Promise; /** * Makes a DELETE request. * @param path - The API endpoint path. * @param options - Optional fetch request options. * @returns A promise that resolves with the response data. */ delete(path: string, options?: RequestOptions): Promise; /** * Makes a raw HTTP request with streaming support and returns the Response object. * Does not parse the response body - allows caller to handle streaming responses. * @param path - The API endpoint path. * @param options - Request options including streaming body support. * @returns A promise that resolves with the raw Response object. */ requestRaw(path: string, options?: { method?: string; headers?: Record; body?: BodyInit | null; signal?: AbortSignal; timeout?: number; allowProxyPath?: boolean; skipAuth?: boolean; }): Promise; } export default ApiClient; //# sourceMappingURL=ApiClient.d.ts.map