@data-client/rest 0.15.6 → 0.16.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 (54) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/dist/index.js +61 -18
  3. package/dist/index.umd.min.js +1 -1
  4. package/legacy/NetworkError.js +16 -1
  5. package/legacy/RestEndpoint.js +17 -4
  6. package/legacy/RestEndpointTypes.js +1 -1
  7. package/legacy/RestHelpers.js +29 -16
  8. package/legacy/pathTypes.js +1 -1
  9. package/legacy/resource.js +3 -1
  10. package/legacy/resourceTypes.js +1 -1
  11. package/lib/NetworkError.d.ts +12 -0
  12. package/lib/NetworkError.d.ts.map +1 -1
  13. package/lib/NetworkError.js +16 -1
  14. package/lib/RestEndpoint.js +17 -4
  15. package/lib/RestEndpointTypes.d.ts +43 -9
  16. package/lib/RestEndpointTypes.d.ts.map +1 -1
  17. package/lib/RestEndpointTypes.js +1 -1
  18. package/lib/RestHelpers.d.ts +2 -2
  19. package/lib/RestHelpers.d.ts.map +1 -1
  20. package/lib/RestHelpers.js +29 -16
  21. package/lib/pathTypes.d.ts +14 -13
  22. package/lib/pathTypes.d.ts.map +1 -1
  23. package/lib/pathTypes.js +1 -1
  24. package/lib/resource.d.ts.map +1 -1
  25. package/lib/resource.js +3 -1
  26. package/lib/resourceTypes.d.ts +5 -1
  27. package/lib/resourceTypes.d.ts.map +1 -1
  28. package/lib/resourceTypes.js +1 -1
  29. package/package.json +5 -5
  30. package/src/NetworkError.ts +15 -0
  31. package/src/RestEndpoint.js +21 -3
  32. package/src/RestEndpointTypes.ts +33 -9
  33. package/src/RestHelpers.ts +34 -26
  34. package/src/__tests__/Resource.test.ts +131 -0
  35. package/src/__tests__/RestEndpoint.ts +212 -4
  36. package/src/__tests__/__snapshots__/RestEndpoint.ts.snap +2 -0
  37. package/src/__tests__/__snapshots__/resource-construction.test.ts.snap +1 -1
  38. package/src/__tests__/hookifyResource.ts +7 -0
  39. package/src/__tests__/resource-construction.test.ts +543 -0
  40. package/src/pathTypes.ts +35 -23
  41. package/src/resource.ts +2 -0
  42. package/src/resourceTypes.ts +3 -1
  43. package/ts4.0/NetworkError.d.ts +12 -0
  44. package/ts4.0/RestEndpointTypes.d.ts +61 -9
  45. package/ts4.0/RestHelpers.d.ts +2 -2
  46. package/ts4.0/pathTypes.d.ts +1 -1
  47. package/ts4.0/resourceExtendable.d.ts +1 -1
  48. package/ts4.0/resourceTypes.d.ts +7 -1
  49. package/ts4.1/NetworkError.d.ts +12 -0
  50. package/ts4.1/RestEndpointTypes.d.ts +61 -9
  51. package/ts4.1/RestHelpers.d.ts +2 -2
  52. package/ts4.1/pathTypes.d.ts +14 -13
  53. package/ts4.1/resourceExtendable.d.ts +1 -1
  54. package/ts4.1/resourceTypes.d.ts +7 -1
@@ -7,5 +7,17 @@ export default class NetworkError extends Error {
7
7
  response: Response;
8
8
  name: string;
9
9
  constructor(response: Response);
10
+ /** Serialize the error for logging and debugging.
11
+ *
12
+ * Error properties are non-enumerable by default, so `JSON.stringify()`
13
+ * on a plain Error produces `{}`. This ensures status, message, and the
14
+ * request URL are always included in serialized output.
15
+ */
16
+ toJSON(): {
17
+ name: string;
18
+ status: number;
19
+ message: string;
20
+ url: string;
21
+ };
10
22
  }
11
23
  //# sourceMappingURL=NetworkError.d.ts.map
@@ -117,6 +117,13 @@ export interface RestInstance<F extends FetchFunction = FetchFunction, S extends
117
117
  remove: RemoveEndpoint<F, ExtractCollection<S>['remove'], Exclude<O, 'body' | 'method'> & {
118
118
  body: OptionsToAdderBodyArgument<O> | OptionsToAdderBodyArgument<O>[] | FormData;
119
119
  }>;
