@data-client/rest 0.18.0 → 0.18.2

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 (73) hide show
  1. package/CHANGELOG.md +198 -1
  2. package/dist/index.js +16 -7
  3. package/dist/index.umd.min.js +1 -1
  4. package/legacy/RestEndpoint.js +6 -5
  5. package/legacy/RestEndpointTypes.js +1 -1
  6. package/legacy/extractCollection.js +3 -1
  7. package/legacy/paramsToString.js +1 -1
  8. package/legacy/paramsToString.native.js +1 -1
  9. package/legacy/pathTypes.js +1 -1
  10. package/legacy/resource.js +10 -4
  11. package/legacy/resourceExtendable.js +1 -1
  12. package/legacy/resourceExtensionTypes.js +1 -1
  13. package/legacy/resourceTypes.js +1 -1
  14. package/lib/NetworkError.d.ts.map +1 -1
  15. package/lib/RestEndpoint.js +6 -5
  16. package/lib/RestEndpointTypes.d.ts +49 -20
  17. package/lib/RestEndpointTypes.d.ts.map +1 -1
  18. package/lib/RestEndpointTypes.js +1 -1
  19. package/lib/extractCollection.d.ts +8 -1
  20. package/lib/extractCollection.d.ts.map +1 -1
  21. package/lib/extractCollection.js +3 -1
  22. package/lib/paramsToString.d.ts.map +1 -1
  23. package/lib/paramsToString.js +1 -1
  24. package/lib/paramsToString.native.d.ts.map +1 -1
  25. package/lib/paramsToString.native.js +1 -1
  26. package/lib/pathTypes.d.ts +33 -7
  27. package/lib/pathTypes.d.ts.map +1 -1
  28. package/lib/pathTypes.js +1 -1
  29. package/lib/resource.d.ts +1 -1
  30. package/lib/resource.d.ts.map +1 -1
  31. package/lib/resource.js +10 -4
  32. package/lib/resourceExtendable.d.ts +4 -4
  33. package/lib/resourceExtendable.d.ts.map +1 -1
  34. package/lib/resourceExtendable.js +1 -1
  35. package/lib/resourceExtensionTypes.d.ts +7 -7
  36. package/lib/resourceExtensionTypes.d.ts.map +1 -1
  37. package/lib/resourceExtensionTypes.js +1 -1
  38. package/lib/resourceTypes.d.ts +8 -2
  39. package/lib/resourceTypes.d.ts.map +1 -1
  40. package/lib/resourceTypes.js +1 -1
  41. package/lib/test-fixtures.d.ts +7 -7
  42. package/lib/test-fixtures.d.ts.map +1 -1
  43. package/package.json +7 -7
  44. package/src/RestEndpoint.js +8 -7
  45. package/src/RestEndpointTypes.ts +116 -53
  46. package/src/__tests__/RestEndpoint.ts +23 -7
  47. package/src/__tests__/__snapshots__/RestEndpoint.ts.snap +1 -1
  48. package/src/__tests__/resource-construction.test.ts +47 -0
  49. package/src/extractCollection.ts +3 -0
  50. package/src/paramsToString.native.ts +1 -5
  51. package/src/paramsToString.ts +1 -5
  52. package/src/pathTypes.ts +105 -31
  53. package/src/resource.ts +11 -6
  54. package/src/resourceExtendable.ts +15 -11
  55. package/src/resourceExtensionTypes.ts +16 -10
  56. package/src/resourceTypes.ts +6 -4
  57. package/ts4.0/RestEndpointTypes.d.ts +57 -22
  58. package/ts4.0/extractCollection.d.ts +8 -1
  59. package/ts4.0/mapCollection.d.ts +11 -16
  60. package/ts4.0/resource.d.ts +1 -1
  61. package/ts4.0/resourceExtendable.d.ts +4 -4
  62. package/ts4.0/resourceExtensionTypes.d.ts +7 -7
  63. package/ts4.0/resourceTypes.d.ts +8 -2
  64. package/ts4.0/test-fixtures.d.ts +7 -7
  65. package/ts4.1/RestEndpointTypes.d.ts +57 -22
  66. package/ts4.1/extractCollection.d.ts +8 -1
  67. package/ts4.1/mapCollection.d.ts +11 -16
  68. package/ts4.1/pathTypes.d.ts +33 -7
  69. package/ts4.1/resource.d.ts +1 -1
  70. package/ts4.1/resourceExtendable.d.ts +4 -4
  71. package/ts4.1/resourceExtensionTypes.d.ts +7 -7
  72. package/ts4.1/resourceTypes.d.ts +8 -2
  73. package/ts4.1/test-fixtures.d.ts +7 -7
