UNPKG

backstrap-server

Version:

Backstrap is a lightweight framework for building APIs

186 lines (173 loc) 7.18 kB
const util = require('util'); const fs = require('fs'); const path = require('path'); const rootDir = path.dirname(require.main.filename); class Endpoints { #file = null; #extensionFile = null; constructor(file) { this.areas = []; this.#file = file; this.#extensionFile = null; this.settings = null; } init(s) { this.settings = s; this.#extensionFile = this.#file.replace(/^\.\//, '').replace('_in', ''); try { // INTERNAL ENDPOINTS JSON IS INCLUDED IN THE PACKAGE if(this.#file.substring(0,2) !== './') this.#file = './'+this.#file; // USER-DEFINED ENDPOINT JSON IS IN THE PROJECT ROOT this.#extensionFile = `${rootDir}/${this.#extensionFile}`; this.areas = require(this.#file); // FOR EACH CUSTOM ENDPOINT SPECIFIED IN USER DEFINED ENDPOINTS FILE // UPDATE OR ADD TO endpointData AS APPLICABLE let customEndpointData = require(this.#extensionFile); var areaNames = Object.keys(customEndpointData); for(var aIdx = 0; aIdx < areaNames.length; aIdx++) { var customArea = customEndpointData[areaNames[aIdx]] // THIS IS A NEW AREA. JUST ADD IT TO THE ENDPOINT DATA if(this.areas[areaNames[aIdx]] == undefined || this.areas[areaNames[aIdx]] == null) { this.areas[areaNames[aIdx]] = customArea; } // WE ALREADY HAVE THIS AREA, MUST CHECK EACH CONTROLLER else { var area = this.areas[areaNames[aIdx]]; // FOR EACH CUSTOM CONTROLLER for(var cIdx = 0; cIdx < customArea.length; cIdx++) { var originalController = null; for(var 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.areas[areaNames[aIdx]].push(customArea[cIdx]); } // OTHERWISE WE HAVE THIS CONTROLLER AND WE NEED TO CHECK EACH METHOD else { var customMethods = customArea[cIdx].methods; for(var mIdx = 0; mIdx < customMethods.length; mIdx++) { var customMethod = customMethods[mIdx]; for(var omIdx = 0; omIdx < originalController.methods.length; omIdx++) { var originalMethod = originalController.methods[omIdx]; var foundMethod = false; if(customMethod.verb == originalMethod.verb && customMethod.call == originalMethod.call) { foundMethod = true; break; } } if(!foundMethod) { this.areas[areaNames[aIdx]][ocIdx].methods.push(customMethod); } } } } } } } catch(e) { console.error("Initialization Error -- endpoints.js"); console.error(e); } } save() { return new Promise((resolve, reject) => { // SEPARATE USER-DEFINED ENDPOINT DESCRIPTORS FROM // CORE SYSTEM ENDPOINT DESCRIPTORS var customEndpoints = {}; var systemEndpoints = {}; var areaNames = Object.keys(this.areas); // FOR EACH AREA IN THE ENDPOINTS DATA for(var aIdx = 0; aIdx < areaNames.length; aIdx++) { var area = this.areas[areaNames[aIdx]]; // FOR EACH CONTROLLER IN THE ENDPOINTS DATA for(var cIdx = 0; cIdx < area.length; cIdx++) { var controller = area[cIdx]; // FOR EACH METHOD IN THE ENDPOINTS DATA for(var mIdx = 0; mIdx < controller.methods.length; mIdx++) { var 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]] = []; } var 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 var cntrl = JSON.parse(JSON.stringify(controller)); cntrl.methods = []; var foundController = false; for(var ctIdx = 0; ctIdx < cArea.length; ctIdx++) { var 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]] = []; } var 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 var cntrl = JSON.parse(JSON.stringify(controller)); cntrl.methods = []; var foundController = false; for(var ctIdx = 0; ctIdx < cArea.length; ctIdx++) { var 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); } } } } } var fswrite = util.promisify(fs.writeFile); Promise.all([fswrite(this.#file, JSON.stringify(systemEndpoints, null, 4)), fswrite(this.#extensionFile, JSON.stringify(customEndpoints, null, 4))]) .then((write_res) => { resolve(true); }) .catch((err) => { let errorObj = new ErrorObj(400, 'e0002', __filename, 'save', 'error writing to Endpoints config file', 'External error', err ); reject(errorObj); }); }); } } const instance = new Endpoints('Endpoints_in.json'); module.exports = instance;