120
+ /** Move item between collections (PATCH) - removes from old, adds to new
121
+ * @see https://dataclient.io/rest/api/RestEndpoint#move
122
+ */
123
+ move: MoveEndpoint<F, ExtractCollection<S>['move'], {
124
+ path: 'movePath' extends keyof O ? O['movePath'] & string : O['path'];
125
+ body: OptionsToAdderBodyArgument<O> | FormData;
126
+ }>;
120
127
  }
121
128
  export type RestEndpointExtendOptions<O extends PartialRestGenerics, E extends {
122
129
  body?: any;
@@ -127,19 +134,31 @@ export type RestEndpointExtendOptions<O extends PartialRestGenerics, E extends {
127
134
  type OptionsToRestEndpoint<O extends PartialRestGenerics, E extends RestInstanceBase & {
128
135
  body?: any;
129
136
  paginationField?: string;
130
- }, F extends FetchFunction> = 'path' extends keyof O ? RestType<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, OptionsToBodyArgument<'body' extends keyof O ? O : E, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
137
+ }, F extends FetchFunction> = 'path' extends keyof O ? RestType<'searchParams' extends keyof O ? [
138
+ O['searchParams']
139
+ ] extends [
140
+ undefined
141
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, OptionsToBodyArgument<'body' extends keyof O ? O : E, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
131
142
  path: Exclude<O['path'], undefined>;
132
143
  body: 'body' extends keyof O ? O['body'] : E['body'];
133
144
  searchParams: 'searchParams' extends keyof O ? O['searchParams'] : E['searchParams'];
134
145
  method: 'method' extends keyof O ? O['method'] : E['method'];
135
146
  paginationField: 'paginationField' extends keyof O ? O['paginationField'] : E['paginationField'];
136
- }> : 'body' extends keyof O ? RestType<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<E['path'], undefined>> : PathArgs<Exclude<E['path'], undefined>>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
147
+ }> : 'body' extends keyof O ? RestType<'searchParams' extends keyof O ? [
148
+ O['searchParams']
149
+ ] extends [
150
+ undefined
151
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<E['path'], undefined>> : PathArgs<Exclude<E['path'], undefined>>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
137
152
  path: E['path'];
138
153
  body: O['body'];
139
154
  searchParams: 'searchParams' extends keyof O ? O['searchParams'] : E['searchParams'];
140
155
  method: 'method' extends keyof O ? O['method'] : E['method'];
141
156
  paginationField: 'paginationField' extends keyof O ? O['paginationField'] : Extract<E['paginationField'], string>;
142
- }> : 'searchParams' extends keyof O ? RestType<O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<E['path'], undefined>>, OptionsToBodyArgument<E, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
157
+ }> : 'searchParams' extends keyof O ? RestType<[
158
+ O['searchParams']
159
+ ] extends [
160
+ undefined
161
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<E['path'], undefined>>, OptionsToBodyArgument<E, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
143
162
  path: E['path'];
144
163
  body: E['body'];
145
164
  searchParams: O['searchParams'];
@@ -231,7 +250,11 @@ export type AddEndpoint<F extends FetchFunction = FetchFunction, S extends Schem
231
250
  } = {
232
251
  path: string;
233
252
  body: any;
234
- }> = RestInstanceBase<RestFetch<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method'> & {
253
+ }> = RestInstanceBase<RestFetch<'searchParams' extends keyof O ? [
254
+ O['searchParams']
255
+ ] extends [
256
+ undefined
257
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method'> & {
235
258
  method: 'POST';
236
259
  }>;
237
260
  export type RemoveEndpoint<F extends FetchFunction = FetchFunction, S extends Schema | undefined = any, O extends {
@@ -241,7 +264,20 @@ export type RemoveEndpoint<F extends FetchFunction = FetchFunction, S extends Sc
241
264
  } = {
242
265
  path: string;
243
266
  body: any;
244
- }> = RestInstanceBase<RestFetch<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method'> & {
267
+ }> = RestInstanceBase<RestFetch<'searchParams' extends keyof O ? [
268
+ O['searchParams']
269
+ ] extends [
270
+ undefined
271
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method'> & {
272
+ method: 'PATCH';
273
+ }>;
274
+ export type MoveEndpoint<F extends FetchFunction = FetchFunction, S extends Schema | undefined = any, O extends {
275
+ path: string;
276
+ body: any;
277
+ } = {
278
+ path: string;
279
+ body: any;
280
+ }> = RestInstanceBase<RestFetch<PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method' | 'searchParams'> & {
245
281
  method: 'PATCH';