@@ -1,5 +1,5 @@
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>;
1
+ type CleanKey<S extends string> = S extends `"${string}"` ? S extends `"${infer K}"` ? K : S : S;
2
+ type KeyName<K extends string> = K extends `*${string}` | `${string}}` ? CleanKey<K extends `*${infer N}}` ? N : K extends `*${infer N}` ? N : K extends `${infer N}}` ? N : K> : CleanKey<K>;
3
3
  type KeyVal<K extends string> = K extends `*${string}` ? string[] : string | number;
4
4
  /** Parameters for a given path */
5
5
  export type PathArgs<S extends string> = unknown extends S ? any : PathKeys<S> extends never ? unknown : KeysToArgs<PathKeys<S>>;
@@ -7,13 +7,39 @@ export type PathArgs<S extends string> = unknown extends S ? any : PathKeys<S> e
7
7
  * preventing `(params, body) | (body)` union overloads in ParamFetchWithBody. */
8
8
  export type SoftPathArgs<P extends string> = unknown extends P ? any : string extends P ? unknown : PathArgs<P>;
9
9
  /** Computes the union of keys for a path string */
10
- export type PathKeys<S extends string> = string extends S ? string : S extends `${infer A}\\${':' | '*' | '}'}${infer B}` ? PathKeys<A> | PathKeys<B> : Splits<S, ':'> | Splits<S, '*'>;
11
- 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;
12
- export type KeysToArgs<Key extends string> = {
10
+ export type PathKeys<S extends string> = string extends S ? string : S extends `${string}\\${string}` ? S extends `${infer A}\\${':' | '*' | '}'}${infer B}` ? PathKeys<A> | PathKeys<B> : ColonSplits<S> | StarSplits<S> : ColonSplits<S> | StarSplits<S>;
11
+ /** Characters that end a :param or *wildcard token */
12
+ type PathDelimiter = '/' | '\\' | '%' | '&' | '*' | ':' | '{' | ';' | ',' | '!' | '@';
13
+ /** Token after every ':' in S */
14
+ type ColonSplits<S extends string> = S extends `${string}:${infer K}` ? PathToken<K> | ColonSplits<K> : never;
15
+ /** `*`-prefixed token after every '*' in S */
16
+ type StarSplits<S extends string> = S extends `${string}*${infer K}` ? `*${PathToken<K>}` | StarSplits<K> : never;
17
+ /** Prefix of K up to (excluding) its first PathDelimiter.
18
+ *
19
+ * Fast path: no delimiter at all, or the first '/' ends a delimiter-free token.
20
+ * The delimiter-union templates without `infer` are matched without instantiation. */
21
+ type PathToken<K extends string> = K extends `${string}${PathDelimiter}${string}` ? K extends `${infer H}/${string}` ? H extends `${string}${PathDelimiter}${string}` ? PathTokenSlow<H> : H : PathTokenSlow<K> : K;
22
+ /** Cuts at the first occurrence of each delimiter (union); recursing on each
23
+ * candidate converges on the shortest, delimiter-free prefix. */
24
+ type PathTokenSlow<K extends string> = K extends `${infer H}${PathDelimiter}${string}` ? PathToken<H> : K;
25
+ export type KeysToArgs<Key extends string> = OptionalArgs<Key> & (RequiredPathKeys<Key> extends never ? unknown : RequiredArgs<Key>);
26
+ /** Wide keys (`string`, template patterns) keep the original key-remapping
27
+ * form so index signatures (and their `keyof`) stay exactly the same. */
28
+ type HasWideKey<Key extends string> = true extends (Key extends string ? {} extends {
29
+ [P in Key]: 1;
30
+ } ? true : never : never) ? true : false;
31
+ type OptionalArgs<Key extends string> = HasWideKey<Key> extends true ? {
13
32
  [K in Key as K extends `${string}}` ? KeyName<K> : never]?: KeyVal<K>;
14
- } & (Exclude<Key, `${string}}`> extends never ? unknown : {
33
+ } : {
34
+ [N in KeyName<OptionalPathKeys<Key>>]?: (N extends KeyName<Extract<OptionalPathKeys<Key>, `*${string}`>> ? string[] : never) | (N extends KeyName<Exclude<OptionalPathKeys<Key>, `*${string}`>> ? string | number : never);
35
+ };
36
+ type RequiredArgs<Key extends string> = HasWideKey<Key> extends true ? {
15
37
  [K in Key as K extends `${string}}` ? never : KeyName<K>]: KeyVal<K>;
16
- });
38
+ } : {
39
+ [N in KeyName<RequiredPathKeys<Key>>]: (N extends KeyName<Extract<RequiredPathKeys<Key>, `*${string}`>> ? string[] : never) | (N extends KeyName<Exclude<RequiredPathKeys<Key>, `*${string}`>> ? string | number : never);
40
+ };
41
+ type OptionalPathKeys<Key extends string> = Extract<Key, `${string}}`>;
42
+ type RequiredPathKeys<Key extends string> = Exclude<Key, `${string}}`>;
17
43
  export type PathArgsAndSearch<S extends string> = unknown extends S ? any : Exclude<PathKeys<S>, `${string}}`> extends never ? Record<string, number | string | boolean> | undefined : {
18
44
  [K in PathKeys<S> as K extends `${string}}` ? never : KeyName<K>]: KeyVal<K>;
19
45
  } & Record<string, number | string | string[]>;
