fully-api
Version:
API framework for Fully Stacked, LLC REST-ful APIs
312 lines • 17.1 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Endpoints = void 0;
const ErrorObj_1 = require("./ErrorObj");
const Q = require('q');
const fs_1 = __importDefault(require("fs"));
const aws_sdk_1 = __importDefault(require("aws-sdk"));
aws_sdk_1.default.config.region = 'us-east-1';
// ===============================================================================
// UTILITY FUNCTIONS
// ===============================================================================
let endpointData;
class Endpoints {
constructor(s) {
this.s3 = new aws_sdk_1.default.S3();
this.settings = s;
}
init(b, f, f_ext, rs) {
const deferred = Q.defer();
this.bucket = b;
this.file = f;
this.extensionFile = f_ext;
this.remoteSettings = rs;
if (this.remoteSettings == null || this.remoteSettings === false) {
try {
this.endpointData = require(this.file);
// FOR EACH CUSTOM ENDPOINT SPECIFIED IN USER DEFINED ENDPOINTS FILE
// UPDATE OR ADD TO endpointData AS APPLICABLE
const customEndpointData = require(this.extensionFile);
const areas = Object.keys(customEndpointData);
for (let aIdx = 0; aIdx < areas.length; aIdx++) {
const customArea = customEndpointData[areas[aIdx]];
// THIS IS A NEW AREA. JUST ADD IT TO THE ENDPOINT DATA
if (this.endpointData[areas[aIdx]] == undefined || this.endpointData[areas[aIdx]] == null) {
this.endpointData[areas[aIdx]] = customArea;
}
// WE ALREADY HAVE THIS AREA, MUST CHECK EACH CONTROLLER
else {
const area = this.endpointData[areas[aIdx]];
// FOR EACH CUSTOM CONTROLLER
for (let cIdx = 0; cIdx < customArea.length; cIdx++) {
let originalController = null;
let ocIdx;
for (ocIdx = 0; ocIdx < area.length; ocIdx++) {
if (customArea[cIdx].name == area[ocIdx].name &&
customArea[cIdx].version == area[ocIdx].version) {
originalController = area[ocIdx];
break;
}
}
// IF WE COULDN'T FIND THIS CONTROLLER, JUST ADD IT
if (originalController == null) {
this.endpointData[areas[aIdx]].push(customArea[cIdx]);
}
// OTHERWISE WE HAVE THIS CONTROLLER AND WE NEED TO CHECK EACH METHOD
else {
const customMethods = customArea[cIdx].methods;
for (let mIdx = 0; mIdx < customMethods.length; mIdx++) {
const customMethod = customMethods[mIdx];
let foundMethod;
for (let omIdx = 0; omIdx < originalController.methods.length; omIdx++) {
const originalMethod = originalController.methods[omIdx];
foundMethod = false;
if (customMethod.verb == originalMethod.verb &&
customMethod.call == originalMethod.call) {
foundMethod = true;
break;
}
}
if (!foundMethod) {
this.endpointData[areas[aIdx]][ocIdx].methods.push(customMethod);
}
}
}
}
}
}
Endpoints.prototype.data = this.endpointData;
endpointData = Endpoints.prototype.data;
deferred.resolve(true);
}
catch (e) {
deferred.reject(e);
}
}
else {
Endpoints.prototype.data = {};
endpointData = Endpoints.prototype.data;
this.s3.getObject({ Bucket: this.bucket, Key: this.file }, function (err, res) {
if (!err) {
const obj = JSON.parse(res.Body.toString());
this.endpointData = obj;
this.s3.getObject({ Bucket: this.bucket, Key: this.extensionFile }, function (c_err, c_res) {
if (!c_err) {
const customEndpointData = JSON.parse(c_res.Body.toString());
const areas = Object.keys(customEndpointData);
for (let aIdx = 0; aIdx < areas.length; aIdx++) {
const customArea = customEndpointData[areas[aIdx]];
// THIS IS A NEW AREA. JUST ADD IT TO THE ENDPOINT DATA
if (this.endpointData[areas[aIdx]] == undefined || this.endpointData[areas[aIdx]] == null) {
this.endpointData[areas[aIdx]] = customArea;
}
// WE ALREADY HAVE THIS AREA, MUST CHECK EACH CONTROLLER
else {
const area = this.endpointData[areas[aIdx]];
// FOR EACH CUSTOM CONTROLLER
for (let cIdx = 0; cIdx < customArea.length; cIdx++) {
let originalController = null;
let ocIdx;
for (ocIdx = 0; ocIdx < area.length; ocIdx++) {
if (customArea[cIdx].name == area[ocIdx].name &&
customArea[cIdx].version == area[ocIdx].version) {
originalController = area[ocIdx];
break;
}
}
// IF WE COULDN'T FIND THIS CONTROLLER, JUST ADD IT
if (originalController == null) {
this.endpointData[areas[aIdx]].push(customArea[cIdx]);
}
// OTHERWISE WE HAVE THIS CONTROLLER AND WE NEED TO CHECK EACH METHOD
else {
let foundMethod = false;
const customMethods = customArea[cIdx].methods;
for (let mIdx = 0; mIdx < customMethods.length; mIdx++) {
const customMethod = customMethods[mIdx];
for (let omIdx = 0; omIdx < originalController.methods.length; omIdx++) {
const originalMethod = originalController.methods[omIdx];
if (customMethod.verb == originalMethod.verb &&
customMethod.call == originalMethod.call) {
foundMethod = true;
break;
}
}
if (!foundMethod) {
this.endpointData[areas[aIdx]][ocIdx].methods.push(customMethod);
}
}
}
}
}
}
this.data = this.endpointData;
deferred.resolve(true);
}
else {
const errorObj = new ErrorObj_1.ErrorObj(500, 'e1001', __filename, 'init', 'error getting file from S3', 'External error', c_err);
deferred.reject(errorObj);
}
});
}
else {
const errorObj = new ErrorObj_1.ErrorObj(500, 'e0001', __filename, 'init', 'error getting file from S3', 'External error', err);
deferred.reject(errorObj);
}
});
}
return deferred.promise;
}
getEndpointData() {
return endpointData;
}
reload() {
const e = this;
const deferred = Q.defer();
e.init(this.bucket, this.file, this.extensionFile, this.remoteSettings)
.then(function (res) {
deferred.resolve(res);
})
.fail(function (err) {
if (err !== undefined && err !== null && typeof (err.addToError) === 'function') {
deferred.reject(err.addToError(__filename, 'reload'));
}
else {
const errorObj = new ErrorObj_1.ErrorObj(500, 'e1001', __filename, 'reload', 'error reloading endpoints config', 'External error', err);
deferred.reject(errorObj);
}
});
return deferred.promise;
}
save(doNetworkReload) {
const deferred = Q.defer();
// SEPARATE USER-DEFINED ENDPOINT DESCRIPTORS FROM
// CORE SYSTEM ENDPOINT DESCRIPTORS
const customEndpoints = {};
const systemEndpoints = {};
const eData = this.constructor.prototype.data;
const areaNames = Object.keys(eData);
// FOR EACH AREA IN THE ENDPOINTS DATA
for (let aIdx = 0; aIdx < areaNames.length; aIdx++) {
const area = eData[areaNames[aIdx]];
// FOR EACH CONTROLLER IN THE ENDPOINTS DATA
for (let cIdx = 0; cIdx < area.length; cIdx++) {
const controller = area[cIdx];
// FOR EACH METHOD IN THE ENDPOINTS DATA
for (let mIdx = 0; mIdx < controller.methods.length; mIdx++) {
const method = controller.methods[mIdx];
// USER CREATED METHOD
if (method.isUserCreated == null || method.isUserCreated == true) {
// THE customEndpoints OBJECT DOES NOT HAVE AN ENTRY FOR THIS AREA
if (!customEndpoints.hasOwnProperty(areaNames[aIdx])) {
customEndpoints[areaNames[aIdx]] = [];
}
const cArea = customEndpoints[areaNames[aIdx]];
// IF NO MATCHING CONTROLLER IS FOUND,
// DEEP COPY USING JSON stringify/parse
// AND REMOVE THE METHODS. THIS WILL GIVE US JUST THE
// HEADER INFO FROM THE CONTROLLER
let cntrl = JSON.parse(JSON.stringify(controller));
cntrl.methods = [];
let foundController = false;
for (let ctIdx = 0; ctIdx < cArea.length; ctIdx++) {
const c = cArea[ctIdx];
if (controller.name == c.name && controller.version == c.version) {
// FOUND THE CONTROLLER IN customEndpoints, SO USE THAT ONE
cntrl = c;
foundController = true;
break;
}
}
cntrl.methods.push(method);
if (!foundController) {
cArea.push(cntrl);
}
}
// SYSTEM METHOD
else {
// THE systemEndpoints OBJECT DOES NOT HAVE AN ENTRY FOR THIS AREA
if (!systemEndpoints.hasOwnProperty(areaNames[aIdx])) {
systemEndpoints[areaNames[aIdx]] = [];
}
const cArea = systemEndpoints[areaNames[aIdx]];
// IF NO MATCHING CONTROLLER IS FOUND,
// DEEP COPY USING JSON stringify/parse
// AND REMOVE THE METHODS. THIS WILL GIVE US JUST THE
// HEADER INFO FROM THE CONTROLLER
let cntrl = JSON.parse(JSON.stringify(controller));
cntrl.methods = [];
let foundController = false;
for (let ctIdx = 0; ctIdx < cArea.length; ctIdx++) {
const c = cArea[ctIdx];
if (controller.name == c.name && controller.version == c.version) {
// FOUND THE CONTROLLER IN systemEndpoints, SO USE THAT ONE
cntrl = c;
foundController = true;
break;
}
}
cntrl.methods.push(method);
if (!foundController) {
cArea.push(cntrl);
}
}
}
}
}
if (this.remoteSettings == null || this.remoteSettings === false) {
const fswrite = Q.denodeify(fs_1.default.writeFile);
Q.all([fswrite(this.file, JSON.stringify(systemEndpoints, null, 4)), fswrite(this.extensionFile, JSON.stringify(customEndpoints, null, 4))])
.then(function (write_res) {
deferred.resolve(true);
})
.fail(function (err) {
const errorObj = new ErrorObj_1.ErrorObj(400, 'e0002', __filename, 'save', 'error writing to Endpoints config file', 'External error', err);
deferred.reject(errorObj);
});
}
else {
this.s3.putObject({ Bucket: this.bucket, Key: this.file, Body: JSON.stringify(systemEndpoints, null, 4) }, function (err, save_res) {
if (!err) {
this.s3.putObject({ Bucket: this.bucket, Key: this.xtensionFile, Body: JSON.stringify(customEndpoints, null, 4) }, function (c_err, c_save_res) {
if (!c_err) {
if (doNetworkReload === true) {
this.settings.reloadNetwork()
.then(function (reload_res) {
deferred.resolve(true);
})
.fail(function (err) {
if (err !== undefined && err !== null && typeof (err.addToError) === 'function') {
deferred.reject(err.addToError(__filename, 'save'));
}
else {
const errorObj = new ErrorObj_1.ErrorObj(500, 'e1003', __filename, 'save', 'error saving endpoints config', 'External error', err);
deferred.reject(errorObj);
}
});
}
else {
deferred.resolve(true);
}
}
else {
const errorObj = new ErrorObj_1.ErrorObj(500, 'e0004', __filename, 'save', 'error saving endpoints', 'S3 error', err);
deferred.reject(errorObj);
}
});
}
else {
const errorObj = new ErrorObj_1.ErrorObj(500, 'e0003', __filename, 'save', 'error saving endpoints', 'S3 error', err);
deferred.reject(errorObj);
}
});
}
return deferred.promise;
}
;
}
exports.Endpoints = Endpoints;
//# sourceMappingURL=endpoints.js.map