246
282
  }>;
247
283
  type OptionsToAdderBodyArgument<O extends {
@@ -277,14 +313,22 @@ export interface RestEndpointOptions<F extends FetchFunction = FetchFunction, S
277
313
  url?(...args: Parameters<F>): string;
278
314
  update?: EndpointUpdateFunction<F, S>;
279
315
  }
280
- export type RestEndpointConstructorOptions<O extends RestGenerics = any> = RestEndpointOptions<RestFetch<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : O extends {
316
+ export type RestEndpointConstructorOptions<O extends RestGenerics = any> = RestEndpointOptions<RestFetch<'searchParams' extends keyof O ? [
317
+ O['searchParams']
318
+ ] extends [
319
+ undefined
320
+ ] ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : O extends {
281
321
  sideEffect: true;
282
322
  } ? 'POST' : 'GET'>, O['process'] extends {} ? ReturnType<O['process']> : any>, O['schema']>;
283
323
  /** Simplifies endpoint definitions that follow REST patterns
284
324
  *
285
325
  * @see https://dataclient.io/rest/api/RestEndpoint
286
326
  */
287
- export interface RestEndpoint<O extends RestGenerics = any> extends RestInstance<RestFetch<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : O extends {
327
+ export interface RestEndpoint<O extends RestGenerics = any> extends RestInstance<RestFetch<'searchParams' extends keyof O ? [
328
+ O['searchParams']
329
+ ] extends [
330
+ undefined
331
+ ] ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : O extends {
288
332
  sideEffect: true;
289
333
  } ? 'POST' : 'GET'>, O['process'] extends {} ? ReturnType<O['process']> : any>, 'schema' extends keyof O ? O['schema'] : undefined, 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : MethodToSide<O['method']>, 'method' extends keyof O ? O : O & {
290
334
  method: O extends {
@@ -363,7 +407,11 @@ export type GetEndpoint<O extends {
363
407
  } = {
364
408
  path: string;
365
409
  schema: Schema;
366
- }> = RestTypeNoBody<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, O['schema'], undefined, any, O & {
410
+ }> = RestTypeNoBody<'searchParams' extends keyof O ? [
411
+ O['searchParams']
412
+ ] extends [
413
+ undefined
414
+ ] ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, O['schema'], undefined, any, O & {
367
415
  method: 'GET';
368
416
  }>;
369
417
  export type MutateEndpoint<O extends {
@@ -377,7 +425,11 @@ export type MutateEndpoint<O extends {
377
425
  path: string;
378
426
  body: any;
379
427
  schema: Schema;
380
- }> = RestTypeWithBody<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, O['schema'], true, O['body'], any, O & {
428
+ }> = RestTypeWithBody<'searchParams' extends keyof O ? [
429
+ O['searchParams']
430
+ ] extends [
431
+ undefined
432
+ ] ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, O['schema'], true, O['body'], any, O & {
381
433
  body: any;
382
434
  method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
383
435
  }>;
@@ -1,6 +1,6 @@
1
- import { PathFunction } from 'path-to-regexp';
1
+ import { PathFunction, ParamData } from 'path-to-regexp';
2
2
  import { ShortenPath } from './pathTypes.js';
3
- export declare function getUrlBase(path: string): PathFunction;
3
+ export declare function getUrlBase(path: string): PathFunction<ParamData>;
4
4
  export declare function getUrlTokens(path: string): Set<string>;
5
5
  export declare function isPojo(obj: unknown): obj is Record<string, any>;
6
6
  export declare function shortenPath<S extends string>(path: S): ShortenPath<S>;
@@ -11,7 +11,7 @@ export declare type KeysToArgs<Key extends string> = {
11
11
  };
12
12
  export declare type PathArgsAndSearch<S extends string> =
13
13
  PathKeys<S> extends never
14
- ? Record<string, number | string> | undefined
14
+ ? Record<string, number | string | boolean> | undefined
15
15
  : {
16
16
  [K in PathKeys<S>]: string | number;
17
17
  } & Record<string, number | string>;
@@ -15,7 +15,7 @@ export interface Extendable<O extends ResourceGenerics = {
15
15
  }, ExtendKey extends string, ExtendOptions extends PartialRestGenerics | {}>(this: R, key: ExtendKey, options: Readonly<RestEndpointExtendOptions<ExtendOptions, R['get'], EndpointToFunction<R['get']>> & ExtendOptions>): R & {
16
16
  [key in ExtendKey]: RestExtendedEndpoint<ExtendOptions, R['get']>;
17
17
  };
18
- extend<R extends ResourceInterface, Get extends PartialRestGenerics = any, GetList extends PartialRestGenerics = any, Update extends PartialRestGenerics = any, PartialUpdate extends PartialRestGenerics = any, Delete extends PartialRestGenerics = any>(this: R, options: ResourceEndpointExtensions<R, Get, GetList, Update, PartialUpdate, Delete>): CustomResource<R, O, Get, GetList, Update, PartialUpdate, Delete>;
18
+ extend<R extends ResourceInterface, Get extends PartialRestGenerics = {}, GetList extends PartialRestGenerics = {}, Update extends PartialRestGenerics = {}, PartialUpdate extends PartialRestGenerics = {}, Delete extends PartialRestGenerics = {}>(this: R, options: ResourceEndpointExtensions<R, Get, GetList, Update, PartialUpdate, Delete>): CustomResource<R, O, Get, GetList, Update, PartialUpdate, Delete>;
19
19
  extend<R extends ResourceInterface, T extends Record<string, EndpointInterface>>(this: R, extender: (baseResource: R) => T): ExtendedResource<R, T>;
20
20
  }
21
21
  //# sourceMappingURL=resourceExtendable.d.ts.map
@@ -71,9 +71,14 @@ export interface Resource<O extends ResourceGenerics = {
71
71
  path: ShortenPath<O['path']>;
72
72
  schema: schema.Collection<[
73
73
  O['schema']
74
- ], ParamToArgs<O['searchParams'] extends undefined ? KeysToArgs<ShortenPath<O['path']>> : O['searchParams'] & PathArgs<ShortenPath<O['path']>>>>;
74
+ ], ParamToArgs<[
75
+ O['searchParams']
76
+ ] extends [
77
+ undefined
78
+ ] ? KeysToArgs<ShortenPath<O['path']>> : O['searchParams'] & PathArgs<ShortenPath<O['path']>>>>;
75
79
  body: 'body' extends keyof O ? O['body'] : Partial<Denormalize<O['schema']>>;
76
80
  searchParams: O['searchParams'];
81
+ movePath: O['path'];
77
82
  } & Pick<O, 'paginationField'>> : GetEndpoint<{
78
83
  path: ShortenPath<O['path']>;
79
84
  schema: schema.Collection<[
@@ -81,6 +86,7 @@ export interface Resource<O extends ResourceGenerics = {
81
86
  ], ParamToArgs<(Record<string, number | string | boolean> | undefined) & PathArgs<ShortenPath<O['path']>>>>;
82
87
  body: 'body' extends keyof O ? O['body'] : Partial<Denormalize<O['schema']>>;
83
88
  searchParams: Record<string, number | string | boolean> | undefined;
89
+ movePath: O['path'];
84
90
  } & Pick<O, 'paginationField'>>;
85
91
  /** Create a new item (POST)
86
92
  *
@@ -7,5 +7,17 @@ export default class NetworkError extends Error {
7
7
  response: Response;
8
8
  name: string;
9
9
  constructor(response: Response);
10
+ /** Serialize the error for logging and debugging.
11
+ *
12
+ * Error properties are non-enumerable by default, so `JSON.stringify()`
13
+ * on a plain Error produces `{}`. This ensures status, message, and the
14
+ * request URL are always included in serialized output.
15
+ */
16
+ toJSON(): {
17
+ name: string;
18
+ status: number;
19
+ message: string;
20
+ url: string;
21
+ };
10
22
  }
11
23
  //# sourceMappingURL=NetworkError.d.ts.map
@@ -117,6 +117,13 @@ export interface RestInstance<F extends FetchFunction = FetchFunction, S extends
117
117
  remove: RemoveEndpoint<F, ExtractCollection<S>['remove'], Exclude<O, 'body' | 'method'> & {
118
118
  body: OptionsToAdderBodyArgument<O> | OptionsToAdderBodyArgument<O>[] | FormData;
119
119
  }>;
120
+ /** Move item between collections (PATCH) - removes from old, adds to new
121
+ * @see https://dataclient.io/rest/api/RestEndpoint#move
122
+ */
123
+ move: MoveEndpoint<F, ExtractCollection<S>['move'], {
124
+ path: 'movePath' extends keyof O ? O['movePath'] & string : O['path'];
125
+ body: OptionsToAdderBodyArgument<O> | FormData;
126
+ }>;
120
127
  }
121
128
  export type RestEndpointExtendOptions<O extends PartialRestGenerics, E extends {
122
129
  body?: any;
@@ -127,19 +134,31 @@ export type RestEndpointExtendOptions<O extends PartialRestGenerics, E extends {
127
134
  type OptionsToRestEndpoint<O extends PartialRestGenerics, E extends RestInstanceBase & {
128
135
  body?: any;
129
136
  paginationField?: string;
130
- }, F extends FetchFunction> = 'path' extends keyof O ? RestType<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, OptionsToBodyArgument<'body' extends keyof O ? O : E, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
137
+ }, F extends FetchFunction> = 'path' extends keyof O ? RestType<'searchParams' extends keyof O ? [
138
+ O['searchParams']
139
+ ] extends [
140
+ undefined
141
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, OptionsToBodyArgument<'body' extends keyof O ? O : E, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
131
142
  path: Exclude<O['path'], undefined>;
132
143
  body: 'body' extends keyof O ? O['body'] : E['body'];
133
144
  searchParams: 'searchParams' extends keyof O ? O['searchParams'] : E['searchParams'];
134
145
  method: 'method' extends keyof O ? O['method'] : E['method'];
135
146
  paginationField: 'paginationField' extends keyof O ? O['paginationField'] : E['paginationField'];
136
- }> : 'body' extends keyof O ? RestType<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<E['path'], undefined>> : PathArgs<Exclude<E['path'], undefined>>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
147
+ }> : 'body' extends keyof O ? RestType<'searchParams' extends keyof O ? [
148
+ O['searchParams']
149
+ ] extends [
150
+ undefined
151
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<E['path'], undefined>> : PathArgs<Exclude<E['path'], undefined>>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
137
152
  path: E['path'];
138
153
  body: O['body'];
139
154
  searchParams: 'searchParams' extends keyof O ? O['searchParams'] : E['searchParams'];
140
155
  method: 'method' extends keyof O ? O['method'] : E['method'];
141
156
  paginationField: 'paginationField' extends keyof O ? O['paginationField'] : Extract<E['paginationField'], string>;
142
- }> : 'searchParams' extends keyof O ? RestType<O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<E['path'], undefined>>, OptionsToBodyArgument<E, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
157
+ }> : 'searchParams' extends keyof O ? RestType<[
158
+ O['searchParams']
159
+ ] extends [
160
+ undefined
161
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<E['path'], undefined>>, OptionsToBodyArgument<E, 'method' extends keyof O ? O['method'] : E['method']>, 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : 'method' extends keyof O ? MethodToSide<O['method']> : E['sideEffect'], O['process'] extends {} ? ReturnType<O['process']> : ResolveType<F>, {
143
162
  path: E['path'];
144
163
  body: E['body'];
145
164
  searchParams: O['searchParams'];
@@ -231,7 +250,11 @@ export type AddEndpoint<F extends FetchFunction = FetchFunction, S extends Schem
231
250
  } = {
232
251
  path: string;
233
252
  body: any;
234
- }> = RestInstanceBase<RestFetch<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method'> & {
253
+ }> = RestInstanceBase<RestFetch<'searchParams' extends keyof O ? [
254
+ O['searchParams']
255
+ ] extends [
256
+ undefined
257
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method'> & {
235
258
  method: 'POST';
236
259
  }>;
237
260
  export type RemoveEndpoint<F extends FetchFunction = FetchFunction, S extends Schema | undefined = any, O extends {
@@ -241,7 +264,20 @@ export type RemoveEndpoint<F extends FetchFunction = FetchFunction, S extends Sc
241
264
  } = {
242
265
  path: string;
243
266
  body: any;
244
- }> = RestInstanceBase<RestFetch<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method'> & {
267
+ }> = RestInstanceBase<RestFetch<'searchParams' extends keyof O ? [
268
+ O['searchParams']
269
+ ] extends [
270
+ undefined
271
+ ] ? PathArgs<Exclude<O['path'], undefined>> : O['searchParams'] & PathArgs<Exclude<O['path'], undefined>> : PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method'> & {
272
+ method: 'PATCH';
273
+ }>;
274
+ export type MoveEndpoint<F extends FetchFunction = FetchFunction, S extends Schema | undefined = any, O extends {
275
+ path: string;
276
+ body: any;
277
+ } = {
278
+ path: string;
279
+ body: any;
280
+ }> = RestInstanceBase<RestFetch<PathArgs<Exclude<O['path'], undefined>>, O['body'], ResolveType<F>>, S, true, Omit<O, 'method' | 'searchParams'> & {
245
281
  method: 'PATCH';
246
282
  }>;
