UNPKG

ketting

Version:

Opiniated HATEAOS / Rest client.

169 lines 5.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseState = exports.BaseHeadState = void 0; const link_1 = require("../link"); const action_1 = require("../action"); const uri_1 = require("../util/uri"); const uri_template_1 = require("../util/uri-template"); const util_1 = require("../http/util"); /** * Implements a State object for HEAD responses */ class BaseHeadState { constructor(init) { this.client = init.client; this.uri = init.uri; this.headers = init.headers; this.timestamp = Date.now(); this.links = init.links; } /** * Follows a relationship, based on its reltype. For example, this might be * 'alternate', 'item', 'edit' or a custom url-based one. * * This function can also follow templated uris. You can specify uri * variables in the optional variables argument. */ follow(rel, variables) { const link = this.links.get(rel); if (!link) throw new link_1.LinkNotFound(`Link with rel ${rel} on ${this.uri} not found`); let href; if (link.templated) { href = (0, uri_template_1.expand)(link, variables || {}); } else { href = (0, uri_1.resolve)(link); } if (link.hints?.status === 'deprecated') { /* eslint-disable-next-line no-console */ console.warn(`[ketting] The ${link.rel} link on ${this.uri} is marked deprecated.`, link); } return this.client.go(href); } /** * Follows a relationship based on its reltype. This function returns a * Promise that resolves to an array of Resource objects. * * If no resources were found, the array will be empty. */ followAll(rel) { return this.links.getMany(rel).map(link => { if (link.hints?.status === 'deprecated') { /* eslint-disable-next-line no-console */ console.warn(`[ketting] The ${link.rel} link on ${this.uri} is marked deprecated.`, link); } const href = (0, uri_1.resolve)(link); return this.client.go(href); }); } /** * Content-headers are a subset of HTTP headers that related directly * to the content. The obvious ones are Content-Type. * * This set of headers will be sent by the server along with a GET * response, but will also be sent back to the server in a PUT * request. */ contentHeaders() { const result = {}; for (const contentHeader of util_1.entityHeaderNames) { if (this.headers.has(contentHeader)) { result[contentHeader] = this.headers.get(contentHeader); } } return new Headers(result); } } exports.BaseHeadState = BaseHeadState; /** * The Base State provides a convenient way to implement a new State type. */ class BaseState extends BaseHeadState { constructor(init) { super(init); this.data = init.data; this.actionInfo = init.actions || []; this.embedded = init.embedded || []; } /** * Return an action by name. * * If no name is given, the first action is returned. This is useful for * formats that only supply 1 action, and no name. */ action(name) { if (!this.actionInfo.length) { throw new action_1.ActionNotFound('This State does not define any actions'); } if (name === undefined) { return new action_1.SimpleAction(this.client, this.actionInfo[0]); } for (const action of this.actionInfo) { if (action.name === name) { return new action_1.SimpleAction(this.client, action); } } throw new action_1.ActionNotFound('This State defines no action'); } /** * Returns all actions */ actions() { return this.actionInfo.map(action => new action_1.SimpleAction(this.client, action)); } /** * Checks if the specified action exists. * * If no name is given, checks if _any_ action exists. */ hasAction(name) { if (name === undefined) return this.actionInfo.length > 0; for (const action of this.actionInfo) { if (name === action.name) { return true; } } return false; } /** * 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() { if ((global.Buffer && this.data instanceof Buffer) || (global.Blob && this.data instanceof Blob) || typeof this.data === 'string') { return this.data; } return JSON.stringify(this.data); } /** * Certain formats can embed other resources, identified by their * own URI. * * When a format has embedded resources, we will use these to warm * the cache. * * This method returns every embedded resource. */ getEmbedded() { return this.embedded; } clone() { return new BaseState({ client: this.client, uri: this.uri, data: this.data, headers: new Headers(this.headers), links: new link_1.Links(this.links.defaultContext, this.links.getAll()), actions: this.actionInfo, }); } } exports.BaseState = BaseState; //# sourceMappingURL=base-state.js.map