ketting 7.0.1 → 7.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 (81) hide show
  1. package/LICENSE +1 -1
  2. package/browser/ketting.min.js +1 -1
  3. package/browser/ketting.min.js.map +1 -1
  4. package/dist/client.d.ts +24 -4
  5. package/dist/client.js +96 -29
  6. package/dist/client.js.map +1 -1
  7. package/dist/http/error.js +1 -1
  8. package/dist/http/error.js.map +1 -1
  9. package/dist/http/fetch-polyfill.js.map +1 -1
  10. package/dist/http/fetcher.js +3 -3
  11. package/dist/http/fetcher.js.map +1 -1
  12. package/dist/index.d.ts +3 -1
  13. package/dist/index.js +7 -5
  14. package/dist/index.js.map +1 -1
  15. package/dist/link.js +2 -2
  16. package/dist/link.js.map +1 -1
  17. package/dist/middlewares/accept-header.js +1 -1
  18. package/dist/middlewares/accept-header.js.map +1 -1
  19. package/dist/middlewares/cache.js +30 -25
  20. package/dist/middlewares/cache.js.map +1 -1
  21. package/dist/middlewares/warning.js +2 -1
  22. package/dist/middlewares/warning.js.map +1 -1
  23. package/dist/resource.d.ts +1 -1
  24. package/dist/resource.js +6 -6
  25. package/dist/resource.js.map +1 -1
  26. package/dist/src/client.d.ts +24 -4
  27. package/dist/src/index.d.ts +3 -1
  28. package/dist/src/resource.d.ts +1 -1
  29. package/dist/state/base-state.js +6 -4
  30. package/dist/state/base-state.js.map +1 -1
  31. package/dist/state/binary.js +1 -1
  32. package/dist/state/binary.js.map +1 -1
  33. package/dist/state/collection-json.js +1 -1
  34. package/dist/state/collection-json.js.map +1 -1
  35. package/dist/state/hal.js +13 -9
  36. package/dist/state/hal.js.map +1 -1
  37. package/dist/state/head.js +1 -1
  38. package/dist/state/head.js.map +1 -1
  39. package/dist/state/html.js +3 -3
  40. package/dist/state/html.js.map +1 -1
  41. package/dist/state/jsonapi.js +1 -1
  42. package/dist/state/jsonapi.js.map +1 -1
  43. package/dist/state/siren.js +3 -3
  44. package/dist/state/siren.js.map +1 -1
  45. package/dist/state/text.js +1 -1
  46. package/dist/state/text.js.map +1 -1
  47. package/dist/util/html.js +2 -2
  48. package/dist/util/html.js.map +1 -1
  49. package/dist/util/html.web.js +2 -2
  50. package/dist/util/html.web.js.map +1 -1
  51. package/dist/util/uri-template.js +1 -1
  52. package/dist/util/uri-template.js.map +1 -1
  53. package/dist/util/uri.js +3 -3
  54. package/dist/util/uri.js.map +1 -1
  55. package/dist/util/uri.web.js +1 -1
  56. package/dist/util/uri.web.js.map +1 -1
  57. package/package.json +11 -10
  58. package/src/action.ts +2 -2
  59. package/src/client.ts +119 -34
  60. package/src/field.ts +9 -9
  61. package/src/http/error.ts +7 -7
  62. package/src/http/fetch-polyfill.ts +4 -4
  63. package/src/http/fetcher.ts +3 -3
  64. package/src/index.ts +3 -5
  65. package/src/link.ts +10 -10
  66. package/src/middlewares/accept-header.ts +1 -1
  67. package/src/middlewares/cache.ts +31 -24
  68. package/src/middlewares/warning.ts +1 -0
  69. package/src/resource.ts +8 -8
  70. package/src/state/base-state.ts +5 -3
  71. package/src/state/collection-json.ts +28 -28
  72. package/src/state/hal.ts +12 -7
  73. package/src/state/interface.ts +2 -2
  74. package/src/state/jsonapi.ts +9 -9
  75. package/src/state/siren.ts +23 -23
  76. package/src/types.ts +1 -1
  77. package/src/util/html.ts +10 -10
  78. package/src/util/html.web.ts +7 -7
  79. package/src/util/uri.ts +1 -1
  80. package/src/util/uri.web.ts +2 -2
  81. package/changelog.md +0 -894
@@ -45,55 +45,55 @@ export const factory: StateFactory = async (client, uri, response): Promise<CjSt
45
45
  };
