@data-client/rest 0.1.0 → 0.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/dist/index.js +10 -14
- package/dist/index.umd.min.js +1 -1
- package/legacy/OptionsToFunction.js +1 -1
- package/legacy/RestEndpoint.js +5 -5
- package/legacy/createResource.js +8 -10
- package/legacy/index.js +2 -1
- package/legacy/next/index.js +4 -4
- package/legacy/resourceTypes.js +2 -0
- package/lib/OptionsToFunction.d.ts.map +1 -1
- package/lib/OptionsToFunction.js +1 -1
- package/lib/RestEndpoint.d.ts +29 -35
- package/lib/RestEndpoint.js +5 -5
- package/lib/createResource.d.ts +51 -31
- package/lib/createResource.d.ts.map +1 -1
- package/lib/createResource.js +7 -11
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/next/index.d.ts +5 -5
- package/lib/next/index.d.ts.map +1 -1
- package/lib/next/index.js +4 -4
- package/lib/resourceTypes.d.ts.map +1 -0
- package/lib/resourceTypes.js +2 -0
- package/package.json +3 -3
- package/src/OptionsToFunction.ts +0 -1
- package/src/RestEndpoint.d.ts +29 -35
- package/src/RestEndpoint.js +4 -4
- package/src/__tests__/RestEndpoint.ts +38 -9
- package/src/__tests__/createResource.test.ts +3 -4
- package/src/__tests__/hookifyResource.ts +7 -3
- package/src/__tests__/types.test.ts +332 -212
- package/src/createResource.ts +81 -60
- package/src/index.ts +2 -2
- package/src/next/index.ts +5 -5
- package/ts4.0/RestEndpoint.d.ts +18 -32
- package/ts4.0/createResource.d.ts +59 -31
- package/ts4.0/index.d.ts +3 -1
- package/ts4.0/next/index.d.ts +5 -5
- package/legacy/next/OptionsToFunction.js +0 -2
- package/legacy/next/RestEndpoint.js +0 -225
- package/legacy/next/createResource.js +0 -86
- package/legacy/next/resourceTypes.js +0 -2
- package/lib/next/OptionsToFunction.d.ts +0 -7
- package/lib/next/OptionsToFunction.d.ts.map +0 -1
- package/lib/next/OptionsToFunction.js +0 -2
- package/lib/next/RestEndpoint.d.ts +0 -542
- package/lib/next/RestEndpoint.js +0 -229
- package/lib/next/createResource.d.ts +0 -86
- package/lib/next/createResource.d.ts.map +0 -1
- package/lib/next/createResource.js +0 -100
- package/lib/next/resourceTypes.d.ts.map +0 -1
- package/lib/next/resourceTypes.js +0 -2
- package/src/next/OptionsToFunction.ts +0 -41
- package/src/next/RestEndpoint.d.ts +0 -542
- package/src/next/RestEndpoint.js +0 -262
- package/src/next/__tests__/RestEndpoint.ts +0 -1333
- package/src/next/__tests__/__snapshots__/RestEndpoint.ts.snap +0 -18
- package/src/next/__tests__/types.test.ts +0 -429
- package/src/next/createResource.ts +0 -194
- package/ts4.0/next/OptionsToFunction.d.ts +0 -16
- package/ts4.0/next/RestEndpoint.d.ts +0 -226
- package/ts4.0/next/createResource.d.ts +0 -94
- /package/lib/{next/resourceTypes.d.ts → resourceTypes.d.ts} +0 -0
- /package/src/{next/resourceTypes.ts → resourceTypes.ts} +0 -0
- /package/ts4.0/{next/resourceTypes.d.ts → resourceTypes.d.ts} +0 -0
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`RestEndpoint.fetch() should reject if content-type does not exist with schema 1`] = `[NetworkError: Unexpected text response for schema CoolerArticle]`;
|
|
4
|
-
|
|
5
|
-
exports[`RestEndpoint.fetch() should reject if content-type is not json with schema 1`] = `
|
|
6
|
-
[NetworkError: Unexpected html response for schema CoolerArticle
|
|
7
|
-
This likely means no API endpoint was configured for this request, resulting in an HTML fallback.
|
|
8
|
-
|
|
9
|
-
Response (first 300 characters): <body>this is html</body>]
|
|
10
|
-
`;
|
|
11
|
-
|
|
12
|
-
exports[`RestEndpoint.fetch() should reject with custom message if content type is set but json parsable 1`] = `
|
|
13
|
-
[NetworkError: "content-type" header does not include "json", but JSON response found.
|
|
14
|
-
See https://www.rfc-editor.org/rfc/rfc4627 for information on JSON responses
|
|
15
|
-
|
|
16
|
-
Using parsed JSON.
|
|
17
|
-
If text content was expected see https://resthooks.io/rest/api/RestEndpoint#parseResponse]
|
|
18
|
-
`;
|
|
@@ -1,429 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
2
|
-
import { Entity, schema } from '@data-client/endpoint';
|
|
3
|
-
import { useSuspense } from '@data-client/react';
|
|
4
|
-
import { User } from '__tests__/new';
|
|
5
|
-
|
|
6
|
-
import createResource from '../createResource';
|
|
7
|
-
import RestEndpoint, { MutateEndpoint } from '../RestEndpoint';
|
|
8
|
-
|
|
9
|
-
it('RestEndpoint construct and extend with typed options', () => {
|
|
10
|
-
new RestEndpoint({
|
|
11
|
-
path: '/todos/',
|
|
12
|
-
getOptimisticResponse(snap, body) {
|
|
13
|
-
return body;
|
|
14
|
-
},
|
|
15
|
-
schema: User,
|
|
16
|
-
method: 'POST',
|
|
17
|
-
});
|
|
18
|
-
// variable/unknown number of args
|
|
19
|
-
new RestEndpoint({
|
|
20
|
-
path: '/todos/',
|
|
21
|
-
searchParams: {} as { userId?: string | number } | undefined,
|
|
22
|
-
getOptimisticResponse(snap, ...args) {
|
|
23
|
-
return args[args.length - 1];
|
|
24
|
-
},
|
|
25
|
-
schema: User,
|
|
26
|
-
method: 'POST',
|
|
27
|
-
});
|
|
28
|
-
new RestEndpoint({
|
|
29
|
-
path: '/todos/:id',
|
|
30
|
-
searchParams: {} as { userId?: string | number } | undefined,
|
|
31
|
-
getOptimisticResponse(snap, params, body) {
|
|
32
|
-
return body;
|
|
33
|
-
},
|
|
34
|
-
schema: User,
|
|
35
|
-
method: 'POST',
|
|
36
|
-
});
|
|
37
|
-
new RestEndpoint({
|
|
38
|
-
path: '/todos/:id',
|
|
39
|
-
searchParams: {} as { userId?: string | number } | undefined,
|
|
40
|
-
getOptimisticResponse(snap, params, body) {
|
|
41
|
-
return body;
|
|
42
|
-
},
|
|
43
|
-
schema: User,
|
|
44
|
-
method: 'POST',
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const nopath = new RestEndpoint({
|
|
48
|
-
path: '/todos/',
|
|
49
|
-
schema: User,
|
|
50
|
-
method: 'POST',
|
|
51
|
-
});
|
|
52
|
-
const somepath = new RestEndpoint({
|
|
53
|
-
path: '/todos/:id',
|
|
54
|
-
schema: User,
|
|
55
|
-
method: 'POST',
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
nopath.extend({
|
|
59
|
-
getOptimisticResponse(snap, body) {
|
|
60
|
-
return body;
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
nopath.extend({
|
|
64
|
-
searchParams: {} as { userId?: string | number } | undefined,
|
|
65
|
-
getOptimisticResponse(snap, ...args) {
|
|
66
|
-
return args[args.length - 1];
|
|
67
|
-
},
|
|
68
|
-
});
|
|
69
|
-
somepath.extend({
|
|
70
|
-
searchParams: {} as { userId?: string | number } | undefined,
|
|
71
|
-
getOptimisticResponse(snap, args, body) {
|
|
72
|
-
return body;
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should customize resources', () => {
|
|
78
|
-
class Todo extends Entity {
|
|
79
|
-
id = '';
|
|
80
|
-
userId = 0;
|
|
81
|
-
title = '';
|
|
82
|
-
completed = false;
|
|
83
|
-
|
|
84
|
-
static key = 'Todo';
|
|
85
|
-
pk() {
|
|
86
|
-
return this.id;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const TodoResource = createResource({
|
|
91
|
-
path: '/todos/:id',
|
|
92
|
-
schema: Todo,
|
|
93
|
-
});
|
|
94
|
-
TodoResource.create.extend({
|
|
95
|
-
searchParams: {} as { userId?: string | number } | undefined,
|
|
96
|
-
getOptimisticResponse(snap, ...args) {
|
|
97
|
-
return args[args.length - 1];
|
|
98
|
-
},
|
|
99
|
-
});
|
|
100
|
-
const partial = TodoResource.partialUpdate.extend({
|
|
101
|
-
getOptimisticResponse(snap, { id }, body) {
|
|
102
|
-
return {
|
|
103
|
-
id,
|
|
104
|
-
...body,
|
|
105
|
-
};
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
() => partial({ id: 5 }, { title: 'hi' });
|
|
109
|
-
const a: MutateEndpoint<{
|
|
110
|
-
path: '/todos/';
|
|
111
|
-
body: Partial<Todo>;
|
|
112
|
-
schema: typeof Todo;
|
|
113
|
-
}> = TodoResource.create.extend({ schema: Todo }) as any;
|
|
114
|
-
a.extend({
|
|
115
|
-
searchParams: {} as { userId?: string | number } | undefined,
|
|
116
|
-
getOptimisticResponse(snap, ...args) {
|
|
117
|
-
return args[args.length - 1];
|
|
118
|
-
},
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
() => useSuspense(TodoResource.getList);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// path: ['/todos', '/todos/:id', '/todos/:id?', string]
|
|
125
|
-
it('should precisely type function arguments', () => {
|
|
126
|
-
// path: '/todos'
|
|
127
|
-
() => {
|
|
128
|
-
const optionalUndefSearch = new RestEndpoint({
|
|
129
|
-
path: '/todos',
|
|
130
|
-
searchParams: {} as
|
|
131
|
-
| {
|
|
132
|
-
userId?: string | number;
|
|
133
|
-
}
|
|
134
|
-
| undefined,
|
|
135
|
-
});
|
|
136
|
-
const optionalSearch = new RestEndpoint({
|
|
137
|
-
path: '/todos',
|
|
138
|
-
searchParams: {} as {
|
|
139
|
-
userId?: string | number;
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
const undef = new RestEndpoint({
|
|
143
|
-
path: '/todos',
|
|
144
|
-
searchParams: undefined,
|
|
145
|
-
});
|
|
146
|
-
const requiredSearch = new RestEndpoint({
|
|
147
|
-
path: '/todos',
|
|
148
|
-
searchParams: {} as {
|
|
149
|
-
userId: string | number;
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
const noSearch = new RestEndpoint({
|
|
153
|
-
path: '/todos',
|
|
154
|
-
});
|
|
155
|
-
() => optionalUndefSearch();
|
|
156
|
-
() => optionalUndefSearch({});
|
|
157
|
-
() => optionalUndefSearch({ userId: 'hi' });
|
|
158
|
-
// @ts-expect-error
|
|
159
|
-
() => optionalUndefSearch(5);
|
|
160
|
-
// @ts-expect-error
|
|
161
|
-
() => optionalUndefSearch({ userId: 'hi' }, { userId: 'hi' });
|
|
162
|
-
|
|
163
|
-
() => optionalSearch();
|
|
164
|
-
() => optionalSearch({});
|
|
165
|
-
() => optionalSearch({ userId: 'hi' });
|
|
166
|
-
// @ts-expect-error
|
|
167
|
-
() => optionalSearch(5);
|
|
168
|
-
// @ts-expect-error
|
|
169
|
-
() => optionalSearch({ userId: 'hi' }, { userId: 'hi' });
|
|
170
|
-
|
|
171
|
-
// @ts-expect-error
|
|
172
|
-
() => requiredSearch();
|
|
173
|
-
// @ts-expect-error
|
|
174
|
-
() => requiredSearch({});
|
|
175
|
-
() => requiredSearch({ userId: 'hi' });
|
|
176
|
-
// @ts-expect-error
|
|
177
|
-
() => requiredSearch(5);
|
|
178
|
-
// @ts-expect-error
|
|
179
|
-
() => requiredSearch({ userId: 'hi' }, { userId: 'hi' });
|
|
180
|
-
|
|
181
|
-
() => undef();
|
|
182
|
-
// @ts-expect-error
|
|
183
|
-
() => undef({});
|
|
184
|
-
// @ts-expect-error
|
|
185
|
-
() => undef({ userId: 'hi' });
|
|
186
|
-
// @ts-expect-error
|
|
187
|
-
() => undef(5);
|
|
188
|
-
|
|
189
|
-
() => noSearch();
|
|
190
|
-
// @ts-expect-error
|
|
191
|
-
() => noSearch({});
|
|
192
|
-
// @ts-expect-error
|
|
193
|
-
() => noSearch({ userId: 'hi' });
|
|
194
|
-
// @ts-expect-error
|
|
195
|
-
() => noSearch(5);
|
|
196
|
-
};
|
|
197
|
-
// path: '/todos/:id?'
|
|
198
|
-
() => {
|
|
199
|
-
const optionalUndefSearch = new RestEndpoint({
|
|
200
|
-
path: '/todos/:id?',
|
|
201
|
-
searchParams: {} as
|
|
202
|
-
| {
|
|
203
|
-
userId?: string | number;
|
|
204
|
-
}
|
|
205
|
-
| undefined,
|
|
206
|
-
});
|
|
207
|
-
const optionalSearch = new RestEndpoint({
|
|
208
|
-
path: '/todos/:id?',
|
|
209
|
-
searchParams: {} as {
|
|
210
|
-
userId?: string | number;
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
const undef = new RestEndpoint({
|
|
214
|
-
path: '/todos/:id?',
|
|
215
|
-
searchParams: undefined,
|
|
216
|
-
});
|
|
217
|
-
const requiredSearch = new RestEndpoint({
|
|
218
|
-
path: '/todos/:id?',
|
|
219
|
-
searchParams: {} as {
|
|
220
|
-
userId: string | number;
|
|
221
|
-
},
|
|
222
|
-
});
|
|
223
|
-
const noSearch = new RestEndpoint({
|
|
224
|
-
path: '/todos/:id?',
|
|
225
|
-
});
|
|
226
|
-
() => optionalUndefSearch();
|
|
227
|
-
() => optionalUndefSearch({});
|
|
228
|
-
() => optionalUndefSearch({ id: '5' });
|
|
229
|
-
() => optionalUndefSearch({ userId: 'hi' });
|
|
230
|
-
() => optionalUndefSearch({ userId: 'hi', id: '5' });
|
|
231
|
-
// @ts-expect-error
|
|
232
|
-
() => optionalUndefSearch(5);
|
|
233
|
-
// @ts-expect-error
|
|
234
|
-
() => optionalUndefSearch({ userId: 'hi' }, { userId: 'hi' });
|
|
235
|
-
|
|
236
|
-
() => optionalSearch();
|
|
237
|
-
() => optionalSearch({});
|
|
238
|
-
() => optionalSearch({ id: '5' });
|
|
239
|
-
() => optionalSearch({ userId: 'hi' });
|
|
240
|
-
() => optionalSearch({ userId: 'hi', id: '5' });
|
|
241
|
-
// @ts-expect-error
|
|
242
|
-
() => optionalSearch(5);
|
|
243
|
-
// @ts-expect-error
|
|
244
|
-
() => optionalSearch({ userId: 'hi' }, { userId: 'hi' });
|
|
245
|
-
|
|
246
|
-
// @ts-expect-error
|
|
247
|
-
() => requiredSearch();
|
|
248
|
-
// @ts-expect-error
|
|
249
|
-
() => requiredSearch({});
|
|
250
|
-
// @ts-expect-error
|
|
251
|
-
() => requiredSearch({ id: '5' });
|
|
252
|
-
() => requiredSearch({ userId: 'hi' });
|
|
253
|
-
() => requiredSearch({ userId: 'hi', id: '5' });
|
|
254
|
-
// @ts-expect-error
|
|
255
|
-
() => requiredSearch(5);
|
|
256
|
-
// @ts-expect-error
|
|
257
|
-
() => requiredSearch({ userId: 'hi' }, { userId: 'hi' });
|
|
258
|
-
|
|
259
|
-
() => undef();
|
|
260
|
-
// @ts-ignore TODO
|
|
261
|
-
() => undef({});
|
|
262
|
-
// @ts-ignore TODO
|
|
263
|
-
() => undef({ id: '5' });
|
|
264
|
-
// @ts-expect-error
|
|
265
|
-
() => undef({ userId: 'hi' });
|
|
266
|
-
// @ts-expect-error
|
|
267
|
-
() => undef(5);
|
|
268
|
-
|
|
269
|
-
() => noSearch();
|
|
270
|
-
() => noSearch({});
|
|
271
|
-
() => noSearch({ id: '5' });
|
|
272
|
-
// @ts-expect-error
|
|
273
|
-
() => noSearch({ userId: 'hi' });
|
|
274
|
-
// @ts-expect-error
|
|
275
|
-
() => noSearch(5);
|
|
276
|
-
};
|
|
277
|
-
// path: '/todos/:id'
|
|
278
|
-
() => {
|
|
279
|
-
const optionalUndefSearch = new RestEndpoint({
|
|
280
|
-
path: '/todos/:id',
|
|
281
|
-
searchParams: {} as
|
|
282
|
-
| {
|
|
283
|
-
userId?: string | number;
|
|
284
|
-
}
|
|
285
|
-
| undefined,
|
|
286
|
-
});
|
|
287
|
-
const optionalSearch = new RestEndpoint({
|
|
288
|
-
path: '/todos/:id',
|
|
289
|
-
searchParams: {} as {
|
|
290
|
-
userId?: string | number;
|
|
291
|
-
},
|
|
292
|
-
});
|
|
293
|
-
const undef = new RestEndpoint({
|
|
294
|
-
path: '/todos/:id',
|
|
295
|
-
searchParams: undefined,
|
|
296
|
-
});
|
|
297
|
-
const requiredSearch = new RestEndpoint({
|
|
298
|
-
path: '/todos/:id',
|
|
299
|
-
searchParams: {} as {
|
|
300
|
-
userId: string | number;
|
|
301
|
-
},
|
|
302
|
-
});
|
|
303
|
-
const noSearch = new RestEndpoint({
|
|
304
|
-
path: '/todos/:id',
|
|
305
|
-
});
|
|
306
|
-
// @ts-expect-error
|
|
307
|
-
() => optionalUndefSearch();
|
|
308
|
-
() => optionalUndefSearch({ id: '5' });
|
|
309
|
-
() => optionalUndefSearch({ id: '5', userId: 'hi' });
|
|
310
|
-
// @ts-expect-error
|
|
311
|
-
() => optionalUndefSearch(5);
|
|
312
|
-
() =>
|
|
313
|
-
// @ts-expect-error
|
|
314
|
-
optionalUndefSearch({ id: '5', userId: 'hi' }, { id: '5', userId: 'hi' });
|
|
315
|
-
|
|
316
|
-
// @ts-expect-error
|
|
317
|
-
() => optionalSearch();
|
|
318
|
-
() => optionalSearch({ id: '5' });
|
|
319
|
-
() => optionalSearch({ id: '5', userId: 'hi' });
|
|
320
|
-
// @ts-expect-error
|
|
321
|
-
() => optionalSearch(5);
|
|
322
|
-
// @ts-expect-error
|
|
323
|
-
() => optionalSearch({ id: '5', userId: 'hi' }, { id: '5', userId: 'hi' });
|
|
324
|
-
|
|
325
|
-
// @ts-expect-error
|
|
326
|
-
() => requiredSearch();
|
|
327
|
-
// @ts-expect-error
|
|
328
|
-
() => requiredSearch({ id: '5' });
|
|
329
|
-
() => requiredSearch({ id: '5', userId: 'hi' });
|
|
330
|
-
// @ts-expect-error
|
|
331
|
-
() => requiredSearch(5);
|
|
332
|
-
// @ts-expect-error
|
|
333
|
-
() => requiredSearch({ id: '5', userId: 'hi' }, { id: '5', userId: 'hi' });
|
|
334
|
-
|
|
335
|
-
// @ts-expect-error
|
|
336
|
-
() => undef();
|
|
337
|
-
// @ts-expect-error
|
|
338
|
-
() => undef({});
|
|
339
|
-
// @ts-expect-error
|
|
340
|
-
() => undef({ id: '5', userId: 'hi' });
|
|
341
|
-
// @ts-expect-error
|
|
342
|
-
() => undef(5);
|
|
343
|
-
|
|
344
|
-
// @ts-expect-error
|
|
345
|
-
() => noSearch();
|
|
346
|
-
() => noSearch({ id: '5' });
|
|
347
|
-
// @ts-expect-error
|
|
348
|
-
() => noSearch({ id: '5', userId: 'hi' });
|
|
349
|
-
// @ts-expect-error
|
|
350
|
-
() => noSearch(5);
|
|
351
|
-
};
|
|
352
|
-
// path: string
|
|
353
|
-
() => {
|
|
354
|
-
const optionalUndefSearch = new RestEndpoint({
|
|
355
|
-
path: '' as string,
|
|
356
|
-
searchParams: {} as
|
|
357
|
-
| {
|
|
358
|
-
userId?: string | number;
|
|
359
|
-
}
|
|
360
|
-
| undefined,
|
|
361
|
-
});
|
|
362
|
-
const optionalSearch = new RestEndpoint({
|
|
363
|
-
path: '' as string,
|
|
364
|
-
searchParams: {} as {
|
|
365
|
-
userId?: string | number;
|
|
366
|
-
},
|
|
367
|
-
});
|
|
368
|
-
const undef = new RestEndpoint({
|
|
369
|
-
path: '' as string,
|
|
370
|
-
searchParams: undefined,
|
|
371
|
-
});
|
|
372
|
-
const requiredSearch = new RestEndpoint({
|
|
373
|
-
path: '' as string,
|
|
374
|
-
searchParams: {} as {
|
|
375
|
-
userId: string | number;
|
|
376
|
-
},
|
|
377
|
-
});
|
|
378
|
-
const noSearch = new RestEndpoint({
|
|
379
|
-
path: '' as string,
|
|
380
|
-
});
|
|
381
|
-
() => optionalUndefSearch();
|
|
382
|
-
() => optionalUndefSearch({});
|
|
383
|
-
() => optionalUndefSearch({ id: '5' });
|
|
384
|
-
() => optionalUndefSearch({ userId: 'hi' });
|
|
385
|
-
() => optionalUndefSearch({ userId: 'hi', id: '5' });
|
|
386
|
-
// @ts-expect-error
|
|
387
|
-
() => optionalUndefSearch(5);
|
|
388
|
-
// @ts-expect-error
|
|
389
|
-
() => optionalUndefSearch({ userId: 'hi' }, { userId: 'hi' });
|
|
390
|
-
|
|
391
|
-
() => optionalSearch();
|
|
392
|
-
() => optionalSearch({});
|
|
393
|
-
() => optionalSearch({ id: '5' });
|
|
394
|
-
() => optionalSearch({ userId: 'hi' });
|
|
395
|
-
() => optionalSearch({ userId: 'hi', id: '5' });
|
|
396
|
-
// @ts-expect-error
|
|
397
|
-
() => optionalSearch(5);
|
|
398
|
-
// @ts-expect-error
|
|
399
|
-
() => optionalSearch({ userId: 'hi' }, { userId: 'hi' });
|
|
400
|
-
|
|
401
|
-
// @ts-expect-error
|
|
402
|
-
() => requiredSearch();
|
|
403
|
-
// @ts-expect-error
|
|
404
|
-
() => requiredSearch({});
|
|
405
|
-
// @ts-expect-error
|
|
406
|
-
() => requiredSearch({ id: '5' });
|
|
407
|
-
() => requiredSearch({ userId: 'hi' });
|
|
408
|
-
() => requiredSearch({ userId: 'hi', id: '5' });
|
|
409
|
-
// @ts-expect-error
|
|
410
|
-
() => requiredSearch(5);
|
|
411
|
-
// @ts-expect-error
|
|
412
|
-
() => requiredSearch({ userId: 'hi' }, { userId: 'hi' });
|
|
413
|
-
|
|
414
|
-
() => undef();
|
|
415
|
-
// @ts-ignore TODO
|
|
416
|
-
() => undef({});
|
|
417
|
-
// @ts-ignore TODO
|
|
418
|
-
() => undef({ id: '5' });
|
|
419
|
-
// @ts-expect-error
|
|
420
|
-
() => undef(5);
|
|
421
|
-
|
|
422
|
-
() => noSearch();
|
|
423
|
-
() => noSearch({});
|
|
424
|
-
() => noSearch({ id: '5' });
|
|
425
|
-
() => noSearch({ userId: 'hi' });
|
|
426
|
-
// @ts-expect-error
|
|
427
|
-
() => noSearch(5);
|
|
428
|
-
};
|
|
429
|
-
});
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AbortOptimistic,
|
|
3
|
-
SnapshotInterface,
|
|
4
|
-
schema,
|
|
5
|
-
} from '@data-client/endpoint';
|
|
6
|
-
import type { Schema, Denormalize } from '@data-client/endpoint';
|
|
7
|
-
|
|
8
|
-
import { ResourceGenerics, ResourceOptions } from './resourceTypes.js';
|
|
9
|
-
import RestEndpoint, {
|
|
10
|
-
GetEndpoint,
|
|
11
|
-
MutateEndpoint,
|
|
12
|
-
RestInstance,
|
|
13
|
-
RestTypeNoBody,
|
|
14
|
-
} from './RestEndpoint.js';
|
|
15
|
-
import { PathArgs, ShortenPath } from '../pathTypes.js';
|
|
16
|
-
import { shortenPath } from '../RestHelpers.js';
|
|
17
|
-
|
|
18
|
-
const { Invalidate, Collection } = schema;
|
|
19
|
-
|
|
20
|
-
/** Creates collection of Endpoints for common operations on a given data/schema.
|
|
21
|
-
*
|
|
22
|
-
* @see https://resthooks.io/rest/api/createResource
|
|
23
|
-
*/
|
|
24
|
-
export default function createResource<O extends ResourceGenerics>({
|
|
25
|
-
path,
|
|
26
|
-
schema,
|
|
27
|
-
Endpoint = RestEndpoint,
|
|
28
|
-
optimistic,
|
|
29
|
-
...extraOptions
|
|
30
|
-
}: Readonly<O> & ResourceOptions): Resource<O> {
|
|
31
|
-
const shortenedPath = shortenPath(path);
|
|
32
|
-
const getName = (name: string) => `${(schema as any)?.name}.${name}`;
|
|
33
|
-
const extraMutateOptions = { ...extraOptions };
|
|
34
|
-
const extraPartialOptions = { ...extraOptions };
|
|
35
|
-
const get: GetEndpoint<{ path: O['path']; schema: O['schema'] }> =
|
|
36
|
-
new Endpoint({
|
|
37
|
-
...extraOptions,
|
|
38
|
-
path,
|
|
39
|
-
schema,
|
|
40
|
-
name: getName('get'),
|
|
41
|
-
}) as any;
|
|
42
|
-
if (optimistic) {
|
|
43
|
-
(extraMutateOptions as any).getOptimisticResponse = optimisticUpdate;
|
|
44
|
-
(extraPartialOptions as any).getOptimisticResponse = optimisticPartial(get);
|
|
45
|
-
}
|
|
46
|
-
const getList = new Endpoint({
|
|
47
|
-
...extraMutateOptions,
|
|
48
|
-
path: shortenedPath,
|
|
49
|
-
schema: new Collection([schema as any]),
|
|
50
|
-
name: getName('getList'),
|
|
51
|
-
});
|
|
52
|
-
return {
|
|
53
|
-
get,
|
|
54
|
-
getList,
|
|
55
|
-
create: getList.push.extend({ name: getName('create') }),
|
|
56
|
-
update: new Endpoint({
|
|
57
|
-
...extraMutateOptions,
|
|
58
|
-
path,
|
|
59
|
-
schema,
|
|
60
|
-
method: 'PUT',
|
|
61
|
-
name: getName('update'),
|
|
62
|
-
}),
|
|
63
|
-
partialUpdate: new Endpoint({
|
|
64
|
-
...extraPartialOptions,
|
|
65
|
-
path,
|
|
66
|
-
schema,
|
|
67
|
-
method: 'PATCH',
|
|
68
|
-
name: getName('partialUpdate'),
|
|
69
|
-
}),
|
|
70
|
-
delete: new Endpoint({
|
|
71
|
-
...extraMutateOptions,
|
|
72
|
-
path,
|
|
73
|
-
schema: (schema as any).process ? new Invalidate(schema as any) : schema,
|
|
74
|
-
method: 'DELETE',
|
|
75
|
-
name: getName('delete'),
|
|
76
|
-
process(res: any, params: any) {
|
|
77
|
-
return res && Object.keys(res).length ? res : params;
|
|
78
|
-
},
|
|
79
|
-
getOptimisticResponse: optimistic ? (optimisticDelete as any) : undefined,
|
|
80
|
-
}),
|
|
81
|
-
} as any;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function optimisticUpdate(snap: SnapshotInterface, params: any, body: any) {
|
|
85
|
-
return {
|
|
86
|
-
...params,
|
|
87
|
-
...body,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
function optimisticPartial(getEndpoint: GetEndpoint) {
|
|
91
|
-
return function (snap: SnapshotInterface, params: any, body: any) {
|
|
92
|
-
const { data } = snap.getResponse(getEndpoint, params) as { data: any };
|
|
93
|
-
if (!data) throw new AbortOptimistic();
|
|
94
|
-
return {
|
|
95
|
-
...params,
|
|
96
|
-
...data,
|
|
97
|
-
// even tho we don't always have two arguments, the extra one will simply be undefined which spreads fine
|
|
98
|
-
...body,
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
function optimisticDelete(snap: SnapshotInterface, params: any) {
|
|
103
|
-
return params;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export interface Resource<
|
|
107
|
-
O extends ResourceGenerics = { path: string; schema: any },
|
|
108
|
-
> {
|
|
109
|
-
/** Get a singular item
|
|
110
|
-
*
|
|
111
|
-
* @see https://resthooks.io/rest/api/createResource#get
|
|
112
|
-
*/
|
|
113
|
-
get: GetEndpoint<{ path: O['path']; schema: O['schema'] }>;
|
|
114
|
-
/** Get a list of item
|
|
115
|
-
*
|
|
116
|
-
* @see https://resthooks.io/rest/api/createResource#getlist
|
|
117
|
-
*/
|
|
118
|
-
getList: 'searchParams' extends keyof O
|
|
119
|
-
? GetEndpoint<{
|
|
120
|
-
path: ShortenPath<O['path']>;
|
|
121
|
-
schema: schema.Collection<[O['schema']]>;
|
|
122
|
-
searchParams: O['searchParams'];
|
|
123
|
-
}>
|
|
124
|
-
: GetEndpoint<{
|
|
125
|
-
path: ShortenPath<O['path']>;
|
|
126
|
-
schema: schema.Collection<[O['schema']]>;
|
|
127
|
-
searchParams: Record<string, number | string | boolean> | undefined;
|
|
128
|
-
}>;
|
|
129
|
-
/** Create a new item (POST)
|
|
130
|
-
*
|
|
131
|
-
* @see https://resthooks.io/rest/api/createResource#create
|
|
132
|
-
*/
|
|
133
|
-
create: 'searchParams' extends keyof O
|
|
134
|
-
? MutateEndpoint<{
|
|
135
|
-
path: ShortenPath<O['path']>;
|
|
136
|
-
schema: schema.Collection<[O['schema']]>['push'];
|
|
137
|
-
body: 'body' extends keyof O
|
|
138
|
-
? O['body']
|
|
139
|
-
: Partial<Denormalize<O['schema']>>;
|
|
140
|
-
searchParams: O['searchParams'];
|
|
141
|
-
}>
|
|
142
|
-
: MutateEndpoint<{
|
|
143
|
-
path: ShortenPath<O['path']>;
|
|
144
|
-
schema: schema.Collection<[O['schema']]>['push'];
|
|
145
|
-
body: 'body' extends keyof O
|
|
146
|
-
? O['body']
|
|
147
|
-
: Partial<Denormalize<O['schema']>>;
|
|
148
|
-
}>;
|
|
149
|
-
/** Update an item (PUT)
|
|
150
|
-
*
|
|
151
|
-
* @see https://resthooks.io/rest/api/createResource#update
|
|
152
|
-
*/
|
|
153
|
-
update: 'body' extends keyof O
|
|
154
|
-
? MutateEndpoint<{
|
|
155
|
-
path: O['path'];
|
|
156
|
-
body: O['body'];
|
|
157
|
-
schema: O['schema'];
|
|
158
|
-
}>
|
|
159
|
-
: MutateEndpoint<{
|
|
160
|
-
path: O['path'];
|
|
161
|
-
body: Partial<Denormalize<O['schema']>>;
|
|
162
|
-
schema: O['schema'];
|
|
163
|
-
}>;
|
|
164
|
-
/** Update an item (PATCH)
|
|
165
|
-
*
|
|
166
|
-
* @see https://resthooks.io/rest/api/createResource#partialupdate
|
|
167
|
-
*/
|
|
168
|
-
partialUpdate: 'body' extends keyof O
|
|
169
|
-
? MutateEndpoint<{
|
|
170
|
-
path: O['path'];
|
|
171
|
-
body: Partial<O['body']>;
|
|
172
|
-
schema: O['schema'];
|
|
173
|
-
}>
|
|
174
|
-
: MutateEndpoint<{
|
|
175
|
-
path: O['path'];
|
|
176
|
-
body: Partial<Denormalize<O['schema']>>;
|
|
177
|
-
schema: O['schema'];
|
|
178
|
-
}>;
|
|
179
|
-
/** Delete an item (DELETE)
|
|
180
|
-
*
|
|
181
|
-
* @see https://resthooks.io/rest/api/createResource#delete
|
|
182
|
-
*/
|
|
183
|
-
delete: RestTypeNoBody<
|
|
184
|
-
PathArgs<O['path']>,
|
|
185
|
-
O['schema'] extends schema.EntityInterface & { process: any }
|
|
186
|
-
? schema.Invalidate<O['schema']>
|
|
187
|
-
: O['schema'],
|
|
188
|
-
undefined,
|
|
189
|
-
Partial<PathArgs<O['path']>>,
|
|
190
|
-
{
|
|
191
|
-
path: O['path'];
|
|
192
|
-
}
|
|
193
|
-
>;
|
|
194
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { FetchFunction, ResolveType } from '@data-client/endpoint';
|
|
2
|
-
|
|
3
|
-
import { PartialRestGenerics, RestInstance } from './RestEndpoint.js';
|
|
4
|
-
|
|
5
|
-
export type OptionsToFunction<
|
|
6
|
-
O extends PartialRestGenerics,
|
|
7
|
-
E extends RestInstance & {
|
|
8
|
-
body?: any;
|
|
9
|
-
},
|
|
10
|
-
F extends FetchFunction,
|
|
11
|
-
> = (
|
|
12
|
-
this: ThisParameterType<F>,
|
|
13
|
-
...args: any
|
|
14
|
-
) => Promise<
|
|
15
|
-
O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>
|
|
16
|
-
>;
|