@@ -3,5 +3,5 @@ import { ResourceGenerics, ResourceOptions, Resource } from './resourceTypes.js'
3
3
  *
4
4
  * @see https://dataclient.io/rest/api/resource
5
5
  */
6
- export default function resource<O extends ResourceGenerics>({ path, schema, Endpoint, Collection, nonFilterArgumentKeys, optimistic, paginationField, ...extraOptions }: Readonly<O> & ResourceOptions): Resource<O>;
6
+ export default function resource<O extends ResourceGenerics>({ path, schema, Endpoint, Collection, nonFilterArgumentKeys, optimistic, paginationField, ...extraOptions }: Readonly<O> & O & ResourceOptions): Resource<O>;
7
7
  //# sourceMappingURL=resource.d.ts.map
@@ -2,20 +2,20 @@ import type { EndpointInterface, EndpointToFunction } from '@data-client/endpoin
2
2
  import type { ResourcePath } from './pathTypes.js';
3
3
  import type { ResourceExtension, ResourceEndpointExtensions, CustomResource, ExtendedResource } from './resourceExtensionTypes.js';
4
4
  import type { ResourceGenerics, ResourceInterface } from './resourceTypes.js';
5
- import type { PartialRestGenerics, RestEndpointExtendOptions, RestExtendedEndpoint, RestInstanceBase } from './RestEndpoint.js';
5
+ import type { ExtendableRestGenerics, RestEndpointExtendOptions, RestExtendedEndpoint, RestInstanceBase } from './RestEndpoint.js';
6
6
  export interface Extendable<O extends ResourceGenerics = {
7
7
  path: ResourcePath;
8
8
  schema: any;
9
9
  }> {
10
10
  extend<R extends {
11
11
  [K in ExtendKey]: RestInstanceBase;
12
- }, ExtendKey extends Exclude<Extract<keyof R, string>, 'extend'>, ExtendOptions extends PartialRestGenerics | {}>(this: R, key: ExtendKey, options: Readonly<RestEndpointExtendOptions<ExtendOptions, R[ExtendKey], EndpointToFunction<R[ExtendKey]>> & ExtendOptions>): ResourceExtension<R, ExtendKey, ExtendOptions>;
12
+ }, ExtendKey extends Exclude<Extract<keyof R, string>, 'extend'>, ExtendOptions extends ExtendableRestGenerics | {}>(this: R, key: ExtendKey, options: Readonly<RestEndpointExtendOptions<ExtendOptions, R[ExtendKey], EndpointToFunction<R[ExtendKey]>> & ExtendOptions> & ExtendOptions): ResourceExtension<R, ExtendKey, ExtendOptions>;
13
13
  extend<R extends {
14
14
  get: RestInstanceBase;
15
- }, ExtendKey extends string, ExtendOptions extends PartialRestGenerics | {}>(this: R, key: ExtendKey, options: Readonly<RestEndpointExtendOptions<ExtendOptions, R['get'], EndpointToFunction<R['get']>> & ExtendOptions>): R & {
15
+ }, ExtendKey extends string, ExtendOptions extends ExtendableRestGenerics | {}>(this: R, key: ExtendKey, options: Readonly<RestEndpointExtendOptions<ExtendOptions, R['get'], EndpointToFunction<R['get']>> & ExtendOptions> & ExtendOptions): R & {
16
16
  [key in ExtendKey]: RestExtendedEndpoint<ExtendOptions, R['get']>;
17
17
  };
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>;
18
+ extend<R extends ResourceInterface, Get extends ExtendableRestGenerics = {}, GetList extends ExtendableRestGenerics = {}, Update extends ExtendableRestGenerics = {}, PartialUpdate extends ExtendableRestGenerics = {}, Delete extends ExtendableRestGenerics = {}>(this: R, options: ResourceEndpointExtensions<R, Get, GetList, Update, PartialUpdate, Delete>): CustomResource<R, O, Get, GetList, Update, PartialUpdate, Delete> & Omit<R, keyof ResourceInterface | 'extend'>;
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
@@ -3,7 +3,7 @@ import { OptionsToFunction } from './OptionsToFunction.js';
3
3
  import type { ResourcePath } from './pathTypes.js';
