@webex/webex-core
Version:
Plugin handling for Cisco Webex
348 lines (345 loc) • 14 kB
JavaScript
;
var _Array$from = require("@babel/runtime-corejs2/core-js/array/from");
var _Symbol = require("@babel/runtime-corejs2/core-js/symbol");
var _Symbol$iterator = require("@babel/runtime-corejs2/core-js/symbol/iterator");
var _Array$isArray = require("@babel/runtime-corejs2/core-js/array/is-array");
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
_Object$defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
var _ampersandState = _interopRequireDefault(require("ampersand-state"));
var _lodash = require("lodash");
var _serviceDetail = _interopRequireDefault(require("./service-detail"));
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && o[_Symbol$iterator] || o["@@iterator"]; if (!it) { if (_Array$isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
/**
* @class
*/
var ServiceCatalog = _ampersandState.default.extend({
namespace: 'ServiceCatalog',
props: {
serviceGroups: ['object', true, function () {
return {
discovery: [],
override: [],
preauth: [],
postauth: [],
signin: []
};
}],
status: ['object', true, function () {
return {
discovery: {
ready: false,
collecting: false
},
override: {
ready: false,
collecting: false
},
preauth: {
ready: false,
collecting: false
},
postauth: {
ready: false,
collecting: false
},
signin: {
ready: false,
collecting: false
}
};
}],
isReady: ['boolean', false, false],
allowedDomains: ['array', false, function () {
return [];
}]
},
/**
* @private
* Get all service details for a given service group or return all details if no group is specified.
* @param {ServiceGroup} serviceGroup - The name of the service group to retrieve details for.
* @returns {Array<IServiceDetail>} - An array of service details.
*/
_getAllServiceDetails: function _getAllServiceDetails(serviceGroup) {
var serviceDetails = typeof serviceGroup === 'string' ? this.serviceGroups[serviceGroup] || [] : [].concat((0, _toConsumableArray2.default)(this.serviceGroups.override), (0, _toConsumableArray2.default)(this.serviceGroups.postauth), (0, _toConsumableArray2.default)(this.serviceGroups.signin), (0, _toConsumableArray2.default)(this.serviceGroups.preauth), (0, _toConsumableArray2.default)(this.serviceGroups.discovery));
return serviceDetails;
},
/**
* @private
* Search the service details array to locate a `ServiceDetails`
* class object based on its id.
* @param {string} clusterId
* @param {ServiceGroup} [serviceGroup]
* @returns {IServiceDetail}
*/
_getServiceDetail: function _getServiceDetail(clusterId, serviceGroup) {
var serviceDetails = this._getAllServiceDetails(serviceGroup);
return serviceDetails.find(function (serviceDetail) {
return serviceDetail.id === clusterId;
});
},
/**
* @private
* Safely load one or more `ServiceDetail`s into this `ServiceCatalog` instance.
* @param {ServiceGroup} serviceGroup
* @param {Array<ServiceDetail>} serviceDetails
* @returns {void}
*/
_loadServiceDetails: function _loadServiceDetails(serviceGroup, serviceDetails) {
var _this = this;
// declare namespaces outside of loop
var existingService;
serviceDetails.forEach(function (service) {
existingService = _this._getServiceDetail(service.id, serviceGroup);
if (!existingService) {
_this.serviceGroups[serviceGroup].push(service);
}
});
},
/**
* @private
* Safely unload one or more `ServiceDetail`s into this `Services` instance
* @param {ServiceGroup} serviceGroup
* @param {Array<ServiceDetail>} serviceDetails
* @returns {void}
*/
_unloadServiceDetails: function _unloadServiceDetails(serviceGroup, serviceDetails) {
var _this2 = this;
// declare namespaces outside of loop
var existingService;
serviceDetails.forEach(function (service) {
existingService = _this2._getServiceDetail(service.id, serviceGroup);
if (existingService) {
_this2.serviceGroups[serviceGroup].splice(_this2.serviceGroups[serviceGroup].indexOf(existingService), 1);
}
});
},
/**
* Clear all collected catalog data and reset catalog status.
*
* @returns {void}
*/
clean: function clean() {
this.serviceGroups.preauth.length = 0;
this.serviceGroups.signin.length = 0;
this.serviceGroups.postauth.length = 0;
this.status.preauth = {
ready: false
};
this.status.signin = {
ready: false
};
this.status.postauth = {
ready: false
};
},
/**
* Search over all service groups to find a cluster id based
* on a given url.
* @param {string} url - Must be parsable by `Url`
* @returns {string | undefined} - ClusterId of a given url
*/
findClusterId: function findClusterId(url) {
try {
var _allServiceDetails$fi;
var incomingUrlObj = new URL(url);
var allServiceDetails = this._getAllServiceDetails();
return (_allServiceDetails$fi = allServiceDetails.find(function (serviceDetail) {
return serviceDetail.serviceUrls.find(function (_ref) {
var host = _ref.host;
return host === incomingUrlObj.host;
});
})) === null || _allServiceDetails$fi === void 0 ? void 0 : _allServiceDetails$fi.id;
} catch (_unused) {
// If the URL is invalid or can't be found, return undefined
return undefined;
}
},
/**
* Search over all service groups and return a service value from a provided
* clusterId.
* @param {object} params
* @param {string} params.clusterId - clusterId of found service
* @param {ServiceGroup} [params.serviceGroup] - specify service group
* @returns {object} service
* @returns {string} service.name
* @returns {string} service.url
*/
findServiceFromClusterId: function findServiceFromClusterId() {
var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
clusterId = _ref2.clusterId,
serviceGroup = _ref2.serviceGroup;
var serviceDetails = this._getServiceDetail(clusterId, serviceGroup);
if (serviceDetails) {
return {
name: serviceDetails.serviceName,
url: serviceDetails.get()
};
}
return undefined;
},
/**
* Find a service based on the provided url.
* @param {string} url - Must be parsable by `Url`
* @returns {IServiceDetail} - ServiceDetail assocated with provided url
*/
findServiceDetailFromUrl: function findServiceDetailFromUrl(url) {
var serviceDetails = this._getAllServiceDetails();
return serviceDetails.find(function (_ref3) {
var serviceUrls = _ref3.serviceUrls;
var _iterator = _createForOfIteratorHelper(serviceUrls),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var serviceUrl = _step.value;
if (url.startsWith(serviceUrl.baseUrl)) {
return true;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return false;
});
},
/**
* Finds an allowed domain that matches a specific url.
*
* @param {string} url - The url to match the allowed domains against.
* @returns {string} - The matching allowed domain.
*/
findAllowedDomain: function findAllowedDomain(url) {
try {
var urlObj = new URL(url);
return this.allowedDomains.find(function (allowedDomain) {
return urlObj.host.includes(allowedDomain);
});
} catch (_unused2) {
// If the URL is invalid or can't be found, return undefined
return undefined;
}
},
/**
* Get a service url from the current services list by name. Return undefined
* if the service is not found.
* @param {string} clusterId
* @param {ServiceGroup} serviceGroup
* @returns {string | undefined}
*/
get: function get(clusterId, serviceGroup) {
var serviceDetail = this._getServiceDetail(clusterId, serviceGroup);
return serviceDetail ? serviceDetail.get() : undefined;
},
/**
* Get the current allowed domains list.
*
* @returns {Array<string>} - the current allowed domains list.
*/
getAllowedDomains: function getAllowedDomains() {
return (0, _toConsumableArray2.default)(this.allowedDomains);
},
/**
* Mark a priority host service url as failed.
* This will mark the host associated with the
* `ServiceDetail` to be removed from the its
* respective host array, and then return the next
* viable host from the `ServiceDetail` host array,
* or the `ServiceDetail` default url if no other priority
* hosts are available, or if `noPriorityHosts` is set to
* `true`.
* @param {string} url
* @returns {string}
*/
markFailedServiceUrl: function markFailedServiceUrl(url) {
var serviceDetails = this._getAllServiceDetails();
var serviceDetailWithFailedHost = serviceDetails.find(function (serviceDetail) {
return serviceDetail.failHost(url);
});
// if we couldn't find the url we wanted to fail, return undefined
if (!serviceDetailWithFailedHost) {
return undefined;
}
return serviceDetailWithFailedHost.get();
},
/**
* Set the allowed domains for the catalog.
*
* @param {Array<string>} allowedDomains - allowed domains to be assigned.
* @returns {void}
*/
setAllowedDomains: function setAllowedDomains(allowedDomains) {
this.allowedDomains = (0, _toConsumableArray2.default)(allowedDomains);
},
/**
*
* @param {Array<string>} newAllowedDomains - new allowed domains to add to existing set of allowed domains
* @returns {void}
*/
addAllowedDomains: function addAllowedDomains(newAllowedDomains) {
this.allowedDomains = (0, _lodash.union)(this.allowedDomains, newAllowedDomains);
},
/**
* Update the current list of `ServiceDetail`s against a provided
* service hostmap.
* @emits ServiceCatalog#preauthorized
* @emits ServiceCatalog#postauthorized
* @param {ServiceGroup} serviceGroup
* @param {Array<IServiceDetail>} serviceDetails
* @returns {void}
*/
updateServiceGroups: function updateServiceGroups(serviceGroup, serviceDetails) {
var _this3 = this;
var currentServiceDetails = this.serviceGroups[serviceGroup];
var unusedServicesDetails = currentServiceDetails.filter(function (serviceDetail) {
return serviceDetails.every(function (_ref4) {
var id = _ref4.id;
return id !== serviceDetail.id;
});
});
this._unloadServiceDetails(serviceGroup, unusedServicesDetails);
serviceDetails.forEach(function (serviceObj) {
var serviceDetail = _this3._getServiceDetail(serviceObj.id, serviceGroup);
if (serviceDetail) {
serviceDetail.serviceUrls = serviceObj.serviceUrls || [];
} else {
_this3._loadServiceDetails(serviceGroup, [new _serviceDetail.default(serviceObj)]);
}
});
this.status[serviceGroup].ready = true;
this.trigger(serviceGroup);
},
/**
* Wait until the service catalog is available,
* or reject after a timeout of 60 seconds.
* @param {ServiceGroup} serviceGroup
* @param {number} [timeout] - in seconds
* @returns {Promise<void>}
*/
waitForCatalog: function waitForCatalog(serviceGroup, timeout) {
var _this4 = this;
return new _promise.default(function (resolve, reject) {
if (_this4.status[serviceGroup].ready) {
resolve();
}
var validatedTimeout = typeof timeout === 'number' && timeout >= 0 ? timeout : 60;
var timeoutTimer = setTimeout(function () {
return reject(new Error("services: timeout occured while waiting for '".concat(serviceGroup, "' catalog to populate")));
}, validatedTimeout * 1000);
_this4.once(serviceGroup, function () {
clearTimeout(timeoutTimer);
resolve();
});
});
}
});
var _default = exports.default = ServiceCatalog;
//# sourceMappingURL=service-catalog.js.map