@ahoo-wang/fetcher-react 3.9.3 → 3.9.5

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/README.md CHANGED
@@ -131,30 +131,26 @@ The `createExecuteApiHooks` function automatically discovers all function method
131
131
 
132
132
  ```typescript jsx
133
133
  import { createExecuteApiHooks } from '@ahoo-wang/fetcher-react';
134
+ import { api, get, post, patch, path, body, autoGeneratedError } from '@ahoo-wang/fetcher-decorator';
134
135
 
135
- // Define your API object (can be a class instance or plain object)
136
+ // Define your API service using decorators
137
+ import { api, get, post, patch, path, body, autoGeneratedError } from '@ahoo-wang/fetcher-decorator';
138
+
139
+ @api('/users')
136
140
  class UserApi {
137
- async getUser(id: string): Promise<User> {
138
- const response = await fetch(`/api/users/${id}`);
139
- return response.json();
141
+ @get('/{id}')
142
+ getUser(@path('id') id: string): Promise<User> {
143
+ throw autoGeneratedError(id);
140
144
  }
141
145
 
142
- async createUser(data: { name: string; email: string }): Promise<User> {
143
- const response = await fetch('/api/users', {
144
- method: 'POST',
145
- headers: { 'Content-Type': 'application/json' },
146
- body: JSON.stringify(data),
147
- });
148
- return response.json();
146
+ @post('')
147
+ createUser(@body() data: { name: string; email: string }): Promise<User> {
148
+ throw autoGeneratedError(data);
149
149
  }
150
150
 
151
- async updateUser(id: string, updates: Partial<User>): Promise<User> {
152
- const response = await fetch(`/api/users/${id}`, {
153
- method: 'PATCH',
154
- headers: { 'Content-Type': 'application/json' },
155
- body: JSON.stringify(updates),
156
- });
157
- return response.json();
151
+ @patch('/{id}')
152
+ updateUser(@path('id') id: string, @body() updates: Partial<User>): Promise<User> {
153
+ throw autoGeneratedError(id, updates);
158
154
  }
159
155
  }
160
156
 
@@ -223,11 +219,19 @@ class ApiError extends Error {
223
219
  }
224
220
 
225
221
  // Generate hooks with custom error type
222
+ @api('/data')
223
+ class DataApi {
224
+ @get('/{id}')
225
+ getData(@path('id') id: string): Promise<Data> {
226
+ throw autoGeneratedError(id);
227
+ }
228
+ }
229
+
226
230
  const apiHooks = createExecuteApiHooks<
227
231
  { getData: (id: string) => Promise<Data> },
228
232
  ApiError
229
233
  >({
230
- api: { getData },
234
+ api: new DataApi(),
231
235
  errorType: ApiError,
232
236
  });
233
237
 
@@ -295,6 +299,183 @@ function ApiComponent() {
295
299
  }
296
300
  ```
297
301
 
