UNPKG

rest-boubou

Version:

RESTful HTTP client library

140 lines (123 loc) 4.48 kB
/* * Copyright 2013-2015 the original author or authors * @license MIT, see LICENSE.txt for details * * @author Scott Andrews */ (function (define) { 'use strict'; define(function (require) { var pathPrefix, template, find, lazyPromise, responsePromise, when; pathPrefix = require('../../../interceptor/pathPrefix'); template = require('../../../interceptor/template'); find = require('../../../util/find'); lazyPromise = require('../../../util/lazyPromise'); responsePromise = require('../../../util/responsePromise'); when = require('when'); function defineProperty(obj, name, value) { Object.defineProperty(obj, name, { value: value, configurable: true, enumerable: false, writeable: true }); } /** * Hypertext Application Language serializer * * Implemented to https://tools.ietf.org/html/draft-kelly-json-hal-06 * * As the spec is still a draft, this implementation will be updated as the * spec evolves * * Objects are read as HAL indexing links and embedded objects on to the * resource. Objects are written as plain JSON. * * Embedded relationships are indexed onto the resource by the relationship * as a promise for the related resource. * * Links are indexed onto the resource as a lazy promise that will GET the * resource when a handler is first registered on the promise. * * A `requestFor` method is added to the entity to make a request for the * relationship. * * A `clientFor` method is added to the entity to get a full Client for a * relationship. * * The `_links` and `_embedded` properties on the resource are made * non-enumerable. */ return { read: function (str, opts) { var client, console; opts = opts || {}; client = opts.client; console = opts.console || console; function deprecationWarning(relationship, deprecation) { if (deprecation && console && console.warn || console.log) { (console.warn || console.log).call(console, 'Relationship \'' + relationship + '\' is deprecated, see ' + deprecation); } } return opts.registry.lookup(opts.mime.suffix).then(function (converter) { return when(converter.read(str, opts)).then(function (root) { find.findProperties(root, '_embedded', function (embedded, resource, name) { Object.keys(embedded).forEach(function (relationship) { if (relationship in resource) { return; } var related = responsePromise({ entity: embedded[relationship] }); defineProperty(resource, relationship, related); }); defineProperty(resource, name, embedded); }); find.findProperties(root, '_links', function (links, resource, name) { Object.keys(links).forEach(function (relationship) { var link = links[relationship]; if (relationship in resource) { return; } defineProperty(resource, relationship, responsePromise.make(lazyPromise(function () { if (link.deprecation) { deprecationWarning(relationship, link.deprecation); } if (link.templated === true) { return template(client)({ path: link.href }); } return client({ path: link.href }); }))); }); defineProperty(resource, name, links); defineProperty(resource, 'clientFor', function (relationship, clientOverride) { var link = links[relationship]; if (!link) { throw new Error('Unknown relationship: ' + relationship); } if (link.deprecation) { deprecationWarning(relationship, link.deprecation); } if (link.templated === true) { return template( clientOverride || client, { template: link.href } ); } return pathPrefix( clientOverride || client, { prefix: link.href } ); }); defineProperty(resource, 'requestFor', function (relationship, request, clientOverride) { var client = this.clientFor(relationship, clientOverride); return client(request); }); }); return root; }); }); }, write: function (obj, opts) { return opts.registry.lookup(opts.mime.suffix).then(function (converter) { return converter.write(obj, opts); }); } }; }); }( typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); } // Boilerplate for AMD and Node ));