247
283
  type OptionsToAdderBodyArgument<O extends {
@@ -277,14 +313,22 @@ export interface RestEndpointOptions<F extends FetchFunction = FetchFunction, S
277
313
  url?(...args: Parameters<F>): string;
278
314
  update?: EndpointUpdateFunction<F, S>;
279
315
  }
280
- export type RestEndpointConstructorOptions<O extends RestGenerics = any> = RestEndpointOptions<RestFetch<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : O extends {
316
+ export type RestEndpointConstructorOptions<O extends RestGenerics = any> = RestEndpointOptions<RestFetch<'searchParams' extends keyof O ? [
317
+ O['searchParams']
318
+ ] extends [
319
+ undefined
320
+ ] ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : O extends {
281
321
  sideEffect: true;
282
322
  } ? 'POST' : 'GET'>, O['process'] extends {} ? ReturnType<O['process']> : any>, O['schema']>;
283
323
  /** Simplifies endpoint definitions that follow REST patterns
284
324
  *
285
325
  * @see https://dataclient.io/rest/api/RestEndpoint
286
326
  */
287
- export interface RestEndpoint<O extends RestGenerics = any> extends RestInstance<RestFetch<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : O extends {
327
+ export interface RestEndpoint<O extends RestGenerics = any> extends RestInstance<RestFetch<'searchParams' extends keyof O ? [
328
+ O['searchParams']
329
+ ] extends [
330
+ undefined
331
+ ] ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, OptionsToBodyArgument<O, 'method' extends keyof O ? O['method'] : O extends {
288
332
  sideEffect: true;
289
333
  } ? 'POST' : 'GET'>, O['process'] extends {} ? ReturnType<O['process']> : any>, 'schema' extends keyof O ? O['schema'] : undefined, 'sideEffect' extends keyof O ? Extract<O['sideEffect'], boolean | undefined> : MethodToSide<O['method']>, 'method' extends keyof O ? O : O & {
290
334
  method: O extends {
@@ -363,7 +407,11 @@ export type GetEndpoint<O extends {
363
407
  } = {
364
408
  path: string;
365
409
  schema: Schema;
366
- }> = RestTypeNoBody<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, O['schema'], undefined, any, O & {
410
+ }> = RestTypeNoBody<'searchParams' extends keyof O ? [
411
+ O['searchParams']
412
+ ] extends [
413
+ undefined
414
+ ] ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, O['schema'], undefined, any, O & {
367
415
  method: 'GET';
368
416
  }>;
369
417
  export type MutateEndpoint<O extends {
@@ -377,7 +425,11 @@ export type MutateEndpoint<O extends {
377
425
  path: string;
378
426
  body: any;
379
427
  schema: Schema;
380
- }> = RestTypeWithBody<'searchParams' extends keyof O ? O['searchParams'] extends undefined ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, O['schema'], true, O['body'], any, O & {
428
+ }> = RestTypeWithBody<'searchParams' extends keyof O ? [
429
+ O['searchParams']
430
+ ] extends [
431
+ undefined
432
+ ] ? PathArgs<O['path']> : O['searchParams'] & PathArgs<O['path']> : PathArgs<O['path']>, O['schema'], true, O['body'], any, O & {
381
433
  body: any;
382
434
  method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
383
435
  }>;
@@ -1,6 +1,6 @@
1
- import { PathFunction } from 'path-to-regexp';
1
+ import { PathFunction, ParamData } from 'path-to-regexp';
2
2
  import { ShortenPath } from './pathTypes.js';
3
- export declare function getUrlBase(path: string): PathFunction;
3
+ export declare function getUrlBase(path: string): PathFunction<ParamData>;
4
4
  export declare function getUrlTokens(path: string): Set<string>;
5
5
  export declare function isPojo(obj: unknown): obj is Record<string, any>;
6
6
  export declare function shortenPath<S extends string>(path: S): ShortenPath<S>;
@@ -1,21 +1,22 @@
1
- type OnlyOptional<S extends string> = S extends `${infer K}}?` ? K : S extends `${infer K}?` ? K : never;
2
- type OnlyRequired<S extends string> = S extends `${string}?` ? never : S;
1
+ type CleanKey<S extends string> = S extends `"${infer K}"` ? K : S;
2
+ type KeyName<K extends string> = CleanKey<K extends `*${infer N}}` ? N : K extends `*${infer N}` ? N : K extends `${infer N}}` ? N : K>;
3
+ type KeyVal<K extends string> = K extends `*${string}` ? string[] : string | number;
3
4
  /** Parameters for a given path */
4
5
  export type PathArgs<S extends string> = PathKeys<S> extends never ? unknown : KeysToArgs<PathKeys<S>>;
5
6
  /** Computes the union of keys for a path string */
6
- export type PathKeys<S extends string> = string extends S ? string : S extends `${infer A}\\${':' | '?' | '+' | '*' | '{' | '}'}${infer B}` ? PathKeys<A> | PathKeys<B> : PathSplits<S>;
7
- type PathSplits<S extends string> = S extends (`${string}:${infer K}${'/' | ',' | '%' | '&' | '+' | '*' | '{'}${infer R}`) ? PathSplits<`:${K}`> | PathSplits<R> : S extends `${string}:${infer K}:${infer R}` ? PathSplits<`:${K}`> | PathSplits<`:${R}`> : S extends `${string}:${infer K}` ? K : never;
7
+ export type PathKeys<S extends string> = string extends S ? string : S extends `${infer A}\\${':' | '*' | '}'}${infer B}` ? PathKeys<A> | PathKeys<B> : Splits<S, ':'> | Splits<S, '*'>;
8
+ type Splits<S extends string, M extends ':' | '*'> = S extends `${string}${M}${infer K}${M}${infer R}` ? Splits<`${M}${K}`, M> | Splits<`${M}${R}`, M> : S extends (`${string}${M}${infer K}${'/' | '\\' | '%' | '&' | '*' | ':' | '{' | ';' | ',' | '!' | '@'}${infer R}`) ? Splits<`${M}${K}`, M> | Splits<R, M> : S extends `${string}${M}${infer K}` ? M extends '*' ? `*${K}` : K : never;
8
9
  export type KeysToArgs<Key extends string> = {
9
- [K in Key as OnlyOptional<K>]?: string | number;
10
- } & (OnlyRequired<Key> extends never ? unknown : {
11
- [K in Key as OnlyRequired<K>]: string | number;
10
+ [K in Key as K extends `${string}}` ? KeyName<K> : never]?: KeyVal<K>;
11
+ } & (Exclude<Key, `${string}}`> extends never ? unknown : {
12
+ [K in Key as K extends `${string}}` ? never : KeyName<K>]: KeyVal<K>;
12
13
  });
13
- export type PathArgsAndSearch<S extends string> = OnlyRequired<PathKeys<S>> extends never ? Record<string, number | string | boolean> | undefined : {
14
- [K in PathKeys<S> as OnlyRequired<K>]: string | number;
15
- } & Record<string, number | string>;
16
- /** Removes the last :token */
17
- export type ShortenPath<S extends string> = string extends S ? string : S extends `${infer B}:${infer R}` ? TrimColon<`${B}:${ShortenPath<R>}`> : '';
18
- type TrimColon<S extends string> = string extends S ? string : S extends `${infer R}:` ? R : S;
14
+ export type PathArgsAndSearch<S extends string> = Exclude<PathKeys<S>, `${string}}`> extends never ? Record<string, number | string | boolean> | undefined : {
15
+ [K in PathKeys<S> as K extends `${string}}` ? never : KeyName<K>]: KeyVal<K>;
16
+ } & Record<string, number | string | string[]>;
17
+ /** Removes the last :param or *wildcard token */
18
+ export type ShortenPath<S extends string> = string extends S ? string : S extends `${infer B}:${infer R}` ? TrimToken<`${B}:${ShortenPath<R>}`> : S extends `${infer B}*${infer R}` ? TrimToken<`${B}*${ShortenPath<R>}`> : '';
19
+ type TrimToken<S extends string> = string extends S ? string : S extends `${infer R}:` ? R : S extends `${infer R}*` ? R : S;
19
20
  export type ResourcePath = string;
20
21
  export {};
21
22
  //# sourceMappingURL=pathTypes.d.ts.map
@@ -15,7 +15,7 @@ export interface Extendable<O extends ResourceGenerics = {
15
15
  }, ExtendKey extends string, ExtendOptions extends PartialRestGenerics | {}>(this: R, key: ExtendKey, options: Readonly<RestEndpointExtendOptions<ExtendOptions, R['get'], EndpointToFunction<R['get']>> & ExtendOptions>): R & {
16
16
  [key in ExtendKey]: RestExtendedEndpoint<ExtendOptions, R['get']>;
17
17
  };
18
- extend<R extends ResourceInterface, Get extends PartialRestGenerics = any, GetList extends PartialRestGenerics = any, Update extends PartialRestGenerics = any, PartialUpdate extends PartialRestGenerics = any, Delete extends PartialRestGenerics = any>(this: R, options: ResourceEndpointExtensions<R, Get, GetList, Update, PartialUpdate, Delete>): CustomResource<R, O, Get, GetList, Update, PartialUpdate, Delete>;
18
+ extend<R extends ResourceInterface, Get extends PartialRestGenerics = {}, GetList extends PartialRestGenerics = {}, Update extends PartialRestGenerics = {}, PartialUpdate extends PartialRestGenerics = {}, Delete extends PartialRestGenerics = {}>(this: R, options: ResourceEndpointExtensions<R, Get, GetList, Update, PartialUpdate, Delete>): CustomResource<R, O, Get, GetList, Update, PartialUpdate, Delete>;
19
19
  extend<R extends ResourceInterface, T extends Record<string, EndpointInterface>>(this: R, extender: (baseResource: R) => T): ExtendedResource<R, T>;
20
20
  }
21
21
  //# sourceMappingURL=resourceExtendable.d.ts.map
@@ -71,9 +71,14 @@ export interface Resource<O extends ResourceGenerics = {
71
71
  path: ShortenPath<O['path']>;
72
72
  schema: schema.Collection<[
73
73
  O['schema']
74
- ], ParamToArgs<O['searchParams'] extends undefined ? KeysToArgs<ShortenPath<O['path']>> : O['searchParams'] & PathArgs<ShortenPath<O['path']>>>>;
74
+ ], ParamToArgs<[
75
+ O['searchParams']
76
+ ] extends [
77
+ undefined
78
+ ] ? KeysToArgs<ShortenPath<O['path']>> : O['searchParams'] & PathArgs<ShortenPath<O['path']>>>>;
75
79
  body: 'body' extends keyof O ? O['body'] : Partial<Denormalize<O['schema']>>;
76
80
  searchParams: O['searchParams'];
81
+ movePath: O['path'];
77
82
  } & Pick<O, 'paginationField'>> : GetEndpoint<{
78
83
  path: ShortenPath<O['path']>;
79
84
  schema: schema.Collection<[
@@ -81,6 +86,7 @@ export interface Resource<O extends ResourceGenerics = {
81
86
  ], ParamToArgs<(Record<string, number | string | boolean> | undefined) & PathArgs<ShortenPath<O['path']>>>>;
82
87
  body: 'body' extends keyof O ? O['body'] : Partial<Denormalize<O['schema']>>;
83
88
  searchParams: Record<string, number | string | boolean> | undefined;
89
+ movePath: O['path'];
84
90
  } & Pick<O, 'paginationField'>>;
85
91
  /** Create a new item (POST)
86
92
  *