vue-api-kit 1.1.1 → 1.2.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/README.md CHANGED
@@ -34,6 +34,23 @@ const api = createApiClient({
34
34
  name: z.string(),
35
35
  email: z.string()
36
36
  })
37
+ },
38
+ // POST query for complex searches
39
+ searchUsers: {
40
+ method: 'POST',
41
+ path: '/users/search',
42
+ data: z.object({
43
+ query: z.string(),
44
+ filters: z.object({
45
+ active: z.boolean().optional(),
46
+ role: z.string().optional()
47
+ }).optional()
48
+ }),
49
+ response: z.array(z.object({
50
+ id: z.number(),
51
+ name: z.string(),
52
+ email: z.string()
53
+ }))
37
54
  }
38
55
  },
39
56
  mutations: {
@@ -70,7 +87,11 @@ const api = createApiClient({
70
87
 
71
88
  ## 📖 Usage in Vue Components
72
89
 
73
- ### Queries (GET requests)
90
+ ### Queries (GET and POST requests)
91
+
92
+ Queries support both GET and POST methods, allowing you to fetch data with complex search criteria.
93
+
94
+ #### GET Queries
74
95
 
75
96
  ```vue
76
97
  <script setup lang="ts">
@@ -111,6 +132,51 @@ const { result: data } = api.query.getUsers({
111
132
  </template>
112
133
  ```
113
134
 
135
+ #### POST Queries
136
+
137
+ POST queries are perfect for complex searches, filtering, or any operation that requires sending data in the request body.
138
+
139
+ ```vue
140
+ <script setup lang="ts">
141
+ import { api } from './api';
142
+ import { ref } from 'vue';
143
+
144
+ const searchTerm = ref('');
145
+
146
+ const { result, isLoading, refetch } = api.query.searchUsers({
147
+ data: {
148
+ query: searchTerm.value,
149
+ filters: {
150
+ active: true,
151
+ role: 'admin'
152
+ }
153
+ },
154
+ loadOnMount: false,
155
+ onResult: (data) => {
156
+ console.log('Search results:', data);
157
+ }
158
+ });
159
+
160
+ const handleSearch = () => {
161
+ refetch();
162
+ };
163
+ </script>
164
+
165
+ <template>
166
+ <div>
167
+ <input v-model="searchTerm" @keyup.enter="handleSearch" />
168
+ <button @click="handleSearch" :disabled="isLoading">Search</button>
169
+
170
+ <div v-if="isLoading">Searching...</div>
171
+ <div v-else-if="result">
172
+ <div v-for="user in result" :key="user.id">
173
+ {{ user.name }}
174
+ </div>
175
+ </div>
176
+ </div>
177
+ </template>
178
+ ```
179
+
114
180
  ### Mutations (POST, PUT, DELETE)
115
181
 
116
182
  ```vue
@@ -156,11 +222,13 @@ async function handleSubmit() {
156
222
  - ✅ **Zod Validation**: Built-in request/response validation
157
223
  - ✅ **Vue 3 Composition API**: Reactive state management
158
224
  - ✅ **Auto Loading States**: Built-in loading, error, and success states
159
- - ✅ **File Upload**: Support for multipart/form-data
225
+ - ✅ **POST Queries**: Support for both GET and POST methods in queries for complex data retrieval
226
+ - ✅ **File Upload**: Support for multipart/form-data in mutations
160
227
  - ✅ **Path Parameters**: Automatic path parameter replacement
161
228
  - ✅ **Debouncing**: Built-in request debouncing
162
229
  - ✅ **Global Error Handling**: Centralized error management
163
230
  - ✅ **Request Interceptors**: Modify requests before sending
231
+ - ✅ **Fully Typed**: Complete type inference for params, data, and response
164
232
 
165
233
  ## 🔧 Advanced Configuration
166
234
 
@@ -207,6 +275,8 @@ const api = createApiClient({
207
275
 
208
276
  ## 📤 File Upload Example
209
277
 
278
+ File uploads are supported in mutations using the `isMultipart` flag.
279
+
210
280
  ```typescript
211
281
  const api = createApiClient({
212
282
  baseURL: 'https://api.example.com',
@@ -230,7 +300,7 @@ const { mutate, uploadProgress } = api.mutation.uploadImage({
230
300
  });
231
301
 
232
302
  async function handleUpload(file: File) {
233
- await mutate({ file });
303
+ await mutate({ data: { file } });
234
304
  }
235
305
  ```
236
306
 
@@ -42,6 +42,6 @@ import { ApiClientOptions, ApiMutation, ApiQuery, Infer, MutationResult, QueryRe
42
42
  * const { mutate } = api.mutation.createUser();
43
43
  */
44
44
  export declare function createApiClient<Q extends Record<string, ApiQuery>, M extends Record<string, ApiMutation>>(options: ApiClientOptions<Q, M>): {
45
- query: { [K in keyof Q]: (options?: UseQueryOptions<Infer<Q[K]["params"]>, Infer<Q[K]["response"]>>) => QueryResult<Infer<Q[K]["response"]>>; };
45
+ query: { [K in keyof Q]: (options?: UseQueryOptions<Infer<Q[K]["params"]>, Infer<Q[K]["data"]>, Infer<Q[K]["response"]>>) => QueryResult<Infer<Q[K]["response"]>>; };
46
46
  mutation: { [K_1 in keyof M]: (options?: UseMutationOptions<Infer<M[K_1]["response"]>>) => MutationResult<Infer<M[K_1]["response"]>, Infer<M[K_1]["data"]>, Infer<M[K_1]["params"]>>; };
47
47
  };
@@ -17,8 +17,9 @@ export type HTTPMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
17
17
  */
18
18
  export type Infer<T> = T extends ZodType<infer U> ? U : any;
19
19
  /**
20
- * Defines a query (GET request) endpoint configuration
21
- * @template TParams - Zod schema for query parameters
20
+ * Defines a query endpoint configuration (supports GET and POST methods)
21
+ * @template TParams - Zod schema for query/path parameters
22
+ * @template TData - Zod schema for request body (POST only)
22
23
  * @template TResponse - Zod schema for response data
23
24
  * @example
24
25
  * const getUsers: ApiQuery = {
@@ -27,11 +28,19 @@ export type Infer<T> = T extends ZodType<infer U> ? U : any;
27
28
  * params: z.object({ page: z.number() }),
28
29
  * response: z.array(z.object({ id: z.number(), name: z.string() }))
29
30
  * };
31
+ * @example
32
+ * const searchUsers: ApiQuery = {
33
+ * method: "POST",
34
+ * path: "/users/search",
35
+ * data: z.object({ query: z.string() }),
36
+ * response: z.array(z.object({ id: z.number(), name: z.string() }))
37
+ * };
30
38
  */
31
- export interface ApiQuery<TParams extends ZodType<any> | undefined = ZodType<any> | undefined, TResponse extends ZodType<any> | undefined = ZodType<any> | undefined> {
32
- method?: Extract<HTTPMethod, "GET">;
39
+ export interface ApiQuery<TParams extends ZodType<any> | undefined = ZodType<any> | undefined, TData extends ZodType<any> | undefined = ZodType<any> | undefined, TResponse extends ZodType<any> | undefined = ZodType<any> | undefined> {
40
+ method?: Extract<HTTPMethod, "GET" | "POST">;
33
41
  path: string;
34
42
  params?: TParams;
43
+ data?: TData;
35
44
  response?: TResponse;
36
45
  }
37
46
  /**
@@ -88,6 +97,7 @@ export interface ApiClientOptions<Q extends Record<string, ApiQuery> = Record<st
88
97
  /**
89
98
  * Options for configuring a query hook
90
99
  * @template TParams - Type of query parameters
100
+ * @template TData - Type of request body data (for POST queries)
91
101
  * @template TResult - Type of result data
92
102
  * @example
93
103
  * const options: UseQueryOptions = {
@@ -97,14 +107,22 @@ export interface ApiClientOptions<Q extends Record<string, ApiQuery> = Record<st
97
107
  * onResult: (data) => console.log(data),
98
108
  * onError: (error) => console.error(error)
99
109
  * };
110
+ * @example
111
+ * const options: UseQueryOptions = {
112
+ * data: { query: "search term" },
113
+ * loadOnMount: true,
114
+ * onResult: (data) => console.log(data)
115
+ * };
100
116
  */
101
- export interface UseQueryOptions<TParams = any, TResult = any> {
117
+ export interface UseQueryOptions<TParams = any, TData = any, TResult = any> {
102
118
  params?: TParams;
119
+ data?: TData;
103
120
  loadOnMount?: boolean;
104
121
  debounce?: number;
105
122
  onResult?: (result: TResult) => void;
106
123
  onError?: (error: AxiosError | ZodError | Error) => void;
107
124
  onZodError?: (issues: Omit<$ZodIssue, "input">[]) => void;
125
+ onUploadProgress?: (progress: number) => void;
108
126
  }
109
127
  /**
110
128
  * Options for configuring a mutation hook
@@ -131,6 +149,7 @@ export interface UseMutationOptions<TResult = any> {
131
149
  * // isLoading.value indicates loading state
132
150
  * // errorMessage.value contains any error message
133
151
  * // refetch() to manually trigger a new request
152
+ * // uploadProgress.value shows upload progress (0-100) for POST queries with file uploads
134
153
  */
135
154
  export interface QueryResult<TResult> {
136
155
  result: Ref<TResult | undefined>;
@@ -138,6 +157,7 @@ export interface QueryResult<TResult> {
138
157
  zodErrors: Ref<Omit<$ZodIssue, "input">[] | undefined>;
139
158
  isLoading: Ref<boolean>;
140
159
  isDone: Ref<boolean>;
160
+ uploadProgress: Ref<number>;
141
161
  refetch: () => Promise<void>;
142
162
  }
143
163
  /**