UNPKG

lambdaws

Version:

AWS lambda functions made easy

122 lines (98 loc) 4.14 kB
var fs = require('fs'), zip = require('node-zip'), path = require('path'); require('./extensions/string'); var DEPENDENCIES_DEFAULT_FOLDER = 'node_modules', MAX_LAMBDA_ZIP_SIZE = 25e+6; var _generateZip = function(_zip){ var options = { type: 'nodebuffer', compression: 'DEFLATE' } var zipped = _zip.generate(options); if(zipped.length >= MAX_LAMBDA_ZIP_SIZE) { throw Error('The zipped function is larger than the maximum file zipe you can upload to AWS Lambda'); } return zipped; } var _getDependencyFolder = function(dep) { var depFolder = path.dirname(require.resolve(dep)) + path.sep; var subFolders = depFolder.split(path.sep); var node_modules_index = subFolders.lastIndexOf('node_modules') + 1; // Zero-based indexes var folders = subFolders.splice(0, node_modules_index + 1); // We select the next folder return folders.join(path.sep); // TODO throw better errors if require fails }; var _addDepsToZip = function(_zip, deps){ var depsFolders = deps .filter(function(dep){ return !dep.startsWith(global.constants.EXTERNALS_PREPENDING_STR) && !dep.startsWith(global.constants.INTERNALS_PREPENDING_STR); }) .map(function(dep) { return _getDependencyFolder(dep); }).filter(function(dep){ // we exclude those deps because they are built-in node and zipping . folder is not wanted return dep !== '.'; }); var zipModules = _zip.folder(DEPENDENCIES_DEFAULT_FOLDER); depsFolders.forEach(function(folder) { _addFolderRecursiveToZipNode(folder, zipModules); }); } var _addFolderRecursiveToZipNode = function(folder, zipNode) { var basename = path.basename(folder); var node = zipNode.folder(basename); var files = fs.readdirSync(folder); files.forEach(function(file) { var fullPath = path.join(folder, file); if(fs.statSync(fullPath).isDirectory()) _addFolderRecursiveToZipNode(fullPath, node); else // TODO It would be nice to exclude non-mandatory files like .md, .txt etc node.file(file, fs.readFileSync(fullPath)); }); }; var _addHandlersToZip = function(zip, configs) { var callbackHandler = !!configs.ignoreResponse ? '_emptyCallbackHandler.js' : '_SQSCallbackHandler.js'; var callbackHandlerFile = fs.readFileSync(__dirname + '/internals/' + callbackHandler); var externalsHandlerFile = fs.readFileSync(__dirname + '/internals/_externalsHandler.js'); var utilsFile = fs.readFileSync(__dirname + '/internals/_utils.js'); zip.file('_callbackHandler.js', callbackHandlerFile); zip.file('_externalsHandler.js', externalsHandlerFile); zip.file('_utils.js', utilsFile); }; var _addInternalsToZip = function(zip, deps) { var internals = deps.filter(function(d) { return d.startsWith(global.constants.INTERNALS_PREPENDING_STR); }); if(internals.length === 0) return; var node = zip.folder(global.constants.INTERNALS_FOLDER_NAME); for(var i in internals) { var internal = internals[i].substr(global.constants.INTERNALS_PREPENDING_STR.length); var fileName = path.basename(internal); node.file(fileName, fs.readFileSync(internal)); } }; module.exports = { zipFunction : function(stringFunc, deps, configs){ var _zip = zip(); _zip.file('index.js', stringFunc); _addHandlersToZip(_zip, configs); _addInternalsToZip(_zip, deps); if (deps) { _addDepsToZip(_zip, deps); } return _generateZip(_zip); }, zipModule : function(moduleOverride, modulePath, deps, configs){ var _zip = zip(); var moduleFile = fs.readFileSync(modulePath); _zip.file('module.js', moduleFile); _zip.file('index.js', moduleOverride); _addHandlersToZip(_zip, configs); _addInternalsToZip(_zip, deps); if (deps) { _addDepsToZip(_zip, deps); } return _generateZip(_zip); } }