UNPKG

apiextender

Version:

This module deals with to extend an API backend that adds a specific feature to an existing API as plugin(add-in, addin, add-on, addon). apiextender let to enable third-party developers to create abilities which extend an application and supports the a

233 lines (193 loc) 7.67 kB
var plugin = require("../.././plugin/extend"); var responseinterceptor=require('responseinterceptor'); var async=require('async'); var fs = require('fs'); function LoadParams(params,req){ var values={}; params.forEach(function(element,index){ values[element]=req[element]; }); return values; } function writeParams(params,req, beforeParams){ if((typeof params) ==="object"){ async.eachOf(params, function(value,key, callback) { if(beforeParams) beforeParams[key]=value; req[key]=value; }); }else{ req.before=params; } } function setErrorResponse(res,err){ var errorString=""; switch(err.error_code) { case 400: errorString="Bad Request"; break; case 401: errorString="Unauthorized"; break; case 403: errorString="Forbidden"; break; case 404: errorString="Not Found"; break; case 409: errorString="Conflict"; break; case 500: errorString="Internal Server Error"; break; case 504: errorString="Gateway Timeout"; break; default: errorString=err.error_code; break; } if((typeof err.error_message) === 'object') err.error_message=JSON.stringify(err.error_message); res.status(err.error_code).send({error:errorString, error_message:err.error_message}); } function extendGet(app,method,ext) { method=method.toLocaleLowerCase(); app[method](ext.resource, function(req,res,next) { var params= LoadParams(ext.params,req); if(ext.mode=="override") { ext.extender(params,null,null,function (err, val) { if(!err) { res.send(val); } else{ setErrorResponse(res,err); } }); } else if(ext.mode=="before") { ext.extender(params,null,null,function (err, val) { if(!err){ writeParams(val, req); next(); }else{ setErrorResponse(res,err); } }); }else if(ext.mode=="after") { responseinterceptor.interceptOnFly(req,res,function(body,cType, request, clb){ if(!(req.before_after_error==true)) { ext.extender(params, body, cType, function (err, val) { if (!err) { clb(val); } else { req.before_after_error = true; if((typeof err.error_message).indexOf("object")<0) res.setHeader('content-type', 'text/javascript'); setErrorResponse(res,err); } }); }else clb(body); }); next(); } else if(ext.mode=="before_after") { ext.extender.before(params,null,null,function (err, val) { if(!err) { writeParams(val, req, params); next(); }else{ req.before_after_error=true; setErrorResponse(res,err); } }); responseinterceptor.interceptOnFly(req,res,function(body,cType, request, clb){ if(!(req.before_after_error==true)) { ext.extender.after(params, body, cType, function (err, val) { if (!err) { clb(val); } else { req.before_after_error = true; if((typeof err.error_message).indexOf("object")<0) res.setHeader('content-type', 'text/javascript'); setErrorResponse(res,err); } }); }else clb(body); }); }else next(); // do nothing }); } exports.extend=function(app){ async.eachSeries(plugin, function(ext, callback) { if( ext.enabled && (ext.enabled===true)) extendGet(app,ext.method,ext); callback(); }); }; function getErrorHandlers(app,error_map) { var route, stack; stack = app._router.stack; async.eachOfSeries(stack, function(layer,key, callback) { if (layer && layer.name == '<anonymous>' && layer.route == undefined) callback(key); else callback(); }, function(err_map) { var error_handlers=null; if(err_map){ error_handlers = stack.splice(err_map); app._router.stack=stack; } error_map(error_handlers); }); } exports.install=function(app,extender,save){ getErrorHandlers(app,function(error_handlers){ extendGet(app,extender.method,extender); if(error_handlers) app._router.stack.push.apply(app._router.stack, error_handlers); if(save){ plugin.push(extender); var functionToString="[\n"; async.eachSeries(plugin,function(obj,callback){ functionToString += " {\n"; functionToString += (" \"resource\":\"") + obj.resource.toString() + "\",\n"; functionToString += (" \"method\":\"") + obj.method.toString() + "\",\n"; functionToString += (" \"mode\":\"") + obj.mode.toString() + "\",\n"; functionToString += " \"params\":[" ; obj.params.forEach(function (value) { functionToString+="\"" + value.toString() + "\","; }); if(obj.params.length>0) functionToString=functionToString.slice(0,-1); functionToString+="],\n"; if(obj.extender && obj.extender.before) { functionToString += (" \"extender\":{\n"); functionToString += (" \"before\":") + obj.extender.before.toString() + ",\n"; functionToString += (" \"after\":") + obj.extender.after.toString() + "\n"; functionToString += (" }\n"); }else{ functionToString += (" \"extender\":") + obj.extender.toString() + "\n"; } functionToString += " },\n"; callback(); },function(err){ functionToString=functionToString.slice(0,-2); // remove , and \n functionToString+="\n]"; var nfile='var express = require(\'express\');\n\r' + '\n\r' + 'var plugins=' + functionToString + ';\n\r' + 'module.exports = plugins;'; fs.writeFile("./plugin/extend.js", nfile, function(err) { console.log("DONE:" + err); }); }); } }); }; /* * <table><tbody> <tr><th align="left">Alessandro Romanino</th><td><a href="https://github.com/aromanino">GitHub/aromanino</a></td><td><a href="mailto:a.romanino@gmail.com">mailto:a.romanino@gmail.com</a></td></tr> <tr><th align="left">Guido Porruvecchio</th><td><a href="https://github.com/gporruvecchio">GitHub/porruvecchio</a></td><td><a href="mailto:guido.porruvecchio@gmail.com">mailto:guido.porruvecchio@gmail.com</a></td></tr> </tbody></table> * */