ketting
Version:
Opiniated HATEAOS / Rest client.
162 lines • 5.46 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.factory = exports.SirenState = void 0;
const base_state_1 = require("./base-state");
const util_1 = require("../http/util");
const link_1 = require("../link");
const uri_1 = require("../util/uri");
/**
* Represents a resource state in the Siren format
*/
class SirenState extends base_state_1.BaseState {
/**
* Returns a serialization of the state that can be used in a HTTP
* response.
*
* For example, a JSON object might simply serialize using
* JSON.serialize().
*/
serializeBody() {
throw new Error('Reserializing Siren states is not yet supported. Please log an issue in the Ketting project to help figure out how this should be done');
}
clone() {
return new SirenState(this.uri, this.data, new Headers(this.headers), new link_1.Links(this.uri, this.links), [], this.actionInfo);
}
}
exports.SirenState = SirenState;
/**
* Turns a HTTP response into a SirenState
*/
const factory = async (uri, response) => {
const body = await response.json();
const links = util_1.parseLink(uri, response.headers.get('Link'));
links.add(...parseSirenLinks(uri, body));
return new SirenState(uri, body.properties, response.headers, links, parseSirenEmbedded(uri, body, response.headers), body.actions ? body.actions.map(action => parseSirenAction(uri, action)) : []);
};
exports.factory = factory;
function parseSirenLinks(contextUri, body) {
const result = [];
if (body.links !== undefined) {
for (const link of body.links) {
result.push(...parseSirenLink(contextUri, link));
}
}
if (body.entities !== undefined) {
for (const subEntity of body.entities) {
if (subEntity.href !== undefined) {
result.push(...parseSirenLink(contextUri, subEntity));
}
else {
result.push(...parseSirenSubEntityAsLink(contextUri, subEntity));
}
}
}
return result;
}
function parseSirenLink(contextUri, link) {
const result = [];
const { rel: rels } = link, attributes = __rest(link, ["rel"]);
for (const rel of rels) {
const newLink = Object.assign({ rel, context: contextUri }, attributes);
result.push(newLink);
}
return result;
}
function parseSirenEmbedded(contextUri, body, headers) {
if (body.entities === undefined) {
return [];
}
const result = [];
for (const entity of body.entities) {
if (isSubEntity(entity)) {
const subState = parseSirenSubEntityAsEmbedded(contextUri, entity, headers);
if (subState !== null) {
result.push(subState);
}
}
}
return result;
}
function parseSirenSubEntityAsLink(contextUri, subEntity) {
if (subEntity.links === undefined) {
// We don't yet support subentities that don't have a URI.
return [];
}
let selfHref = null;
for (const link of subEntity.links) {
if (link.rel.includes('self')) {
selfHref = link.href;
}
}
if (selfHref === null) {
// We don't yet support subentities that don't have a URI.
return [];
}
return subEntity.rel.map(rel => {
const title = subEntity.title;
const link = {
href: selfHref,
rel,
context: contextUri,
};
if (title) {
link.title = title;
}
return link;
});
}
function parseSirenSubEntityAsEmbedded(contextUri, subEntity, headers) {
if (subEntity.links === undefined) {
// We don't yet support subentities that don't have a URI.
return null;
}
let selfHref = null;
for (const link of subEntity.links) {
if (link.rel.includes('self')) {
selfHref = link.href;
}
}
if (!selfHref) {
// We don't yet support subentities that don't have a URI.
return null;
}
const subEntityUrl = uri_1.resolve(contextUri, selfHref);
return new SirenState(subEntityUrl, subEntity.properties, headers, new link_1.Links(selfHref, parseSirenLinks(selfHref, subEntity)));
}
function isSubEntity(input) {
return input.href === undefined;
}
function parseSirenAction(uri, action) {
return {
uri: uri_1.resolve(uri, action.href),
name: action.name,
title: action.title,
method: action.method || 'GET',
contentType: action.type || 'application/x-www-form-urlencoded',
fields: action.fields ? action.fields.map(field => sirenFieldToField(field)) : [],
};
}
function sirenFieldToField(input) {
const result = {
name: input.name,
type: input.type || 'text',
required: false,
readOnly: false,
};
if (input.value) {
result.value = input.value;
}
return result;
}
//# sourceMappingURL=siren.js.map