@signalwire/compatibility-api
Version:
SignalWire Compatibility API
190 lines (160 loc) • 4.67 kB
JavaScript
'use strict';
var _ = require('lodash');
var RestException = require('./RestException');
/**
* @constructor
*
* @description Base page object to maintain request state.
*
* @param {Version} version - A twilio version instance
* @param {Object} response - The http response
* @param {Object} solution - path solution
*/
function Page(version, response, solution) {
var payload = this.processResponse(response);
this._version = version;
this._payload = payload;
this._solution = solution;
this.nextPageUrl = this.getNextPageUrl();
this.previousPageUrl = this.getPreviousPageUrl();
this.instances = this.loadInstances(this.loadPage(payload));
}
/**
* @constant META_KEYS
* @description meta keys returned in a list request
*/
Page.prototype.META_KEYS = [
'end',
'first_page_uri',
'last_page_uri',
'next_page_uri',
'num_pages',
'page',
'page_size',
'previous_page_uri',
'start',
'total',
'uri',
];
/**
* Get the url of the previous page of records
*
* @return {string|undefined} url of the previous page
*/
Page.prototype.getPreviousPageUrl = function() {
if ('meta' in this._payload && 'previous_page_url' in this._payload.meta && this._payload.meta.previous_page_url) { // jshint ignore:line
return this._payload.meta.previous_page_url; // jshint ignore:line
}
if ('previous_page_uri' in this._payload && this._payload.previous_page_uri) { // jshint ignore:line
return this._version._domain.absoluteUrl(this._payload.previous_page_uri); // jshint ignore:line
}
return undefined;
};
/**
* Get the url of the next page of records
*
* @return {string|undefined} url of the next page
*/
Page.prototype.getNextPageUrl = function() {
if ('meta' in this._payload && 'next_page_url' in this._payload.meta && this._payload.meta.next_page_url) { // jshint ignore:line
return this._payload.meta.next_page_url; // jshint ignore:line
}
if ('next_page_uri' in this._payload && this._payload.next_page_uri) { // jshint ignore:line
return this._version._domain.absoluteUrl(this._payload.next_page_uri); // jshint ignore:line
}
return undefined;
};
/**
* Build a new instance given a json payload
* @abstract
*
* @param {object} payload - Payload response from the API
* @return {object} instance of a resource
*/
Page.prototype.getInstance = function(payload) {
throw new Error('Page.get_instance() must be implemented in the derived class');
};
/**
* Load a list of records
*
* @param {object} resources json payload of records
* @return {Array} list of resources
*/
Page.prototype.loadInstances = function(resources) {
return _.map(resources, function(resource) {
return this.getInstance(resource);
}.bind(this));
};
/**
* Fetch the next page of records
*
* @return {promise} promise that resolves to next page of results
*/
Page.prototype.nextPage = function() {
if (!this.nextPageUrl) {
return undefined;
}
var promise = this._version._domain.twilio.request({
method: 'GET',
uri: this.nextPageUrl,
});
promise = promise.then(function(response) {
return new this.constructor(this._version, response, this._solution);
}.bind(this));
return promise;
};
/**
* Fetch the previous page of records
*
* @return {promise} promise that resolves to previous page of results
*/
Page.prototype.previousPage = function() {
if (!this.previousPageUrl) {
return undefined;
}
var promise = this._version._domain.twilio.request({
method: 'GET',
uri: this.previousPageUrl,
});
promise = promise.then(function(response) {
return new this.constructor(this._version, response, this._solution);
}.bind(this));
return promise;
};
/**
* Parse json response from API
* @throws {Error} If non 200 status code is returned
*
* @param {object} response API response
* @return {object} json parsed response
*/
Page.prototype.processResponse = function(response) {
if (response.statusCode !== 200) {
throw new RestException(response);
}
if (typeof response.body === 'string') {
return JSON.parse(response.body);
}
return response.body;
};
/**
* Load a page of records
* @throws {Error} If records cannot be deserialized
*
* @param {object} payload json payload
* @return {array} the page of records
*/
Page.prototype.loadPage = function(payload) {
if ('meta' in payload && 'key' in payload.meta) {
return payload[payload.meta.key];
}
var keys = _.chain(payload)
.keys()
.difference(this.META_KEYS)
.value();
if (keys.length === 1) {
return payload[keys[0]];
}
throw new Error('Page Records cannot be deserialized');
};
module.exports = Page;