46
46
 
47
47
  type CjDocument = {
48
- collection: CjCollection,
48
+ collection: CjCollection;
49
49
  };
50
50
 
51
51
  type CjCollection = {
52
- version?: string,
53
- href?: string,
54
- links?: CjLink[],
55
- items?: CjItem[],
56
- queries?: CjQuery[],
57
- template?: CjTemplate,
58
- error?: CjError
52
+ version?: string;
53
+ href?: string;
54
+ links?: CjLink[];
55
+ items?: CjItem[];
56
+ queries?: CjQuery[];
57
+ template?: CjTemplate;
58
+ error?: CjError;
59
59
  };
60
60
 
61
61
  type CjError = {
62
- title?: string,
63
- code?: string,
64
- message?: string,
62
+ title?: string;
63
+ code?: string;
64
+ message?: string;
65
65
  };
66
66
 
67
67
  type CjTemplate = {
68
- data?: CjProperty[]
68
+ data?: CjProperty[];
69
69
  };
70
70
 
71
71
  type CjItem = {
72
- href?: string,
73
- data?: CjProperty[],
74
- links?: CjLink[],
72
+ href?: string;
73
+ data?: CjProperty[];
74
+ links?: CjLink[];
75
75
  };
76
76
 
77
77
  type CjProperty = {
78
- name: string,
79
- value?: string,
80
- prompt?: string
78
+ name: string;
79
+ value?: string;
80
+ prompt?: string;
81
81
  };
82
82
 
83
83
  type CjQuery = {
84
- href: string,
85
- rel: string,
86
- name?: string,
87
- prompt?: string,
88
- data?: CjProperty[]
84
+ href: string;
85
+ rel: string;
86
+ name?: string;
87
+ prompt?: string;
88
+ data?: CjProperty[];
89
89
  };
90
90
 
91
91
  type CjLink = {
92
- href: string,
93
- rel: string,
94
- name?: string,
95
- render?: 'image' | 'link',
96
- prompt?: string
92
+ href: string;
93
+ rel: string;
94
+ name?: string;
95
+ render?: 'image' | 'link';
96
+ prompt?: string;
97
97
  };
98
98
 
99
99
 
