UNPKG

rest-methods

Version:

Declaratively publish functions for remote invocation.

176 lines (140 loc) 5.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var _lodash = require("lodash"); var _lodash2 = _interopRequireDefault(_lodash); var _bluebird = require("bluebird"); var _bluebird2 = _interopRequireDefault(_bluebird); var _errors = require("../errors"); var _pageJs = require("../page-js"); var _pageJs2 = _interopRequireDefault(_pageJs); var _url = require("../url"); var parseError = function parseError(err) { // Convert the [HttpError] into a [ServerMethodError]. try { var _JSON$parse = JSON.parse(err.message); var status = _JSON$parse.status; var method = _JSON$parse.method; var args = _JSON$parse.args; var message = _JSON$parse.message; } catch (e) { // The server did not return JSON details about the method error. message = err.message; } return new _errors.ServerMethodError(status, method, args, message); }; /** * Represents a proxy to a single method on the server. */ var ClientMethod = (function () { /** * Constructor. * @param name: The unique name of the method. * @param http: The HTTP object to use for making requests. * @param options: * - host: The host-name of the remote server. * - url: The method"s URL path/route-pattern. * - get: Definition of the GET function, eg. { params:["text", "number"] } * - put: .. * - post: .. * - delete: .. */ function ClientMethod(name, http) { var _this = this; var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; _classCallCheck(this, ClientMethod); if (!http) { throw new Error("An [http] gateway was not given to the [ClientMethod]."); } // Prepare the URL. var url = options.url; if (!url) { // If a URL was not specified use the method name. url = "/" + name.replace(/^\/*/, ""); } // Store values. this.name = name; this.verbs = {}; this.urlPattern = url; this.route = new _pageJs2["default"].Route(this.urlPattern); this.http = http; this.host = options.host; // Store individual invoker methods for each HTTP verb. ["get", "put", "post", "delete"].forEach(function (verb) { if (options[verb]) { _this.verbs[verb] = options[verb]; } }); } /** * The URL to the method"s resource. * @param args: Optional. An array of arguments. */ _createClass(ClientMethod, [{ key: "url", value: function url() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return (0, _url.getMethodUrl)(this.name, this.host, this.route, args); } /** * Invokes the method on the server. * @param verb: The HTTP verb (GET | PUT | POST | DELETE) * @param args: An array of arguments. * @return promise. */ }, { key: "invoke", value: function invoke() { var _this2 = this; for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } var verb = arguments.length <= 0 || arguments[0] === undefined ? "GET" : arguments[0]; // Setup initial conditions. verb = verb.toUpperCase(); args = _lodash2["default"].flatten(args); args = _lodash2["default"].compact(args); return new _bluebird2["default"](function (resolve, reject) { // Prepare the URL. var url = _this2.url(args); var urlParamsTotal = _this2.route.keys.length; if (urlParamsTotal > 0) { // The URL contained parameters that were taken from the args. // Remove them from the set of arguments passed in the payload. args = _lodash2["default"].clone(args); args = args.splice(urlParamsTotal, args.length); } if ((verb === "GET" || verb === "DELETE") && args.length > 0) { var msg = "Cannot send arguments to the \"" + _this2.name + "\", REST does not allow you to submit data to a " + verb + " method. Instead use the PUT or POST verbs."; if (urlParamsTotal > 0) { msg += " This method\"s URL does, however, take parameters (" + _this2.urlPattern + ")."; } throw new Error(msg); } // Setup the payload to send. var payload = { verb: verb, method: _this2.name, args: args }; // Send to the server. var httpMethod = _this2.http[verb.toLowerCase()]; httpMethod(url, payload).then(function (result) { resolve(result); })["catch"](function (err) { err = parseError(err); reject(err); }); }); } }]); return ClientMethod; })(); exports["default"] = ClientMethod; module.exports = exports["default"];