@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,725 @@
|
|
|
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
|
+
file: zod.instanceof(File),
|
|
27
|
+
description: 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
|
+
// MULTIPART MUTATION METHOD - DEFAULT MODE (UseDiscriminator=false)
|
|
58
|
+
// ============================================================================
|
|
59
|
+
|
|
60
|
+
describe('ClientInstance<false> multipartMutation() method', () => {
|
|
61
|
+
describe('POST multipart mutations', () => {
|
|
62
|
+
test('POST multipart mutation with request schema', () => {
|
|
63
|
+
const mutation = client.multipartMutation({
|
|
64
|
+
method: 'POST',
|
|
65
|
+
url: '/upload',
|
|
66
|
+
requestSchema,
|
|
67
|
+
responseSchema,
|
|
68
|
+
processResponse: (data) => data,
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
assertType<
|
|
72
|
+
() => UseMutationResult<ResponseType, Error, { data: RequestType }>
|
|
73
|
+
>(mutation)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('POST multipart mutation with URL params', () => {
|
|
77
|
+
const mutation = client.multipartMutation({
|
|
78
|
+
method: 'POST',
|
|
79
|
+
url: '/users/$userId/avatar',
|
|
80
|
+
requestSchema,
|
|
81
|
+
responseSchema,
|
|
82
|
+
processResponse: (data) => data,
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
assertType<
|
|
86
|
+
() => UseMutationResult<
|
|
87
|
+
ResponseType,
|
|
88
|
+
Error,
|
|
89
|
+
{ urlParams: { userId: string | number }; data: RequestType }
|
|
90
|
+
>
|
|
91
|
+
>(mutation)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
test('POST multipart mutation with multiple URL params', () => {
|
|
95
|
+
const mutation = client.multipartMutation({
|
|
96
|
+
method: 'POST',
|
|
97
|
+
url: '/orgs/$orgId/users/$userId/avatar',
|
|
98
|
+
requestSchema,
|
|
99
|
+
responseSchema,
|
|
100
|
+
processResponse: (data) => data,
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
assertType<
|
|
104
|
+
() => UseMutationResult<
|
|
105
|
+
ResponseType,
|
|
106
|
+
Error,
|
|
107
|
+
{
|
|
108
|
+
urlParams: { orgId: string | number; userId: string | number }
|
|
109
|
+
data: RequestType
|
|
110
|
+
}
|
|
111
|
+
>
|
|
112
|
+
>(mutation)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
test('POST multipart mutation with query schema', () => {
|
|
116
|
+
const mutation = client.multipartMutation({
|
|
117
|
+
method: 'POST',
|
|
118
|
+
url: '/upload',
|
|
119
|
+
requestSchema,
|
|
120
|
+
querySchema,
|
|
121
|
+
responseSchema,
|
|
122
|
+
processResponse: (data) => data,
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
assertType<
|
|
126
|
+
() => UseMutationResult<
|
|
127
|
+
ResponseType,
|
|
128
|
+
Error,
|
|
129
|
+
{ data: RequestType; params: QueryType }
|
|
130
|
+
>
|
|
131
|
+
>(mutation)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
test('POST multipart mutation with all schemas', () => {
|
|
135
|
+
const mutation = client.multipartMutation({
|
|
136
|
+
method: 'POST',
|
|
137
|
+
url: '/users/$userId/files',
|
|
138
|
+
requestSchema,
|
|
139
|
+
querySchema,
|
|
140
|
+
responseSchema,
|
|
141
|
+
processResponse: (data) => data,
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
assertType<
|
|
145
|
+
() => UseMutationResult<
|
|
146
|
+
ResponseType,
|
|
147
|
+
Error,
|
|
148
|
+
{
|
|
149
|
+
urlParams: { userId: string | number }
|
|
150
|
+
data: RequestType
|
|
151
|
+
params: QueryType
|
|
152
|
+
}
|
|
153
|
+
>
|
|
154
|
+
>(mutation)
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
test('POST multipart mutation with custom result type', () => {
|
|
158
|
+
const mutation = client.multipartMutation({
|
|
159
|
+
method: 'POST',
|
|
160
|
+
url: '/upload',
|
|
161
|
+
requestSchema,
|
|
162
|
+
responseSchema,
|
|
163
|
+
processResponse: (data) => ({
|
|
164
|
+
uploaded: true,
|
|
165
|
+
fileId: data.id,
|
|
166
|
+
}),
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
assertType<
|
|
170
|
+
() => UseMutationResult<
|
|
171
|
+
{ uploaded: boolean; fileId: string },
|
|
172
|
+
Error,
|
|
173
|
+
{ data: RequestType }
|
|
174
|
+
>
|
|
175
|
+
>(mutation)
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
describe('PUT multipart mutations', () => {
|
|
180
|
+
test('PUT multipart mutation', () => {
|
|
181
|
+
const mutation = client.multipartMutation({
|
|
182
|
+
method: 'PUT',
|
|
183
|
+
url: '/files/$fileId',
|
|
184
|
+
requestSchema,
|
|
185
|
+
responseSchema,
|
|
186
|
+
processResponse: (data) => data,
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
assertType<
|
|
190
|
+
() => UseMutationResult<
|
|
191
|
+
ResponseType,
|
|
192
|
+
Error,
|
|
193
|
+
{ urlParams: { fileId: string | number }; data: RequestType }
|
|
194
|
+
>
|
|
195
|
+
>(mutation)
|
|
196
|
+
})
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
describe('PATCH multipart mutations', () => {
|
|
200
|
+
test('PATCH multipart mutation', () => {
|
|
201
|
+
const mutation = client.multipartMutation({
|
|
202
|
+
method: 'PATCH',
|
|
203
|
+
url: '/files/$fileId',
|
|
204
|
+
requestSchema,
|
|
205
|
+
responseSchema,
|
|
206
|
+
processResponse: (data) => data,
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
assertType<
|
|
210
|
+
() => UseMutationResult<
|
|
211
|
+
ResponseType,
|
|
212
|
+
Error,
|
|
213
|
+
{ urlParams: { fileId: string | number }; data: RequestType }
|
|
214
|
+
>
|
|
215
|
+
>(mutation)
|
|
216
|
+
})
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
describe('useKey option', () => {
|
|
220
|
+
test('multipart mutation with useKey requires urlParams in call', () => {
|
|
221
|
+
const mutation = client.multipartMutation({
|
|
222
|
+
method: 'POST',
|
|
223
|
+
url: '/users/$userId/avatar',
|
|
224
|
+
useKey: true,
|
|
225
|
+
requestSchema,
|
|
226
|
+
responseSchema,
|
|
227
|
+
processResponse: (data) => data,
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
assertType<
|
|
231
|
+
(params: {
|
|
232
|
+
urlParams: { userId: string | number }
|
|
233
|
+
}) => UseMutationResult<
|
|
234
|
+
ResponseType,
|
|
235
|
+
Error,
|
|
236
|
+
{ urlParams: { userId: string | number }; data: RequestType }
|
|
237
|
+
>
|
|
238
|
+
>(mutation)
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
test('multipart mutation with useKey has MutationHelpers', () => {
|
|
242
|
+
const mutation = client.multipartMutation({
|
|
243
|
+
method: 'POST',
|
|
244
|
+
url: '/users/$userId/avatar',
|
|
245
|
+
useKey: true,
|
|
246
|
+
requestSchema,
|
|
247
|
+
responseSchema,
|
|
248
|
+
processResponse: (data) => data,
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
assertType<
|
|
252
|
+
MutationHelpers<'/users/$userId/avatar', ResponseType>['mutationKey']
|
|
253
|
+
>(mutation.mutationKey)
|
|
254
|
+
assertType<
|
|
255
|
+
MutationHelpers<'/users/$userId/avatar', ResponseType>['useIsMutating']
|
|
256
|
+
>(mutation.useIsMutating)
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
test('multipart mutation with useKey and querySchema', () => {
|
|
260
|
+
const mutation = client.multipartMutation({
|
|
261
|
+
method: 'POST',
|
|
262
|
+
url: '/users/$userId/files',
|
|
263
|
+
useKey: true,
|
|
264
|
+
requestSchema,
|
|
265
|
+
querySchema,
|
|
266
|
+
responseSchema,
|
|
267
|
+
processResponse: (data) => data,
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
assertType<
|
|
271
|
+
(params: {
|
|
272
|
+
urlParams: { userId: string | number }
|
|
273
|
+
}) => UseMutationResult<
|
|
274
|
+
ResponseType,
|
|
275
|
+
Error,
|
|
276
|
+
{
|
|
277
|
+
urlParams: { userId: string | number }
|
|
278
|
+
data: RequestType
|
|
279
|
+
params: QueryType
|
|
280
|
+
}
|
|
281
|
+
>
|
|
282
|
+
>(mutation)
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
test('multipart mutation with useKey without URL params', () => {
|
|
286
|
+
const mutation = client.multipartMutation({
|
|
287
|
+
method: 'POST',
|
|
288
|
+
url: '/upload',
|
|
289
|
+
useKey: true,
|
|
290
|
+
requestSchema,
|
|
291
|
+
responseSchema,
|
|
292
|
+
processResponse: (data) => data,
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
assertType<
|
|
296
|
+
(params: {}) => UseMutationResult<
|
|
297
|
+
ResponseType,
|
|
298
|
+
Error,
|
|
299
|
+
{ data: RequestType }
|
|
300
|
+
>
|
|
301
|
+
>(mutation)
|
|
302
|
+
})
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
describe('callback options', () => {
|
|
306
|
+
test('onMutate receives variables and context', () => {
|
|
307
|
+
client.multipartMutation({
|
|
308
|
+
method: 'POST',
|
|
309
|
+
url: '/upload',
|
|
310
|
+
requestSchema,
|
|
311
|
+
responseSchema,
|
|
312
|
+
processResponse: (data) => data,
|
|
313
|
+
onMutate: (variables, context) => {
|
|
314
|
+
assertType<{ data: RequestType }>(variables)
|
|
315
|
+
assertType<{ meta: Record<string, unknown> | undefined }>(context)
|
|
316
|
+
return { previousFiles: [] }
|
|
317
|
+
},
|
|
318
|
+
})
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
test('onSuccess receives data, variables, and context', () => {
|
|
322
|
+
client.multipartMutation({
|
|
323
|
+
method: 'POST',
|
|
324
|
+
url: '/upload',
|
|
325
|
+
requestSchema,
|
|
326
|
+
responseSchema,
|
|
327
|
+
processResponse: (data) => data,
|
|
328
|
+
onSuccess: (data, variables, context) => {
|
|
329
|
+
assertType<ResponseType>(data)
|
|
330
|
+
assertType<{ data: RequestType }>(variables)
|
|
331
|
+
assertType<{ onMutateResult: unknown }>(context)
|
|
332
|
+
},
|
|
333
|
+
})
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
test('onError receives error, variables, and context', () => {
|
|
337
|
+
client.multipartMutation({
|
|
338
|
+
method: 'POST',
|
|
339
|
+
url: '/upload',
|
|
340
|
+
requestSchema,
|
|
341
|
+
responseSchema,
|
|
342
|
+
processResponse: (data) => data,
|
|
343
|
+
onError: (error, variables, context) => {
|
|
344
|
+
assertType<Error>(error)
|
|
345
|
+
assertType<{ data: RequestType }>(variables)
|
|
346
|
+
assertType<{ onMutateResult: unknown }>(context)
|
|
347
|
+
},
|
|
348
|
+
})
|
|
349
|
+
})
|
|
350
|
+
|
|
351
|
+
test('onSettled receives data, error, variables, and context', () => {
|
|
352
|
+
client.multipartMutation({
|
|
353
|
+
method: 'POST',
|
|
354
|
+
url: '/upload',
|
|
355
|
+
requestSchema,
|
|
356
|
+
responseSchema,
|
|
357
|
+
processResponse: (data) => data,
|
|
358
|
+
onSettled: (data, error, variables, context) => {
|
|
359
|
+
assertType<ResponseType | undefined>(data)
|
|
360
|
+
assertType<Error | null>(error)
|
|
361
|
+
assertType<{ data: RequestType }>(variables)
|
|
362
|
+
assertType<{ onMutateResult: unknown }>(context)
|
|
363
|
+
},
|
|
364
|
+
})
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
test('useContext provides custom context', () => {
|
|
368
|
+
client.multipartMutation({
|
|
369
|
+
method: 'POST',
|
|
370
|
+
url: '/upload',
|
|
371
|
+
requestSchema,
|
|
372
|
+
responseSchema,
|
|
373
|
+
processResponse: (data) => data,
|
|
374
|
+
useContext: () => ({ uploadProgress: 0 }),
|
|
375
|
+
onMutate: (_variables, context) => {
|
|
376
|
+
assertType<{ uploadProgress: number }>(context)
|
|
377
|
+
},
|
|
378
|
+
})
|
|
379
|
+
})
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
describe('errorSchema (errors thrown, not in return type)', () => {
|
|
383
|
+
test('multipart mutation with errorSchema returns only success type', () => {
|
|
384
|
+
const mutation = client.multipartMutation({
|
|
385
|
+
method: 'POST',
|
|
386
|
+
url: '/upload',
|
|
387
|
+
requestSchema,
|
|
388
|
+
responseSchema,
|
|
389
|
+
errorSchema,
|
|
390
|
+
processResponse: (data) => data,
|
|
391
|
+
})
|
|
392
|
+
|
|
393
|
+
assertType<
|
|
394
|
+
() => UseMutationResult<ResponseType, Error, { data: RequestType }>
|
|
395
|
+
>(mutation)
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
test('processResponse receives only success type', () => {
|
|
399
|
+
client.multipartMutation({
|
|
400
|
+
method: 'POST',
|
|
401
|
+
url: '/upload',
|
|
402
|
+
requestSchema,
|
|
403
|
+
responseSchema,
|
|
404
|
+
errorSchema,
|
|
405
|
+
processResponse: (data) => {
|
|
406
|
+
assertType<ResponseType>(data)
|
|
407
|
+
return data
|
|
408
|
+
},
|
|
409
|
+
})
|
|
410
|
+
})
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
describe('EndpointHelper', () => {
|
|
414
|
+
test('multipart mutation exposes endpoint property', () => {
|
|
415
|
+
const mutation = client.multipartMutation({
|
|
416
|
+
method: 'POST',
|
|
417
|
+
url: '/upload',
|
|
418
|
+
requestSchema,
|
|
419
|
+
responseSchema,
|
|
420
|
+
processResponse: (data) => data,
|
|
421
|
+
})
|
|
422
|
+
|
|
423
|
+
assertType<
|
|
424
|
+
EndpointHelper<
|
|
425
|
+
'POST',
|
|
426
|
+
'/upload',
|
|
427
|
+
typeof requestSchema,
|
|
428
|
+
typeof responseSchema
|
|
429
|
+
>['endpoint']
|
|
430
|
+
>(mutation.endpoint)
|
|
431
|
+
})
|
|
432
|
+
|
|
433
|
+
test('multipart mutation with querySchema exposes endpoint', () => {
|
|
434
|
+
const mutation = client.multipartMutation({
|
|
435
|
+
method: 'POST',
|
|
436
|
+
url: '/upload',
|
|
437
|
+
requestSchema,
|
|
438
|
+
querySchema,
|
|
439
|
+
responseSchema,
|
|
440
|
+
processResponse: (data) => data,
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
assertType<
|
|
444
|
+
EndpointHelper<
|
|
445
|
+
'POST',
|
|
446
|
+
'/upload',
|
|
447
|
+
typeof requestSchema,
|
|
448
|
+
typeof responseSchema,
|
|
449
|
+
typeof querySchema
|
|
450
|
+
>['endpoint']
|
|
451
|
+
>(mutation.endpoint)
|
|
452
|
+
})
|
|
453
|
+
})
|
|
454
|
+
})
|
|
455
|
+
|
|
456
|
+
// ============================================================================
|
|
457
|
+
// MULTIPART MUTATION METHOD - DISCRIMINATOR MODE (UseDiscriminator=true)
|
|
458
|
+
// ============================================================================
|
|
459
|
+
|
|
460
|
+
describe('ClientInstance<true> multipartMutation() method (discriminator mode)', () => {
|
|
461
|
+
describe('errorSchema includes error union in TData', () => {
|
|
462
|
+
test('multipart mutation with errorSchema returns union result type', () => {
|
|
463
|
+
const mutation = clientWithDiscriminator.multipartMutation({
|
|
464
|
+
method: 'POST',
|
|
465
|
+
url: '/upload',
|
|
466
|
+
requestSchema,
|
|
467
|
+
responseSchema,
|
|
468
|
+
errorSchema,
|
|
469
|
+
processResponse: (data) => data,
|
|
470
|
+
})
|
|
471
|
+
|
|
472
|
+
assertType<
|
|
473
|
+
() => UseMutationResult<
|
|
474
|
+
ResponseWithErrors,
|
|
475
|
+
Error,
|
|
476
|
+
{ data: RequestType }
|
|
477
|
+
>
|
|
478
|
+
>(mutation)
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
test('processResponse receives union type', () => {
|
|
482
|
+
clientWithDiscriminator.multipartMutation({
|
|
483
|
+
method: 'POST',
|
|
484
|
+
url: '/upload',
|
|
485
|
+
requestSchema,
|
|
486
|
+
responseSchema,
|
|
487
|
+
errorSchema,
|
|
488
|
+
processResponse: (data) => {
|
|
489
|
+
assertType<ResponseWithErrors>(data)
|
|
490
|
+
return data
|
|
491
|
+
},
|
|
492
|
+
})
|
|
493
|
+
})
|
|
494
|
+
|
|
495
|
+
test('processResponse can transform union type', () => {
|
|
496
|
+
type ExpectedResult =
|
|
497
|
+
| { ok: false; error: ErrorUnion }
|
|
498
|
+
| { ok: true; data: ResponseType }
|
|
499
|
+
|
|
500
|
+
const mutation = clientWithDiscriminator.multipartMutation({
|
|
501
|
+
method: 'POST',
|
|
502
|
+
url: '/upload',
|
|
503
|
+
requestSchema,
|
|
504
|
+
responseSchema,
|
|
505
|
+
errorSchema,
|
|
506
|
+
processResponse: (data): ExpectedResult => {
|
|
507
|
+
// Use 'id' property to discriminate - only ResponseType has 'id'
|
|
508
|
+
if ('id' in data) {
|
|
509
|
+
return { ok: true, data }
|
|
510
|
+
}
|
|
511
|
+
return { ok: false, error: data }
|
|
512
|
+
},
|
|
513
|
+
})
|
|
514
|
+
|
|
515
|
+
assertType<
|
|
516
|
+
() => UseMutationResult<ExpectedResult, Error, { data: RequestType }>
|
|
517
|
+
>(mutation)
|
|
518
|
+
})
|
|
519
|
+
|
|
520
|
+
test('onSuccess receives union type', () => {
|
|
521
|
+
clientWithDiscriminator.multipartMutation({
|
|
522
|
+
method: 'POST',
|
|
523
|
+
url: '/upload',
|
|
524
|
+
requestSchema,
|
|
525
|
+
responseSchema,
|
|
526
|
+
errorSchema,
|
|
527
|
+
processResponse: (data) => data,
|
|
528
|
+
onSuccess: (data) => {
|
|
529
|
+
assertType<ResponseWithErrors>(data)
|
|
530
|
+
},
|
|
531
|
+
})
|
|
532
|
+
})
|
|
533
|
+
})
|
|
534
|
+
|
|
535
|
+
describe('without errorSchema behaves same as default', () => {
|
|
536
|
+
test('multipart mutation without errorSchema returns only success type', () => {
|
|
537
|
+
const mutation = clientWithDiscriminator.multipartMutation({
|
|
538
|
+
method: 'POST',
|
|
539
|
+
url: '/upload',
|
|
540
|
+
requestSchema,
|
|
541
|
+
responseSchema,
|
|
542
|
+
processResponse: (data) => data,
|
|
543
|
+
})
|
|
544
|
+
|
|
545
|
+
assertType<
|
|
546
|
+
() => UseMutationResult<ResponseType, Error, { data: RequestType }>
|
|
547
|
+
>(mutation)
|
|
548
|
+
})
|
|
549
|
+
})
|
|
550
|
+
})
|
|
551
|
+
|
|
552
|
+
// ============================================================================
|
|
553
|
+
// ERROR CASES - Should fail type checking
|
|
554
|
+
// ============================================================================
|
|
555
|
+
|
|
556
|
+
describe('multipartMutation() error cases', () => {
|
|
557
|
+
describe('missing required parameters in variables', () => {
|
|
558
|
+
test('multipartMutation().mutate() without data', () => {
|
|
559
|
+
const mutation = client.multipartMutation({
|
|
560
|
+
method: 'POST',
|
|
561
|
+
url: '/upload',
|
|
562
|
+
requestSchema,
|
|
563
|
+
responseSchema,
|
|
564
|
+
processResponse: (data) => data,
|
|
565
|
+
})
|
|
566
|
+
|
|
567
|
+
const { mutate } = mutation()
|
|
568
|
+
|
|
569
|
+
// @ts-expect-error - missing data
|
|
570
|
+
mutate({})
|
|
571
|
+
})
|
|
572
|
+
|
|
573
|
+
test('multipartMutation().mutate() without urlParams when URL has params', () => {
|
|
574
|
+
const mutation = client.multipartMutation({
|
|
575
|
+
method: 'POST',
|
|
576
|
+
url: '/users/$userId/avatar',
|
|
577
|
+
requestSchema,
|
|
578
|
+
responseSchema,
|
|
579
|
+
processResponse: (data) => data,
|
|
580
|
+
})
|
|
581
|
+
|
|
582
|
+
const { mutate } = mutation()
|
|
583
|
+
|
|
584
|
+
// @ts-expect-error - missing urlParams
|
|
585
|
+
mutate({ data: { file: new File([], 'test.txt'), description: 'test' } })
|
|
586
|
+
})
|
|
587
|
+
|
|
588
|
+
test('multipartMutation().mutate() without params when querySchema is defined', () => {
|
|
589
|
+
const mutation = client.multipartMutation({
|
|
590
|
+
method: 'POST',
|
|
591
|
+
url: '/upload',
|
|
592
|
+
requestSchema,
|
|
593
|
+
querySchema,
|
|
594
|
+
responseSchema,
|
|
595
|
+
processResponse: (data) => data,
|
|
596
|
+
})
|
|
597
|
+
|
|
598
|
+
const { mutate } = mutation()
|
|
599
|
+
|
|
600
|
+
// @ts-expect-error - missing params
|
|
601
|
+
mutate({ data: { file: new File([], 'test.txt'), description: 'test' } })
|
|
602
|
+
})
|
|
603
|
+
})
|
|
604
|
+
|
|
605
|
+
describe('missing useKey call params', () => {
|
|
606
|
+
test('multipart mutation with useKey called without urlParams', () => {
|
|
607
|
+
const mutation = client.multipartMutation({
|
|
608
|
+
method: 'POST',
|
|
609
|
+
url: '/users/$userId/avatar',
|
|
610
|
+
useKey: true,
|
|
611
|
+
requestSchema,
|
|
612
|
+
responseSchema,
|
|
613
|
+
processResponse: (data) => data,
|
|
614
|
+
})
|
|
615
|
+
|
|
616
|
+
// @ts-expect-error - missing urlParams in call
|
|
617
|
+
mutation()
|
|
618
|
+
})
|
|
619
|
+
})
|
|
620
|
+
|
|
621
|
+
describe('wrong parameter types in variables', () => {
|
|
622
|
+
test('data with wrong shape', () => {
|
|
623
|
+
const mutation = client.multipartMutation({
|
|
624
|
+
method: 'POST',
|
|
625
|
+
url: '/upload',
|
|
626
|
+
requestSchema,
|
|
627
|
+
responseSchema,
|
|
628
|
+
processResponse: (data) => data,
|
|
629
|
+
})
|
|
630
|
+
|
|
631
|
+
const { mutate } = mutation()
|
|
632
|
+
|
|
633
|
+
// @ts-expect-error - wrong property names
|
|
634
|
+
mutate({ data: { document: new File([], 'test.txt'), desc: 'test' } })
|
|
635
|
+
})
|
|
636
|
+
|
|
637
|
+
test('data with wrong value types', () => {
|
|
638
|
+
const mutation = client.multipartMutation({
|
|
639
|
+
method: 'POST',
|
|
640
|
+
url: '/upload',
|
|
641
|
+
requestSchema,
|
|
642
|
+
responseSchema,
|
|
643
|
+
processResponse: (data) => data,
|
|
644
|
+
})
|
|
645
|
+
|
|
646
|
+
const { mutate } = mutation()
|
|
647
|
+
|
|
648
|
+
// @ts-expect-error - file should be File, not string
|
|
649
|
+
mutate({ data: { file: 'not-a-file', description: 'test' } })
|
|
650
|
+
})
|
|
651
|
+
|
|
652
|
+
test('urlParams with wrong type', () => {
|
|
653
|
+
const mutation = client.multipartMutation({
|
|
654
|
+
method: 'POST',
|
|
655
|
+
url: '/users/$userId/avatar',
|
|
656
|
+
requestSchema,
|
|
657
|
+
responseSchema,
|
|
658
|
+
processResponse: (data) => data,
|
|
659
|
+
})
|
|
660
|
+
|
|
661
|
+
const { mutate } = mutation()
|
|
662
|
+
|
|
663
|
+
mutate({
|
|
664
|
+
urlParams: {
|
|
665
|
+
// @ts-expect-error - userId should be string | number, not boolean
|
|
666
|
+
userId: true,
|
|
667
|
+
},
|
|
668
|
+
data: { file: new File([], 'test.txt'), description: 'test' },
|
|
669
|
+
})
|
|
670
|
+
})
|
|
671
|
+
|
|
672
|
+
test('params with wrong shape', () => {
|
|
673
|
+
const mutation = client.multipartMutation({
|
|
674
|
+
method: 'POST',
|
|
675
|
+
url: '/upload',
|
|
676
|
+
requestSchema,
|
|
677
|
+
querySchema,
|
|
678
|
+
responseSchema,
|
|
679
|
+
processResponse: (data) => data,
|
|
680
|
+
})
|
|
681
|
+
|
|
682
|
+
const { mutate } = mutation()
|
|
683
|
+
|
|
684
|
+
mutate({
|
|
685
|
+
data: { file: new File([], 'test.txt'), description: 'test' },
|
|
686
|
+
params: {
|
|
687
|
+
// @ts-expect-error - wrong property names
|
|
688
|
+
offset: 0,
|
|
689
|
+
count: 10,
|
|
690
|
+
},
|
|
691
|
+
})
|
|
692
|
+
})
|
|
693
|
+
})
|
|
694
|
+
|
|
695
|
+
describe('processResponse type safety', () => {
|
|
696
|
+
test('processResponse receives correct input type', () => {
|
|
697
|
+
client.multipartMutation({
|
|
698
|
+
method: 'POST',
|
|
699
|
+
url: '/upload',
|
|
700
|
+
requestSchema,
|
|
701
|
+
responseSchema,
|
|
702
|
+
processResponse: (data) => {
|
|
703
|
+
// @ts-expect-error - data doesn't have 'nonExistent' property
|
|
704
|
+
return data.nonExistent
|
|
705
|
+
},
|
|
706
|
+
})
|
|
707
|
+
})
|
|
708
|
+
})
|
|
709
|
+
|
|
710
|
+
describe('callback type safety', () => {
|
|
711
|
+
test('onSuccess data type matches processResponse result', () => {
|
|
712
|
+
client.multipartMutation({
|
|
713
|
+
method: 'POST',
|
|
714
|
+
url: '/upload',
|
|
715
|
+
requestSchema,
|
|
716
|
+
responseSchema,
|
|
717
|
+
processResponse: (data) => ({ transformed: data.name }),
|
|
718
|
+
onSuccess: (data) => {
|
|
719
|
+
// @ts-expect-error - data is { transformed: string }, not ResponseType
|
|
720
|
+
const _id: string = data.id
|
|
721
|
+
},
|
|
722
|
+
})
|
|
723
|
+
})
|
|
724
|
+
})
|
|
725
|
+
})
|