package/src/state/hal.ts CHANGED
@@ -204,7 +204,7 @@ function parseHalLink(context: string, rel: string, links: hal.HalLink[]): Link[
204
204
  */
205
205
  function parseHalEmbedded(client: Client, context: string, body: hal.HalResource, headers: Headers): HalState<any>[] {
206
206
 
207
- if (body._embedded === undefined) {
207
+ if (body._embedded === undefined || !body._embedded) {
208
208
  return [];
209
209
  }
210
210
 
@@ -222,10 +222,14 @@ function parseHalEmbedded(client: Client, context: string, body: hal.HalResource
222
222
  }
223
223
  for (const embeddedItem of embeddedList) {
224
224
 
225
- if (embeddedItem._links === undefined || embeddedItem._links.self === undefined || Array.isArray(embeddedItem._links.self)) {
226
- // Skip any embedded without a self link.
225
+ if (embeddedItem._links?.self?.href === undefined) {
226
+ // eslint-disable-next-line no-console
227
+ console.warn('An item in _embedded was ignored. Each item must have a single "self" link');
227
228
  continue;
228
229
  }
230
+
231
+ const embeddedSelf = resolve(context, embeddedItem._links.self.href);
232
+
229
233
  // Remove _links and _embedded from body
230
234
  const {
231
235
  _embedded,
@@ -235,16 +239,16 @@ function parseHalEmbedded(client: Client, context: string, body: hal.HalResource
235
239
 
236
240
  result.push(new HalState({
237
241
  client,
238
- uri: resolve(context, embeddedItem._links.self.href),
242
+ uri: embeddedSelf,
239
243
  data: newBody,
240
244
  headers: new Headers({
241
245
  'Content-Type': headers.get('Content-Type')!,
242
246
  }),
243
- links: new Links(context, parseHalLinks(context, embeddedItem)),
247
+ links: new Links(embeddedSelf, parseHalLinks(context, embeddedItem)),
244
248
  // Parsing nested embedded items. Note that we assume that the base url is relative to
245
249
  // the outermost parent, not relative to the embedded item. HAL is not clear on this.
246
- embedded: parseHalEmbedded(client, context, embeddedItem, headers),
247
- actions: parseHalForms(context, embeddedItem)
250
+ embedded: parseHalEmbedded(client, embeddedSelf, embeddedItem, headers),
251
+ actions: parseHalForms(embeddedSelf, embeddedItem)
248
252
  }));
249
253
  }
250
254
  }
@@ -284,6 +288,7 @@ function parseHalField(halField: hal.HalFormsProperty): Field {
284
288
  const baseField = {
285
289
  name: halField.name,
286
290
  type: 'select' as const,
291
+ label: halField.prompt,
287
292
  required: halField.required || false,
288
293
  readOnly: halField.readOnly || false,
289
294
  multiple: halField.options.multiple as any,
@@ -15,12 +15,12 @@ export type State<T = any> = {
15
15
  *
16
16
  * In the case of a JSON response, this will be deserialized
17
17
  */
18
- data: T
18
+ data: T;
19
19
 
20
20
  /**
21
21
  * All links associated with the resource.
22
22
  */
23
- links: Links,
23
+ links: Links;
24
24
 
25
25
  /**
26
26
  * The full list of HTTP headers that were sent with the response.
@@ -36,9 +36,9 @@ type JsonApiLink = string | { href: string };
36
36
  * or on resource objects.
37
37
  */
38
38
  type JsonApiLinksObject = {
39
- self?: JsonApiLink,
40
- profile?: JsonApiLink,
41
- [rel: string]: JsonApiLink | JsonApiLink[] | undefined
39
+ self?: JsonApiLink;
40
+ profile?: JsonApiLink;
41
+ [rel: string]: JsonApiLink | JsonApiLink[] | undefined;
42
42
  };
43
43
 
44
44
  /**
@@ -46,9 +46,9 @@ type JsonApiLinksObject = {
46
46
  * we care about.
47
47
  */
48
48
  type JsonApiResource = {
49
- type: string,
50
- id: string,
51
- links?: JsonApiLinksObject,
49
+ type: string;
50
+ id: string;
51
+ links?: JsonApiLinksObject;
52
52
  };
53
53
 
54
54
 
@@ -58,9 +58,9 @@ type JsonApiResource = {
58
58
  * untyped.
59
59
  */
60
60
  type JsonApiTopLevelObject = {
61
- links?: JsonApiLinksObject,
62
- data: JsonApiResource | JsonApiResource[] | null,
63
- [s: string]: any
61
+ links?: JsonApiLinksObject;
62
+ data: JsonApiResource | JsonApiResource[] | null;
63
+ [s: string]: any;
64
64
  };
65
65
 
66
66
  /**
@@ -66,14 +66,14 @@ type SirenProperties = Record<string, any> | undefined;
66
66
 
67
67
  type SirenEntity<T extends SirenProperties> = {
68
68
 
69
- class?: string[],
69
+ class?: string[];
70
70
 
71
- properties: T
72
- entities?: (SirenLink | SirenSubEntity)[],
71
+ properties: T;
72
+ entities?: (SirenLink | SirenSubEntity)[];
73
73
 
74
- links?: SirenLink[],
75
- actions?: SirenAction[],
76
- title?: string,
74
+ links?: SirenLink[];
75
+ actions?: SirenAction[];
76
+ title?: string;
77
77
 
78
78
  };
79
79
 
@@ -81,30 +81,30 @@ type SirenSubEntity = SirenEntity<any> & { rel: string[] };
81
81
 
82
82
  type SirenLink = {
83
83
 
84
- class?: string[],
85
- rel: string[],
86
- href: string,
87
- type?: string,
88
- title?: string,
84
+ class?: string[];
85
+ rel: string[];
86
+ href: string;
87
+ type?: string;
88
+ title?: string;
89
89
 
90
90
  };
91
91
 
92
92
  type SirenAction = {
93
- name: string,
94
- class?: string[],
95
- method?: string,
96
- href: string,
97
- title?: string,
98
- type?: string,
99
- fields?: SirenField[],
93
+ name: string;
94
+ class?: string[];
95
+ method?: string;
96
+ href: string;
97
+ title?: string;
98
+ type?: string;
99
+ fields?: SirenField[];
100
100
  };
101
101
 
102
102
  type SirenField = {
103
- name: string,
104
- class?: string[],
105
- type?: 'hidden' | 'text' | 'search' | 'tel' | 'url' | 'email' | 'password' | 'datetime' | 'date' | 'month' | 'week' | 'time' | 'datetime-local' | 'number' | 'range' | 'color' | 'checkbox' | 'radio' | 'file'
106
- value?: string,
107
- title?: string
103
+ name: string;
104
+ class?: string[];
105
+ type?: 'hidden' | 'text' | 'search' | 'tel' | 'url' | 'email' | 'password' | 'datetime' | 'date' | 'month' | 'week' | 'time' | 'datetime-local' | 'number' | 'range' | 'color' | 'checkbox' | 'radio' | 'file';
106
+ value?: string;
107
+ title?: string;
108
108
  };
109
109
 
110
110
  function parseSirenLinks(contextUri: string, body: SirenEntity<any>): Link[] {
package/src/types.ts CHANGED
@@ -29,7 +29,7 @@ export type RequestOptions<T = any> = {
29
29
  *
30
30
  * If this is not set, we'll fall back to 'headers'
31
31
  */
32
- getContentHeaders?: () => HttpHeaders | Headers,
32
+ getContentHeaders?: () => HttpHeaders | Headers;
33
33
 
34
34
  /**
35
35
  * Full list of HTTP headers.
package/src/util/html.ts CHANGED
@@ -3,17 +3,17 @@ import { Link } from '../link';
3
3
  import { resolve } from './uri';
4
4
 
5
5
  export type HtmlForm = {
6
- action: string,
7
- method: string | null,
8
- enctype: string | null,
9
- rel: string | null,
10
- id: string | null,
6
+ action: string;
7
+ method: string | null;
8
+ enctype: string | null;
9
+ rel: string | null;
10
+ id: string | null;
11
11
  }
12
12
 
13
13
  type ParseHtmlResult = {
14
14
 
15
- links: Link[],
16
- forms: HtmlForm[],
15
+ links: Link[];
16
+ forms: HtmlForm[];
17
17
 
18
18
  }
19
19
 
@@ -56,16 +56,16 @@ function parseLink(contextUri: string, node: sax.Tag): Link[] {
56
56
  return [];
57
57
  }
58
58
 
59
- const rels = <string> node.attributes.REL;
59
+ const rels = node.attributes.REL as string;
60
60
 
61
61
  const links: Link[] = [];
62
62
  for (const rel of rels.split(' ')) {
63
63
 
64
- const type = <string>node.attributes.TYPE;
64
+ const type = node.attributes.TYPE as string;
65
65
  const link: Link = {
66
66
  rel,
67
67
  context: contextUri,
68
- href: <string> node.attributes.HREF,
68
+ href: node.attributes.HREF as string,
69
69
  };
70
70
  if (type) link.type = type;
71
71
  links.push(link);
@@ -2,17 +2,17 @@ import { Link } from '../link';
2
2
  import { resolve } from './uri';
3
3
 
4
4
  export type HtmlForm = {
5
- action: string,
6
- method: string | null,
7
- enctype: string | null,
8
- rel: string | null,
9
- id: string | null,
5
+ action: string;
6
+ method: string | null;
7
+ enctype: string | null;
8
+ rel: string | null;
9
+ id: string | null;
10
10
  }
11
11
 
12
12
  type ParseHtmlResult = {
13
13
 
14
- links: Link[],
15
- forms: HtmlForm[],
14
+ links: Link[];
15
+ forms: HtmlForm[];
16
16
 
17
17
  }
18
18
  export function parseHtml(contextUri: string, body: string): ParseHtmlResult {
package/src/util/uri.ts CHANGED
@@ -2,7 +2,7 @@ import { parse as p, resolve as r } from 'url';
2
2
  import { Link } from '../link';
3
3
 
4
4
  type UrlParts = {
5
- host?: string|null,
5
+ host?: string|null;
6
6
  };
7
7
 
8
8
  /**
@@ -1,7 +1,7 @@
1
1
  import { Link } from '../link';
2
2
 
3
3
  type UrlParts = {
4
- host?: string,
4
+ host?: string;
5
5
  };
6
6
 
7
7
  /**
@@ -32,7 +32,7 @@ export function resolve(base: string|Link, relative?: string): string {
32
32
 
33
33
  const doc = document;
34
34
  const oldBase = doc.getElementsByTagName('base')[0];
35
- const oldHref = oldBase && oldBase.href;
35
+ const oldHref = oldBase?.href;
36
36
  const docHead = doc.head || doc.getElementsByTagName('head')[0];
37
37
  const ourBase = oldBase || docHead.appendChild(doc.createElement('base'));
38
38
  const resolver = doc.createElement('a');