-
-
Notifications
You must be signed in to change notification settings - Fork 131
/
Copy pathfetchHydra.ts
112 lines (99 loc) · 2.96 KB
/
fetchHydra.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { HttpError } from 'react-admin';
import {
fetchJsonLd,
getDocumentationUrlFromHeaders,
} from '@api-platform/api-doc-parser';
import jsonld from 'jsonld';
import type { ContextDefinition, NodeObject } from 'jsonld';
import type { JsonLdObj } from 'jsonld/jsonld-spec';
import type { HttpClientOptions, HydraHttpClientResponse } from '../types.js';
/**
* Sends HTTP requests to a Hydra API.
*/
function fetchHydra(
url: URL,
options: HttpClientOptions = {},
): Promise<HydraHttpClientResponse> {
let requestHeaders = options.headers ?? new Headers();
if (
typeof requestHeaders !== 'function' &&
options.user &&
options.user.authenticated &&
options.user.token
) {
requestHeaders = new Headers(requestHeaders);
requestHeaders.set('Authorization', options.user.token);
}
const authOptions = { ...options, headers: requestHeaders };
return fetchJsonLd(url.href, authOptions).then((data) => {
const { status, statusText, headers } = data.response;
const body = 'body' in data ? data.body : undefined;
if (status < 200 || status >= 300) {
if (!body) {
return Promise.reject(new HttpError(statusText, status));
}
delete (body as NodeObject).trace;
const documentLoader = (input: string) => {
const loaderOptions = authOptions;
loaderOptions.method = 'GET';
delete loaderOptions.body;
return fetchJsonLd(input, loaderOptions).then((response) => {
if (!('body' in response)) {
throw new Error(
'An empty response was received when expanding JSON-LD error document.',
);
}
return response;
});
};
const base = getDocumentationUrlFromHeaders(headers);
return (
'@context' in body
? jsonld.expand(body, {
base,
documentLoader,
})
: documentLoader(base).then((response) =>
jsonld.expand(body, {
expandContext: response.document as ContextDefinition,
}),
)
)
.then((json) =>
Promise.reject(
new HttpError(
(
json[0]?.[
'http://www.w3.org/ns/hydra/core#description'
] as JsonLdObj[]
)?.[0]?.['@value'],
status,
json,
),
),
)
.catch((e) => {
if ('body' in e) {
return Promise.reject(e);
}
return Promise.reject(new HttpError(statusText, status));
});
}
if (Array.isArray(body)) {
return Promise.reject(
new Error('Hydra response should not be an array.'),
);
}
if (body && !('@id' in body)) {
return Promise.reject(
new Error('Hydra response needs to have an @id member.'),
);
}
return {
status,
headers,
json: body as NodeObject,
};
});
}
export default fetchHydra;