import type { FilterExpression } from '../types/filter.types'; /** * Custom fetcher function type for HTTP requests (FR29, FR31). * Receives the entity name and request, returns the search response. * Gives full control over URL construction, HTTP client, headers, etc. * * @example * // Using fetch with custom URL and auth. Throwing `ApiError` (not a plain `Error`) * // lets LookupField show a message the user can act on — "no tienes permisos", * // "tu sesión expiró", etc. — instead of the raw status code; a plain `Error` still * // works, it just falls back to a generic message since there's no status to read. * const fetcher: Fetcher = async (entity, request) => { * const response = await fetch(`/api/v2/${entity}/search`, { * method: 'POST', * headers: { * 'Content-Type': 'application/json', * 'Authorization': `Bearer ${getToken()}`, * }, * body: JSON.stringify(request), * }) * if (!response.ok) throw new ApiError(`API Error: ${response.status}`, response.status, response.statusText) * return response.json() * } * * @example * // Using axios * const fetcher: Fetcher = async (entity, request) => { * const { data } = await axios.post(`/api/${entity}/search`, request) * return data * } * * @example * // Using the createFetcher helper for simple cases * import { createFetcher } from 'siesa-ui-kit' * const fetcher = createFetcher('/api') */ export type Fetcher = >(entity: string, request: SearchRequest) => Promise>; /** Sort configuration for API requests (FR17) */ export interface OrderBy { /** Field name to sort by */ field: string; /** Sort direction */ direction: 'asc' | 'desc'; } /** * How `search` should match against `searchFields`. * - `'startsWith'` — matches records whose field begins with the search text (default) * - `'contains'` — matches records whose field contains the search text anywhere * - `'equals'` — exact match. Not user-facing (no toggle icon for it) — LookupField uses * this internally when the user types a full code and presses Enter without having * navigated to a result, to resolve/verify that exact record instead of guessing from * a prefix/substring match. */ export type SearchOperator = 'startsWith' | 'contains' | 'equals'; /** Request body for search API calls */ export interface SearchRequest { /** Fields to return in the response (always includes 'Id' - PascalCase standard) */ fields: string[]; /** Search text (empty for initial load) */ search?: string; /** Fields to search against (defaults to displayFields) */ searchFields?: string[]; /** * How `search` should be matched. Defaults to `'startsWith'`. `'startsWith'`/`'contains'` * are toggled by the user via the icons inside the search box; `'equals'` is only ever * sent by LookupField itself (Enter-to-resolve-exact-code), never user-toggled. The * fetcher/backend is responsible for actually applying it — LookupField only tracks and * forwards the chosen mode. */ searchOperator?: SearchOperator; /** Page number (1-indexed) */ page: number; /** Records per page */ pageSize: number; /** Filter conditions in expressive format */ filters?: FilterExpression; /** Sort order for results */ orderBy?: OrderBy; } /** Response body from search API calls [UPDATED v0.4 - removed total] */ export interface SearchResponse { /** Array of matching records */ data: TRecord[]; /** Current page number */ page: number; /** Page size used */ pageSize: number; } /** * Error thrown when an API request fails. `createFetcher` throws this automatically; * a custom `Fetcher` should throw it too (instead of a plain `Error`) so LookupField * can turn `status` into a message the user can actually act on — see * `getFriendlyErrorMessage` and the `error.*` translation keys. */ export declare class ApiError extends Error { readonly status: number; readonly statusText: string; constructor(message: string, status: number, statusText: string); } //# sourceMappingURL=api.types.d.ts.map