UNPKG

@incdevco/framework

Version:
309 lines (175 loc) 5.68 kB
var Util = require('util'); var Promise = require('bluebird'); var Base = require('../index'); var Request = require('./request'); var Response = require('./response'); function Lambda(config) { 'use strict'; Base.call(this, config); this.console = config.console || console; this.logger = config.logger || console; this.routes = []; this.useOriginalPath = (config.useOriginalPath) ? true : false; } Util.inherits(Lambda, Base); Lambda.prototype.handleException = function (exception, event, request, response) { 'use strict'; this.log(exception, exception.stack); response.statusCode = 500; if (typeof response.body === 'string') { response.body = {}; } response.body.message = 'An Error Occurred'; if (exception.message === 'Not Found' || exception.message === 'Not Allowed' || exception.code === 'ConditionalCheckFailedException') { throw exception; } else { throw new Error('An Error Occurred'); } //return true; //throw response; }; Lambda.prototype.handler = function (event, context) { 'use strict'; var request, response, self = this; request = new Request(self, event); response = new Response(); this.log('original-event', JSON.stringify(event, null, 2)); Promise.try(function () { return self.route(event, request, response); }) .then(function () { return self.pre(event, request, response); }) .then(function () { return request.handler(event, request, response); }) .then(function () { self.log('pre post response', Util.inspect(response)); return self.post(event, request, response); }) .catch(function (exception) { return self.handleException(exception, event, request, response); }) .then(function () { /* if (typeof response.body !== 'string') { response.body = JSON.stringify(response.body); } */ self.log('final response', Util.inspect(response)); context.succeed(response.body); }) .catch(function (exception) { context.fail(exception); }); }; Lambda.prototype.log = function () { 'use strict'; this.console.log.apply(this.console, arguments); }; Lambda.prototype.options = function (event, request, response) { 'use strict'; response.headers['Access-Control-Allow-Headers'] = 'authorization, content-type, x-amz-date, x-amz-security-token, x-api-key'; response.headers['Access-Control-Allow-Methods'] = 'DELETE,POST,PUT'; response.headers['Access-Control-Allow-Origin'] = '*'; response.body = ''; return Promise.resolve(true); }; Lambda.prototype.pre = function (event, request, response) { 'use strict'; return this.Promise.resolve(true); }; Lambda.prototype.Promise = Promise; Lambda.prototype.post = function (event, request, response) { 'use strict'; return this.Promise.resolve(true); }; Lambda.prototype.register = function (path, method, handler) { if (this.useOriginalPath) { return this.registerWithOriginalPath(path, method, handler); } else { return this.registerWithPath(path, method, handler); } }; Lambda.prototype.registerWithOriginalPath = function (path, method, handler) { var route = { handler: handler, method: method, params: {}, path: path, regex: path }; this.routes.push(route); return this; }; Lambda.prototype.registerWithPath = function (path, method, handler) { var params = path.match(/:([^\/]+)/ig); var route = { handler: handler, method: method, params: params, path: path, regex: path }; if (route.params) { route.params.forEach(function (param) { route.regex = route.regex.replace(param, '([a-zA-Z0-9-%]+)'); }); } route.regex = new RegExp('^' + route.regex + '$', 'i'); this.routes.push(route); return this; }; Lambda.prototype.route = function (event, request) { 'use strict'; if (request.method === 'OPTIONS') { request.handler = this.options.bind(this); return Promise.resolve(true); } this.log('request', JSON.stringify(request, null, 2)); if (this.useOriginalPath) { return this.routeWithOriginalPath(event, request); } else { return this.routeWithPath(event, request); } }; Lambda.prototype.routeWithOriginalPath = function (event, request) { 'use strict'; var match; for (var i = this.routes.length; i--; ) { if (this.routes[i].method === request.method) { if (this.routes[i].path === request.originalPath) { match = true; request.handler = this.routes[i].handler; } } } if (match) { return Promise.resolve(true); } else { return Promise.reject(new Error('Not Found')); } }; Lambda.prototype.routeWithPath = function (event, request) { 'use strict'; var match, test; for (var i = this.routes.length; i--; ) { if (this.routes[i].method === request.method) { test = this.routes[i].regex.exec(request.path); if (test !== null && test[0] === request.path) { match = true; //this.log('match', test[0]); request.handler = this.routes[i].handler; } } } if (match) { return Promise.resolve(true); } else { return Promise.reject(new Error('Not Found')); } }; module.exports = Lambda;