302
+ #### createQueryApiHooks
303
+
304
+ 🚀 **Automatic Type-Safe Query API Hooks Generation** - Generate fully typed React query hooks from API objects with automatic query state management, auto-execution, and advanced execution control.
305
+
306
+ The `createQueryApiHooks` function automatically discovers query methods from an API object and creates corresponding React hooks that extend `useQuery`. Each generated hook provides automatic query parameter management, state management, and supports custom execution callbacks with type-safe query access.
307
+
308
+ **Key Features:**
309
+
310
+ - **Automatic Method Discovery**: Traverses object properties and prototype chains
311
+ - **Type-Safe Query Hooks**: Full TypeScript inference for query parameters and return types
312
+ - **Query State Management**: Built-in `setQuery` and `getQuery` for parameter management
313
+ - **Auto-Execution**: Optional automatic execution when query parameters change
314
+ - **Execution Control**: `onBeforeExecute` callback for query inspection/modification and abort controller access
315
+ - **Custom Error Types**: Support for specifying error types beyond the default `FetcherError`
316
+
317
+ ```typescript jsx
318
+ import { createQueryApiHooks } from '@ahoo-wang/fetcher-react';
319
+ import { api, get, post, patch, path, body, autoGeneratedError } from '@ahoo-wang/fetcher-decorator';
320
+
321
+ // Define your API service using decorators
322
+ @api('/users')
323
+ class UserApi {
324
+ @get('')
325
+ getUsers(query: UserListQuery, attributes?: Record<string, any>): Promise<User[]> {
326
+ throw autoGeneratedError(query, attributes);
327
+ }
328
+
329
+ @get('/{id}')
330
+ getUser(query: { id: string }, attributes?: Record<string, any>): Promise<User> {
331
+ throw autoGeneratedError(query, attributes);
332
+ }
333
+
334
+ @post('')
335
+ createUser(query: { name: string; email: string }, attributes?: Record<string, any>): Promise<User> {
336
+ throw autoGeneratedError(query, attributes);
337
+ }
338
+ }
339
+
340
+ const apiHooks = createQueryApiHooks({ api: new UserApi() });
341
+
342
+ function UserListComponent() {
343
+ const { loading, result, error, execute, setQuery, getQuery } = apiHooks.useGetUsers({
344
+ initialQuery: { page: 1, limit: 10 },
345
+ autoExecute: true,
346
+ onBeforeExecute: (abortController, query) => {
347
+ // query is fully typed as UserListQuery
348
+ console.log('Executing query:', query);
349
+ // Modify query parameters in place if needed
350
+ query.page = Math.max(1, query.page);
351
+ },
352
+ });
353
+
354
+ const handlePageChange = (page: number) => {
355
+ // Automatically updates query and triggers execution (if autoExecute: true)
356
+ setQuery({ ...getQuery(), page });
357
+ };
358
+
359
+ if (loading) return <div>Loading...</div>;
360
+ if (error) return <div>Error: {error.message}</div>;
361
+
362
+ return (
363
+ <div>
364
+ <button onClick={() => handlePageChange(2)}>Go to page 2</button>
365
+ {result?.map(user => (
366
+ <div key={user.id}>{user.name}</div>
367
+ ))}
368
+ </div>
369
+ );
370
+ }
371
+
372
+ function UserDetailComponent() {
373
+ const { result: user, execute } = apiHooks.useGetUser({
374
+ initialQuery: { id: '123' },
375
+ });
376
+
377
+ return (
378
+ <div>
379
+ <button onClick={execute}>Load User</button>
380
+ {user && <div>User: {user.name}</div>}
381
+ </div>
382
+ );
383
+ }
384
+ ```
385
+
386
+ **Custom Error Types:**
387
+
388
+ ```typescript jsx
389
+ import { createQueryApiHooks } from '@ahoo-wang/fetcher-react';
390
+
391
+ // Define custom error type
392
+ class ApiError extends Error {
393
+ constructor(
394
+ public statusCode: number,
395
+ message: string,
396
+ ) {
397
+ super(message);
398
+ }
399
+ }
400
+
401
+ // Generate query hooks with custom error type
402
+ @api('/data')
403
+ class DataApi {
404
+ @get('/{id}')
405
+ getData(
406
+ query: { id: string },
407
+ attributes?: Record<string, any>,
408
+ ): Promise<Data> {
409
+ throw autoGeneratedError(query, attributes);
410
+ }
411
+ }
412
+
413
+ const apiHooks = createQueryApiHooks<
414
+ {
415
+ getData: (
416
+ query: { id: string },
417
+ attributes?: Record<string, any>,
418
+ ) => Promise<Data>;
419
+ },
420
+ ApiError
421
+ >({
422
+ api: new DataApi(),
423
+ errorType: ApiError,
424
+ });
425
+
426
+ function MyComponent() {
427
+ const { error, execute } = apiHooks.useGetData();
428
+
429
+ // error is now typed as ApiError | undefined
430
+ if (error) {
431
+ console.log('Status code:', error.statusCode); // TypeScript knows about statusCode
432
+ }
433
+ }
434
+ ```
435
+
436
+ **Advanced Usage with Manual Query Management:**
437
+
438
+ ```typescript jsx
439
+ import { createQueryApiHooks } from '@ahoo-wang/fetcher-react';
440
+
441
+ const apiHooks = createQueryApiHooks({ api: userApi });
442
+
443
+ function SearchComponent() {
444
+ const { loading, result, setQuery, getQuery } = apiHooks.useGetUsers({
445
+ initialQuery: { search: '', page: 1 },
446
+ autoExecute: false, // Manual execution control
447
+ });
448
+
449
+ const handleSearch = (searchTerm: string) => {
450
+ // Update query without automatic execution
451
+ setQuery({ search: searchTerm, page: 1 });
452
+ };
453
+
454
+ const handleSearchSubmit = () => {
455
+ // Manually execute with current query
456
+ apiHooks.useGetUsers().execute();
457
+ };
458
+
459
+ const currentQuery = getQuery(); // Access current query parameters
460
+
461
+ return (
462
+ <div>
463
+ <input
464
+ value={currentQuery.search}
465
+ onChange={(e) => handleSearch(e.target.value)}
466
+ placeholder="Search users..."
467
+ />
468
+ <button onClick={handleSearchSubmit} disabled={loading}>
469
+ {loading ? 'Searching...' : 'Search'}
470
+ </button>
471
+ {result?.map(user => (
472
+ <div key={user.id}>{user.name}</div>
473
+ ))}
474
+ </div>
475
+ );
476
+ }
477
+ ```
478
+
298
479
  ### Core Hooks
