ketting
Version:
Opinionated HATEOAS / Rest client.
73 lines • 2.17 kB
JavaScript
import { BaseState } from './base-state.js';
import { parseLink } from '../http/util.js';
/**
* Turns a HTTP response into a JsonApiState
*/
export const factory = async (client, uri, response) => {
const body = await response.json();
const links = parseLink(uri, response.headers.get('Link'));
links.add(...parseJsonApiLinks(uri, body), ...parseJsonApiCollection(uri, body));
return new BaseState({
client,
uri,
data: body,
headers: response.headers,
links: links,
});
};
/**
* This function takes a JSON:API object, and extracts the links property.
*/
function parseJsonApiLinks(contextUri, body) {
const result = [];
if (body.links === undefined) {
return result;
}
for (const [rel, linkValue] of Object.entries(body.links)) {
if (Array.isArray(linkValue)) {
result.push(...linkValue.map(link => parseJsonApiLink(contextUri, rel, link)));
}
else {
result.push(parseJsonApiLink(contextUri, rel, linkValue));
}
}
return result;
}
/**
* Find collection members in JSON:API objects.
*
* A JSON:API top-level object might represent a collection that has 0 or more
* members.
*
* Members of this collection should appear as an 'item' link to the parent.
*/
function parseJsonApiCollection(contextUri, body) {
if (!Array.isArray(body.data)) {
// Not a collection
return [];
}
const result = [];
for (const member of body.data) {
if ('links' in member && 'self' in member.links) {
const selfLink = parseJsonApiLink(contextUri, 'self', member.links.self);
result.push({
context: contextUri,
href: selfLink.href,
rel: 'item'
});
}
}
return result;
}
/**
* This function takes a single link value from a JSON:API link object, and
* returns a object of type Link
*/
function parseJsonApiLink(contextUri, rel, link) {
return ({
context: contextUri,
rel,
href: typeof link === 'string' ? link : link.href,
});
}
//# sourceMappingURL=jsonapi.js.map