4
4
  import { Extendable } from './resourceExtendable.js';
5
5
  import { ResourceGenerics, ResourceInterface } from './resourceTypes.js';
6
- import type { PartialRestGenerics, RestExtendedEndpoint, RestInstanceBase, RestEndpointOptions } from './RestEndpoint.js';
6
+ import type { ExtendableRestGenerics, PartialRestGenerics, RestExtendedEndpoint, RestInstanceBase, RestEndpointOptions } from './RestEndpoint.js';
7
7
  export type ResourceExtension<R extends {
8
8
  [K in ExtendKey]: RestInstanceBase;
9
9
  }, ExtendKey extends Exclude<Extract<keyof R, string>, 'extend'>, O extends PartialRestGenerics | {}> = {
@@ -23,11 +23,11 @@ export interface CustomResource<R extends ResourceInterface, O extends ResourceG
23
23
  delete: unknown extends Delete ? R['delete'] : PartialRestGenerics extends Delete ? R['delete'] : RestExtendedEndpoint<Delete, R['delete']>;
24
24
  }
25
25
  export type ExtendedResource<R extends ResourceInterface, T extends Record<string, EndpointInterface>> = Omit<R, keyof T> & T;
26
- export interface ResourceEndpointExtensions<R extends ResourceInterface, Get extends PartialRestGenerics = {}, GetList extends PartialRestGenerics = {}, Update extends PartialRestGenerics = {}, PartialUpdate extends PartialRestGenerics = {}, Delete extends PartialRestGenerics = {}> {
27
- readonly get?: RestEndpointOptions<unknown extends Get ? EndpointToFunction<R['get']> : OptionsToFunction<Get, R['get'], EndpointToFunction<R['get']>>, R['get']['schema']> & Readonly<Get>;
28
- readonly getList?: RestEndpointOptions<unknown extends GetList ? EndpointToFunction<R['getList']> : OptionsToFunction<GetList, R['getList'], EndpointToFunction<R['getList']>>, R['getList']['schema']> & Readonly<GetList>;
29
- readonly update?: RestEndpointOptions<unknown extends Update ? EndpointToFunction<R['update']> : OptionsToFunction<Update, R['update'], EndpointToFunction<R['update']>>, R['update']['schema']> & Readonly<Update>;
30
- readonly partialUpdate?: RestEndpointOptions<unknown extends PartialUpdate ? EndpointToFunction<R['partialUpdate']> : OptionsToFunction<PartialUpdate, R['partialUpdate'], EndpointToFunction<R['partialUpdate']>>, R['partialUpdate']['schema']> & Readonly<PartialUpdate>;
31
- readonly delete?: RestEndpointOptions<unknown extends Delete ? EndpointToFunction<R['delete']> : OptionsToFunction<Delete, R['delete'], EndpointToFunction<R['delete']>>, R['delete']['schema']> & Readonly<Delete>;
26
+ export interface ResourceEndpointExtensions<R extends ResourceInterface, Get extends ExtendableRestGenerics = {}, GetList extends ExtendableRestGenerics = {}, Update extends ExtendableRestGenerics = {}, PartialUpdate extends ExtendableRestGenerics = {}, Delete extends ExtendableRestGenerics = {}> {
27
+ readonly get?: RestEndpointOptions<unknown extends Get ? EndpointToFunction<R['get']> : OptionsToFunction<Get, R['get'], EndpointToFunction<R['get']>>, R['get']['schema']> & Readonly<Get> & Get;
28
+ readonly getList?: RestEndpointOptions<unknown extends GetList ? EndpointToFunction<R['getList']> : OptionsToFunction<GetList, R['getList'], EndpointToFunction<R['getList']>>, R['getList']['schema']> & Readonly<GetList> & GetList;
29
+ readonly update?: RestEndpointOptions<unknown extends Update ? EndpointToFunction<R['update']> : OptionsToFunction<Update, R['update'], EndpointToFunction<R['update']>>, R['update']['schema']> & Readonly<Update> & Update;
30
+ readonly partialUpdate?: RestEndpointOptions<unknown extends PartialUpdate ? EndpointToFunction<R['partialUpdate']> : OptionsToFunction<PartialUpdate, R['partialUpdate'], EndpointToFunction<R['partialUpdate']>>, R['partialUpdate']['schema']> & Readonly<PartialUpdate> & PartialUpdate;
31
+ readonly delete?: RestEndpointOptions<unknown extends Delete ? EndpointToFunction<R['delete']> : OptionsToFunction<Delete, R['delete'], EndpointToFunction<R['delete']>>, R['delete']['schema']> & Readonly<Delete> & Delete;
32
32
  }
33
33
  //# sourceMappingURL=resourceExtensionTypes.d.ts.map
@@ -99,14 +99,14 @@ export interface Resource<O extends ResourceGenerics = {
99
99
  schema: schema.Collection<[
100
100
  O['schema']
101
101
  ]>['push'];
102
- body: 'body' extends keyof O ? O['body'] : Partial<Denormalize<O['schema']>>;
102
+ body: CreateBody<O> | CreateBody<O>[] | FormData;
103
103
  searchParams: O['searchParams'];
104
104
  }> : MutateEndpoint<{
105
105
  path: ShortenPath<O['path']>;
106
106
  schema: schema.Collection<[
107
107
  O['schema']
108
108
  ]>['push'];
109
- body: 'body' extends keyof O ? O['body'] : Partial<Denormalize<O['schema']>>;
109
+ body: CreateBody<O> | CreateBody<O>[] | FormData;
110
110
  }>;
111
111
  /** Update an item (PUT)
112
112
  *
@@ -151,4 +151,10 @@ export interface ResourceInterface {
151
151
  partialUpdate: RestInstanceBase;
152
152
  delete: RestInstanceBase;
153
153
  }
154
+ /** Matches getList.push's body, since create is getList.push at runtime */
155
+ type CreateBody<O extends {
156
+ body?: any;
157
+ schema: Schema;
158
+ }> = 'body' extends keyof O ? O['body'] : Partial<Denormalize<O['schema']>>;
159
+ export {};
154
160
  //# sourceMappingURL=resourceTypes.d.ts.map
@@ -19,10 +19,10 @@ export declare const articlesPages: {
19
19
  content: string;
20
20
  tags: string[];
21
21
  } | {
22
+ tags?: undefined;
22
23
  id: number;
23
24
  title: string;
24
25
  content: string;
25
- tags?: undefined;
26
26
  })[];
