{"version":3,"file":"create-data-provider.cjs","names":[],"sources":["../../src/data/create-data-provider.ts"],"sourcesContent":["import type { ApiClient, RequestOptions } from \"@/http/types\";\nimport type { OffsetPage } from \"@/query/pagination\";\n\n/** Query-param values accepted by the API client for a list request. */\ntype ParamValue = string | number | boolean | undefined | null;\n\n/** Filters passed to {@link DataProvider.getList}, spread verbatim into the query string. */\nexport type DataFilters = Record<string, ParamValue>;\n\n/** Parameters for a paginated, sorted, filtered list request. */\nexport interface GetListParams {\n    /** Offset pagination — 1-based `page` and `pageSize`. */\n    pagination?: { page?: number; pageSize?: number };\n    /** Single-field sort. `order` defaults to `\"asc\"`. */\n    sort?: { field: string; order?: \"asc\" | \"desc\" };\n    /** Arbitrary filter query params, spread onto the request. */\n    filters?: DataFilters;\n}\n\n/**\n * Refine-style data provider over the Tempest FastAPI SDK CRUD/pagination\n * conventions. Implementations are stateless wrappers around an {@link ApiClient}.\n */\nexport interface DataProvider {\n    /**\n     * Fetch a paginated list of a resource.\n     *\n     * @param resource - The resource name (e.g. `\"users\"`).\n     * @param params - Pagination, sort and filter parameters.\n     * @returns The offset-paginated envelope.\n     */\n    getList<T>(resource: string, params?: GetListParams): Promise<OffsetPage<T>>;\n    /**\n     * Fetch a single record by id.\n     *\n     * @param resource - The resource name.\n     * @param id - The record id.\n     * @returns The record.\n     */\n    getOne<T>(resource: string, id: string | number): Promise<T>;\n    /**\n     * Fetch many records by id (default: parallel {@link DataProvider.getOne}).\n     *\n     * @param resource - The resource name.\n     * @param ids - The record ids.\n     * @returns The records, in the same order as `ids`.\n     */\n    getMany<T>(resource: string, ids: (string | number)[]): Promise<T[]>;\n    /**\n     * Create a record.\n     *\n     * @param resource - The resource name.\n     * @param data - The creation payload.\n     * @returns The created record.\n     */\n    create<T>(resource: string, data: unknown): Promise<T>;\n    /**\n     * Update a record (PATCH by default, PUT when configured).\n     *\n     * @param resource - The resource name.\n     * @param id - The record id.\n     * @param data - The update payload.\n     * @returns The updated record.\n     */\n    update<T>(resource: string, id: string | number, data: unknown): Promise<T>;\n    /**\n     * Delete a record by id.\n     *\n     * @param resource - The resource name.\n     * @param id - The record id.\n     * @returns The delete response (often the deleted record).\n     */\n    deleteOne<T>(resource: string, id: string | number): Promise<T>;\n}\n\n/** Options to tailor {@link createDataProvider} to a backend's conventions. */\nexport interface DataProviderOptions {\n    /** Query-param name for the page number. Default: `\"page\"`. */\n    pageParam?: string;\n    /** Query-param name for the page size. Default: `\"size\"`. */\n    sizeParam?: string;\n    /** Query-param name for the sort field. Default: `\"order_by\"`. */\n    sortFieldParam?: string;\n    /** Query-param name for the sort order. Default: `\"ascending\"`. */\n    sortOrderParam?: string;\n    /**\n     * When `true` (default), emit the sort order as a boolean\n     * (`order:\"asc\"` → `true`). When `false`, emit the literal `\"asc\"`/`\"desc\"`.\n     */\n    sortOrderAsBoolean?: boolean;\n    /** HTTP method used by {@link DataProvider.update}. Default: `\"patch\"`. */\n    updateMethod?: \"patch\" | \"put\";\n    /**\n     * Build the request path for a resource (and optional id).\n     * Default: `id == null ? \"/\" + resource : \"/\" + resource + \"/\" + id`.\n     */\n    buildPath?: (resource: string, id?: string | number) => string;\n}\n\nconst defaultBuildPath = (resource: string, id?: string | number): string =>\n    id == null ? `/${resource}` : `/${resource}/${id}`;\n\n/**\n * Create a {@link DataProvider} bound to an {@link ApiClient}.\n *\n * Maps Refine-style calls to the Tempest FastAPI SDK conventions: list →\n * `GET /{resource}?page=&size=&order_by=&ascending=&...filters`, one →\n * `GET /{resource}/{id}`, create → `POST`, update → `PATCH`/`PUT`,\n * delete → `DELETE`.\n *\n * @param client - The HTTP client created by `createApiClient`.\n * @param options - Optional overrides for param names, sort encoding,\n *   update method and path building.\n * @returns A stateless data provider.\n *\n * @example\n * const dataProvider = createDataProvider(apiClient);\n * const page = await dataProvider.getList<User>(\"users\", {\n *     pagination: { page: 1, pageSize: 20 },\n *     sort: { field: \"created_at\", order: \"desc\" },\n *     filters: { active: true },\n * });\n */\nexport function createDataProvider(\n    client: ApiClient,\n    options: DataProviderOptions = {},\n): DataProvider {\n    const {\n        pageParam = \"page\",\n        sizeParam = \"size\",\n        sortFieldParam = \"order_by\",\n        sortOrderParam = \"ascending\",\n        sortOrderAsBoolean = true,\n        updateMethod = \"patch\",\n        buildPath = defaultBuildPath,\n    } = options;\n\n    const provider: DataProvider = {\n        getList<T>(resource: string, params: GetListParams = {}): Promise<OffsetPage<T>> {\n            const { pagination, sort, filters } = params;\n            const query: Record<string, ParamValue> = {};\n\n            if (pagination?.page != null) query[pageParam] = pagination.page;\n            if (pagination?.pageSize != null) query[sizeParam] = pagination.pageSize;\n\n            if (sort?.field) {\n                const order = sort.order ?? \"asc\";\n                query[sortFieldParam] = sort.field;\n                query[sortOrderParam] = sortOrderAsBoolean ? order === \"asc\" : order;\n            }\n\n            if (filters) {\n                for (const [key, value] of Object.entries(filters)) {\n                    query[key] = value;\n                }\n            }\n\n            const requestOptions: RequestOptions = { params: query };\n            return client.get<OffsetPage<T>>(buildPath(resource), requestOptions);\n        },\n\n        getOne<T>(resource: string, id: string | number): Promise<T> {\n            return client.get<T>(buildPath(resource, id));\n        },\n\n        getMany<T>(resource: string, ids: (string | number)[]): Promise<T[]> {\n            return Promise.all(ids.map((id) => provider.getOne<T>(resource, id)));\n        },\n\n        create<T>(resource: string, data: unknown): Promise<T> {\n            return client.post<T>(buildPath(resource), { body: data });\n        },\n\n        update<T>(resource: string, id: string | number, data: unknown): Promise<T> {\n            const path = buildPath(resource, id);\n            return updateMethod === \"put\"\n                ? client.put<T>(path, { body: data })\n                : client.patch<T>(path, { body: data });\n        },\n\n        deleteOne<T>(resource: string, id: string | number): Promise<T> {\n            return client.delete<T>(buildPath(resource, id));\n        },\n    };\n\n    return provider;\n}\n"],"mappings":"AAmGA,IAAM,GAAoB,EAAkB,IACxC,GAAM,KAAO,IAAI,IAAa,IAAI,EAAS,GAAG,IAuBlD,SAAgB,EACZ,EACA,EAA+B,CAAC,EACpB,CACZ,GAAM,CACF,YAAY,OACZ,YAAY,OACZ,iBAAiB,WACjB,iBAAiB,YACjB,qBAAqB,GACrB,eAAe,QACf,YAAY,GACZ,EAEE,EAAyB,CAC3B,QAAW,EAAkB,EAAwB,CAAC,EAA2B,CAC7E,GAAM,CAAE,aAAY,OAAM,WAAY,EAChC,EAAoC,CAAC,EAK3C,GAHI,GAAY,MAAQ,OAAM,EAAM,GAAa,EAAW,MACxD,GAAY,UAAY,OAAM,EAAM,GAAa,EAAW,UAE5D,GAAM,MAAO,CACb,IAAM,EAAQ,EAAK,OAAS,MAC5B,EAAM,GAAkB,EAAK,MAC7B,EAAM,GAAkB,EAAqB,IAAU,MAAQ,CACnE,CAEA,GAAI,EACA,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAO,EAC7C,EAAM,GAAO,EAIrB,IAAM,EAAiC,CAAE,OAAQ,CAAM,EACvD,OAAO,EAAO,IAAmB,EAAU,CAAQ,EAAG,CAAc,CACxE,EAEA,OAAU,EAAkB,EAAiC,CACzD,OAAO,EAAO,IAAO,EAAU,EAAU,CAAE,CAAC,CAChD,EAEA,QAAW,EAAkB,EAAwC,CACjE,OAAO,QAAQ,IAAI,EAAI,IAAK,GAAO,EAAS,OAAU,EAAU,CAAE,CAAC,CAAC,CACxE,EAEA,OAAU,EAAkB,EAA2B,CACnD,OAAO,EAAO,KAAQ,EAAU,CAAQ,EAAG,CAAE,KAAM,CAAK,CAAC,CAC7D,EAEA,OAAU,EAAkB,EAAqB,EAA2B,CACxE,IAAM,EAAO,EAAU,EAAU,CAAE,EACnC,OAAO,IAAiB,MAClB,EAAO,IAAO,EAAM,CAAE,KAAM,CAAK,CAAC,EAClC,EAAO,MAAS,EAAM,CAAE,KAAM,CAAK,CAAC,CAC9C,EAEA,UAAa,EAAkB,EAAiC,CAC5D,OAAO,EAAO,OAAU,EAAU,EAAU,CAAE,CAAC,CACnD,CACJ,EAEA,OAAO,CACX"}