@navios/react-query 0.7.1 → 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/CHANGELOG.md +171 -1
- package/README.md +152 -4
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/client/declare-client.mts.html +1264 -0
- package/coverage/client/index.html +116 -0
- package/coverage/clover.xml +160 -0
- package/coverage/coverage-final.json +8 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +146 -0
- package/coverage/mutation/index.html +131 -0
- package/coverage/mutation/key-creator.mts.html +277 -0
- package/coverage/mutation/make-hook.mts.html +952 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/query/index.html +161 -0
- package/coverage/query/key-creator.mts.html +415 -0
- package/coverage/query/make-infinite-options.mts.html +601 -0
- package/coverage/query/make-options.mts.html +838 -0
- package/coverage/query/prefetch.mts.html +1063 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/src/__tests__/errorSchema.spec.d.mts +2 -0
- package/dist/src/__tests__/errorSchema.spec.d.mts.map +1 -0
- package/dist/src/__tests__/prefetch.spec.d.mts +2 -0
- package/dist/src/__tests__/prefetch.spec.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/from-endpoint.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/from-endpoint.spec-d.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/infinite-query.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/infinite-query.spec-d.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/multipart-mutation.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/multipart-mutation.spec-d.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/mutation.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/mutation.spec-d.d.mts.map +1 -0
- package/dist/src/client/__type-tests__/query.spec-d.d.mts +2 -0
- package/dist/src/client/__type-tests__/query.spec-d.d.mts.map +1 -0
- package/dist/src/client/declare-client.d.mts +15 -8
- package/dist/src/client/declare-client.d.mts.map +1 -1
- package/dist/src/client/types/from-endpoint.d.mts +130 -0
- package/dist/src/client/types/from-endpoint.d.mts.map +1 -0
- package/dist/src/client/types/helpers.d.mts +74 -0
- package/dist/src/client/types/helpers.d.mts.map +1 -0
- package/dist/src/client/types/index.d.mts +21 -0
- package/dist/src/client/types/index.d.mts.map +1 -0
- package/dist/src/client/types/infinite-query.d.mts +61 -0
- package/dist/src/client/types/infinite-query.d.mts.map +1 -0
- package/dist/src/client/types/multipart-mutation.d.mts +98 -0
- package/dist/src/client/types/multipart-mutation.d.mts.map +1 -0
- package/dist/src/client/types/mutation.d.mts +75 -0
- package/dist/src/client/types/mutation.d.mts.map +1 -0
- package/dist/src/client/types/query.d.mts +65 -0
- package/dist/src/client/types/query.d.mts.map +1 -0
- package/dist/src/client/types.d.mts +1 -608
- package/dist/src/client/types.d.mts.map +1 -1
- package/dist/src/common/types.d.mts +40 -3
- package/dist/src/common/types.d.mts.map +1 -1
- package/dist/src/mutation/index.d.mts +1 -0
- package/dist/src/mutation/index.d.mts.map +1 -1
- package/dist/src/mutation/make-hook.d.mts +42 -16
- package/dist/src/mutation/make-hook.d.mts.map +1 -1
- package/dist/src/mutation/optimistic.d.mts +172 -0
- package/dist/src/mutation/optimistic.d.mts.map +1 -0
- package/dist/src/mutation/types.d.mts +41 -20
- package/dist/src/mutation/types.d.mts.map +1 -1
- package/dist/src/query/index.d.mts +1 -0
- package/dist/src/query/index.d.mts.map +1 -1
- package/dist/src/query/key-creator.d.mts.map +1 -1
- package/dist/src/query/make-infinite-options.d.mts +3 -2
- package/dist/src/query/make-infinite-options.d.mts.map +1 -1
- package/dist/src/query/make-options.d.mts +42 -12
- package/dist/src/query/make-options.d.mts.map +1 -1
- package/dist/src/query/prefetch.d.mts +245 -0
- package/dist/src/query/prefetch.d.mts.map +1 -0
- package/dist/src/query/types.d.mts +25 -18
- package/dist/src/query/types.d.mts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/index.cjs +451 -28
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1019 -600
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +1016 -597
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +447 -29
- package/lib/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/declare-client.spec.mts +229 -2
- package/src/__tests__/errorSchema.spec.mts +391 -0
- package/src/__tests__/make-mutation.spec.mts +6 -5
- package/src/__tests__/makeDataTag.spec.mts +2 -1
- package/src/__tests__/makeQueryOptions.spec.mts +2 -1
- package/src/__tests__/prefetch.spec.mts +310 -0
- package/src/client/__type-tests__/from-endpoint.spec-d.mts +550 -0
- package/src/client/__type-tests__/infinite-query.spec-d.mts +648 -0
- package/src/client/__type-tests__/multipart-mutation.spec-d.mts +725 -0
- package/src/client/__type-tests__/mutation.spec-d.mts +757 -0
- package/src/client/__type-tests__/query.spec-d.mts +701 -0
- package/src/client/declare-client.mts +59 -34
- package/src/client/types/from-endpoint.mts +344 -0
- package/src/client/types/helpers.mts +140 -0
- package/src/client/types/index.mts +26 -0
- package/src/client/types/infinite-query.mts +133 -0
- package/src/client/types/multipart-mutation.mts +264 -0
- package/src/client/types/mutation.mts +176 -0
- package/src/client/types/query.mts +132 -0
- package/src/client/types.mts +1 -1935
- package/src/common/types.mts +67 -3
- package/src/mutation/index.mts +1 -0
- package/src/mutation/make-hook.mts +171 -63
- package/src/mutation/optimistic.mts +300 -0
- package/src/mutation/types.mts +87 -30
- package/src/query/index.mts +1 -0
- package/src/query/key-creator.mts +24 -13
- package/src/query/make-infinite-options.mts +53 -10
- package/src/query/make-options.mts +184 -43
- package/src/query/prefetch.mts +326 -0
- package/src/query/types.mts +56 -17
- package/src/client/__type-tests__/client-instance.spec-d.mts +0 -852
|
@@ -0,0 +1,757 @@
|
|
|
1
|
+
import type { ErrorSchemaRecord } from '@navios/builder'
|
|
2
|
+
import type { UseMutationResult } from '@tanstack/react-query'
|
|
3
|
+
import type { z } from 'zod/v4'
|
|
4
|
+
|
|
5
|
+
import { assertType, describe, test } from 'vitest'
|
|
6
|
+
import { z as zod } from 'zod/v4'
|
|
7
|
+
|
|
8
|
+
import type { MutationHelpers } from '../../mutation/types.mjs'
|
|
9
|
+
import type { ClientInstance, EndpointHelper } from '../types.mjs'
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// TEST SCHEMAS
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
const responseSchema = zod.object({
|
|
16
|
+
id: zod.string(),
|
|
17
|
+
name: zod.string(),
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const querySchema = zod.object({
|
|
21
|
+
page: zod.number(),
|
|
22
|
+
limit: zod.number(),
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const requestSchema = zod.object({
|
|
26
|
+
name: zod.string(),
|
|
27
|
+
email: zod.string(),
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const error400Schema = zod.object({ error: zod.string(), code: zod.number() })
|
|
31
|
+
const error404Schema = zod.object({ notFound: zod.literal(true) })
|
|
32
|
+
const error500Schema = zod.object({ serverError: zod.string() })
|
|
33
|
+
|
|
34
|
+
const errorSchema = {
|
|
35
|
+
400: error400Schema,
|
|
36
|
+
404: error404Schema,
|
|
37
|
+
500: error500Schema,
|
|
38
|
+
} satisfies ErrorSchemaRecord
|
|
39
|
+
|
|
40
|
+
type ResponseType = z.output<typeof responseSchema>
|
|
41
|
+
type QueryType = z.input<typeof querySchema>
|
|
42
|
+
type RequestType = z.input<typeof requestSchema>
|
|
43
|
+
type Error400 = z.output<typeof error400Schema>
|
|
44
|
+
type Error404 = z.output<typeof error404Schema>
|
|
45
|
+
type Error500 = z.output<typeof error500Schema>
|
|
46
|
+
type ErrorUnion = Error400 | Error404 | Error500
|
|
47
|
+
type ResponseWithErrors = ResponseType | ErrorUnion
|
|
48
|
+
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// CLIENT INSTANCE DECLARATIONS
|
|
51
|
+
// ============================================================================
|
|
52
|
+
|
|
53
|
+
declare const client: ClientInstance<false>
|
|
54
|
+
declare const clientWithDiscriminator: ClientInstance<true>
|
|
55
|
+
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// MUTATION METHOD - DEFAULT MODE (UseDiscriminator=false)
|
|
58
|
+
// ============================================================================
|
|
59
|
+
|
|
60
|
+
describe('ClientInstance<false> mutation() method', () => {
|
|
61
|
+
describe('POST mutations', () => {
|
|
62
|
+
test('POST mutation with request schema only', () => {
|
|
63
|
+
const mutation = client.mutation({
|
|
64
|
+
method: 'POST',
|
|
65
|
+
url: '/users',
|
|
66
|
+
requestSchema,
|
|
67
|
+
responseSchema,
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
assertType<
|
|
71
|
+
() => UseMutationResult<ResponseType, Error, { data: RequestType }>
|
|
72
|
+
>(mutation)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('POST mutation with processResponse', () => {
|
|
76
|
+
const mutation = client.mutation({
|
|
77
|
+
method: 'POST',
|
|
78
|
+
url: '/users',
|
|
79
|
+
requestSchema,
|
|
80
|
+
responseSchema,
|
|
81
|
+
processResponse: (data) => data,
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
assertType<
|
|
85
|
+
() => UseMutationResult<ResponseType, Error, { data: RequestType }>
|
|
86
|
+
>(mutation)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('POST mutation with URL params', () => {
|
|
90
|
+
const mutation = client.mutation({
|
|
91
|
+
method: 'POST',
|
|
92
|
+
url: '/users/$userId/posts',
|
|
93
|
+
requestSchema,
|
|
94
|
+
responseSchema,
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
assertType<
|
|
98
|
+
() => UseMutationResult<
|
|
99
|
+
ResponseType,
|
|
100
|
+
Error,
|
|
101
|
+
{ urlParams: { userId: string | number }; data: RequestType }
|
|
102
|
+
>
|
|
103
|
+
>(mutation)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test('POST mutation with multiple URL params', () => {
|
|
107
|
+
const mutation = client.mutation({
|
|
108
|
+
method: 'POST',
|
|
109
|
+
url: '/orgs/$orgId/users/$userId/posts',
|
|
110
|
+
requestSchema,
|
|
111
|
+
responseSchema,
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
assertType<
|
|
115
|
+
() => UseMutationResult<
|
|
116
|
+
ResponseType,
|
|
117
|
+
Error,
|
|
118
|
+
{
|
|
119
|
+
urlParams: { orgId: string | number; userId: string | number }
|
|
120
|
+
data: RequestType
|
|
121
|
+
}
|
|
122
|
+
>
|
|
123
|
+
>(mutation)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
test('POST mutation with query schema', () => {
|
|
127
|
+
const mutation = client.mutation({
|
|
128
|
+
method: 'POST',
|
|
129
|
+
url: '/users',
|
|
130
|
+
requestSchema,
|
|
131
|
+
querySchema,
|
|
132
|
+
responseSchema,
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
assertType<
|
|
136
|
+
() => UseMutationResult<
|
|
137
|
+
ResponseType,
|
|
138
|
+
Error,
|
|
139
|
+
{ data: RequestType; params: QueryType }
|
|
140
|
+
>
|
|
141
|
+
>(mutation)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
test('POST mutation with all schemas', () => {
|
|
145
|
+
const mutation = client.mutation({
|
|
146
|
+
method: 'POST',
|
|
147
|
+
url: '/users/$userId',
|
|
148
|
+
requestSchema,
|
|
149
|
+
querySchema,
|
|
150
|
+
responseSchema,
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
assertType<
|
|
154
|
+
() => UseMutationResult<
|
|
155
|
+
ResponseType,
|
|
156
|
+
Error,
|
|
157
|
+
{
|
|
158
|
+
urlParams: { userId: string | number }
|
|
159
|
+
data: RequestType
|
|
160
|
+
params: QueryType
|
|
161
|
+
}
|
|
162
|
+
>
|
|
163
|
+
>(mutation)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
test('POST mutation with custom result type', () => {
|
|
167
|
+
const mutation = client.mutation({
|
|
168
|
+
method: 'POST',
|
|
169
|
+
url: '/users',
|
|
170
|
+
requestSchema,
|
|
171
|
+
responseSchema,
|
|
172
|
+
processResponse: (data) => ({ processed: true, name: data.name }),
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
assertType<
|
|
176
|
+
() => UseMutationResult<
|
|
177
|
+
{ processed: boolean; name: string },
|
|
178
|
+
Error,
|
|
179
|
+
{ data: RequestType }
|
|
180
|
+
>
|
|
181
|
+
>(mutation)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
describe('PUT mutations', () => {
|
|
186
|
+
test('PUT mutation with URL params', () => {
|
|
187
|
+
const mutation = client.mutation({
|
|
188
|
+
method: 'PUT',
|
|
189
|
+
url: '/users/$userId',
|
|
190
|
+
requestSchema,
|
|
191
|
+
responseSchema,
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
assertType<
|
|
195
|
+
() => UseMutationResult<
|
|
196
|
+
ResponseType,
|
|
197
|
+
Error,
|
|
198
|
+
{ urlParams: { userId: string | number }; data: RequestType }
|
|
199
|
+
>
|
|
200
|
+
>(mutation)
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
describe('PATCH mutations', () => {
|
|
205
|
+
test('PATCH mutation with URL params and query schema', () => {
|
|
206
|
+
const mutation = client.mutation({
|
|
207
|
+
method: 'PATCH',
|
|
208
|
+
url: '/users/$userId',
|
|
209
|
+
requestSchema,
|
|
210
|
+
querySchema,
|
|
211
|
+
responseSchema,
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
assertType<
|
|
215
|
+
() => UseMutationResult<
|
|
216
|
+
ResponseType,
|
|
217
|
+
Error,
|
|
218
|
+
{
|
|
219
|
+
urlParams: { userId: string | number }
|
|
220
|
+
data: RequestType
|
|
221
|
+
params: QueryType
|
|
222
|
+
}
|
|
223
|
+
>
|
|
224
|
+
>(mutation)
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
describe('DELETE mutations', () => {
|
|
229
|
+
test('DELETE mutation without request schema', () => {
|
|
230
|
+
const mutation = client.mutation({
|
|
231
|
+
method: 'DELETE',
|
|
232
|
+
url: '/users/$userId',
|
|
233
|
+
responseSchema,
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
assertType<
|
|
237
|
+
() => UseMutationResult<
|
|
238
|
+
ResponseType,
|
|
239
|
+
Error,
|
|
240
|
+
{ urlParams: { userId: string | number } }
|
|
241
|
+
>
|
|
242
|
+
>(mutation)
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
test('DELETE mutation with query schema', () => {
|
|
246
|
+
const mutation = client.mutation({
|
|
247
|
+
method: 'DELETE',
|
|
248
|
+
url: '/cache',
|
|
249
|
+
querySchema,
|
|
250
|
+
responseSchema,
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
assertType<
|
|
254
|
+
() => UseMutationResult<ResponseType, Error, { params: QueryType }>
|
|
255
|
+
>(mutation)
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
test('DELETE mutation with URL params and query schema', () => {
|
|
259
|
+
const mutation = client.mutation({
|
|
260
|
+
method: 'DELETE',
|
|
261
|
+
url: '/users/$userId',
|
|
262
|
+
querySchema,
|
|
263
|
+
responseSchema,
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
assertType<
|
|
267
|
+
() => UseMutationResult<
|
|
268
|
+
ResponseType,
|
|
269
|
+
Error,
|
|
270
|
+
{ urlParams: { userId: string | number }; params: QueryType }
|
|
271
|
+
>
|
|
272
|
+
>(mutation)
|
|
273
|
+
})
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
describe('useKey option', () => {
|
|
277
|
+
test('POST mutation with useKey requires urlParams in call', () => {
|
|
278
|
+
const mutation = client.mutation({
|
|
279
|
+
method: 'POST',
|
|
280
|
+
url: '/users/$userId',
|
|
281
|
+
useKey: true,
|
|
282
|
+
requestSchema,
|
|
283
|
+
responseSchema,
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
assertType<
|
|
287
|
+
(params: {
|
|
288
|
+
urlParams: { userId: string | number }
|
|
289
|
+
}) => UseMutationResult<
|
|
290
|
+
ResponseType,
|
|
291
|
+
Error,
|
|
292
|
+
{ urlParams: { userId: string | number }; data: RequestType }
|
|
293
|
+
>
|
|
294
|
+
>(mutation)
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
test('mutation with useKey has MutationHelpers', () => {
|
|
298
|
+
const mutation = client.mutation({
|
|
299
|
+
method: 'POST',
|
|
300
|
+
url: '/users/$userId',
|
|
301
|
+
useKey: true,
|
|
302
|
+
requestSchema,
|
|
303
|
+
responseSchema,
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
assertType<MutationHelpers<'/users/$userId', ResponseType>['mutationKey']>(
|
|
307
|
+
mutation.mutationKey,
|
|
308
|
+
)
|
|
309
|
+
assertType<
|
|
310
|
+
MutationHelpers<'/users/$userId', ResponseType>['useIsMutating']
|
|
311
|
+
>(mutation.useIsMutating)
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
test('DELETE mutation with useKey and URL params', () => {
|
|
315
|
+
const mutation = client.mutation({
|
|
316
|
+
method: 'DELETE',
|
|
317
|
+
url: '/users/$userId',
|
|
318
|
+
useKey: true,
|
|
319
|
+
responseSchema,
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
assertType<
|
|
323
|
+
(params: {
|
|
324
|
+
urlParams: { userId: string | number }
|
|
325
|
+
}) => UseMutationResult<
|
|
326
|
+
ResponseType,
|
|
327
|
+
Error,
|
|
328
|
+
{ urlParams: { userId: string | number } }
|
|
329
|
+
>
|
|
330
|
+
>(mutation)
|
|
331
|
+
})
|
|
332
|
+
|
|
333
|
+
test('DELETE mutation with useKey and querySchema', () => {
|
|
334
|
+
const mutation = client.mutation({
|
|
335
|
+
method: 'DELETE',
|
|
336
|
+
url: '/users/$userId',
|
|
337
|
+
useKey: true,
|
|
338
|
+
querySchema,
|
|
339
|
+
responseSchema,
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
assertType<
|
|
343
|
+
(params: {
|
|
344
|
+
urlParams: { userId: string | number }
|
|
345
|
+
}) => UseMutationResult<
|
|
346
|
+
ResponseType,
|
|
347
|
+
Error,
|
|
348
|
+
{ urlParams: { userId: string | number }; params: QueryType }
|
|
349
|
+
>
|
|
350
|
+
>(mutation)
|
|
351
|
+
})
|
|
352
|
+
|
|
353
|
+
test('mutation with useKey without URL params', () => {
|
|
354
|
+
const mutation = client.mutation({
|
|
355
|
+
method: 'DELETE',
|
|
356
|
+
url: '/cache',
|
|
357
|
+
useKey: true,
|
|
358
|
+
responseSchema,
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
assertType<(params: {}) => UseMutationResult<ResponseType, Error, {}>>(
|
|
362
|
+
mutation,
|
|
363
|
+
)
|
|
364
|
+
})
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
describe('callback options', () => {
|
|
368
|
+
test('onMutate receives variables and context', () => {
|
|
369
|
+
client.mutation({
|
|
370
|
+
method: 'POST',
|
|
371
|
+
url: '/users',
|
|
372
|
+
requestSchema,
|
|
373
|
+
responseSchema,
|
|
374
|
+
onMutate: (variables, context) => {
|
|
375
|
+
assertType<{ data: RequestType }>(variables)
|
|
376
|
+
assertType<{ meta: Record<string, unknown> | undefined }>(context)
|
|
377
|
+
return { previousData: [] }
|
|
378
|
+
},
|
|
379
|
+
})
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
test('onSuccess receives data, variables, and context', () => {
|
|
383
|
+
client.mutation({
|
|
384
|
+
method: 'POST',
|
|
385
|
+
url: '/users',
|
|
386
|
+
requestSchema,
|
|
387
|
+
responseSchema,
|
|
388
|
+
processResponse: (data) => data,
|
|
389
|
+
onSuccess: (data, variables, context) => {
|
|
390
|
+
assertType<ResponseType>(data)
|
|
391
|
+
assertType<{ data: RequestType }>(variables)
|
|
392
|
+
assertType<{ onMutateResult: unknown }>(context)
|
|
393
|
+
},
|
|
394
|
+
})
|
|
395
|
+
})
|
|
396
|
+
|
|
397
|
+
test('onError receives error, variables, and context', () => {
|
|
398
|
+
client.mutation({
|
|
399
|
+
method: 'POST',
|
|
400
|
+
url: '/users',
|
|
401
|
+
requestSchema,
|
|
402
|
+
responseSchema,
|
|
403
|
+
onError: (error, variables, context) => {
|
|
404
|
+
assertType<Error>(error)
|
|
405
|
+
assertType<{ data: RequestType }>(variables)
|
|
406
|
+
assertType<{ onMutateResult: unknown }>(context)
|
|
407
|
+
},
|
|
408
|
+
})
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
test('onSettled receives data, error, variables, and context', () => {
|
|
412
|
+
client.mutation({
|
|
413
|
+
method: 'POST',
|
|
414
|
+
url: '/users',
|
|
415
|
+
requestSchema,
|
|
416
|
+
responseSchema,
|
|
417
|
+
processResponse: (data) => data,
|
|
418
|
+
onSettled: (data, error, variables, context) => {
|
|
419
|
+
assertType<ResponseType | undefined>(data)
|
|
420
|
+
assertType<Error | null>(error)
|
|
421
|
+
assertType<{ data: RequestType }>(variables)
|
|
422
|
+
assertType<{ onMutateResult: unknown }>(context)
|
|
423
|
+
},
|
|
424
|
+
})
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
test('useContext provides custom context', () => {
|
|
428
|
+
client.mutation({
|
|
429
|
+
method: 'POST',
|
|
430
|
+
url: '/users',
|
|
431
|
+
requestSchema,
|
|
432
|
+
responseSchema,
|
|
433
|
+
useContext: () => ({ queryClient: {} as unknown }),
|
|
434
|
+
onMutate: (_variables, context) => {
|
|
435
|
+
assertType<{ queryClient: unknown }>(context)
|
|
436
|
+
},
|
|
437
|
+
})
|
|
438
|
+
})
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
describe('errorSchema (errors thrown, not in return type)', () => {
|
|
442
|
+
test('mutation with errorSchema returns only success type', () => {
|
|
443
|
+
const mutation = client.mutation({
|
|
444
|
+
method: 'POST',
|
|
445
|
+
url: '/users',
|
|
446
|
+
requestSchema,
|
|
447
|
+
responseSchema,
|
|
448
|
+
errorSchema,
|
|
449
|
+
})
|
|
450
|
+
|
|
451
|
+
assertType<
|
|
452
|
+
() => UseMutationResult<
|
|
453
|
+
ResponseType,
|
|
454
|
+
Error,
|
|
455
|
+
{ data: RequestType },
|
|
456
|
+
unknown
|
|
457
|
+
>
|
|
458
|
+
>(mutation)
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
test('processResponse receives only success type', () => {
|
|
462
|
+
client.mutation({
|
|
463
|
+
method: 'POST',
|
|
464
|
+
url: '/users',
|
|
465
|
+
requestSchema,
|
|
466
|
+
responseSchema,
|
|
467
|
+
errorSchema,
|
|
468
|
+
processResponse: (data) => {
|
|
469
|
+
assertType<ResponseType>(data)
|
|
470
|
+
return data
|
|
471
|
+
},
|
|
472
|
+
})
|
|
473
|
+
})
|
|
474
|
+
})
|
|
475
|
+
|
|
476
|
+
describe('EndpointHelper', () => {
|
|
477
|
+
test('mutation exposes endpoint property', () => {
|
|
478
|
+
const mutation = client.mutation({
|
|
479
|
+
method: 'POST',
|
|
480
|
+
url: '/users',
|
|
481
|
+
requestSchema,
|
|
482
|
+
responseSchema,
|
|
483
|
+
})
|
|
484
|
+
|
|
485
|
+
assertType<
|
|
486
|
+
EndpointHelper<
|
|
487
|
+
{
|
|
488
|
+
method: 'POST'
|
|
489
|
+
url: '/users'
|
|
490
|
+
querySchema: undefined
|
|
491
|
+
requestSchema: typeof requestSchema
|
|
492
|
+
responseSchema: typeof responseSchema
|
|
493
|
+
errorSchema: undefined
|
|
494
|
+
urlParamsSchema: undefined
|
|
495
|
+
},
|
|
496
|
+
false
|
|
497
|
+
>['endpoint']
|
|
498
|
+
>(mutation.endpoint)
|
|
499
|
+
})
|
|
500
|
+
})
|
|
501
|
+
})
|
|
502
|
+
|
|
503
|
+
// ============================================================================
|
|
504
|
+
// MUTATION METHOD - DISCRIMINATOR MODE (UseDiscriminator=true)
|
|
505
|
+
// ============================================================================
|
|
506
|
+
|
|
507
|
+
describe('ClientInstance<true> mutation() method (discriminator mode)', () => {
|
|
508
|
+
describe('errorSchema includes error union in TData', () => {
|
|
509
|
+
test('POST mutation with errorSchema returns union result type', () => {
|
|
510
|
+
const mutation = clientWithDiscriminator.mutation({
|
|
511
|
+
method: 'POST',
|
|
512
|
+
url: '/users',
|
|
513
|
+
requestSchema,
|
|
514
|
+
responseSchema,
|
|
515
|
+
errorSchema,
|
|
516
|
+
})
|
|
517
|
+
|
|
518
|
+
assertType<
|
|
519
|
+
() => UseMutationResult<
|
|
520
|
+
ResponseWithErrors,
|
|
521
|
+
Error,
|
|
522
|
+
{ data: RequestType },
|
|
523
|
+
unknown
|
|
524
|
+
>
|
|
525
|
+
>(mutation)
|
|
526
|
+
})
|
|
527
|
+
|
|
528
|
+
test('processResponse receives union type', () => {
|
|
529
|
+
clientWithDiscriminator.mutation({
|
|
530
|
+
method: 'POST',
|
|
531
|
+
url: '/users',
|
|
532
|
+
requestSchema,
|
|
533
|
+
responseSchema,
|
|
534
|
+
errorSchema,
|
|
535
|
+
processResponse: (data) => {
|
|
536
|
+
assertType<ResponseWithErrors>(data)
|
|
537
|
+
return data
|
|
538
|
+
},
|
|
539
|
+
})
|
|
540
|
+
})
|
|
541
|
+
|
|
542
|
+
test('processResponse can transform union type', () => {
|
|
543
|
+
// Note: This test verifies processResponse receives the union type.
|
|
544
|
+
// The exact return type assertion is complex due to readonly inference.
|
|
545
|
+
clientWithDiscriminator.mutation({
|
|
546
|
+
method: 'POST',
|
|
547
|
+
url: '/users',
|
|
548
|
+
requestSchema,
|
|
549
|
+
responseSchema,
|
|
550
|
+
errorSchema,
|
|
551
|
+
processResponse: (data): { handled: boolean; original: typeof data } => {
|
|
552
|
+
assertType<ResponseWithErrors>(data)
|
|
553
|
+
return { handled: true, original: data }
|
|
554
|
+
},
|
|
555
|
+
})
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
test('onSuccess receives union type', () => {
|
|
559
|
+
clientWithDiscriminator.mutation({
|
|
560
|
+
method: 'POST',
|
|
561
|
+
url: '/users',
|
|
562
|
+
requestSchema,
|
|
563
|
+
responseSchema,
|
|
564
|
+
errorSchema,
|
|
565
|
+
processResponse: (data) => data,
|
|
566
|
+
onSuccess: (data) => {
|
|
567
|
+
assertType<ResponseWithErrors>(data)
|
|
568
|
+
},
|
|
569
|
+
})
|
|
570
|
+
})
|
|
571
|
+
})
|
|
572
|
+
|
|
573
|
+
describe('without errorSchema behaves same as default', () => {
|
|
574
|
+
test('mutation without errorSchema returns only success type', () => {
|
|
575
|
+
const mutation = clientWithDiscriminator.mutation({
|
|
576
|
+
method: 'POST',
|
|
577
|
+
url: '/users',
|
|
578
|
+
requestSchema,
|
|
579
|
+
responseSchema,
|
|
580
|
+
})
|
|
581
|
+
|
|
582
|
+
assertType<
|
|
583
|
+
() => UseMutationResult<
|
|
584
|
+
ResponseType,
|
|
585
|
+
Error,
|
|
586
|
+
{ data: RequestType },
|
|
587
|
+
unknown
|
|
588
|
+
>
|
|
589
|
+
>(mutation)
|
|
590
|
+
})
|
|
591
|
+
})
|
|
592
|
+
})
|
|
593
|
+
|
|
594
|
+
// ============================================================================
|
|
595
|
+
// ERROR CASES - Should fail type checking
|
|
596
|
+
// ============================================================================
|
|
597
|
+
|
|
598
|
+
describe('mutation() error cases', () => {
|
|
599
|
+
describe('missing required parameters in variables', () => {
|
|
600
|
+
test('mutation().mutate() without data when requestSchema is defined', () => {
|
|
601
|
+
const mutation = client.mutation({
|
|
602
|
+
method: 'POST',
|
|
603
|
+
url: '/users',
|
|
604
|
+
requestSchema,
|
|
605
|
+
responseSchema,
|
|
606
|
+
})
|
|
607
|
+
|
|
608
|
+
const { mutate } = mutation()
|
|
609
|
+
|
|
610
|
+
// @ts-expect-error - missing data
|
|
611
|
+
mutate({})
|
|
612
|
+
})
|
|
613
|
+
|
|
614
|
+
test('mutation().mutate() without urlParams when URL has params', () => {
|
|
615
|
+
const mutation = client.mutation({
|
|
616
|
+
method: 'POST',
|
|
617
|
+
url: '/users/$userId',
|
|
618
|
+
requestSchema,
|
|
619
|
+
responseSchema,
|
|
620
|
+
})
|
|
621
|
+
|
|
622
|
+
const { mutate } = mutation()
|
|
623
|
+
|
|
624
|
+
// @ts-expect-error - missing urlParams
|
|
625
|
+
mutate({ data: { name: 'test', email: 'test@test.com' } })
|
|
626
|
+
})
|
|
627
|
+
|
|
628
|
+
test('mutation().mutate() without params when querySchema is defined', () => {
|
|
629
|
+
const mutation = client.mutation({
|
|
630
|
+
method: 'POST',
|
|
631
|
+
url: '/users',
|
|
632
|
+
requestSchema,
|
|
633
|
+
querySchema,
|
|
634
|
+
responseSchema,
|
|
635
|
+
})
|
|
636
|
+
|
|
637
|
+
const { mutate } = mutation()
|
|
638
|
+
|
|
639
|
+
// @ts-expect-error - missing params
|
|
640
|
+
mutate({ data: { name: 'test', email: 'test@test.com' } })
|
|
641
|
+
})
|
|
642
|
+
})
|
|
643
|
+
|
|
644
|
+
describe('missing useKey call params', () => {
|
|
645
|
+
test('mutation with useKey called without urlParams', () => {
|
|
646
|
+
const mutation = client.mutation({
|
|
647
|
+
method: 'POST',
|
|
648
|
+
url: '/users/$userId',
|
|
649
|
+
useKey: true,
|
|
650
|
+
requestSchema,
|
|
651
|
+
responseSchema,
|
|
652
|
+
})
|
|
653
|
+
|
|
654
|
+
// @ts-expect-error - missing urlParams in call
|
|
655
|
+
mutation()
|
|
656
|
+
})
|
|
657
|
+
})
|
|
658
|
+
|
|
659
|
+
describe('wrong parameter types in variables', () => {
|
|
660
|
+
test('data with wrong shape', () => {
|
|
661
|
+
const mutation = client.mutation({
|
|
662
|
+
method: 'POST',
|
|
663
|
+
url: '/users',
|
|
664
|
+
requestSchema,
|
|
665
|
+
responseSchema,
|
|
666
|
+
})
|
|
667
|
+
|
|
668
|
+
const { mutate } = mutation()
|
|
669
|
+
|
|
670
|
+
// @ts-expect-error - wrong property names
|
|
671
|
+
mutate({ data: { username: 'test', mail: 'test@test.com' } })
|
|
672
|
+
})
|
|
673
|
+
|
|
674
|
+
test('data with wrong value types', () => {
|
|
675
|
+
const mutation = client.mutation({
|
|
676
|
+
method: 'POST',
|
|
677
|
+
url: '/users',
|
|
678
|
+
requestSchema,
|
|
679
|
+
responseSchema,
|
|
680
|
+
})
|
|
681
|
+
|
|
682
|
+
const { mutate } = mutation()
|
|
683
|
+
|
|
684
|
+
// @ts-expect-error - name should be string, not number
|
|
685
|
+
mutate({ data: { name: 123, email: 'test@test.com' } })
|
|
686
|
+
})
|
|
687
|
+
|
|
688
|
+
test('urlParams with wrong type', () => {
|
|
689
|
+
const mutation = client.mutation({
|
|
690
|
+
method: 'POST',
|
|
691
|
+
url: '/users/$userId',
|
|
692
|
+
requestSchema,
|
|
693
|
+
responseSchema,
|
|
694
|
+
})
|
|
695
|
+
|
|
696
|
+
const { mutate } = mutation()
|
|
697
|
+
|
|
698
|
+
mutate({
|
|
699
|
+
// @ts-expect-error - userId should be string | number, not boolean
|
|
700
|
+
urlParams: { userId: true },
|
|
701
|
+
data: { name: 'test', email: 'test@test.com' },
|
|
702
|
+
})
|
|
703
|
+
})
|
|
704
|
+
|
|
705
|
+
test('params with wrong shape', () => {
|
|
706
|
+
const mutation = client.mutation({
|
|
707
|
+
method: 'POST',
|
|
708
|
+
url: '/users',
|
|
709
|
+
requestSchema,
|
|
710
|
+
querySchema,
|
|
711
|
+
responseSchema,
|
|
712
|
+
})
|
|
713
|
+
|
|
714
|
+
const { mutate } = mutation()
|
|
715
|
+
|
|
716
|
+
mutate({
|
|
717
|
+
data: { name: 'test', email: 'test@test.com' },
|
|
718
|
+
params: {
|
|
719
|
+
// @ts-expect-error - wrong property names
|
|
720
|
+
offset: 0,
|
|
721
|
+
count: 10,
|
|
722
|
+
},
|
|
723
|
+
})
|
|
724
|
+
})
|
|
725
|
+
})
|
|
726
|
+
|
|
727
|
+
describe('processResponse type safety', () => {
|
|
728
|
+
test('processResponse receives correct input type', () => {
|
|
729
|
+
client.mutation({
|
|
730
|
+
method: 'POST',
|
|
731
|
+
url: '/users',
|
|
732
|
+
requestSchema,
|
|
733
|
+
responseSchema,
|
|
734
|
+
processResponse: (data) => {
|
|
735
|
+
// @ts-expect-error - data doesn't have 'nonExistent' property
|
|
736
|
+
return data.nonExistent
|
|
737
|
+
},
|
|
738
|
+
})
|
|
739
|
+
})
|
|
740
|
+
})
|
|
741
|
+
|
|
742
|
+
describe('callback type safety', () => {
|
|
743
|
+
test('onSuccess data type matches processResponse result', () => {
|
|
744
|
+
client.mutation({
|
|
745
|
+
method: 'POST',
|
|
746
|
+
url: '/users',
|
|
747
|
+
requestSchema,
|
|
748
|
+
responseSchema,
|
|
749
|
+
processResponse: (data) => ({ transformed: data.name }),
|
|
750
|
+
onSuccess: (data) => {
|
|
751
|
+
// @ts-expect-error - data is { transformed: string }, not ResponseType
|
|
752
|
+
const _id: string = data.id
|
|
753
|
+
},
|
|
754
|
+
})
|
|
755
|
+
})
|
|
756
|
+
})
|
|
757
|
+
})
|