27
27
  };
28
28
  export declare const users: {
@@ -42,6 +42,7 @@ export declare const nested: ({
42
42
  email?: undefined;
43
43
  };
44
44
  } | {
45
+ tags?: undefined;
45
46
  id: number;
46
47
  title: string;
47
48
  content: string;
@@ -50,7 +51,6 @@ export declare const nested: ({
50
51
  username: string;
51
52
  email: string;
52
53
  };
53
- tags?: undefined;
54
54
  })[];
55
55
  export declare const moreNested: ({
56
56
  id: number;
@@ -58,11 +58,12 @@ export declare const moreNested: ({
58
58
  content: string;
59
59
  tags: string[];
60
60
  author: {
61
+ email?: undefined;
61
62
  id: number;
62
63
  username: string;
63
- email?: undefined;
64
64
  };
65
65
  } | {
66
+ tags?: undefined;
66
67
  id: number;
67
68
  title: string;
68
69
  content: string;
@@ -71,7 +72,6 @@ export declare const moreNested: ({
71
72
  username: string;
72
73
  email: string;
73
74
  };
74
- tags?: undefined;
75
75
  })[];
76
76
  export declare const valuesFixture: {
77
77
  first: {
@@ -101,6 +101,7 @@ export declare const paginatedFirstPage: {
101
101
  email?: undefined;
102
102
  };
103
103
  } | {
104
+ tags?: undefined;
104
105
  id: number;
105
106
  title: string;
106
107
  content: string;
@@ -109,7 +110,6 @@ export declare const paginatedFirstPage: {
109
110
  username: string;
110
111
  email: string;
111
112
  };
112
- tags?: undefined;
113
113
  })[];
114
114
  };
115
115
  };
@@ -121,11 +121,12 @@ export declare const paginatedSecondPage: {
121
121
  content: string;
122
122
  tags: string[];
123
123
  author: {
124
+ email?: undefined;
124
125
  id: number;
125
126
  username: string;
126
- email?: undefined;
127
127
  };
128
128
  } | {
129
+ tags?: undefined;
129
130
  id: number;
130
131
  title: string;
131
132
  content: string;
@@ -134,7 +135,6 @@ export declare const paginatedSecondPage: {
134
135
  username: string;
135
136
  email: string;
136
137
  };
137
- tags?: undefined;
138
138
  })[];
139
139
  };
140
140
  };