@tpzdsp/next-toolkit 2.2.0 → 2.3.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/http/query.ts +120 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tpzdsp/next-toolkit",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "A reusable React component library for Next.js applications",
5
5
  "packageManager": "pnpm@11.5.3",
6
6
  "engines": {
package/src/http/query.ts CHANGED
@@ -9,9 +9,12 @@ import {
9
9
  type BetterFetchOption,
10
10
  } from '@better-fetch/fetch';
11
11
  import {
12
+ useMutation,
12
13
  useQuery,
13
14
  useSuspenseQuery,
14
15
  type QueryKey,
16
+ type UseMutationOptions,
17
+ type UseMutationResult,
15
18
  type UseQueryOptions,
16
19
  type UseQueryResult,
17
20
  type UseSuspenseQueryOptions,
@@ -84,8 +87,8 @@ type SchemaRoutesOf<Option extends CreateFetchOption> = Option extends {
84
87
  ? Routes
85
88
  : undefined;
86
89
 
87
- // We provide the `queryFn` and `queryKeys` automatically, so no need to let the user provide them.
88
- type OmitReactQueryKeys = 'queryKey' | 'queryFn';
90
+ // We provide these keys automatically, so no need to let the user provide them.
91
+ type OmitReactQueryKeys = 'queryKey' | 'queryFn' | 'mutationFn' | 'mutationKey';
89
92
 
90
93
  /**
91
94
  * A higher-order type that creates React Query hooks (`useBetterQuerySafe` and `useBetterSuspenseQuery`)
@@ -183,6 +186,75 @@ type ReactQueryBetterFetch = <
183
186
  OmitReactQueryKeys
184
187
  >,
185
188
  ): UseSuspenseQueryResult<Output>;
189
+
190
+ // Mutation query (error thrown)
191
+
192
+ // Overload that uses schema output (`RoutesWithOutput`)
193
+ useBetterMutation<
194
+ Error = ApiError,
195
+ Route extends RoutesWithOutput<Routes> = RoutesWithOutput<Routes>,
196
+ >(
197
+ route: Route,
198
+ // If the route requires an input, then expect options that provide that input, otherwise just expect options without inputs.
199
+ fetchOptions?: OptionsNoInputOutput,
200
+ queryOptions?: Omit<
201
+ UseMutationOptions<SchemaRouteOutput<Routes, Route>, Error, unknown, unknown>,
202
+ OmitReactQueryKeys
203
+ >,
204
+ ): UseMutationResult<
205
+ SchemaRouteOutput<Routes, Route>,
206
+ Error,
207
+ Route extends RoutesWithInput<Routes> ? OptionsWithInput<Routes, Route> : void
208
+ >;
209
+
210
+ // Overload that allows manual output type instead of schema (`RoutesWithoutOutput`)
211
+ useBetterMutation<
212
+ Output,
213
+ Error = ApiError,
214
+ Route extends RoutesWithoutOutput<Routes> = RoutesWithoutOutput<Routes>,
215
+ >(
216
+ route: Route,
217
+ fetchOptions?: OptionsNoInputOutput,
218
+ queryOptions?: Omit<UseMutationOptions<Output, Error, unknown, unknown>, OmitReactQueryKeys>,
219
+ ): UseMutationResult<
220
+ Output,
221
+ Error,
222
+ Route extends RoutesWithInput<Routes> ? OptionsWithInput<Routes, Route> : void
223
+ >;
224
+
225
+ // Safe mutation (error NOT thrown)
226
+
227
+ // Overload that uses schema output (`RoutesWithOutput`)
228
+ useBetterMutationSafe<
229
+ Error = ApiError,
230
+ Route extends RoutesWithOutput<Routes> = RoutesWithOutput<Routes>,
231
+ >(
232
+ route: Route,
233
+ fetchOptions?: OptionsNoInputOutput,
234
+ queryOptions?: Omit<
235
+ UseMutationOptions<SchemaRouteOutput<Routes, Route>, Error, unknown, unknown>,
236
+ OmitReactQueryKeys
237
+ >,
238
+ ): UseMutationResult<
239
+ SchemaRouteOutput<Routes, Route>,
240
+ Error,
241
+ Route extends RoutesWithInput<Routes> ? OptionsWithInput<Routes, Route> : void
242
+ >;
243
+
244
+ // Overload that allows manual output type instead of schema (`RoutesWithoutOutput`)
245
+ useBetterMutationSafe<
246
+ Output,
247
+ Error = ApiError,
248
+ Route extends RoutesWithoutOutput<Routes> = RoutesWithoutOutput<Routes>,
249
+ >(
250
+ route: Route,
251
+ fetchOptions?: OptionsNoInputOutput,
252
+ queryOptions?: Omit<UseMutationOptions<Output, Error, unknown, unknown>, OmitReactQueryKeys>,
253
+ ): UseMutationResult<
254
+ Output,
255
+ Error,
256
+ Route extends RoutesWithInput<Routes> ? OptionsWithInput<Routes, Route> : void
257
+ >;
186
258
  };
187
259
 
188
260
  /**
@@ -283,5 +355,50 @@ export const reactQueryBetterFetch: ReactQueryBetterFetch = <
283
355
  });
284
356
  };
285
357
 
286
- return { useBetterQuerySafe, useBetterSuspenseQuery };
358
+ const useBetterMutation = <Route extends keyof Routes>(
359
+ route: Route,
360
+ fetchOptions?: InferOptions<FetchSchema, ''>,
361
+ queryOptions?: Omit<
362
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
363
+ UseMutationOptions<any, any, any, unknown>,
364
+ OmitReactQueryKeys | 'throwOnError'
365
+ >,
366
+ ) => {
367
+ return useMutation({
368
+ ...queryOptions,
369
+ mutationKey: [
370
+ route,
371
+ fetchOptions?.body,
372
+ fetchOptions?.params,
373
+ fetchOptions?.query,
374
+ fetchOptions?.headers,
375
+ ],
376
+ mutationFn: (inputs) => anyInstance(route, { ...fetchOptions, ...inputs }),
377
+ throwOnError: true,
378
+ });
379
+ };
380
+
381
+ const useBetterMutationSafe = <Route extends keyof Routes>(
382
+ route: Route,
383
+ fetchOptions?: InferOptions<FetchSchema, ''>,
384
+ queryOptions?: Omit<
385
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
386
+ UseMutationOptions<any, any, any, unknown>,
387
+ OmitReactQueryKeys | 'throwOnError'
388
+ >,
389
+ ) => {
390
+ return useMutation({
391
+ ...queryOptions,
392
+ mutationKey: [
393
+ route,
394
+ fetchOptions?.body,
395
+ fetchOptions?.params,
396
+ fetchOptions?.query,
397
+ fetchOptions?.headers,
398
+ ],
399
+ mutationFn: (inputs) => anyInstance(route, { ...fetchOptions, ...inputs }),
400
+ });
401
+ };
402
+
403
+ return { useBetterQuerySafe, useBetterMutationSafe, useBetterMutation, useBetterSuspenseQuery };
287
404
  };