@krymskyimaksym/react-api-client 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Your Name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,303 @@
1
+ # @krymskyimaksym/react-api-client
2
+
3
+ A lightweight, type-safe API client for React and React Native with built-in hooks for queries, mutations, and pagination.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **Type-Safe**: Full TypeScript support with generic types
8
+ - 🪝 **React Hooks**: Built-in hooks for easy data fetching
9
+ - 📦 **Lightweight**: Zero dependencies (except React)
10
+ - 🔄 **Flexible**: Works with any HTTP client (fetch, axios, etc.)
11
+ - 🚀 **Modern**: ESM and CJS support
12
+ - 🎨 **Customizable**: Inject your own HTTP client and error handlers
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @krymskyimaksym/react-api-client
18
+ # or
19
+ yarn add @krymskyimaksym/react-api-client
20
+ # or
21
+ pnpm add @krymskyimaksym/react-api-client
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ### 1. Configure the API Client
27
+
28
+ First, configure the global API client with your HTTP client and error handlers:
29
+
30
+ ```typescript
31
+ import { configureApiClient } from '@krymskyimaksym/react-api-client';
32
+ import { router } from 'expo-router'; // or your router
33
+
34
+ // Create your HTTP client instance
35
+ const httpClient = {
36
+ async get(url, config) {
37
+ const response = await fetch(url);
38
+ return response.json();
39
+ },
40
+ async request(url, config) {
41
+ const response = await fetch(url, {
42
+ method: config.method,
43
+ body: JSON.stringify(config.data),
44
+ headers: { 'Content-Type': 'application/json' },
45
+ });
46
+ return response.json();
47
+ },
48
+ };
49
+
50
+ // Configure once at app startup
51
+ configureApiClient({
52
+ httpClient,
53
+ onUnauthorized: () => router.replace('/login'),
54
+ });
55
+ ```
56
+
57
+ ### 2. Define Your API Endpoints
58
+
59
+ ```typescript
60
+ import apiClient, { apiMutation, apiPaginate } from '@krymskyimaksym/react-api-client';
61
+
62
+ // Types
63
+ type User = {
64
+ id: string;
65
+ name: string;
66
+ email: string;
67
+ };
68
+
69
+ type CreateUserRequest = {
70
+ name: string;
71
+ email: string;
72
+ };
73
+
74
+ // GET endpoint
75
+ export const userApi = apiClient<User, { id: string }>('/api/users/:id');
76
+
77
+ // POST endpoint
78
+ export const createUserApi = apiMutation<User, CreateUserRequest>(
79
+ '/api/users',
80
+ { method: 'POST' }
81
+ );
82
+
83
+ // Paginated endpoint
84
+ export const usersListApi = apiPaginate<
85
+ { data: User[]; total: number },
86
+ User[]
87
+ >('/api/users');
88
+ ```
89
+
90
+ ### 3. Use in Components
91
+
92
+ #### Query (GET)
93
+
94
+ ```typescript
95
+ function UserProfile({ userId }: { userId: string }) {
96
+ const { data, isLoading, error, refetch } = userApi.useFetch(
97
+ { id: userId },
98
+ {
99
+ onSuccess: (data) => console.log('User loaded:', data),
100
+ onError: (error) => console.error('Error:', error),
101
+ }
102
+ );
103
+
104
+ if (isLoading) return <LoadingSpinner />;
105
+ if (error) return <ErrorMessage error={error} />;
106
+
107
+ return (
108
+ <div>
109
+ <h1>{data?.name}</h1>
110
+ <button onClick={refetch}>Refresh</button>
111
+ </div>
112
+ );
113
+ }
114
+ ```
115
+
116
+ #### Mutation (POST/PUT/PATCH/DELETE)
117
+
118
+ ```typescript
119
+ function CreateUserForm() {
120
+ const { mutate, isLoading, isSuccess, error } = createUserApi.useMutation({
121
+ onSuccess: (data) => {
122
+ console.log('User created:', data);
123
+ // Navigate or update UI
124
+ },
125
+ onError: (error) => {
126
+ console.error('Failed to create user:', error);
127
+ },
128
+ });
129
+
130
+ const handleSubmit = (values: CreateUserRequest) => {
131
+ mutate(values);
132
+ };
133
+
134
+ return (
135
+ <form onSubmit={handleSubmit}>
136
+ {/* form fields */}
137
+ <button type="submit" disabled={isLoading}>
138
+ {isLoading ? 'Creating...' : 'Create User'}
139
+ </button>
140
+ {isSuccess && <p>User created successfully!</p>}
141
+ {error && <p>Error: {error.message}</p>}
142
+ </form>
143
+ );
144
+ }
145
+ ```
146
+
147
+ #### Pagination
148
+
149
+ ```typescript
150
+ function UsersList() {
151
+ const {
152
+ data,
153
+ isLoading,
154
+ hasNextPage,
155
+ fetchNextPage,
156
+ isFetchingNextPage,
157
+ } = usersListApi.usePaginate();
158
+
159
+ return (
160
+ <div>
161
+ {data.map(user => (
162
+ <UserCard key={user.id} user={user} />
163
+ ))}
164
+
165
+ {hasNextPage && (
166
+ <button onClick={fetchNextPage} disabled={isFetchingNextPage}>
167
+ {isFetchingNextPage ? 'Loading...' : 'Load More'}
168
+ </button>
169
+ )}
170
+ </div>
171
+ );
172
+ }
173
+ ```
174
+
175
+ ## API Reference
176
+
177
+ ### `configureApiClient(config)`
178
+
179
+ Configure the global API client. Must be called before using any API functions.
180
+
181
+ ```typescript
182
+ type ApiClientConfig = {
183
+ httpClient: IHttpClient;
184
+ onUnauthorized?: () => void | Promise<void>;
185
+ };
186
+ ```
187
+
188
+ ### `apiClient<ResponseType, RequestParamsType>(endpoint, config)`
189
+
190
+ Creates a query client for GET requests.
191
+
192
+ **Returns:**
193
+ - `fetch(params)` - Async function to fetch data
194
+ - `useFetch(params, options)` - React hook for data fetching
195
+
196
+ ### `apiMutation<ResponseType, RequestParamsType>(endpoint, config)`
197
+
198
+ Creates a mutation client for POST/PUT/PATCH/DELETE requests.
199
+
200
+ **Returns:**
201
+ - `mutate(params)` - Async function to execute mutation
202
+ - `useMutation(options)` - React hook for mutations
203
+
204
+ ### `apiPaginate<ResponseType, DataArrayType>(endpoint, config, options)`
205
+
206
+ Creates a paginated query client.
207
+
208
+ **Returns:**
209
+ - `usePaginate(params, options)` - React hook for paginated data
210
+
211
+ ## Advanced Usage
212
+
213
+ ### Dynamic Endpoints
214
+
215
+ ```typescript
216
+ const userApi = apiClient<User, { id: string }>(
217
+ (params) => `/api/users/${params.id}`
218
+ );
219
+ ```
220
+
221
+ ### Custom Data Extractors for Pagination
222
+
223
+ ```typescript
224
+ const usersApi = apiPaginate<
225
+ { users: User[]; count: number },
226
+ User[]
227
+ >(
228
+ '/api/users',
229
+ { method: 'GET' },
230
+ {
231
+ dataExtractor: (response) => response.users,
232
+ totalExtractor: (response) => response.count,
233
+ }
234
+ );
235
+ ```
236
+
237
+ ### Imperative API Calls
238
+
239
+ ```typescript
240
+ // Without hooks
241
+ const response = await userApi.fetch({ id: '123' });
242
+ if (response.status) {
243
+ console.log('Success:', response);
244
+ } else {
245
+ console.error('Error:', response.message);
246
+ }
247
+ ```
248
+
249
+ ## HTTP Client Interface
250
+
251
+ Your HTTP client must implement this interface:
252
+
253
+ ```typescript
254
+ interface IHttpClient {
255
+ get<T>(url: string, config?: RequestConfig): Promise<T>;
256
+ request<T>(url: string, config: RequestConfig): Promise<T>;
257
+ }
258
+ ```
259
+
260
+ ### Example with Axios
261
+
262
+ ```typescript
263
+ import axios from 'axios';
264
+
265
+ const httpClient = {
266
+ get: (url, config) => axios.get(url, config).then(res => res.data),
267
+ request: (url, config) => axios(url, config).then(res => res.data),
268
+ };
269
+ ```
270
+
271
+ ### Example with Fetch
272
+
273
+ ```typescript
274
+ const httpClient = {
275
+ async get(url, config) {
276
+ const params = new URLSearchParams(config?.params);
277
+ const response = await fetch(`${url}?${params}`);
278
+ if (!response.ok) throw new Error('Request failed');
279
+ return response.json();
280
+ },
281
+ async request(url, config) {
282
+ const response = await fetch(url, {
283
+ method: config.method,
284
+ headers: { 'Content-Type': 'application/json' },
285
+ body: config.data ? JSON.stringify(config.data) : undefined,
286
+ });
287
+ if (!response.ok) throw new Error('Request failed');
288
+ return response.json();
289
+ },
290
+ };
291
+ ```
292
+
293
+ ## License
294
+
295
+ MIT
296
+
297
+ ## Contributing
298
+
299
+ Contributions are welcome! Please open an issue or submit a pull request.
300
+
301
+ ## Support
302
+
303
+ For issues and questions, please use [GitHub Issues](https://github.com/krymskyimaksym/react-api-client/issues).
@@ -0,0 +1,152 @@
1
+ type RequestConfig = {
2
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
3
+ requestParams?: Record<string, string>;
4
+ };
5
+ type ResponseWrapper<DataType, ErrorsType = unknown> = {
6
+ status: boolean;
7
+ message?: string;
8
+ errors?: ErrorsType;
9
+ } & DataType;
10
+ type UseFetchOptions<T> = {
11
+ enabled?: boolean;
12
+ refetchOnMount?: boolean;
13
+ onSuccess?: (data: T) => void;
14
+ onError?: (error: Error) => void;
15
+ };
16
+ type UseFetchResult<T> = {
17
+ data: T | null;
18
+ isLoading: boolean;
19
+ isRefetching: boolean;
20
+ error: Error | null;
21
+ refetch: () => Promise<void>;
22
+ };
23
+ type UsePaginateOptions<T> = {
24
+ enabled?: boolean;
25
+ initialPage?: number;
26
+ initialLimit?: number;
27
+ onSuccess?: (data: T) => void;
28
+ onError?: (error: Error) => void;
29
+ };
30
+ type UsePaginateResult<TData extends unknown[]> = {
31
+ data: TData;
32
+ currentPage: number;
33
+ totalPages: number | null;
34
+ total: number | null;
35
+ hasNextPage: boolean;
36
+ hasPreviousPage: boolean;
37
+ isLoading: boolean;
38
+ isFetchingNextPage: boolean;
39
+ error: Error | null;
40
+ fetchNextPage: () => Promise<void>;
41
+ fetchPreviousPage: () => Promise<void>;
42
+ refetch: () => Promise<void>;
43
+ reset: () => void;
44
+ };
45
+ type UseMutationOptions<TData, TVariables> = {
46
+ onMutate?: (variables: TVariables) => void | Promise<void>;
47
+ onSuccess?: (data: TData, variables: TVariables) => void | Promise<void>;
48
+ onError?: (error: Error, variables: TVariables) => void | Promise<void>;
49
+ onSettled?: (data: TData | null, error: Error | null, variables: TVariables) => void | Promise<void>;
50
+ };
51
+ type UseMutationResult<TData, TVariables> = {
52
+ data: TData | null;
53
+ error: Error | null;
54
+ isLoading: boolean;
55
+ isSuccess: boolean;
56
+ isError: boolean;
57
+ mutate: (variables: TVariables) => void;
58
+ mutateAsync: (variables: TVariables) => Promise<TData>;
59
+ reset: () => void;
60
+ };
61
+ interface IHttpClient {
62
+ get<T>(url: string, config?: {
63
+ params?: Record<string, unknown>;
64
+ }): Promise<T>;
65
+ request<T>(url: string, config: {
66
+ method?: string;
67
+ data?: Record<string, unknown>;
68
+ }): Promise<T>;
69
+ }
70
+ type ApiClientConfig = {
71
+ httpClient: IHttpClient;
72
+ onUnauthorized?: () => void | Promise<void>;
73
+ };
74
+ type ApiClientReturn<ResponseType, RequestParamsType, ErrorResponseType = unknown> = {
75
+ fetch: (params?: RequestParamsType) => Promise<ResponseWrapper<ResponseType, ErrorResponseType>>;
76
+ useFetch: (params?: RequestParamsType, options?: UseFetchOptions<ResponseWrapper<ResponseType, ErrorResponseType>>) => UseFetchResult<ResponseWrapper<ResponseType, ErrorResponseType>>;
77
+ };
78
+ type ApiMutationReturn<ResponseType, RequestParamsType, ErrorResponseType = unknown> = {
79
+ mutate: (params?: RequestParamsType) => Promise<ResponseWrapper<ResponseType, ErrorResponseType>>;
80
+ useMutation: (options?: UseMutationOptions<ResponseWrapper<ResponseType, ErrorResponseType>, RequestParamsType>) => UseMutationResult<ResponseWrapper<ResponseType, ErrorResponseType>, RequestParamsType>;
81
+ };
82
+ type ApiPaginateReturn<ResponseType, RequestParamsType, DataArrayType extends unknown[], ErrorResponseType = unknown> = {
83
+ usePaginate: (params?: Omit<RequestParamsType, 'page' | 'limit'>, options?: UsePaginateOptions<ResponseWrapper<ResponseType, ErrorResponseType>>) => UsePaginateResult<DataArrayType>;
84
+ };
85
+
86
+ /**
87
+ * Configure the API client globally
88
+ * @param config - API client configuration
89
+ *
90
+ * @example
91
+ * import { configureApiClient } from '@krymskyimaksym/react-api-client';
92
+ * import { router } from 'expo-router';
93
+ *
94
+ * configureApiClient({
95
+ * httpClient: myHttpClient,
96
+ * onUnauthorized: () => router.replace('/login')
97
+ * });
98
+ */
99
+ declare function configureApiClient(config: ApiClientConfig): void;
100
+ /**
101
+ * Get the current global configuration
102
+ * @throws Error if configuration is not set
103
+ */
104
+ declare function getConfig(): ApiClientConfig;
105
+ /**
106
+ * Check if the API client is configured
107
+ */
108
+ declare function isConfigured(): boolean;
109
+
110
+ /**
111
+ * Creates an API client for GET requests
112
+ * @param endpoint - URL string or function that generates URL from params
113
+ * @param fetchConfig - Request configuration
114
+ * @returns Object with fetch method and useFetch hook
115
+ *
116
+ * @example
117
+ * const userApi = apiClient<User, { id: string }>('/api/users/:id')
118
+ * const { data } = userApi.useFetch({ id: '123' })
119
+ */
120
+ declare function apiClient<ResponseType = void, RequestParamsType = void, ErrorResponseType = unknown>(endpoint: string | ((arg0: RequestParamsType) => string), fetchConfig?: RequestConfig): ApiClientReturn<ResponseType, RequestParamsType, ErrorResponseType>;
121
+ /**
122
+ * Creates an API client for mutation requests (POST/PUT/PATCH/DELETE)
123
+ * @param endpoint - URL string or function that generates URL from params
124
+ * @param fetchConfig - Request configuration
125
+ * @returns Object with mutate method and useMutation hook
126
+ *
127
+ * @example
128
+ * const createUserApi = apiMutation<User, CreateUserRequest>('/api/users', { method: 'POST' })
129
+ * const { mutate, isLoading } = createUserApi.useMutation()
130
+ */
131
+ declare function apiMutation<ResponseType = void, RequestParamsType = void, ErrorResponseType = unknown>(endpoint: string | ((arg0: RequestParamsType) => string), fetchConfig?: RequestConfig): ApiMutationReturn<ResponseType, RequestParamsType, ErrorResponseType>;
132
+ /**
133
+ * Creates an API client for paginated requests
134
+ * @param endpoint - URL string or function that generates URL from params
135
+ * @param fetchConfig - Request configuration
136
+ * @param options - Pagination options (data/total extractors)
137
+ * @returns Object with usePaginate hook
138
+ *
139
+ * @example
140
+ * const usersApi = apiPaginate<UsersResponse, User[], { search?: string }>('/api/users')
141
+ * const { data, fetchNextPage, hasNextPage } = usersApi.usePaginate()
142
+ */
143
+ declare function apiPaginate<ResponseType extends {
144
+ data: TData;
145
+ total?: number;
146
+ page?: number;
147
+ }, TData extends unknown[], RequestParamsType = void, ErrorResponseType = unknown>(endpoint: string | ((arg0: RequestParamsType) => string), fetchConfig?: RequestConfig, options?: {
148
+ dataExtractor?: (response: ResponseType) => TData;
149
+ totalExtractor?: (response: ResponseType) => number;
150
+ }): ApiPaginateReturn<ResponseType, RequestParamsType, TData, ErrorResponseType>;
151
+
152
+ export { type ApiClientConfig, type IHttpClient, type ResponseWrapper, type UseFetchOptions, type UseFetchResult, type UseMutationOptions, type UseMutationResult, type UsePaginateOptions, type UsePaginateResult, apiMutation, apiPaginate, configureApiClient, apiClient as default, getConfig, isConfigured };
@@ -0,0 +1,152 @@
1
+ type RequestConfig = {
2
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
3
+ requestParams?: Record<string, string>;
4
+ };
5
+ type ResponseWrapper<DataType, ErrorsType = unknown> = {
6
+ status: boolean;
7
+ message?: string;
8
+ errors?: ErrorsType;
9
+ } & DataType;
10
+ type UseFetchOptions<T> = {
11
+ enabled?: boolean;
12
+ refetchOnMount?: boolean;
13
+ onSuccess?: (data: T) => void;
14
+ onError?: (error: Error) => void;
15
+ };
16
+ type UseFetchResult<T> = {
17
+ data: T | null;
18
+ isLoading: boolean;
19
+ isRefetching: boolean;
20
+ error: Error | null;
21
+ refetch: () => Promise<void>;
22
+ };
23
+ type UsePaginateOptions<T> = {
24
+ enabled?: boolean;
25
+ initialPage?: number;
26
+ initialLimit?: number;
27
+ onSuccess?: (data: T) => void;
28
+ onError?: (error: Error) => void;
29
+ };
30
+ type UsePaginateResult<TData extends unknown[]> = {
31
+ data: TData;
32
+ currentPage: number;
33
+ totalPages: number | null;
34
+ total: number | null;
35
+ hasNextPage: boolean;
36
+ hasPreviousPage: boolean;
37
+ isLoading: boolean;
38
+ isFetchingNextPage: boolean;
39
+ error: Error | null;
40
+ fetchNextPage: () => Promise<void>;
41
+ fetchPreviousPage: () => Promise<void>;
42
+ refetch: () => Promise<void>;
43
+ reset: () => void;
44
+ };
45
+ type UseMutationOptions<TData, TVariables> = {
46
+ onMutate?: (variables: TVariables) => void | Promise<void>;
47
+ onSuccess?: (data: TData, variables: TVariables) => void | Promise<void>;
48
+ onError?: (error: Error, variables: TVariables) => void | Promise<void>;
49
+ onSettled?: (data: TData | null, error: Error | null, variables: TVariables) => void | Promise<void>;
50
+ };
51
+ type UseMutationResult<TData, TVariables> = {
52
+ data: TData | null;
53
+ error: Error | null;
54
+ isLoading: boolean;
55
+ isSuccess: boolean;
56
+ isError: boolean;
57
+ mutate: (variables: TVariables) => void;
58
+ mutateAsync: (variables: TVariables) => Promise<TData>;
59
+ reset: () => void;
60
+ };
61
+ interface IHttpClient {
62
+ get<T>(url: string, config?: {
63
+ params?: Record<string, unknown>;
64
+ }): Promise<T>;
65
+ request<T>(url: string, config: {
66
+ method?: string;
67
+ data?: Record<string, unknown>;
68
+ }): Promise<T>;
69
+ }
70
+ type ApiClientConfig = {
71
+ httpClient: IHttpClient;
72
+ onUnauthorized?: () => void | Promise<void>;
73
+ };
74
+ type ApiClientReturn<ResponseType, RequestParamsType, ErrorResponseType = unknown> = {
75
+ fetch: (params?: RequestParamsType) => Promise<ResponseWrapper<ResponseType, ErrorResponseType>>;
76
+ useFetch: (params?: RequestParamsType, options?: UseFetchOptions<ResponseWrapper<ResponseType, ErrorResponseType>>) => UseFetchResult<ResponseWrapper<ResponseType, ErrorResponseType>>;
77
+ };
78
+ type ApiMutationReturn<ResponseType, RequestParamsType, ErrorResponseType = unknown> = {
79
+ mutate: (params?: RequestParamsType) => Promise<ResponseWrapper<ResponseType, ErrorResponseType>>;
80
+ useMutation: (options?: UseMutationOptions<ResponseWrapper<ResponseType, ErrorResponseType>, RequestParamsType>) => UseMutationResult<ResponseWrapper<ResponseType, ErrorResponseType>, RequestParamsType>;
81
+ };
82
+ type ApiPaginateReturn<ResponseType, RequestParamsType, DataArrayType extends unknown[], ErrorResponseType = unknown> = {
83
+ usePaginate: (params?: Omit<RequestParamsType, 'page' | 'limit'>, options?: UsePaginateOptions<ResponseWrapper<ResponseType, ErrorResponseType>>) => UsePaginateResult<DataArrayType>;
84
+ };
85
+
86
+ /**
87
+ * Configure the API client globally
88
+ * @param config - API client configuration
89
+ *
90
+ * @example
91
+ * import { configureApiClient } from '@krymskyimaksym/react-api-client';
92
+ * import { router } from 'expo-router';
93
+ *
94
+ * configureApiClient({
95
+ * httpClient: myHttpClient,
96
+ * onUnauthorized: () => router.replace('/login')
97
+ * });
98
+ */
99
+ declare function configureApiClient(config: ApiClientConfig): void;
100
+ /**
101
+ * Get the current global configuration
102
+ * @throws Error if configuration is not set
103
+ */
104
+ declare function getConfig(): ApiClientConfig;
105
+ /**
106
+ * Check if the API client is configured
107
+ */
108
+ declare function isConfigured(): boolean;
109
+
110
+ /**
111
+ * Creates an API client for GET requests
112
+ * @param endpoint - URL string or function that generates URL from params
113
+ * @param fetchConfig - Request configuration
114
+ * @returns Object with fetch method and useFetch hook
115
+ *
116
+ * @example
117
+ * const userApi = apiClient<User, { id: string }>('/api/users/:id')
118
+ * const { data } = userApi.useFetch({ id: '123' })
119
+ */
120
+ declare function apiClient<ResponseType = void, RequestParamsType = void, ErrorResponseType = unknown>(endpoint: string | ((arg0: RequestParamsType) => string), fetchConfig?: RequestConfig): ApiClientReturn<ResponseType, RequestParamsType, ErrorResponseType>;
121
+ /**
122
+ * Creates an API client for mutation requests (POST/PUT/PATCH/DELETE)
123
+ * @param endpoint - URL string or function that generates URL from params
124
+ * @param fetchConfig - Request configuration
125
+ * @returns Object with mutate method and useMutation hook
126
+ *
127
+ * @example
128
+ * const createUserApi = apiMutation<User, CreateUserRequest>('/api/users', { method: 'POST' })
129
+ * const { mutate, isLoading } = createUserApi.useMutation()
130
+ */
131
+ declare function apiMutation<ResponseType = void, RequestParamsType = void, ErrorResponseType = unknown>(endpoint: string | ((arg0: RequestParamsType) => string), fetchConfig?: RequestConfig): ApiMutationReturn<ResponseType, RequestParamsType, ErrorResponseType>;
132
+ /**
133
+ * Creates an API client for paginated requests
134
+ * @param endpoint - URL string or function that generates URL from params
135
+ * @param fetchConfig - Request configuration
136
+ * @param options - Pagination options (data/total extractors)
137
+ * @returns Object with usePaginate hook
138
+ *
139
+ * @example
140
+ * const usersApi = apiPaginate<UsersResponse, User[], { search?: string }>('/api/users')
141
+ * const { data, fetchNextPage, hasNextPage } = usersApi.usePaginate()
142
+ */
143
+ declare function apiPaginate<ResponseType extends {
144
+ data: TData;
145
+ total?: number;
146
+ page?: number;
147
+ }, TData extends unknown[], RequestParamsType = void, ErrorResponseType = unknown>(endpoint: string | ((arg0: RequestParamsType) => string), fetchConfig?: RequestConfig, options?: {
148
+ dataExtractor?: (response: ResponseType) => TData;
149
+ totalExtractor?: (response: ResponseType) => number;
150
+ }): ApiPaginateReturn<ResponseType, RequestParamsType, TData, ErrorResponseType>;
151
+
152
+ export { type ApiClientConfig, type IHttpClient, type ResponseWrapper, type UseFetchOptions, type UseFetchResult, type UseMutationOptions, type UseMutationResult, type UsePaginateOptions, type UsePaginateResult, apiMutation, apiPaginate, configureApiClient, apiClient as default, getConfig, isConfigured };