af-consul
Version:
A highly specialized function library
173 lines • 7.13 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccessPoints = void 0;
/* eslint-disable no-await-in-loop */
const logger_stub_1 = __importDefault(require("../lib/logger-stub"));
const color_1 = require("../lib/color");
const utils_1 = require("../lib/utils");
const constants_1 = require("../constants");
const PREFIX = 'ACCESS-POINT';
const _logger_ = Symbol.for('_logger_');
const addAdditionalAPProps = (accessPoint) => {
if (accessPoint.noConsul) {
return;
}
Object.defineProperty(accessPoint, 'isAP', { value: true });
Object.defineProperty(accessPoint, 'lastSuccessUpdate', { value: 0, writable: true });
Object.defineProperty(accessPoint, 'idHostPortUpdated', { value: false, writable: true });
accessPoint.waitForHostPortUpdated = async (timeout = constants_1.CONSUL_AP_UPDATE_TIMEOUT_MILLIS) => {
const start = Date.now();
while (!accessPoint.idHostPortUpdated && (Date.now() - start < timeout)) {
await (0, utils_1.sleep)(100);
}
return !!accessPoint.idHostPortUpdated;
};
};
// eslint-disable-next-line import/prefer-default-export
class AccessPoints {
constructor(accessPoints, logger) {
this[_logger_] = logger || logger_stub_1.default;
if (!accessPoints) {
const msg = 'Empty argument "accessPoints" passed to constructor';
this[_logger_].error(msg);
throw new Error(msg);
}
Object.entries(accessPoints).forEach(([apKey, apData]) => {
this.addAP(apKey, apData);
});
}
static normalizePort(port) {
return Number(port) || null;
}
static normalizeProtocol(protocol) {
if (!protocol || !/^https?$/i.test(protocol)) {
protocol = 'http';
}
return protocol === null || protocol === void 0 ? void 0 : protocol.toLowerCase();
}
static normalizeValue(propName, propValue) {
switch (propName) {
case 'port':
return AccessPoints.normalizePort(propValue);
case 'protocol':
return AccessPoints.normalizeProtocol(propValue);
default:
return propValue;
}
}
static getPureProps(accessPointSource) {
const accessPoint = Object.create(null);
Object.entries(accessPointSource).forEach(([propName, propValue]) => {
if (propValue === undefined || typeof propValue === 'function') {
return;
}
if (typeof propValue === 'object' && propValue !== null) {
accessPoint[propName] = { ...propValue };
return;
}
accessPoint[propName] = propValue;
});
return accessPoint;
}
addAP(apKey, apData) {
if (!apData || !(0, utils_1.isObject)(apData)) {
return undefined;
}
if (apData.noConsul) {
this[apKey] = apData;
return AccessPoints.getPureProps(apData);
}
if (!apData.consulServiceName) {
this[_logger_].error(`"${apKey}" access point not added because it lacks "consulServiceName" property`);
return undefined;
}
const accessPoint = {};
addAdditionalAPProps(accessPoint);
// @ts-ignore
this[apKey] = accessPoint;
Object.entries(apData).forEach(([propName, v]) => {
accessPoint[propName] = AccessPoints.normalizeValue(propName, v);
});
accessPoint.id = apKey;
accessPoint.title = accessPoint.title || apKey;
accessPoint.setProps = this.setAP.bind(this, apKey);
return AccessPoints.getPureProps(accessPoint);
}
setAP(apKey, apData) {
if (!apData) {
return undefined;
}
// @ts-ignore
const accessPoint = this[apKey];
if (!accessPoint) {
return this.addAP(apKey, apData);
}
/* istanbul ignore if */
if (!accessPoint.isAP) {
addAdditionalAPProps(accessPoint);
}
const was = [];
const became = [];
const changes = [];
const msgVal = (propName, propValue, valueColor) => {
const ret = (v, color = color_1.blue) => `${color_1.cyan}${propName}${color_1.reset}: ${color}${v}${color_1.reset}`;
return (propValue == null || propValue === '') ? ret(`[${String(propValue)}]`) : ret(propValue, valueColor);
};
Object.entries(apData).forEach(([propName, newV]) => {
if (newV === undefined) {
return;
}
const oldV = accessPoint[propName];
newV = AccessPoints.normalizeValue(propName, newV);
if (oldV !== newV) {
was.push(msgVal(propName, oldV, color_1.magenta));
became.push(msgVal(propName, newV, color_1.green));
changes.push([propName, oldV, newV]);
}
accessPoint[propName] = newV;
});
if (was.length) {
this[_logger_].info(`${PREFIX}: Change AP ${color_1.green}${accessPoint.id}${color_1.reset}/${color_1.cyan}${accessPoint.consulServiceName}${color_1.reset} from ${was.join('; ')} to ${became.join('; ')}`);
}
accessPoint.idHostPortUpdated = accessPoint.idHostPortUpdated
|| !!(accessPoint.host && accessPoint.port && (apData.host || apData.port));
const result = AccessPoints.getPureProps(accessPoint);
result.getChanges = () => (changes.length ? changes : undefined);
return result;
}
getAP(accessPointKey, andNotIsAP) {
if (accessPointKey) {
// @ts-ignore
const accessPoint = this[accessPointKey];
if (!andNotIsAP && !(accessPoint === null || accessPoint === void 0 ? void 0 : accessPoint.isAP)) {
return undefined;
}
return accessPoint;
}
return undefined;
}
/**
* Если передан accessPointKey, то возвращается этот AP, если есть.
* Если accessPointKey НЕ передан, то возвращаются ВСЕ AP
*/
get(accessPointKey, andNotIsAP) {
if (accessPointKey) {
// @ts-ignore
const accessPoint = this[accessPointKey];
if (!accessPoint || (!andNotIsAP && !(accessPoint === null || accessPoint === void 0 ? void 0 : accessPoint.isAP))) {
return undefined;
}
return AccessPoints.getPureProps(accessPoint);
}
const accessPoints = Object.create(null);
Object.values(this).filter((ap) => ap === null || ap === void 0 ? void 0 : ap.isAP).forEach((accessPoint) => {
accessPoints[accessPoint.id] = AccessPoints.getPureProps(accessPoint);
});
return accessPoints;
}
}
exports.AccessPoints = AccessPoints;
//# sourceMappingURL=access-points.js.map
;