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.
- package/LICENSE +1 -1
- package/browser/ketting.min.js +1 -1
- package/browser/ketting.min.js.map +1 -1
- package/dist/client.d.ts +24 -4
- package/dist/client.js +96 -29
- package/dist/client.js.map +1 -1
- package/dist/http/error.js +1 -1
- package/dist/http/error.js.map +1 -1
- package/dist/http/fetch-polyfill.js.map +1 -1
- package/dist/http/fetcher.js +3 -3
- package/dist/http/fetcher.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/link.js +2 -2
- package/dist/link.js.map +1 -1
- package/dist/middlewares/accept-header.js +1 -1
- package/dist/middlewares/accept-header.js.map +1 -1
- package/dist/middlewares/cache.js +30 -25
- package/dist/middlewares/cache.js.map +1 -1
- package/dist/middlewares/warning.js +2 -1
- package/dist/middlewares/warning.js.map +1 -1
- package/dist/resource.d.ts +1 -1
- package/dist/resource.js +6 -6
- package/dist/resource.js.map +1 -1
- package/dist/src/client.d.ts +24 -4
- package/dist/src/index.d.ts +3 -1
- package/dist/src/resource.d.ts +1 -1
- package/dist/state/base-state.js +6 -4
- package/dist/state/base-state.js.map +1 -1
- package/dist/state/binary.js +1 -1
- package/dist/state/binary.js.map +1 -1
- package/dist/state/collection-json.js +1 -1
- package/dist/state/collection-json.js.map +1 -1
- package/dist/state/hal.js +13 -9
- package/dist/state/hal.js.map +1 -1
- package/dist/state/head.js +1 -1
- package/dist/state/head.js.map +1 -1
- package/dist/state/html.js +3 -3
- package/dist/state/html.js.map +1 -1
- package/dist/state/jsonapi.js +1 -1
- package/dist/state/jsonapi.js.map +1 -1
- package/dist/state/siren.js +3 -3
- package/dist/state/siren.js.map +1 -1
- package/dist/state/text.js +1 -1
- package/dist/state/text.js.map +1 -1
- package/dist/util/html.js +2 -2
- package/dist/util/html.js.map +1 -1
- package/dist/util/html.web.js +2 -2
- package/dist/util/html.web.js.map +1 -1
- package/dist/util/uri-template.js +1 -1
- package/dist/util/uri-template.js.map +1 -1
- package/dist/util/uri.js +3 -3
- package/dist/util/uri.js.map +1 -1
- package/dist/util/uri.web.js +1 -1
- package/dist/util/uri.web.js.map +1 -1
- package/package.json +11 -10
- package/src/action.ts +2 -2
- package/src/client.ts +119 -34
- package/src/field.ts +9 -9
- package/src/http/error.ts +7 -7
- package/src/http/fetch-polyfill.ts +4 -4
- package/src/http/fetcher.ts +3 -3
- package/src/index.ts +3 -5
- package/src/link.ts +10 -10
- package/src/middlewares/accept-header.ts +1 -1
- package/src/middlewares/cache.ts +31 -24
- package/src/middlewares/warning.ts +1 -0
- package/src/resource.ts +8 -8
- package/src/state/base-state.ts +5 -3
- package/src/state/collection-json.ts +28 -28
- package/src/state/hal.ts +12 -7
- package/src/state/interface.ts +2 -2
- package/src/state/jsonapi.ts +9 -9
- package/src/state/siren.ts +23 -23
- package/src/types.ts +1 -1
- package/src/util/html.ts +10 -10
- package/src/util/html.web.ts +7 -7
- package/src/util/uri.ts +1 -1
- package/src/util/uri.web.ts +2 -2
- 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
|
|
226
|
-
//
|
|
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:
|
|
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(
|
|
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,
|
|
247
|
-
actions: parseHalForms(
|
|
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,
|
package/src/state/interface.ts
CHANGED
|
@@ -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.
|
package/src/state/jsonapi.ts
CHANGED
|
@@ -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
|
/**
|
package/src/state/siren.ts
CHANGED
|
@@ -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
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 =
|
|
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 =
|
|
64
|
+
const type = node.attributes.TYPE as string;
|
|
65
65
|
const link: Link = {
|
|
66
66
|
rel,
|
|
67
67
|
context: contextUri,
|
|
68
|
-
href:
|
|
68
|
+
href: node.attributes.HREF as string,
|
|
69
69
|
};
|
|
70
70
|
if (type) link.type = type;
|
|
71
71
|
links.push(link);
|
package/src/util/html.web.ts
CHANGED
|
@@ -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
package/src/util/uri.web.ts
CHANGED
|
@@ -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
|
|
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');
|