@data-client/rest 0.15.7 → 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 (42) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/index.js +34 -18
  3. package/dist/index.umd.min.js +1 -1
  4. package/legacy/RestEndpoint.js +7 -4
  5. package/legacy/RestEndpointTypes.js +1 -1
  6. package/legacy/RestHelpers.js +29 -16
  7. package/legacy/pathTypes.js +1 -1
  8. package/legacy/resourceTypes.js +1 -1
  9. package/lib/RestEndpoint.js +7 -4
  10. package/lib/RestEndpointTypes.d.ts +27 -9
  11. package/lib/RestEndpointTypes.d.ts.map +1 -1
  12. package/lib/RestEndpointTypes.js +1 -1
  13. package/lib/RestHelpers.d.ts +2 -2
  14. package/lib/RestHelpers.d.ts.map +1 -1
  15. package/lib/RestHelpers.js +29 -16
  16. package/lib/pathTypes.d.ts +14 -13
  17. package/lib/pathTypes.d.ts.map +1 -1
  18. package/lib/pathTypes.js +1 -1
  19. package/lib/resourceTypes.d.ts +3 -1
  20. package/lib/resourceTypes.d.ts.map +1 -1
  21. package/lib/resourceTypes.js +1 -1
  22. package/package.json +5 -5
  23. package/src/RestEndpoint.js +10 -3
  24. package/src/RestEndpointTypes.ts +9 -9
  25. package/src/RestHelpers.ts +34 -26
  26. package/src/__tests__/Resource.test.ts +56 -0
  27. package/src/__tests__/RestEndpoint.ts +60 -2
  28. package/src/__tests__/__snapshots__/resource-construction.test.ts.snap +1 -1
  29. package/src/__tests__/hookifyResource.ts +7 -0
  30. package/src/__tests__/resource-construction.test.ts +7 -0
  31. package/src/pathTypes.ts +35 -23
  32. package/src/resourceTypes.ts +1 -1
  33. package/ts4.0/RestEndpointTypes.d.ts +45 -9
  34. package/ts4.0/RestHelpers.d.ts +2 -2
  35. package/ts4.0/pathTypes.d.ts +1 -1
  36. package/ts4.0/resourceExtendable.d.ts +1 -1
  37. package/ts4.0/resourceTypes.d.ts +5 -1
  38. package/ts4.1/RestEndpointTypes.d.ts +45 -9
  39. package/ts4.1/RestHelpers.d.ts +2 -2
  40. package/ts4.1/pathTypes.d.ts +14 -13
  41. package/ts4.1/resourceExtendable.d.ts +1 -1
  42. package/ts4.1/resourceTypes.d.ts +5 -1
@@ -134,19 +134,31 @@ export type RestEndpointExtendOptions<O extends PartialRestGenerics, E extends {
134
134
  type OptionsToRestEndpoint<O extends PartialRestGenerics, E extends RestInstanceBase & {
135
135
  body?: any;
136
136
  paginationField?: string;
137
- }, 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>, {
138
142
  path: Exclude<O['path'], undefined>;
139
143
  body: 'body' extends keyof O ? O['body'] : E['body'];
140
144
  searchParams: 'searchParams' extends keyof O ? O['searchParams'] : E['searchParams'];
141
145
  method: 'method' extends keyof O ? O['method'] : E['method'];
142
146
  paginationField: 'paginationField' extends keyof O ? O['paginationField'] : E['paginationField'];
143
- }> : '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>, {
144
152
  path: E['path'];
145
153
  body: O['body'];
146
154
  searchParams: 'searchParams' extends keyof O ? O['searchParams'] : E['searchParams'];
147
155
  method: 'method' extends keyof O ? O['method'] : E['method'];
148
156
  paginationField: 'paginationField' extends keyof O ? O['paginationField'] : Extract<E['paginationField'], string>;
149
- }> : '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>, {
150
162
  path: E['path'];
151
163
  body: E['body'];
152
164
  searchParams: O['searchParams'];
@@ -238,7 +250,11 @@ export type AddEndpoint<F extends FetchFunction = FetchFunction, S extends Schem
238
250
  } = {
239
251
  path: string;
240
252
  body: any;
241
- }> = 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'> & {
242
258
  method: 'POST';
243
259
  }>;
244
260
  export type RemoveEndpoint<F extends FetchFunction = FetchFunction, S extends Schema | undefined = any, O extends {
@@ -248,7 +264,11 @@ export type RemoveEndpoint<F extends FetchFunction = FetchFunction, S extends Sc
248
264
  } = {
249
265
  path: string;
250
266
  body: any;
251
- }> = 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'> & {
252
272
  method: 'PATCH';
253
273
  }>;
254
274
  export type MoveEndpoint<F extends FetchFunction = FetchFunction, S extends Schema | undefined = any, O extends {
@@ -293,14 +313,22 @@ export interface RestEndpointOptions<F extends FetchFunction = FetchFunction, S
293
313
  url?(...args: Parameters<F>): string;
294
314
  update?: EndpointUpdateFunction<F, S>;
295
315
  }
296
- 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 {
297
321
  sideEffect: true;
298
322
  } ? 'POST' : 'GET'>, O['process'] extends {} ? ReturnType<O['process']> : any>, O['schema']>;
299
323
  /** Simplifies endpoint definitions that follow REST patterns
300
324
  *
301
325
  * @see https://dataclient.io/rest/api/RestEndpoint
302
326
  */
303
- 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 {
304
332
  sideEffect: true;
305
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 & {
306
334
  method: O extends {
@@ -379,7 +407,11 @@ export type GetEndpoint<O extends {
379
407
  } = {
380
408
  path: string;
381
409
  schema: Schema;
382
- }> = 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 & {
383
415
  method: 'GET';
384
416
  }>;
385
417
  export type MutateEndpoint<O extends {
@@ -393,7 +425,11 @@ export type MutateEndpoint<O extends {
393
425
  path: string;
394
426
  body: any;
395
427
  schema: Schema;
396
- }> = 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 & {
397
433
  body: any;
398
434
  method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
399
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,7 +71,11 @@ 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'];
77
81
  movePath: O['path'];