@data-client/rest 0.1.0 → 0.3.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 (77) hide show
  1. package/dist/index.js +17 -16
  2. package/dist/index.umd.min.js +1 -1
  3. package/dist/next.js +7 -2
  4. package/legacy/OptionsToFunction.js +1 -1
  5. package/legacy/RestEndpoint.js +5 -5
  6. package/legacy/RestHelpers.js +4 -2
  7. package/legacy/createResource.js +14 -13
  8. package/legacy/index.js +2 -1
  9. package/legacy/next/index.js +4 -4
  10. package/legacy/pathTypes.js +1 -1
  11. package/legacy/resourceTypes.js +2 -0
  12. package/lib/OptionsToFunction.d.ts.map +1 -1
  13. package/lib/OptionsToFunction.js +1 -1
  14. package/lib/RestEndpoint.d.ts +30 -36
  15. package/lib/RestEndpoint.js +5 -5
  16. package/lib/RestHelpers.js +4 -2
  17. package/lib/createResource.d.ts +65 -32
  18. package/lib/createResource.d.ts.map +1 -1
  19. package/lib/createResource.js +11 -12
  20. package/lib/index.d.ts +3 -1
  21. package/lib/index.d.ts.map +1 -1
  22. package/lib/index.js +2 -1
  23. package/lib/next/index.d.ts +5 -5
  24. package/lib/next/index.d.ts.map +1 -1
  25. package/lib/next/index.js +4 -4
  26. package/lib/pathTypes.d.ts +1 -0
  27. package/lib/pathTypes.d.ts.map +1 -1
  28. package/lib/pathTypes.js +1 -1
  29. package/lib/{next/resourceTypes.d.ts → resourceTypes.d.ts} +12 -2
  30. package/lib/resourceTypes.d.ts.map +1 -0
  31. package/lib/resourceTypes.js +2 -0
  32. package/package.json +3 -3
  33. package/src/OptionsToFunction.ts +0 -1
  34. package/src/RestEndpoint.d.ts +30 -36
  35. package/src/RestEndpoint.js +4 -4
  36. package/src/RestHelpers.ts +4 -4
  37. package/src/__tests__/Resource.test.ts +2 -2
  38. package/src/__tests__/RestEndpoint.ts +38 -9
  39. package/src/__tests__/__snapshots__/createResource.test.ts.snap +2 -0
  40. package/src/__tests__/createResource.test.ts +25 -4
  41. package/src/__tests__/hookifyResource.ts +7 -3
  42. package/src/__tests__/types.test.ts +353 -212
  43. package/src/createResource.ts +111 -62
  44. package/src/index.ts +2 -2
  45. package/src/next/index.ts +5 -5
  46. package/src/pathTypes.ts +2 -0
  47. package/src/{next/resourceTypes.ts → resourceTypes.ts} +12 -2
  48. package/ts4.0/RestEndpoint.d.ts +19 -33
  49. package/ts4.0/createResource.d.ts +77 -32
  50. package/ts4.0/index.d.ts +3 -1
  51. package/ts4.0/next/index.d.ts +5 -5
  52. package/ts4.0/pathTypes.d.ts +2 -0
  53. package/ts4.0/{next/resourceTypes.d.ts → resourceTypes.d.ts} +12 -2
  54. package/legacy/next/OptionsToFunction.js +0 -2
  55. package/legacy/next/RestEndpoint.js +0 -225
  56. package/legacy/next/createResource.js +0 -86
  57. package/legacy/next/resourceTypes.js +0 -2
  58. package/lib/next/OptionsToFunction.d.ts +0 -7
  59. package/lib/next/OptionsToFunction.d.ts.map +0 -1
  60. package/lib/next/OptionsToFunction.js +0 -2
  61. package/lib/next/RestEndpoint.d.ts +0 -542
  62. package/lib/next/RestEndpoint.js +0 -229
  63. package/lib/next/createResource.d.ts +0 -86
  64. package/lib/next/createResource.d.ts.map +0 -1
  65. package/lib/next/createResource.js +0 -100
  66. package/lib/next/resourceTypes.d.ts.map +0 -1
  67. package/lib/next/resourceTypes.js +0 -2
  68. package/src/next/OptionsToFunction.ts +0 -41
  69. package/src/next/RestEndpoint.d.ts +0 -542
  70. package/src/next/RestEndpoint.js +0 -262
  71. package/src/next/__tests__/RestEndpoint.ts +0 -1333
  72. package/src/next/__tests__/__snapshots__/RestEndpoint.ts.snap +0 -18
  73. package/src/next/__tests__/types.test.ts +0 -429
  74. package/src/next/createResource.ts +0 -194
  75. package/ts4.0/next/OptionsToFunction.d.ts +0 -16
  76. package/ts4.0/next/RestEndpoint.d.ts +0 -226
  77. package/ts4.0/next/createResource.d.ts +0 -94