299
480
 
300
481
  #### useExecutePromise Hook
package/README.zh-CN.md CHANGED
@@ -129,30 +129,26 @@ function App() {
129
129
 
130
130
  ```typescript jsx
131
131
  import { createExecuteApiHooks } from '@ahoo-wang/fetcher-react';
132
+ import { api, get, post, patch, path, body, autoGeneratedError } from '@ahoo-wang/fetcher-decorator';
132
133
 
133
- // 定义您的 API 对象(可以是类实例或普通对象)
134
+ // 使用装饰器定义您的 API 服务
135
+ import { api, get, post, patch, path, body, autoGeneratedError } from '@ahoo-wang/fetcher-decorator';
136
+
137
+ @api('/users')
134
138
  class UserApi {
135
- async getUser(id: string): Promise<User> {
136
- const response = await fetch(`/api/users/${id}`);
137
- return response.json();
139
+ @get('/{id}')
140
+ getUser(@path('id') id: string): Promise<User> {
141
+ throw autoGeneratedError(id);
138
142
  }
139
143
 
140
- async createUser(data: { name: string; email: string }): Promise<User> {
141
- const response = await fetch('/api/users', {
142
- method: 'POST',
143
- headers: { 'Content-Type': 'application/json' },
144
- body: JSON.stringify(data),
145
- });
146
- return response.json();
144
+ @post('')
145
+ createUser(@body() data: { name: string; email: string }): Promise<User> {
146
+ throw autoGeneratedError(data);
147
147
  }
148
148
 
149
- async updateUser(id: string, updates: Partial<User>): Promise<User> {
150
- const response = await fetch(`/api/users/${id}`, {
151
- method: 'PATCH',
152
- headers: { 'Content-Type': 'application/json' },
153
- body: JSON.stringify(updates),
154
- });
155
- return response.json();
149
+ @patch('/{id}')
150
+ updateUser(@path('id') id: string, @body() updates: Partial<User>): Promise<User> {
151
+ throw autoGeneratedError(id, updates);
156
152
  }
157
153
  }
158
154
 
@@ -221,11 +217,19 @@ class ApiError extends Error {
221
217
  }
222
218
 
223
219
  // 使用自定义错误类型生成 hooks
220
+ @api('/data')
221
+ class DataApi {
222
+ @get('/{id}')
223
+ getData(@path('id') id: string): Promise<Data> {
224
+ throw autoGeneratedError(id);
225
+ }
226
+ }
227
+
224
228
  const apiHooks = createExecuteApiHooks<
225
229
  { getData: (id: string) => Promise<Data> },
226
230
  ApiError
227
231
  >({
228
- api: { getData },
232
+ api: new DataApi(),
229
233
  errorType: ApiError,
230
234
  });
231
235
 
@@ -293,6 +297,183 @@ function ApiComponent() {
293
297
  }
294
298
  ```
295
299
 
300
+ #### createQueryApiHooks
301
+
302
+ 🚀 **自动类型安全查询 API Hooks 生成** - 从 API 对象自动生成完全类型化的 React 查询 hooks,具有自动查询状态管理、自动执行和高级执行控制。
303
+
304
+ `createQueryApiHooks` 函数自动发现 API 对象中的查询方法,并创建相应的扩展 `useQuery` 的 React hooks。每个生成的 hook 都提供自动查询参数管理、状态管理和对具有类型安全查询访问的自定义执行回调的支持。
305
+
306
+ **主要特性:**
307
+
308
+ - **自动方法发现**:遍历对象属性和原型链
309
+ - **类型安全查询 Hooks**:查询参数和返回类型的完整 TypeScript 推断
310
+ - **查询状态管理**:内置 `setQuery` 和 `getQuery` 进行参数管理
311
+ - **自动执行**:查询参数更改时可选的自动执行
312
+ - **执行控制**:`onBeforeExecute` 回调用于查询检查/修改和中止控制器访问
313
+ - **自定义错误类型**:支持指定超出默认 `FetcherError` 的错误类型
314
+
315
+ ```typescript jsx
316
+ import { createQueryApiHooks } from '@ahoo-wang/fetcher-react';
317
+ import { api, get, post, patch, path, body, autoGeneratedError } from '@ahoo-wang/fetcher-decorator';
318
+
319
+ // 使用装饰器定义您的 API 服务
320
+ @api('/users')
321
+ class UserApi {
322
+ @get('')
323
+ getUsers(query: UserListQuery, attributes?: Record<string, any>): Promise<User[]> {
324
+ throw autoGeneratedError(query, attributes);
325
+ }
326
+
327
+ @get('/{id}')
328
+ getUser(query: { id: string }, attributes?: Record<string, any>): Promise<User> {
329
+ throw autoGeneratedError(query, attributes);
330
+ }
331
+
332
+ @post('')
333
+ createUser(query: { name: string; email: string }, attributes?: Record<string, any>): Promise<User> {
334
+ throw autoGeneratedError(query, attributes);
335
+ }
336
+ }
337
+
338
+ const apiHooks = createQueryApiHooks({ api: new UserApi() });
339
+
340
+ function UserListComponent() {
341
+ const { loading, result, error, execute, setQuery, getQuery } = apiHooks.useGetUsers({
342
+ initialQuery: { page: 1, limit: 10 },
343
+ autoExecute: true,
344
+ onBeforeExecute: (abortController, query) => {
345
+ // query 是完全类型化的 UserListQuery
346
+ console.log('正在执行查询:', query);
347
+ // 如果需要,可以就地修改查询参数
348
+ query.page = Math.max(1, query.page);
349
+ },
350
+ });
351
+
352
+ const handlePageChange = (page: number) => {
353
+ // 自动更新查询并触发执行(如果 autoExecute: true)
354
+ setQuery({ ...getQuery(), page });
355
+ };
356
+
357
+ if (loading) return <div>正在加载...</div>;
358
+ if (error) return <div>错误: {error.message}</div>;
359
+
360
+ return (
361
+ <div>
362
+ <button onClick={() => handlePageChange(2)}>转到第2页</button>
363
+ {result?.map(user => (
364
+ <div key={user.id}>{user.name}</div>
365
+ ))}
366
+ </div>
367
+ );
368
+ }
369
+
370
+ function UserDetailComponent() {
371
+ const { result: user, execute } = apiHooks.useGetUser({
372
+ initialQuery: { id: '123' },
373
+ });
374
+
375
+ return (
376
+ <div>
377
+ <button onClick={execute}>加载用户</button>
378
+ {user && <div>用户: {user.name}</div>}
379
+ </div>
380
+ );
381
+ }
382
+ ```
383
+
384
+ **自定义错误类型:**
385
+
386
+ ```typescript jsx
387
+ import { createQueryApiHooks } from '@ahoo-wang/fetcher-react';
388
+
389
+ // 定义自定义错误类型
390
+ class ApiError extends Error {
391
+ constructor(
392
+ public statusCode: number,
393
+ message: string,
394
+ ) {
395
+ super(message);
396
+ }
397
+ }
398
+
399
+ // 使用自定义错误类型生成查询 hooks
400
+ @api('/data')
401
+ class DataApi {
402
+ @get('/{id}')
403
+ getData(
404
+ query: { id: string },
405
+ attributes?: Record<string, any>,
406
+ ): Promise<Data> {
407
+ throw autoGeneratedError(query, attributes);
408
+ }
409
+ }
410
+
411
+ const apiHooks = createQueryApiHooks<
412
+ {
413
+ getData: (
414
+ query: { id: string },
415
+ attributes?: Record<string, any>,
416
+ ) => Promise<Data>;
417
+ },
418
+ ApiError
419
+ >({
420
+ api: new DataApi(),
421
+ errorType: ApiError,
422
+ });
423
+
424
+ function MyComponent() {
425
+ const { error, execute } = apiHooks.useGetData();
426
+
427
+ // error 现在类型化为 ApiError | undefined
428
+ if (error) {
429
+ console.log('状态码:', error.statusCode); // TypeScript 知道 statusCode
430
+ }
431
+ }
432
+ ```
433
+
434
+ **高级用法与手动查询管理:**
435
+
436
+ ```typescript jsx
437
+ import { createQueryApiHooks } from '@ahoo-wang/fetcher-react';
438
+
439
+ const apiHooks = createQueryApiHooks({ api: userApi });
440
+
441
+ function SearchComponent() {
442
+ const { loading, result, setQuery, getQuery } = apiHooks.useGetUsers({
443
+ initialQuery: { search: '', page: 1 },
444
+ autoExecute: false, // 手动执行控制
445
+ });
446
+
447
+ const handleSearch = (searchTerm: string) => {
448
+ // 更新查询而不自动执行
449
+ setQuery({ search: searchTerm, page: 1 });
450
+ };
451
+
452
+ const handleSearchSubmit = () => {
453
+ // 使用当前查询手动执行
454
+ apiHooks.useGetUsers().execute();
455
+ };
456
+
457
+ const currentQuery = getQuery(); // 访问当前查询参数
458
+
459
+ return (
460
+ <div>
461
+ <input
462
+ value={currentQuery.search}
463
+ onChange={(e) => handleSearch(e.target.value)}
464
+ placeholder="搜索用户..."
465
+ />
466
+ <button onClick={handleSearchSubmit} disabled={loading}>
467
+ {loading ? '搜索中...' : '搜索'}
468
+ </button>
469
+ {result?.map(user => (
470
+ <div key={user.id}>{user.name}</div>
471
+ ))}
472
+ </div>
473
+ );
474
+ }
475
+ ```
476
+
296
477
  ### 核心 Hooks
297
478
 
298
479
  #### useExecutePromise
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Shared utilities and types for API hooks generation.
3
+ */
4
+ /**
5
+ * Converts a method name to a React hook name by prefixing with 'use' and capitalizing the first letter.
6
+ * @param methodName - The method name to convert.
7
+ * @returns The converted hook name.
8
+ * @throws {Error} If methodName is empty or null.
9
+ * @example
10
+ * methodNameToHookName('getUser') // 'useGetUser'
11
+ * methodNameToHookName('createPost') // 'useCreatePost'
12
+ * methodNameToHookName('APIGetData') // 'useAPIGetData'
13
+ */
14
+ export declare function methodNameToHookName(methodName: string): string;
15
+ /**
16
+ * Collects all function methods from an object and its prototype chain.
17
+ * @param obj - The object to collect methods from.
18
+ * @returns A map of method names to bound methods.
19
+ */
20
+ export declare function collectMethods<T extends (...args: any[]) => Promise<any>>(obj: Record<string, any>): Map<string, T>;
21
+ /**
22
+ * Common configuration options for API hooks creation functions.
23
+ * @template API - The API object type.
24
+ */
25
+ export interface CreateApiHooksOptions<API extends Record<string, any>> {
26
+ /**
27
+ * The API object containing methods to be wrapped into hooks.
28
+ */
29
+ api: API;
30
+ }
31
+ /**
32
+ * Utility type to extract the hook name from a method name.
33
+ * @template K - The method name key.
34
+ */
35
+ export type HookName<K extends string> = `use${Capitalize<K>}`;
36
+ /**
37
+ * Utility type to check if a value is a function that returns a Promise.
38
+ * @template T - The value to check.
39
+ */
40
+ export type IsPromiseFunction<T> = T extends (...args: any[]) => Promise<any> ? true : false;
41
+ /**
42
+ * Utility type to extract the parameters of a promise-returning function.
43
+ * @template T - The function type.
44
+ */
45
+ export type FunctionParameters<T> = T extends (...args: infer P) => Promise<any> ? P : never;
46
+ /**
47
+ * Utility type to extract the resolved return type of a promise-returning function.
48
+ * @template T - The function type.
49
+ */
50
+ export type FunctionReturnType<T> = T extends (...args: any[]) => Promise<infer R> ? Awaited<R> : never;
51
+ /**
52
+ * Utility type for API method signatures.
53
+ * @template TArgs - Parameter types.
54
+ * @template TReturn - Return type.
55
+ */
56
+ export type ApiMethod<TArgs extends any[] = any[], TReturn = any> = (...args: TArgs) => Promise<TReturn>;
57
+ /**
58
+ * Utility type for query method signatures (with query, attributes, abortController).
59
+ * @template Q - Query type.
60
+ * @template TReturn - Return type.
61
+ */
62
+ export type QueryMethod<Q = any, TReturn = any> = (query: Q, attributes?: Record<string, any>, abortController?: AbortController) => Promise<TReturn>;
63
+ /**
64
+ * Common callback type for pre-execution hooks.
65
+ * @template TParams - The parameters type passed to the callback.
66
+ */
67
+ export type OnBeforeExecuteCallback<TParams> = (abortController: AbortController | undefined, params: TParams) => void;
68
+ /**
69
+ * Utility type to create API hooks mapping.
70
+ * @template API - The API object type.
71
+ * @template MethodType - The method signature type.
72
+ * @template HookType - The hook function type.
73
+ * @template E - Error type.
74
+ */
75
+ export type ApiHooksMapping<API extends Record<string, any>, MethodType extends (...args: any[]) => Promise<any>, HookType> = {
76
+ [K in keyof API as API[K] extends MethodType ? HookName<string & K> : never]: API[K] extends MethodType ? HookType : never;
77
+ };
78
+ //# sourceMappingURL=apiHooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiHooks.d.ts","sourceRoot":"","sources":["../../src/api/apiHooks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAQ/D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EACvE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACvB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CA6BhB;AAMD;;;GAGG;AACH,MAAM,WAAW,qBAAqB,CAAC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IACpE;;OAEG;IACH,GAAG,EAAE,GAAG,CAAC;CACV;AAED;;;GAGG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;AAE/D;;;GAGG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,GACzE,IAAI,GACJ,KAAK,CAAC;AAEV;;;GAGG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,GAC5E,CAAC,GACD,KAAK,CAAC;AAEV;;;GAGG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,CAAC,SAAS,CAC5C,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,OAAO,CAAC,MAAM,CAAC,CAAC,GACjB,OAAO,CAAC,CAAC,CAAC,GACV,KAAK,CAAC;AAEV;;;;GAIG;AACH,MAAM,MAAM,SAAS,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,OAAO,GAAG,GAAG,IAAI,CAClE,GAAG,IAAI,EAAE,KAAK,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;;;GAIG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,CAChD,KAAK,EAAE,CAAC,EACR,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChC,eAAe,CAAC,EAAE,eAAe,KAC9B,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;;GAGG;AACH,MAAM,MAAM,uBAAuB,CAAC,OAAO,IAAI,CAC7C,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,MAAM,EAAE,OAAO,KACZ,IAAI,CAAC;AAEV;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,CACzB,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,UAAU,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EACnD,QAAQ,IACN;KACD,CAAC,IAAI,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,UAAU,GACxC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,GACpB,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,UAAU,GAAG,QAAQ,GAAG,KAAK;CACzD,CAAC"}
@@ -1,14 +1,17 @@
1
1
  import { UseExecutePromiseReturn, UseExecutePromiseOptions } from '../core';
2
2
  import { FetcherError } from '@ahoo-wang/fetcher';
3
+ import { CreateApiHooksOptions, HookName, ApiMethod, FunctionParameters, FunctionReturnType, OnBeforeExecuteCallback } from './apiHooks';
3
4
  /**
4
5
  * Configuration options for createExecuteApiHooks.
5
6
  * @template API - The API object type containing methods that return promises.
6
7
  */
7
- export interface CreateExecuteApiHooksOptions<API extends Record<string, any>> {
8
- /**
9
- * The API object containing methods to be wrapped into hooks.
10
- */
11
- api: API;
8
+ export interface CreateExecuteApiHooksOptions<API extends Record<string, any>> extends CreateApiHooksOptions<API> {
9
+ }
10
+ /**
11
+ * Configuration options for createQueryApiHooks.
12
+ * @template API - The API object type containing query methods.
13
+ */
14
+ export interface CreateQueryApiHooksOptions<API extends Record<string, any>> extends CreateApiHooksOptions<API> {
12
15
  }
13
16
  /**
14
17
  * Options for useApiMethodExecute hook.
@@ -34,7 +37,7 @@ export interface UseApiMethodExecuteOptions<TArgs = any[], TData = any, E = Fetc
34
37
  * }
35
38
  * }
36
39
  */
37
- onBeforeExecute?: (abortController: AbortController, args: TArgs) => void;
40
+ onBeforeExecute?: OnBeforeExecuteCallback<TArgs>;
38
41
  }
39
42
  /**
40
43
  * The return type of createExecuteApiHooks.
@@ -45,8 +48,8 @@ export interface UseApiMethodExecuteOptions<TArgs = any[], TData = any, E = Fetc
45
48
  * @template E - The error type for all hooks (defaults to FetcherError).
46
49
  */
47
50
  export type APIHooks<API extends Record<string, any>, E = FetcherError> = {
48
- [K in keyof API as API[K] extends (...args: any[]) => Promise<any> ? `use${Capitalize<string & K>}` : never]: API[K] extends (...args: any[]) => Promise<any> ? (options?: UseApiMethodExecuteOptions<Parameters<API[K]>, Awaited<ReturnType<API[K]>>, E>) => UseExecutePromiseReturn<Awaited<ReturnType<API[K]>>, E> & {
49
- execute: (...params: Parameters<API[K]>) => Promise<void>;
51
+ [K in keyof API as API[K] extends ApiMethod ? HookName<string & K> : never]: API[K] extends ApiMethod ? (options?: UseApiMethodExecuteOptions<FunctionParameters<API[K]>, FunctionReturnType<API[K]>, E>) => UseExecutePromiseReturn<FunctionReturnType<API[K]>, E> & {
52
+ execute: (...params: FunctionParameters<API[K]>) => Promise<void>;
50
53
  } : never;
51
54
  };
52
55
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"createExecuteApiHooks.d.ts","sourceRoot":"","sources":["../../src/api/createExecuteApiHooks.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,4BAA4B,CAAC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC3E;;OAEG;IACH,GAAG,EAAE,GAAG,CAAC;CACV;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B,CACzC,KAAK,GAAG,GAAG,EAAE,EACb,KAAK,GAAG,GAAG,EACX,CAAC,GAAG,YAAY,CAChB,SAAQ,wBAAwB,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1C;;;;;;;;;;;;;;;;OAgBG;IACH,eAAe,CAAC,EAAE,CAAC,eAAe,EAAE,eAAe,EAAE,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3E;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,CAAC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,IAAI;KACvE,CAAC,IAAI,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,GAC9D,MAAM,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,GAC9B,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,GACvD,CACA,OAAO,CAAC,EAAE,0BAA0B,CAClC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAClB,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAC3B,CAAC,CACF,KACE,uBAAuB,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAC7D,OAAO,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC3D,GACC,KAAK;CACV,CAAC;AAkGF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,CAAC,GAAG,YAAY,EAChB,OAAO,EAAE,4BAA4B,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAa9D"}
1
+ {"version":3,"file":"createExecuteApiHooks.d.ts","sourceRoot":"","sources":["../../src/api/createExecuteApiHooks.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,uBAAuB,EACvB,wBAAwB,EAEzB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAGL,qBAAqB,EACrB,QAAQ,EACR,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,WAAW,4BAA4B,CAC3C,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAC/B,SAAQ,qBAAqB,CAAC,GAAG,CAAC;CAAG;AAEvC;;;GAGG;AACH,MAAM,WAAW,0BAA0B,CACzC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAC/B,SAAQ,qBAAqB,CAAC,GAAG,CAAC;CAAG;AAEvC;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B,CACzC,KAAK,GAAG,GAAG,EAAE,EACb,KAAK,GAAG,GAAG,EACX,CAAC,GAAG,YAAY,CAChB,SAAQ,wBAAwB,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1C;;;;;;;;;;;;;;;;OAgBG;IACH,eAAe,CAAC,EAAE,uBAAuB,CAAC,KAAK,CAAC,CAAC;CAClD;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,CAAC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,IAAI;KACvE,CAAC,IAAI,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,SAAS,GACvC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,GACpB,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,SAAS,GAChC,CACE,OAAO,CAAC,EAAE,0BAA0B,CAClC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAC1B,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAC1B,CAAC,CACF,KACE,uBAAuB,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAC5D,OAAO,EAAE,CAAC,GAAG,MAAM,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACnE,GACD,KAAK;CACV,CAAC;AA4DF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,CAAC,GAAG,YAAY,EAChB,OAAO,EAAE,4BAA4B,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAa9D"}