@data-client/rest 0.15.6 → 0.15.7
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 +47 -0
- package/dist/index.js +27 -0
- package/dist/index.umd.min.js +1 -1
- package/legacy/NetworkError.js +16 -1
- package/legacy/RestEndpoint.js +11 -1
- package/legacy/RestEndpointTypes.js +1 -1
- package/legacy/resource.js +3 -1
- package/legacy/resourceTypes.js +1 -1
- package/lib/NetworkError.d.ts +12 -0
- package/lib/NetworkError.d.ts.map +1 -1
- package/lib/NetworkError.js +16 -1
- package/lib/RestEndpoint.js +11 -1
- package/lib/RestEndpointTypes.d.ts +16 -0
- package/lib/RestEndpointTypes.d.ts.map +1 -1
- package/lib/RestEndpointTypes.js +1 -1
- package/lib/resource.d.ts.map +1 -1
- package/lib/resource.js +3 -1
- package/lib/resourceTypes.d.ts +2 -0
- package/lib/resourceTypes.d.ts.map +1 -1
- package/lib/resourceTypes.js +1 -1
- package/package.json +3 -3
- package/src/NetworkError.ts +15 -0
- package/src/RestEndpoint.js +11 -0
- package/src/RestEndpointTypes.ts +24 -0
- package/src/__tests__/Resource.test.ts +75 -0
- package/src/__tests__/RestEndpoint.ts +152 -2
- package/src/__tests__/__snapshots__/RestEndpoint.ts.snap +2 -0
- package/src/__tests__/resource-construction.test.ts +536 -0
- package/src/resource.ts +2 -0
- package/src/resourceTypes.ts +2 -0
- package/ts4.0/NetworkError.d.ts +12 -0
- package/ts4.0/RestEndpointTypes.d.ts +16 -0
- package/ts4.0/resourceTypes.d.ts +2 -0
- package/ts4.1/NetworkError.d.ts +12 -0
- package/ts4.1/RestEndpointTypes.d.ts +16 -0
- package/ts4.1/resourceTypes.d.ts +2 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Entity, schema, Collection } from '@data-client/endpoint';
|
|
2
|
-
import { useController } from '@data-client/react';
|
|
2
|
+
import { useController, useCache } from '@data-client/react';
|
|
3
3
|
import { useSuspense } from '@data-client/react';
|
|
4
4
|
import { CacheProvider } from '@data-client/react';
|
|
5
5
|
import { CoolerArticle, CoolerArticleResource } from '__tests__/new';
|
|
6
6
|
import nock from 'nock';
|
|
7
7
|
|
|
8
|
-
import { makeRenderDataClient } from '../../../test';
|
|
8
|
+
import { makeRenderDataClient, act } from '../../../test';
|
|
9
9
|
import RestEndpoint, {
|
|
10
10
|
Defaults,
|
|
11
11
|
RestEndpointConstructorOptions,
|
|
@@ -132,6 +132,35 @@ const getNextPage3 = getArticleList3.getPage;
|
|
|
132
132
|
a.getPage({ cursor: 'hi', blob: 'ho' });
|
|
133
133
|
// @ts-expect-error
|
|
134
134
|
a.getPage({ blob: 'ho' });
|
|
135
|
+
|
|
136
|
+
// Compare flat vs nested Collection schema type inference
|
|
137
|
+
const flat = new RestEndpoint({
|
|
138
|
+
urlPrefix: 'http://test.com',
|
|
139
|
+
path: '/articles/:id',
|
|
140
|
+
schema: new Collection([PaginatedArticle]),
|
|
141
|
+
method: 'GET',
|
|
142
|
+
});
|
|
143
|
+
// flat Collection schema should be typed
|
|
144
|
+
// @ts-expect-error - schema should not be any
|
|
145
|
+
flat.move.schema satisfies number;
|
|
146
|
+
// @ts-expect-error - push schema should not be any
|
|
147
|
+
flat.push.schema satisfies number;
|
|
148
|
+
|
|
149
|
+
// nested Collection schema should also be typed
|
|
150
|
+
const nested = new RestEndpoint({
|
|
151
|
+
urlPrefix: 'http://test.com',
|
|
152
|
+
path: '/articles/:id',
|
|
153
|
+
schema: {
|
|
154
|
+
nextPage: '',
|
|
155
|
+
data: { results: new Collection([PaginatedArticle]) },
|
|
156
|
+
},
|
|
157
|
+
method: 'GET',
|
|
158
|
+
searchParams: {} as { group: string },
|
|
159
|
+
});
|
|
160
|
+
// @ts-expect-error - nested move schema should not be any
|
|
161
|
+
nested.move.schema satisfies number;
|
|
162
|
+
// @ts-expect-error - nested push schema should not be any
|
|
163
|
+
nested.push.schema satisfies number;
|
|
135
164
|
};
|
|
136
165
|
|
|
137
166
|
describe('RestEndpoint', () => {
|
|
@@ -364,6 +393,113 @@ describe('RestEndpoint', () => {
|
|
|
364
393
|
expect(getArticleList3.remove.name).toMatchSnapshot();
|
|
365
394
|
});
|
|
366
395
|
|
|
396
|
+
it('move: should extend name of parent endpoint', () => {
|
|
397
|
+
expect(getArticleList3.move.name).toMatchSnapshot();
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it('move should work with deeply nested Collection', async () => {
|
|
401
|
+
class GroupedArticle extends Entity {
|
|
402
|
+
readonly id: number | undefined = undefined;
|
|
403
|
+
readonly title: string = '';
|
|
404
|
+
readonly group: string = '';
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const getGroupedArticles = new RestEndpoint({
|
|
408
|
+
urlPrefix: 'http://test.com',
|
|
409
|
+
path: '/grouped-articles',
|
|
410
|
+
movePath: '/grouped-articles/:id',
|
|
411
|
+
schema: {
|
|
412
|
+
nextPage: '',
|
|
413
|
+
data: { results: new Collection([GroupedArticle]) },
|
|
414
|
+
},
|
|
415
|
+
method: 'GET',
|
|
416
|
+
searchParams: {} as { group: string },
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
// Verify schema is correctly extracted from nested structure
|
|
420
|
+
expect(getGroupedArticles.move.schema).toBeTruthy();
|
|
421
|
+
expect(getGroupedArticles.move.method).toBe('PATCH');
|
|
422
|
+
|
|
423
|
+
// Diagnose schema type - should not be any
|
|
424
|
+
// @ts-expect-error - schema should not be any
|
|
425
|
+
getGroupedArticles.move.schema satisfies number;
|
|
426
|
+
|
|
427
|
+
mynock.patch(/grouped-articles/).reply(200, (uri, body: any) => ({
|
|
428
|
+
id: 2,
|
|
429
|
+
title: 'Article 2',
|
|
430
|
+
group: 'beta',
|
|
431
|
+
...(typeof body === 'string' ? JSON.parse(body) : body),
|
|
432
|
+
}));
|
|
433
|
+
|
|
434
|
+
const { result, controller } = renderDataClient(
|
|
435
|
+
() => {
|
|
436
|
+
return {
|
|
437
|
+
alpha: useCache(getGroupedArticles, { group: 'alpha' }),
|
|
438
|
+
beta: useCache(getGroupedArticles, { group: 'beta' }),
|
|
439
|
+
};
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
initialFixtures: [
|
|
443
|
+
{
|
|
444
|
+
endpoint: getGroupedArticles,
|
|
445
|
+
args: [{ group: 'alpha' }],
|
|
446
|
+
response: {
|
|
447
|
+
nextPage: '2',
|
|
448
|
+
data: {
|
|
449
|
+
results: [
|
|
450
|
+
{ id: 1, title: 'Article 1', group: 'alpha' },
|
|
451
|
+
{ id: 2, title: 'Article 2', group: 'alpha' },
|
|
452
|
+
],
|
|
453
|
+
},
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
endpoint: getGroupedArticles,
|
|
458
|
+
args: [{ group: 'beta' }],
|
|
459
|
+
response: {
|
|
460
|
+
nextPage: '2',
|
|
461
|
+
data: {
|
|
462
|
+
results: [{ id: 3, title: 'Article 3', group: 'beta' }],
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
],
|
|
467
|
+
},
|
|
468
|
+
);
|
|
469
|
+
|
|
470
|
+
expect(result.current.alpha?.data.results).toHaveLength(2);
|
|
471
|
+
expect(result.current.beta?.data.results).toHaveLength(1);
|
|
472
|
+
|
|
473
|
+
// Move article 2 from alpha to beta
|
|
474
|
+
await act(async () => {
|
|
475
|
+
const response = await controller.fetch(
|
|
476
|
+
getGroupedArticles.move,
|
|
477
|
+
{ id: 2 },
|
|
478
|
+
{
|
|
479
|
+
id: 2,
|
|
480
|
+
title: 'Article 2',
|
|
481
|
+
group: 'beta',
|
|
482
|
+
},
|
|
483
|
+
);
|
|
484
|
+
// Type test: response should be a single GroupedArticle, not an array
|
|
485
|
+
response.title satisfies string;
|
|
486
|
+
expect(response.title).toBe('Article 2');
|
|
487
|
+
expect(response.group).toBe('beta');
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
// article should be removed from alpha
|
|
491
|
+
expect(result.current.alpha?.data.results).toHaveLength(1);
|
|
492
|
+
const alphaResults = result.current.alpha!.data.results!;
|
|
493
|
+
expect(alphaResults[0]?.title).toBe('Article 1');
|
|
494
|
+
|
|
495
|
+
// article should be added to beta
|
|
496
|
+
const betaResults = result.current.beta!.data.results!;
|
|
497
|
+
expect(betaResults).toHaveLength(2);
|
|
498
|
+
expect(betaResults.map((a: any) => a.title)).toEqual(
|
|
499
|
+
expect.arrayContaining(['Article 3', 'Article 2']),
|
|
500
|
+
);
|
|
501
|
+
});
|
|
502
|
+
|
|
367
503
|
// TODO: but we need a Values collection
|
|
368
504
|
// it('assign: should extend name of parent endpoint', () => {
|
|
369
505
|
// expect(getArticleList3.assign.name).toMatchSnapshot();
|
|
@@ -1500,6 +1636,20 @@ describe('RestEndpoint.fetch()', () => {
|
|
|
1500
1636
|
expect(noColletionEndpoint.remove.schema).toBeFalsy();
|
|
1501
1637
|
});
|
|
1502
1638
|
|
|
1639
|
+
it('without Collection in schema - endpoint.move schema should be null', () => {
|
|
1640
|
+
const noColletionEndpoint = new RestEndpoint({
|
|
1641
|
+
urlPrefix: 'http://test.com/article-paginated/',
|
|
1642
|
+
path: ':group',
|
|
1643
|
+
name: 'get',
|
|
1644
|
+
schema: {
|
|
1645
|
+
nextPage: '',
|
|
1646
|
+
data: { results: [PaginatedArticle] },
|
|
1647
|
+
},
|
|
1648
|
+
method: 'GET',
|
|
1649
|
+
});
|
|
1650
|
+
expect(noColletionEndpoint.move.schema).toBeFalsy();
|
|
1651
|
+
});
|
|
1652
|
+
|
|
1503
1653
|
it('without Collection in schema - endpoint.getPage should throw', () => {
|
|
1504
1654
|
const noColletionEndpoint = new RestEndpoint({
|
|
1505
1655
|
urlPrefix: 'http://test.com/article-paginated/',
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`RestEndpoint getPage: should extend name of parent endpoint 1`] = `"http://test.com/article-paginated.getPage"`;
|
|
4
4
|
|
|
5
|
+
exports[`RestEndpoint move: should extend name of parent endpoint 1`] = `"http://test.com/article-paginated.partialUpdate"`;
|
|
6
|
+
|
|
5
7
|
exports[`RestEndpoint push: should extend name of parent endpoint 1`] = `"http://test.com/article-paginated.create"`;
|
|
6
8
|
|
|
7
9
|
exports[`RestEndpoint remove: should extend name of parent endpoint 1`] = `"http://test.com/article-paginated.remove"`;
|