@data-client/rest 0.4.1 → 0.6.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 (53) hide show
  1. package/dist/index.js +44 -5
  2. package/dist/index.umd.min.js +1 -1
  3. package/dist/next.js +44 -5
  4. package/legacy/createResource.js +39 -8
  5. package/legacy/index.js +1 -1
  6. package/legacy/next/index.js +1 -1
  7. package/legacy/resourceExtendable.js +2 -0
  8. package/legacy/resourceExtensionTypes.js +2 -0
  9. package/legacy/resourceTypes.js +1 -1
  10. package/lib/RestEndpoint.d.ts +1 -1
  11. package/lib/createResource.d.ts +2 -96
  12. package/lib/createResource.d.ts.map +1 -1
  13. package/lib/createResource.js +45 -6
  14. package/lib/index.d.ts +1 -1
  15. package/lib/index.d.ts.map +1 -1
  16. package/lib/index.js +1 -1
  17. package/lib/next/index.d.ts +1 -1
  18. package/lib/next/index.d.ts.map +1 -1
  19. package/lib/next/index.js +1 -1
  20. package/lib/resourceExtendable.d.ts +25 -0
  21. package/lib/resourceExtendable.d.ts.map +1 -0
  22. package/lib/resourceExtendable.js +2 -0
  23. package/lib/resourceExtensionTypes.d.ts +33 -0
  24. package/lib/resourceExtensionTypes.d.ts.map +1 -0
  25. package/lib/resourceExtensionTypes.js +2 -0
  26. package/lib/resourceTypes.d.ts +94 -4
  27. package/lib/resourceTypes.d.ts.map +1 -1
  28. package/lib/resourceTypes.js +1 -1
  29. package/package.json +1 -1
  30. package/src/RestEndpoint.d.ts +1 -1
  31. package/src/__tests__/createResource.test.ts +490 -19
  32. package/src/createResource.ts +60 -127
  33. package/src/index.ts +1 -1
  34. package/src/next/index.ts +1 -1
  35. package/src/resourceExtendable.ts +95 -0
  36. package/src/resourceExtensionTypes.ts +109 -0
  37. package/src/resourceTypes.ts +119 -4
  38. package/ts4.0/RestEndpoint.d.ts +1 -1
  39. package/ts4.0/createResource.d.ts +2 -108
  40. package/ts4.0/index.d.ts +1 -1
  41. package/ts4.0/next/index.d.ts +1 -1
  42. package/ts4.0/resourceExtendable.d.ts +21 -0
  43. package/ts4.0/resourceExtensionTypes.d.ts +33 -0
  44. package/ts4.0/resourceTypes.d.ts +102 -4
  45. package/ts4.1/RestEndpoint.d.ts +1 -1
  46. package/ts4.1/createResource.d.ts +2 -108
  47. package/ts4.1/index.d.ts +1 -1
  48. package/ts4.1/next/index.d.ts +1 -1
  49. package/ts4.1/resourceExtendable.d.ts +21 -0
  50. package/ts4.1/resourceExtensionTypes.d.ts +33 -0
  51. package/ts4.1/resourceTypes.d.ts +102 -4
  52. package/ts4.0/deleteme.d.ts +0 -0
  53. package/ts4.1/deleteme.d.ts +0 -0
@@ -79,6 +79,425 @@ describe('createResource()', () => {
79
79
  nock.cleanAll();
80
80
  });
81
81
 