@@ -1,205 +1,11 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
1
2
  import { Entity, schema } from '@data-client/endpoint';
3
+ import { useSuspense } from '@data-client/react';
2
4
  import { User } from '__tests__/new';
3
5
 
4
6
  import createResource from '../createResource';
5
- import {
6
- KeysToArgs,
7
- PathArgs,
8
- PathArgsAndSearch,
9
- PathKeys,
10
- ShortenPath,
11
- } from '../pathTypes';
12
- import RestEndpoint, { GetEndpoint, NewGetEndpoint } from '../RestEndpoint';
13
- import { RequiredKeys } from '../utiltypes';
14
-
15
- describe('PathArgs', () => {
16
- it('should infer types', () => {
17
- type C =
18
- 'http\\://test.com/groups/:group?/\\:blah/users/:id?:extra?/:next\\?bob/:last';
19
- function A(args: PathArgs<C>) {}
20
- // @ts-expect-error
21
- () => A({});
22
- () => A({ next: 'hi', last: 'ho' });
23
- // @ts-expect-error
24
- () => A({ next: 'hi', last: 'ho', doesnotexist: 'hi' });
25
- // @ts-expect-error
26
- () => A({ next: 'hi', last: 'ho', blah: 'hi' });
27
- () => A({ next: 'hi', last: 'ho', id: '5', group: 'whatever' });
28
- () => A({ next: 'hi', last: 'ho', extra: '5', group: 'whatever' });
29
- });
30
-
31
- it('should infer types2', () => {
32
- type C = 'http\\://test.com/article-cooler/:id?:title?';
33
- function A(args: PathArgs<C>) {}
34
- () => A({});
35
- () => A({ id: 'ho' });
36
- () => A({ title: 'ho' });
37
- () => A({ id: 'ho', title: 'ho' });
38
- // @ts-expect-error
39
- () => A({ idasd: 'ho' });
40
- // @ts-expect-error
41
- () => A({ next: 'hi', title: 'ho', id: 'hi' });
42
- // @ts-expect-error
43
- () => A(5);
44
- });
45
-
46
- it('should infer types with other characters to stop', () => {
47
- type C = 'http\\://test.com/search/issues?q=:q?%20repo\\::owner/:repo';
48
- function A(args: PathArgs<C>) {}
49
- () => A({ owner: 'data-client', repo: 'data-client' });
50
- () => A({ owner: 'data-client', repo: 'data-client', q: 'is:issue' });
51
- // @ts-expect-error
52
- () => A({ idasd: 'ho' });
53
- // @ts-expect-error
54
- () => A({ owner: 'data-client', repo: 'data-client', extra: 'is:issue' });
55
- // @ts-expect-error
56
- () => A({ owner: 'data-client' });
57
- // @ts-expect-error
58
- () => A(5);
59
- });
60
-
61
- it('should be flexible for string type', () => {
62
- class Parent {
63
- constructor() {}
64
- A(args: PathArgs<string>) {
65
- const b = args['hi'];
66
- }
67
- }
68
- class Child extends Parent {
69
- A(args: { item: string }) {}
70
- }
71
- const thing = new Parent();
72
- () => thing.A({});
73
- () => thing.A({ next: 'hi', last: 'ho' });
74
- const thing2 = new Child();
75
- //@ts-expect-error
76
- () => thing2.A({});
77
- () => thing2.A({ item: 'win' });
78
- });
79
-
80
- it('works with no arguments', () => {
81
- const a: GetEndpoint<PathArgs<'http\\://test.com/article-cooler/'>> =
82
- 0 as any;
83
- () => a();
84
- //@ts-expect-error
85
- () => a({ page: '5' });
86
- //@ts-expect-error
87
- () => a({ sdf: '5' });
88
- //@ts-expect-error
89
- () => a(5);
90
- });
91
-
92
- it('works when combining with known types', () => {
93
- const a: GetEndpoint<
94
- PathArgs<ShortenPath<'/hi'>> & { page: string | number }
95
- > = 0 as any;
96
- () => a({ page: '5' });
97
- //@ts-expect-error
98
- () => a({ sdf: '5' });
99
- //@ts-expect-error
100
- () => a({ page: '5' }, { hi: '5' });
101
- //@ts-expect-error
102
- () => a();
103
- });
104
-
105
- it('works with unions of non-intersecting types', () => {
106
- const a: GetEndpoint<{ id: string | number } | { title: string | number }> =
107
- 0 as any;
108
- () => a({ id: '5' });
109
- () => a({ title: '5' });
110
- // @ts-expect-error
111
- () => a({ id: '5', title: '5' });
112
- // @ts-expect-error
113
- () => a({ id: '5', sdfds: '5' });
114
- //@ts-expect-error
115
- () => a({ sdf: '5' });
116
- //@ts-expect-error
117
- () => a({ page: '5' }, { hi: '5' });
118
- //@ts-expect-error
119
- () => a();
120
- });
121
-
122
- it('works with optional positional args', () => {
123
- const a: GetEndpoint<undefined | { cursor?: string | number }> = 0 as any;
124
- () => a();
125
- () => a({});
126
- () => a({ cursor: 5 });
127
- // @ts-expect-error
128
- () => a({ id: '5' });
129
- //@ts-expect-error
130
- () => a({ cursor: '5' }, { cursor: '5' });
131
- });
132
-
133
- it('searchParams', () => {
134
- const a: GetEndpoint<undefined | { cursor?: string | number }> = 0 as any;
135
- () => a();
136
- () => a({});
137
- () => a({ cursor: 5 });
138
- // @ts-expect-error
139
- () => a({ id: '5' });
140
- //@ts-expect-error
141
- () => a({ cursor: '5' }, { cursor: '5' });
142
- });
143
-
144
- describe('PathArgsAndSearch', () => {
145
- it('works with required path member', () => {
146
- const a: GetEndpoint<
147
- PathArgsAndSearch<'http\\://test.com/groups/:group/users/'>
148
- > = 0 as any;
149
- () => a({ group: '5' });
150
- () => a({ group: '5', sdf: '5' });
151
- //@ts-expect-error
152
- () => a({ asdf: '5' });
153
- //@ts-expect-error
154
- () => a({});
155
- //@ts-expect-error
156
- () => a({ page: '5' }, { hi: '5' });
157
- //@ts-expect-error
158
- () => a();
159
- });
160
- it('works with no path members', () => {
161
- const a: NewGetEndpoint<{
162
- path: 'http\\://test.com/groups';
163
- searchParams: Record<string, number | string | boolean> | undefined;
164
- }> = 0 as any;
165
- /*const a: GetEndpoint<PathArgsAndSearch<'http\\://test.com/groups/'>> =
166
- 0 as any;*/
167
- () => a({ group: '5' });
168
- () => a({ group: '5', sdf: '5' });
169
- () => a();
170
- () => a({ asdf: '5' });
171
- () => a({});
172
- //@ts-expect-error
173
- () => a({ page: '5' }, { hi: '5' });
174
-
175
- () => {
176
- const b = a.extend({
177
- searchParams: {} as { userId?: number | string } | undefined,
178
- });
179
- b({ userId: '5' });
180
- b();
181
- // @ts-expect-error
182
- b({ sdf: '5' });
183
- };
184
- });
185
- });
186
- });
187
-
188
- describe('RequiredKeys', () => {
189
- type Y = {
190
- opt?: string;
191
- bob: string;
192
- charles: number;
193
- [k: string]: string | number | undefined;
194
- };
195
- const a: Record<RequiredKeys<Y>, any> = 5 as any;
196
- () => a.bob;
197
- () => a.charles;
198
- // @ts-expect-error
199
- () => a.opt;
200
- // @ts-expect-error
201
- () => a.sdfsdf;
202
- });
7
+ import { PathArgs, PathKeys } from '../pathTypes';
8
+ import RestEndpoint, { GetEndpoint, MutateEndpoint } from '../RestEndpoint';
203
9
 
204
10
  it('RestEndpoint construct and extend with typed options', () => {
205
11
  new RestEndpoint({
@@ -282,28 +88,363 @@ it('should customize resources', () => {
282
88
  }
283
89
  }
284
90
 
285
- const TodoResourceBase = createResource({
91
+ const TodoResource = createResource({
286
92
  path: '/todos/:id',
287
93
  schema: Todo,
288
94
  });
289
- TodoResourceBase.create.extend({
95
+ TodoResource.create.extend({
290
96
  searchParams: {} as { userId?: string | number } | undefined,
291
97
  getOptimisticResponse(snap, ...args) {
292
98
  return args[args.length - 1];
293
99
  },
294
100
  });
295
- TodoResourceBase.create
296
- .extend({
297
- schema: new schema.Collection([Todo], {
298
- argsKey(...args) {
299
- return { a: 5 };
300
- },
301
- }),
302
- })
303
- .extend({
304
- searchParams: {} as { userId?: string | number } | undefined,
305
- getOptimisticResponse(snap, ...args) {
306
- return args[args.length - 1];
101
+ const partial = TodoResource.partialUpdate.extend({
102
+ getOptimisticResponse(snap, { id }, body) {
103
+ return {
104
+ id,
105
+ ...body,
106
+ };
107
+ },
108
+ });
109
+ () => partial({ id: 5 }, { title: 'hi' });
110
+ const a: MutateEndpoint<{
111
+ path: '/todos/';
112
+ body: Partial<Todo>;
113
+ schema: typeof Todo;
114
+ }> = TodoResource.create.extend({ schema: Todo }) as any;
115
+ a.extend({
116
+ searchParams: {} as { userId?: string | number } | undefined,
117
+ getOptimisticResponse(snap, ...args) {
118
+ return args[args.length - 1];
119
+ },
120
+ });
121
+
122
+ () => useSuspense(TodoResource.getList);
123
+ });
124
+
125
+ // path: ['/todos', '/todos/:id', '/todos/:id?', string]
126
+ it('should precisely type function arguments', () => {
127
+ // path: '/todos'
128
+ () => {
129
+ const optionalUndefSearch = new RestEndpoint({
130
+ path: '/todos',
131
+ searchParams: {} as
132
+ | {
133
+ userId?: string | number;
134
+ }
135
+ | undefined,
136
+ });
137
+ const optionalSearch = new RestEndpoint({
138
+ path: '/todos',
139
+ searchParams: {} as {
140
+ userId?: string | number;
141
+ },
142
+ });
143
+ const undef = new RestEndpoint({
144
+ path: '/todos',
145
+ searchParams: undefined,
146
+ });
147
+ const requiredSearch = new RestEndpoint({
148
+ path: '/todos',
149
+ searchParams: {} as {
150
+ userId: string | number;
151
+ },
152
+ });
153
+ const noSearch = new RestEndpoint({
154
+ path: '/todos',
155
+ });
156
+ () => optionalUndefSearch();
157
+ () => optionalUndefSearch({});
158
+ () => optionalUndefSearch({ userId: 'hi' });
159
+ // @ts-expect-error
160
+ () => optionalUndefSearch(5);
161
+ // @ts-expect-error
162
+ () => optionalUndefSearch({ userId: 'hi' }, { userId: 'hi' });
163
+
164
+ () => optionalSearch();
165
+ () => optionalSearch({});
166
+ () => optionalSearch({ userId: 'hi' });
167
+ // @ts-expect-error
168
+ () => optionalSearch(5);
169
+ // @ts-expect-error
170
+ () => optionalSearch({ userId: 'hi' }, { userId: 'hi' });
171
+
172
+ // @ts-expect-error
173
+ () => requiredSearch();
174
+ // @ts-expect-error
175
+ () => requiredSearch({});
176
+ () => requiredSearch({ userId: 'hi' });
177
+ // @ts-expect-error
178
+ () => requiredSearch(5);
179
+ // @ts-expect-error
180
+ () => requiredSearch({ userId: 'hi' }, { userId: 'hi' });
181
+
182
+ () => undef();
183
+ // @ts-expect-error
184
+ () => undef({});
185
+ // @ts-expect-error
186
+ () => undef({ userId: 'hi' });
187
+ // @ts-expect-error
188
+ () => undef(5);
189
+
190
+ () => noSearch();
191
+ // @ts-expect-error
192
+ () => noSearch({});
193
+ // @ts-expect-error
194
+ () => noSearch({ userId: 'hi' });
195
+ // @ts-expect-error
196
+ () => noSearch(5);
197
+ };
198
+ // path: '/todos/:id?'
199
+ () => {
200
+ const optionalUndefSearch = new RestEndpoint({
201
+ path: '/todos/:id?',
202
+ searchParams: {} as
203
+ | {
204
+ userId?: string | number;
205
+ }
206
+ | undefined,
207
+ });
208
+ const optionalSearch = new RestEndpoint({
209
+ path: '/todos/:id?',
210
+ searchParams: {} as {
211
+ userId?: string | number;
212
+ },
213
+ });
214
+ const undef = new RestEndpoint({
215
+ path: '/todos/:id?',
216
+ searchParams: undefined,
217
+ });
218
+ const requiredSearch = new RestEndpoint({
219
+ path: '/todos/:id?',
220
+ searchParams: {} as {
221
+ userId: string | number;
222
+ },
223
+ });
224
+ const noSearch = new RestEndpoint({
225
+ path: '/todos/:id?',
226
+ });
227
+ () => optionalUndefSearch();
228
+ () => optionalUndefSearch({});
229
+ () => optionalUndefSearch({ id: '5' });
230
+ () => optionalUndefSearch({ userId: 'hi' });
231
+ () => optionalUndefSearch({ userId: 'hi', id: '5' });
232
+ // @ts-expect-error
233
+ () => optionalUndefSearch(5);
234
+ // @ts-expect-error
235
+ () => optionalUndefSearch({ userId: 'hi' }, { userId: 'hi' });
236
+
237
+ () => optionalSearch();
238
+ () => optionalSearch({});
239
+ () => optionalSearch({ id: '5' });
240
+ () => optionalSearch({ userId: 'hi' });
241
+ () => optionalSearch({ userId: 'hi', id: '5' });
242
+ // @ts-expect-error
243
+ () => optionalSearch(5);
244
+ // @ts-expect-error
245
+ () => optionalSearch({ userId: 'hi' }, { userId: 'hi' });
246
+
247
+ // @ts-expect-error
248
+ () => requiredSearch();
249
+ // @ts-expect-error
250
+ () => requiredSearch({});
251
+ // @ts-expect-error
252
+ () => requiredSearch({ id: '5' });
253
+ () => requiredSearch({ userId: 'hi' });
254
+ () => requiredSearch({ userId: 'hi', id: '5' });
255
+ // @ts-expect-error
256
+ () => requiredSearch(5);
257
+ // @ts-expect-error
258
+ () => requiredSearch({ userId: 'hi' }, { userId: 'hi' });
259
+
260
+ () => undef();
261
+ // @ts-ignore TODO
262
+ () => undef({});
263
+ // @ts-ignore TODO
264
+ () => undef({ id: '5' });
265
+ // @ts-expect-error
266
+ () => undef({ userId: 'hi' });
267
+ // @ts-expect-error
268
+ () => undef(5);
269
+
270
+ () => noSearch();
271
+ () => noSearch({});
272
+ () => noSearch({ id: '5' });
273
+ // @ts-expect-error
274
+ () => noSearch({ userId: 'hi' });
275
+ // @ts-expect-error
276
+ () => noSearch(5);
277
+ };
278
+ // path: '/todos/:id'
279
+ () => {
280
+ const optionalUndefSearch = new RestEndpoint({
281
+ path: '/todos/:id',
282
+ searchParams: {} as
283
+ | {
284
+ userId?: string | number;
285
+ }
286
+ | undefined,
287
+ });
288
+ const optionalSearch = new RestEndpoint({
289
+ path: '/todos/:id',
290
+ searchParams: {} as {
291
+ userId?: string | number;
292
+ },
293
+ });
294
+ const undef = new RestEndpoint({
295
+ path: '/todos/:id',
296
+ searchParams: undefined,
297
+ });
298
+ const requiredSearch = new RestEndpoint({
299
+ path: '/todos/:id',
300
+ searchParams: {} as {
301
+ userId: string | number;
307
302
  },
308
303
  });
304
+ const noSearch = new RestEndpoint({
305
+ path: '/todos/:id',
306
+ });
307
+ // @ts-expect-error
308
+ () => optionalUndefSearch();
309
+ () => optionalUndefSearch({ id: '5' });
310
+ () => optionalUndefSearch({ id: '5', userId: 'hi' });
311
+ // @ts-expect-error
312
+ () => optionalUndefSearch(5);
313
+ () =>
314
+ // @ts-expect-error
315
+ optionalUndefSearch({ id: '5', userId: 'hi' }, { id: '5', userId: 'hi' });
316
+
317
+ // @ts-expect-error
318
+ () => optionalSearch();
319
+ () => optionalSearch({ id: '5' });
320
+ () => optionalSearch({ id: '5', userId: 'hi' });
321
+ // @ts-expect-error
322
+ () => optionalSearch(5);
323
+ // @ts-expect-error
324
+ () => optionalSearch({ id: '5', userId: 'hi' }, { id: '5', userId: 'hi' });
325
+
326
+ // @ts-expect-error
327
+ () => requiredSearch();
328
+ // @ts-expect-error
329
+ () => requiredSearch({ id: '5' });
330
+ () => requiredSearch({ id: '5', userId: 'hi' });
331
+ // @ts-expect-error
332
+ () => requiredSearch(5);
333
+ // @ts-expect-error
334
+ () => requiredSearch({ id: '5', userId: 'hi' }, { id: '5', userId: 'hi' });
335
+
336
+ // @ts-expect-error
337
+ () => undef();
338
+ // @ts-expect-error
339
+ () => undef({});
340
+ // @ts-expect-error
341
+ () => undef({ id: '5', userId: 'hi' });
342
+ // @ts-expect-error
343
+ () => undef(5);
344
+
345
+ // @ts-expect-error
346
+ () => noSearch();
347
+ () => noSearch({ id: '5' });
348
+ // @ts-expect-error
349
+ () => noSearch({ id: '5', userId: 'hi' });
350
+ // @ts-expect-error
351
+ () => noSearch(5);
352
+ };
353
+ // path: string
354
+ () => {
355
+ const optionalUndefSearch = new RestEndpoint({
356
+ path: '' as string,
357
+ searchParams: {} as
358
+ | {
359
+ userId?: string | number;
360
+ }
361
+ | undefined,
362
+ });
363
+ const optionalSearch = new RestEndpoint({
364
+ path: '' as string,
365
+ searchParams: {} as {
366
+ userId?: string | number;
367
+ },
368
+ });
369
+ const undef = new RestEndpoint({
370
+ path: '' as string,
371
+ searchParams: undefined,
372
+ });
373
+ const requiredSearch = new RestEndpoint({
374
+ path: '' as string,
375
+ searchParams: {} as {
376
+ userId: string | number;
377
+ },
378
+ });
379
+ const noSearch = new RestEndpoint({
380
+ path: '' as string,
381
+ });
382
+ () => optionalUndefSearch();
383
+ () => optionalUndefSearch({});
384
+ () => optionalUndefSearch({ id: '5' });
385
+ () => optionalUndefSearch({ userId: 'hi' });
386
+ () => optionalUndefSearch({ userId: 'hi', id: '5' });
387
+ // @ts-expect-error
388
+ () => optionalUndefSearch(5);
389
+ // @ts-expect-error
390
+ () => optionalUndefSearch({ userId: 'hi' }, { userId: 'hi' });
391
+
392
+ () => optionalSearch();
393
+ () => optionalSearch({});
394
+ () => optionalSearch({ id: '5' });
395
+ () => optionalSearch({ userId: 'hi' });
396
+ () => optionalSearch({ userId: 'hi', id: '5' });
397
+ // @ts-expect-error
398
+ () => optionalSearch(5);
399
+ // @ts-expect-error
400
+ () => optionalSearch({ userId: 'hi' }, { userId: 'hi' });
401
+
402
+ // @ts-expect-error
403
+ () => requiredSearch();
404
+ // @ts-expect-error
405
+ () => requiredSearch({});
406
+ // @ts-expect-error
407
+ () => requiredSearch({ id: '5' });
408
+ () => requiredSearch({ userId: 'hi' });
409
+ () => requiredSearch({ userId: 'hi', id: '5' });
410
+ // @ts-expect-error
411
+ () => requiredSearch(5);
412
+ // @ts-expect-error
413
+ () => requiredSearch({ userId: 'hi' }, { userId: 'hi' });
414
+
415
+ () => undef();
416
+ // @ts-ignore TODO
417
+ () => undef({});
418
+ // @ts-ignore TODO
419
+ () => undef({ id: '5' });
420
+ // @ts-expect-error
421
+ () => undef(5);
422
+
423
+ () => noSearch();
424
+ () => noSearch({});
425
+ () => noSearch({ id: '5' });
426
+ () => noSearch({ userId: 'hi' });
427
+ // @ts-expect-error
428
+ () => noSearch(5);
429
+ };
430
+ });
431
+
432
+ it('should handle more open ended type definitions', () => {
433
+ () => {
434
+ const unknownParams = new RestEndpoint({
435
+ path: '' as `${string}:${string}`,
436
+ });
437
+
438
+ unknownParams({ hi: 5 });
439
+
440
+ const explicit: GetEndpoint<{
441
+ path: `${string}:${string}`;
442
+ schema: typeof User;
443
+ }> = new RestEndpoint({
444
+ path: '' as `${string}:${string}`,
445
+ schema: User,
446
+ });
447
+ explicit({ hi: 5 });
448
+ explicit.push.process({} as any, { hi: 5 });
449
+ };
309
450
  });