82
+ it('can override endpoint options', async () => {
83
+ const UserResourceBase = createResource({
84
+ path: 'http\\://test.com/groups/:group/users/:id',
85
+ schema: User,
86
+ });
87
+ const UserResource = UserResourceBase.extend('getList', {
88
+ path: ':blob',
89
+ searchParams: {} as { isAdmin?: boolean },
90
+ getOptimisticResponse(snap, params) {
91
+ params.isAdmin;
92
+ params.blob;
93
+ // @ts-expect-error
94
+ params.nothere;
95
+ return [] as User[];
96
+ },
97
+ /*process(users: User[]) {
98
+ return users.slice(0, 7);
99
+ }, TODO: why doesn't this work?*/
100
+ })
101
+ .extend('partialUpdate', {
102
+ getOptimisticResponse(snap, params, body) {
103
+ params.id;
104
+ params.group;
105
+ // @ts-expect-error
106
+ params.nothere;
107
+ return {
108
+ id: params.id,
109
+ ...body,
110
+ };
111
+ },
112
+ })
113
+ .extend('delete', {
114
+ getOptimisticResponse(snap, params) {
115
+ return params;
116
+ },
117
+ })
118
+ .extend('justget', {})
119
+ .extend('current', {
120
+ path: '/current',
121
+ searchParams: {} as { isAdmin?: boolean },
122
+ })
123
+ .extend('toggleAdmin', {
124
+ path: '/toggle/:id',
125
+ method: 'POST',
126
+ body: undefined,
127
+ });
128
+
129
+ () => UserResource.getList({ blob: '5', isAdmin: true });
130
+ () =>
131
+ UserResource.getList.paginated('cursor')({
132
+ blob: '5',
133
+ isAdmin: true,
134
+ cursor: 'next',
135
+ });
136
+ () =>
137
+ UserResource.getList.paginated('cursor')({ blob: '5', cursor: 'next' });
138
+ () =>
139
+ // @ts-expect-error
140
+ UserResource.getList.paginated('cursor')({ blob: '5', isAdmin: true });
141
+ () =>
142
+ // @ts-expect-error
143
+ UserResource.getList.paginated('cursor')({
144
+ cursor: 'next',
145
+ isAdmin: true,
146
+ });
147
+ () => UserResource.get({ group: '1', id: '5' });
148
+ () => UserResource.getList.push({ blob: '5' }, { username: 'bob' });
149
+ () =>
150
+ UserResource.getList.push(
151
+ { blob: '5', isAdmin: true },
152
+ { username: 'bob' },
153
+ );
154
+ () =>
155
+ UserResource.getList.push(
156
+ { blob: '5', isAdmin: false },
157
+ { username: 'bob' },
158
+ );
159
+ // @ts-expect-error
160
+ () => UserResource.getList.push({ group: 'bob' }, { username: 'bob' });
161
+ () => UserResource.get({ id: 'hi', group: 'group' });
162
+ () => UserResource.justget({ group: 'blob', id: '5' });
163
+ // @ts-expect-error
164
+ () => UserResource.justget({ id: '5' });
165
+ () => UserResource.current();
166
+ () => UserResource.current({ isAdmin: true });
167
+ () => UserResource.toggleAdmin({ id: '5' });
168
+ () => {
169
+ // @ts-expect-error - POST should make this have sideEffect true
170
+ const DONOTUSE: false = UserResource.toggleAdmin.sideEffect;
171
+ };
172
+ // @ts-expect-error
173
+ () => UserResource.justget({ id: '5' });
174
+
175
+ mynock.get(`/current`).reply(200, {
176
+ id: 5,
177
+ username: 'bob',
178
+ email: 'bob@bob.com',
179
+ isAdmin: false,
180
+ });
181
+
182
+ const { result, waitForNextUpdate, controller } = renderRestHook(() => {
183
+ return useSuspense(UserResource.current);
184
+ });
185
+ await waitForNextUpdate();
186
+ expect(result.current.email).toBe('bob@bob.com');
187
+ // @ts-expect-error
188
+ expect(result.current.notexist).toBeUndefined();
189
+
190
+ mynock.post(`/5`).reply(200, (uri, body) => ({
191
+ id: 10,
192
+ username: 'bob',
193
+ email: 'bob@bob.com',
194
+ ...(body as any),
195
+ }));
196
+
197
+ const user = await controller.fetch(
198
+ UserResource.getList.push,
199
+ { blob: '5' },
200
+ { username: 'newbob' },
201
+ );
202
+ expect(user.username).toBe('newbob');
203
+ expect(user).toBeInstanceOf(User);
204
+ expect(user.isAdmin).toBe(false);
205
+ });
206
+
207
+ it('can override endpoint options', async () => {
208
+ const UserResourceBase = createResource({
209
+ path: 'http\\://test.com/groups/:group/users/:id',
210
+ schema: User,
211
+ });
212
+ const UserResource = UserResourceBase.extend({
213
+ getList: {
214
+ path: ':blob',
215
+ searchParams: {} as { isAdmin?: boolean },
216
+ getOptimisticResponse(snap, params) {
217
+ params.isAdmin;
218
+ params.blob;
219
+ // @ts-expect-error
220
+ params.nothere;
221
+ return [] as User[];
222
+ },
223
+ /*process(users: User[]) {
224
+ return users.slice(0, 7);
225
+ }, TODO: why doesn't this work?*/
226
+ },
227
+ partialUpdate: {
228
+ getOptimisticResponse(snap, params, body) {
229
+ params.id;
230
+ params.group;
231
+ // @ts-expect-error
232
+ params.nothere;
233
+ return {
234
+ id: params.id,
235
+ ...body,
236
+ };
237
+ },
238
+ },
239
+ delete: {
240
+ getOptimisticResponse(snap, params) {
241
+ return params;
242
+ },
243
+ },
244
+ })
245
+ .extend('justget', {})
246
+ .extend('current', {
247
+ path: '/current',
248
+ searchParams: {} as { isAdmin?: boolean },
249
+ })
250
+ .extend('toggleAdmin', {
251
+ path: '/toggle/:id',
252
+ method: 'POST',
253
+ body: undefined,
254
+ getOptimisticResponse(snap, params) {
255
+ params.id;
256
+ // @ts-expect-error
257
+ params.group;
258
+ return {
259
+ id: params.id,
260
+ };
261
+ },
262
+ });
263
+
264
+ () => UserResource.getList({ blob: '5', isAdmin: true });
265
+ () =>
266
+ UserResource.getList.paginated('cursor')({
267
+ blob: '5',
268
+ isAdmin: true,
269
+ cursor: 'next',
270
+ });
271
+ () =>
272
+ UserResource.getList.paginated('cursor')({ blob: '5', cursor: 'next' });
273
+ // @ts-expect-error
274
+ () => UserResource.getNextPage({ blob: '5', isAdmin: true });
275
+ // @ts-expect-error
276
+ () => UserResource.getNextPage({ cursor: 'next', isAdmin: true });
277
+ () => UserResource.get({ group: '1', id: '5' });
278
+ () => UserResource.getList.push({ blob: '5' }, { username: 'bob' });
279
+ () =>
280
+ UserResource.getList.push(
281
+ { blob: '5', isAdmin: true },
282
+ { username: 'bob' },
283
+ );
284
+ () =>
285
+ UserResource.getList.push(
286
+ { blob: '5', isAdmin: false },
287
+ { username: 'bob' },
288
+ );
289
+ // @ts-expect-error
290
+ () => UserResource.getList.push({ group: 'bob' }, { username: 'bob' });
291
+ () => UserResource.get({ id: 'hi', group: 'group' });
292
+ () => UserResource.justget({ group: 'blob', id: '5' });
293
+ // @ts-expect-error
294
+ () => UserResource.justget({ id: '5' });
295
+ () => UserResource.current();
296
+ () => UserResource.current({ isAdmin: true });
297
+ () => UserResource.toggleAdmin({ id: '5' });
298
+ () => {
299
+ // @ts-expect-error - POST should make this have sideEffect true
300
+ const DONOTUSE: false = UserResource.toggleAdmin.sideEffect;
301
+ };
302
+ // @ts-expect-error
303
+ () => UserResource.justget({ id: '5' });
304
+
305
+ mynock.get(`/current`).reply(200, {
306
+ id: 5,
307
+ username: 'bob',
308
+ email: 'bob@bob.com',
309
+ isAdmin: false,
310
+ });
311
+
312
+ mynock.get(`/5?isAdmin=false`).reply(200, [
313
+ {
314
+ id: 5,
315
+ username: 'bob',
316
+ email: 'bob@bob.com',
317
+ isAdmin: false,
318
+ },
319
+ ]);
320
+
321
+ const { result, waitForNextUpdate, controller } = renderRestHook(() => {
322
+ return [
323
+ useSuspense(UserResource.current),
324
+ useSuspense(UserResource.getList, { blob: '5', isAdmin: false }),
325
+ ] as const;
326
+ });
327
+ await waitForNextUpdate();
328
+ expect(result.current[1].length).toBe(1);
329
+
330
+ expect(result.current[0].email).toBe('bob@bob.com');
331
+ // @ts-expect-error
332
+ expect(result.current[0].notexist).toBeUndefined();
333
+
334
+ mynock.post(`/5?isAdmin=false`).reply(201, (uri, body) => ({
335
+ id: 10,
336
+ username: 'bob',
337
+ email: 'newbob@bob.com',
338
+ ...(body as any),
339
+ }));
340
+
341
+ await act(async () => {
342
+ const user = await controller.fetch(
343
+ UserResource.getList.push,
344
+ { blob: '5', isAdmin: false },
345
+ { username: 'newbob' },
346
+ );
347
+ expect(user.username).toBe('newbob');
348
+ expect(user).toBeInstanceOf(User);
349
+ expect(user.isAdmin).toBe(false);
350
+ });
351
+ expect(result.current[1].length).toBe(2);
352
+ expect(result.current[1][1].username).toBe('newbob');
353
+ });
354
+
355
+ it('can override resource endpoints (function form)', async () => {
356
+ const UserResource = createResource({
357
+ path: 'http\\://test.com/groups/:group/users/:id',
358
+ schema: User,
359
+ paginationField: 'cursor',
360
+ })
361
+ .extend(resourceBase => ({
362
+ getList: resourceBase.getList.extend({
363
+ path: ':blob',
364
+ searchParams: {} as { isAdmin?: boolean },
365
+ getOptimisticResponse(snap, params) {
366
+ params.isAdmin;
367
+ params.blob;
368
+ // @ts-expect-error
369
+ params.nothere;
370
+ return [] as User[];
371
+ },
372
+ /*process(users: User[]) {
373
+ return users.slice(0, 7);
374
+ }, TODO: why doesn't this work?*/
375
+ }),
376
+ partialUpdate: resourceBase.partialUpdate.extend({
377
+ getOptimisticResponse(snap, params, body) {
378
+ params.id;
379
+ params.group;
380
+ // @ts-expect-error
381
+ params.nothere;
382
+ return {
383
+ id: params.id,
384
+ ...body,
385
+ };
386
+ },
387
+ }),
388
+ delete: resourceBase.delete.extend({
389
+ getOptimisticResponse(snap, params) {
390
+ return params;
391
+ },
392
+ }),
393
+ justget: resourceBase.get,
394
+ current: resourceBase.get.extend({
395
+ path: '/current',
396
+ searchParams: {} as { isAdmin?: boolean },
397
+ }),
398
+ toggleAdmin: resourceBase.get.extend({
399
+ path: '/toggle/:id',
400
+ method: 'POST',
401
+ body: undefined,
402
+ getOptimisticResponse(snap, params) {
403
+ params.id;
404
+ // @ts-expect-error
405
+ params.group;
406
+ return {
407
+ id: params.id,
408
+ };
409
+ },
410
+ }),
411
+ }))
412
+ .extend(resourceBase => ({
413
+ getNextPage: resourceBase.getList.paginated('cursor'),
414
+ }));
415
+ () => UserResource.getList({ blob: '5', isAdmin: true });
416
+ () =>
417
+ UserResource.getNextPage({ blob: '5', isAdmin: true, cursor: 'next' });
418
+ () => UserResource.getNextPage({ blob: '5', cursor: 'next' });
419
+ // @ts-expect-error
420
+ () => UserResource.getNextPage({ blob: '5', isAdmin: true });
421
+ // @ts-expect-error
422
+ () => UserResource.getNextPage({ cursor: 'next', isAdmin: true });
423
+ () => UserResource.get({ group: '1', id: '5' });
424
+ () => UserResource.getList.unshift({ blob: '5' }, { username: 'bob' });
425
+ () =>
426
+ UserResource.getList.push(
427
+ { blob: '5', isAdmin: true },
428
+ { username: 'bob' },
429
+ );
430
+ () =>
431
+ UserResource.getList.push(
432
+ { blob: '5', isAdmin: false },
433
+ { username: 'bob' },
434
+ );
435
+ // @ts-expect-error
436
+ () => UserResource.getList.push({ group: 'bob' }, { username: 'bob' });
437
+ () => UserResource.get({ id: 'hi', group: 'group' });
438
+ () => UserResource.justget({ group: 'blob', id: '5' });
439
+ // @ts-expect-error
440
+ () => UserResource.justget({ id: '5' });
441
+ () => UserResource.current();
442
+ () => UserResource.current({ isAdmin: true });
443
+ () => UserResource.toggleAdmin({ id: '5' });
444
+ () => {
445
+ // @ts-expect-error - POST should make this have sideEffect true
446
+ const DONOTUSE: false = UserResource.toggleAdmin.sideEffect;
447
+ };
448
+ // @ts-expect-error
449
+ () => UserResource.justget({ id: '5' });
450
+
451
+ mynock.get(`/current`).reply(200, {
452
+ id: 5,
453
+ username: 'bob',
454
+ email: 'bob@bob.com',
455
+ isAdmin: false,
456
+ });
457
+
458
+ mynock.get(`/5?isAdmin=false`).reply(200, [
459
+ {
460
+ id: 5,
461
+ username: 'bob',
462
+ email: 'bob@bob.com',
463
+ isAdmin: false,
464
+ },
465
+ ]);
466
+
467
+ const { result, waitForNextUpdate, controller } = renderRestHook(() => {
468
+ return [
469
+ useSuspense(UserResource.current),
470
+ useSuspense(UserResource.getList, { blob: '5', isAdmin: false }),
471
+ ] as const;
472
+ });
473
+ await waitForNextUpdate();
474
+ expect(result.current[1].length).toBe(1);
475
+
476
+ expect(result.current[0].email).toBe('bob@bob.com');
477
+ // @ts-expect-error
478
+ expect(result.current[0].notexist).toBeUndefined();
479
+
480
+ mynock.post(`/5?isAdmin=false`).reply(201, (uri, body) => ({
481
+ id: 10,
482
+ username: 'bob',
483
+ email: 'newbob@bob.com',
484
+ ...(body as any),
485
+ }));
486
+
487
+ await act(async () => {
488
+ const user = await controller.fetch(
489
+ UserResource.getList.push,
490
+ { blob: '5', isAdmin: false },
491
+ { username: 'newbob' },
492
+ );
493
+ expect(user.username).toBe('newbob');
494
+ expect(user).toBeInstanceOf(User);
495
+ expect(user.isAdmin).toBe(false);
496
+ });
497
+ expect(result.current[1].length).toBe(2);
498
+ expect(result.current[1][1].username).toBe('newbob');
499
+ });
500
+
82
501
  it('should not allow paths without at least one argument', () => {
83
502
  class Todo extends Entity {
84
503
  id = '';
@@ -203,7 +622,7 @@ describe('createResource()', () => {
203
622
  );
204
623
  });
205
624
 
206
- it('UserResource.create should work', async () => {
625
+ it('UserResource.getList.push should work', async () => {
207
626
  mynock.post(`/groups/five/users`).reply(200, (uri, body: any) => ({
208
627
  id: 5,
209
628
  ...body,
@@ -219,7 +638,7 @@ describe('createResource()', () => {
219
638
  let [_, controller] = result.current;
220
639
  await act(async () => {
221
640
  await controller.fetch(
222
- UserResource.create,
641
+ UserResource.getList.push,
223
642
  { group: 'five' },
224
643
  {
225
644
  username: 'createduser',
@@ -235,25 +654,25 @@ describe('createResource()', () => {
235
654
 
236
655
  () =>
237
656
  controller.fetch(
238
- UserResource.create,
657
+ UserResource.getList.push,
239
658
  // @ts-expect-error
240
659
  { id: 'five' },
241
660
  { username: 'never' },
242
661
  );
243
662
  // @ts-expect-error
244
- () => controller.fetch(UserResource.create, { username: 'never' });
663
+ () => controller.fetch(UserResource.getList.push, { username: 'never' });
245
664
  // @ts-expect-error
246
- () => controller.fetch(UserResource.create, 1, 'hi');
665
+ () => controller.fetch(UserResource.getList.push, 1, 'hi');
247
666
  () =>
248
667
  controller.fetch(
249
- UserResource.create,
668
+ UserResource.getList.push,
250
669
  { group: 'five' },
251
670
  // @ts-expect-error
252
671
  { sdf: 'never' },
253
672
  );
254
673
  () =>
255
674
  controller.fetch(
256
- UserResource.create,
675
+ UserResource.getList.push,
257
676
  // @ts-expect-error
258
677
  { sdf: 'five' },
259
678
  { username: 'never' },
@@ -458,7 +877,7 @@ describe('createResource()', () => {
458
877
  () => FeedResource.getList({ id: '5' }, 5);
459
878
  });
460
879
 
461
- it('should work with create [no args]', async () => {
880
+ it('should work with getList.push [no args]', async () => {
462
881
  mynock.post(`/feed`).reply(200, (uri, body: any) => ({
463
882
  id: 5,
464
883
  ...body,
@@ -473,7 +892,7 @@ describe('createResource()', () => {
473
892
  // eslint-disable-next-line prefer-const
474
893
  let [_, controller] = result.current;
475
894
  await act(() => {
476
- controller.fetch(FeedResource.create, feedPayload);
895
+ controller.fetch(FeedResource.getList.push, feedPayload);
477
896
  });
478
897
  await waitForNextUpdate();
479
898
  const feed = result.current[0];
@@ -493,19 +912,19 @@ describe('createResource()', () => {
493
912
  { username: 'never' },
494
913
  );
495
914
  // @ts-expect-error
496
- () => controller.fetch(UserResource.create, { username: 'never' });
915
+ () => controller.fetch(UserResource.getList.push, { username: 'never' });
497
916
  // @ts-expect-error
498
- () => controller.fetch(UserResource.create, 1, 'hi');
917
+ () => controller.fetch(UserResource.getList.push, 1, 'hi');
499
918
  () =>
500
919
  controller.fetch(
501
- UserResource.create,
920
+ UserResource.getList.push,
502
921
  { group: 'five' },
503
922
  // @ts-expect-error
504
923
  { sdf: 'never' },
505
924
  );
506
925
  () =>
507
926
  controller.fetch(
508
- UserResource.create,
927
+ UserResource.getList.push,
509
928
  // @ts-expect-error
510
929
  { sdf: 'five' },
511
930
  { username: 'never' },
@@ -513,7 +932,7 @@ describe('createResource()', () => {
513
932
  });
514
933
  });
515
934
 
516
- it('UserResource.create.extends() should work', async () => {
935
+ it('UserResource.getList.push.extends() should work', async () => {
517
936
  interface CreateDeviceBody {
518
937
  username: string;
519
938
  }
@@ -524,7 +943,7 @@ describe('createResource()', () => {
524
943
  readonly isAdmin: boolean;
525
944
  }
526
945
 
527
- const createUser = UserResource.create.extend({
946
+ const createUser = UserResource.getList.push.extend({
528
947
  update: (newId, params) => {
529
948
  return {
530
949
  [UserResource.getList.key({ group: params.group })]: (
@@ -539,7 +958,10 @@ describe('createResource()', () => {
539
958
  schema: User,
540
959
  sideEffect: true,
541
960
  process(...args: any) {
542
- return UserResource.create.process.apply(this, args) as UserInterface;
961
+ return UserResource.getList.push.process.apply(
962
+ this,
963
+ args,
964
+ ) as UserInterface;
543
965
  },
544
966
  });
545
967
  const ctrl = new Controller();
@@ -556,7 +978,7 @@ describe('createResource()', () => {
556
978
  );
557
979
  });
558
980
 
559
- it('UserResource.create.extends() should work with zero urlParams', async () => {
981
+ it('UserResource.getList.push.extends() should work with zero urlParams', async () => {
560
982
  const UserResource = createResource({
561
983
  path: 'http\\://test.com/users/:id',
562
984
  schema: User,
@@ -572,7 +994,7 @@ describe('createResource()', () => {
572
994
  readonly isAdmin: boolean;
573
995
  }
574
996
 
575
- const createUser = UserResource.create.extend({
997
+ const createUser = UserResource.getList.push.extend({
576
998
  update: newId => {
577
999
  return {
578
1000
  [UserResource.getList.key()]: (prevResponse = { items: [] }) => ({
@@ -585,7 +1007,10 @@ describe('createResource()', () => {
585
1007
  schema: User,
586
1008
  sideEffect: true,
587
1009
  process(...args: any) {
588
- return UserResource.create.process.apply(this, args) as UserInterface;
1010
+ return UserResource.getList.push.process.apply(
1011
+ this,
1012
+ args,
1013
+ ) as UserInterface;
589
1014
  },
590
1015
  });
591
1016
  const ctrl = new Controller();
@@ -601,4 +1026,50 @@ describe('createResource()', () => {
601
1026
  `"http://test.com/users"`,
602
1027
  );
603
1028
  });
1029
+
1030
+ it('getList.push should use custom lifecycle methods of getList', async () => {
1031
+ mynock.post(`/users`).reply(201, (uri, body: any) => ({
1032
+ ...body,
1033
+ id: 5,
1034
+ }));
1035
+ const UserResource = createResource({
1036
+ path: '/users/:id',
1037
+ schema: User,
1038
+ optimistic: true,
1039
+ }).extend(Base => ({
1040
+ getList: Base.getList.extend({
1041
+ getRequestInit(body) {
1042
+ if (body) {
1043
+ return Base.getList.getRequestInit.call(this, {
1044
+ id: Math.random(),
1045
+ isAdmin: true,
1046
+ ...body,
1047
+ });
1048
+ }
1049
+ return Base.getList.getRequestInit.call(this, body);
1050
+ },
1051
+ }),
1052
+ }));
1053
+
1054
+ const { controller, result } = renderRestHook(
1055
+ () => {
1056
+ return useSuspense(UserResource.getList);
1057
+ },
1058
+ {
1059
+ initialFixtures: [
1060
+ {
1061
+ endpoint: UserResource.getList,
1062
+ args: [],
1063
+ response: [],
1064
+ },
1065
+ ],
1066
+ },
1067
+ );
1068
+ await act(async () => {
1069
+ await controller.fetch(UserResource.getList.push, { username: 'bob' });
1070
+ });
1071
+ expect(result.current.length).toBe(1);
1072
+ // this is set in our override
1073
+ expect(result.current[0].isAdmin).toBe(true);
1074
+ });
604
1075
  });