Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

lambda-local

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lambda-local - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

REQUIRE_SAMPLES.md

11

CHANGELOG.md
# ChangeLog
## 1.0.0 (2016/6/xx)
## 1.2.0 (2016/11/23)
* Added mock functionality
* Dropped Node.js v0.1, v0.12 suport
## 1.1.0 (2016/9/15)
* The default behavior of lambda-local now does not forcefully call the callback function (`-c` option).
* Added AWS region option `-r`. Defaults to `us-east-1`.
* Added AWS profile name option `-p`.
## 1.0.0 (2016/6/10)
* lambda-local can now be imported as a node module, and be executed from other node.js programs

@@ -5,0 +14,0 @@

86

lib/context.js

@@ -11,2 +11,5 @@ 'use strict';

var logger,
unmute;
/*

@@ -49,4 +52,3 @@ * doneStatus & postDone were minimum; probably defined internally in Lambda.

Context.callback = function(result) {
console.log('default context callback');
return result;
return result;
};

@@ -60,9 +62,9 @@

Context.createInvokeId = (function() {
return [
utils.generateRandomHex(8),
utils.generateRandomHex(4),
utils.generateRandomHex(4),
utils.generateRandomHex(4),
utils.generateRandomHex(12)
].join('-');
return [
utils.generateRandomHex(8),
utils.generateRandomHex(4),
utils.generateRandomHex(4),
utils.generateRandomHex(4),
utils.generateRandomHex(12)
].join('-');
})();

@@ -75,15 +77,18 @@

Context._initialize = function(options) {
/* set time */
startTime = new Date().getTime();
timeout = options.timeoutMs;
/* set time */
startTime = new Date().getTime();
timeout = options.timeoutMs;
logger = options.logger;
unmute = options.unmute;
/* set function name */
Context.functionName = options.functionName;
/* set function name */
Context.functionName = options.functionName;
/* set requestid */
Context.awsRequestId = options.awsRequestId;
/* set requestid */
Context.awsRequestId = options.awsRequestId;
/* Set callbackWaitsForEmptyEventLoop */
Context.callbackWaitsForEmptyEventLoop = options.callbackWaitsForEmptyEventLoop;
return;
/* Set callbackWaitsForEmptyEventLoop */
Context.callbackWaitsForEmptyEventLoop = options.callbackWaitsForEmptyEventLoop;
return;
};

@@ -95,16 +100,19 @@

Context.done = function(err, message) {
console.log('END');
console.log('\n');
if (err !== null) {
console.log('Error');
console.log('------');
utils.outputJSON(err);
} else {
console.log('Message');
console.log('------');
utils.outputJSON(message);
}
if (!Context.callbackWaitsForEmptyEventLoop) {
Context.callback(true);
}
if(unmute != null) {unmute(); unmute = null;}
if (!Context.callbackWaitsForEmptyEventLoop) {
Context.callback(err, message);
}
logger.log('info', 'END');
if (err !== null) {
logger.log('error', 'Error');
logger.log('error', '------');
utils.outputJSON(err, logger);
} else {
logger.log('info', 'Message');
logger.log('info', '------');
utils.outputJSON(message, logger);
}
if (Context.callbackWaitsForEmptyEventLoop) {
Context.callback(err, message);
}
};

@@ -116,4 +124,5 @@

Context.fail = function(err) {
console.log('FAILING!!');
Context.done(err);
if(unmute != null) {unmute(); unmute = null;}
logger.log('error', 'FAILING!!');
Context.done(err);
};

@@ -125,3 +134,4 @@

Context.succeed = function(message) {
Context.done(null, message);
if(unmute != null) {unmute(); unmute = null;}
Context.done(null, message);
};

@@ -133,4 +143,4 @@

Context.getRemainingTimeInMillis = function() {
var now = new Date().getTime();
return (timeout + startTime - now);
var now = new Date().getTime();
return (timeout + startTime - now);
};

@@ -9,79 +9,85 @@ 'use strict';

var logger = require('winston');
const mute = require('mute'),
utils = require('./utils.js'),
_context = require('./context.js');
utils = require('./utils.js'),
_context = require('./context.js');
var _setLogger = function(_logger){
if(_logger != null && typeof _logger.loggers != 'undefined'){
logger = _logger;
} else {
throw new TypeError("The object must be a winston logger !");
}
}
var _execute = function(opts) {
var event = opts.event,
lambdaPath = opts.lambdaPath,
lambdaHandler = opts.lambdaHandler || 'handler',
profilePath = opts.profilePath,
profileName = opts.profileName,
region = opts.region || 'us-east-1',
callbackWaitsForEmptyEventLoop = (typeof opts.callbackWaitsForEmptyEventLoop === 'undefined') ?
true : opts.callbackWaitsForEmptyEventLoop,
timeoutMs = (typeof opts.timeoutMs === 'undefined') ? 3000 : opts.timeoutMs,
muteLogs = opts.mute,
unmute = null,
callback = opts.callback;
var event = opts.event,
lambdaFunc = opts.lambdaFunc,
lambdaPath = opts.lambdaPath,
lambdaHandler = opts.lambdaHandler || 'handler',
profilePath = opts.profilePath,
profileName = opts.profileName,
region = opts.region || 'us-east-1',
callbackWaitsForEmptyEventLoop = opts.callbackWaitsForEmptyEventLoop || true,
timeoutMs = opts.timeoutMs || 3000,
muteLogs = opts.mute,
unmute = null,
callback = opts.callback;
if(muteLogs) {
unmute = mute();
}
if (lambdaFunc && lambdaPath) {
throw new SyntaxError("Cannot specify both lambdaFunc and lambdaPath !");
return;
}
if(muteLogs) {
unmute = mute();
}
//load profile
if (profilePath) {
utils.loadAWSCredentials(profilePath, profileName);
}
//load profile
if (profilePath) {
utils.loadAWSCredentials(profilePath, profileName);
}
// set region before the require
process.env['AWS_REGION'] = region;
// set region before the require
process.env['AWS_REGION'] = region;
if (!(lambdaFunc)){
// load lambda function
lambdaFunc = require(utils.getAbsolutePath(lambdaPath));
}
// load lambda function
var lambdaFunc = require(utils.getAbsolutePath(lambdaPath));
// load event & context
var context = this.context;
// load event & context
var context = this.context;
context._initialize({
functionName: lambdaHandler,
awsRequestId: context.createInvokeId,
timeoutMs: timeoutMs,
callbackWaitsForEmptyEventLoop: callbackWaitsForEmptyEventLoop,
unmute: unmute,
logger: logger
});
// export the LAMBDA_TASK_ROOT enviroment variable
process.env['LAMBDA_TASK_ROOT'] = process.cwd();
context._initialize({
functionName: lambdaHandler,
awsRequestId: context.createInvokeId,
timeoutMs: timeoutMs,
callbackWaitsForEmptyEventLoop: callbackWaitsForEmptyEventLoop
});
// export the LAMBDA_TASK_ROOT enviroment variable
process.env['LAMBDA_TASK_ROOT'] = process.cwd();
//setting common other vars environments
process.env['NODE_PATH'] = utils.getAbsolutePath('node_modules');
process.env['LAMBDA_CONSOLE_SOCKET'] = 14;
process.env['LAMBDA_CONTROL_SOCKET'] = 11;
process.env['AWS_SESSION_TOKEN'] = context.awsRequestId; /*Just a random value...*/
//setting common other vars environments
process.env['NODE_PATH'] = utils.getAbsolutePath('node_modules');
process.env['LAMBDA_CONSOLE_SOCKET'] = 14;
process.env['LAMBDA_CONTROL_SOCKET'] = 11;
process.env['AWS_SESSION_TOKEN'] = context.awsRequestId; /*Just a random value...*/
// execute lambda function
logger.log('info', 'Logs');
logger.log('info', '------');
logger.log('info', 'START RequestId: ' + context.awsRequestId);
// execute lambda function
console.log('Logs');
console.log('------');
console.log('START RequestId: ' + context.awsRequestId);
context.callback = callback;
if (callback) {
lambdaFunc[lambdaHandler](event, context, function (err, data) {
if (muteLogs) {
unmute();
}
callback(err, data);
});
} else {
lambdaFunc[lambdaHandler](event, context, function (err, message) {
if (muteLogs) {
unmute();
}
context.done(err, message);
});
}
if(callback) context.callback = callback;
lambdaFunc[lambdaHandler](event, context, context.done);
};
module.exports = {
context: _context,
execute: _execute
context: _context,
execute: _execute,
setLogger: _setLogger
};

@@ -1,2 +0,2 @@

'use strict';
'use strict'

@@ -16,30 +16,36 @@ /**

var _generateRandomHex = function(length) {
var hexVal = '';
for (var i = 0; i < length; i++) {
hexVal += _hexChars[Math.floor(Math.random() * _hexChars.length)];
}
return hexVal;
var hexVal = '';
for (var i = 0; i < length; i++) {
hexVal += _hexChars[Math.floor(Math.random() * _hexChars.length)];
}
return hexVal;
};
var _getAbsolutePath = function(path) {
var res = null,
homeDir = process.env.HOME || process.env.USERPROFILE;
if (path.match(/^\//)) {
res = path;
} else {
if (path === '~') {
res = homeDir;
} else if (path.slice(0, 2) !== '~/') {
res = join(process.cwd(), path);
var res = null,
homeDir = process.env.HOME || process.env.USERPROFILE;
var windowsRegex = /([A-Z|a-z]:\\[^*|"<>?\n]*)|(\\\\.*?\\.*)/;
if (path.match(/^\//) || path.match(windowsRegex)) {
//On Windows and linux
res = path;
} else {
res = join(homeDir, path.slice(2));
if (path === '~') {
//On linux only
res = homeDir;
} else if (path.slice(0, 2) !== '~/') {
//On Windows and linux
res = join(process.cwd(), path);
} else {
//On linux only
res = join(homeDir, path.slice(2));
}
}
}
return res;
return res;
};
var _outputJSON = function(json) {
console.log(typeof json === 'object' ?
JSON.stringify(json, null, '\t') : json);
var _outputJSON = function(json, logger) {
logger.log('info', typeof json === 'object' ?
JSON.stringify(json, null, '\t') : json);
};

@@ -51,34 +57,34 @@

var _loadAWSCredentials = function(path) {
//default parameter
var profileName = arguments.length <= 1 ||
arguments[1] === undefined ||
arguments[1] === null ? 'default' : arguments[1];
//default parameter
var profileName = arguments.length <= 1 ||
arguments[1] === undefined ||
arguments[1] === null ? 'default' : arguments[1];
var fs = require('fs'),
dataRaw = fs.readFileSync(_getAbsolutePath(path)),
data = dataRaw.toString();
var fs = require('fs'),
dataRaw = fs.readFileSync(_getAbsolutePath(path)),
data = dataRaw.toString();
var regex = new RegExp('\\[' + profileName +
'\\](.|\\n|\\r\\n)*?aws_secret_access_key( ?)+=( ?)+(.*)'),
match;
if ((match = regex.exec(data)) !== null) {
process.env['AWS_SECRET_ACCESS_KEY'] = match[4];
} else {
console.log('WARNING: Couldn\'t find the \'aws_secret_access_key\' field inside the file.');
}
var regex = new RegExp('\\[' + profileName +
'\\](.|\\n|\\r\\n)*?aws_secret_access_key( ?)+=( ?)+(.*)'),
match;
if ((match = regex.exec(data)) !== null) {
process.env['AWS_SECRET_ACCESS_KEY'] = match[4];
} else {
console.log('WARNING: Couldn\'t find the \'aws_secret_access_key\' field inside the file.');
}
regex = new RegExp('\\[' + profileName + '\\](.|\\n|\\r\\n)*?aws_access_key_id( ?)+=( ?)+(.*)');
if ((match = regex.exec(data)) !== null) {
process.env['AWS_ACCESS_KEY_ID'] = match[4];
} else {
console.log('WARNING: Couldn\'t find the \'aws_access_key_id\' field inside the file.');
}
regex = new RegExp('\\[' + profileName + '\\](.|\\n|\\r\\n)*?aws_access_key_id( ?)+=( ?)+(.*)');
if ((match = regex.exec(data)) !== null) {
process.env['AWS_ACCESS_KEY_ID'] = match[4];
} else {
console.log('WARNING: Couldn\'t find the \'aws_access_key_id\' field inside the file.');
}
};
module.exports = {
hexChars: _hexChars,
generateRandomHex: _generateRandomHex,
getAbsolutePath: _getAbsolutePath,
outputJSON: _outputJSON,
loadAWSCredentials: _loadAWSCredentials
hexChars: _hexChars,
generateRandomHex: _generateRandomHex,
getAbsolutePath: _getAbsolutePath,
outputJSON: _outputJSON,
loadAWSCredentials: _loadAWSCredentials
};
{
"name": "lambda-local",
"version": "1.1.0",
"version": "1.2.0",
"description": "Commandline tool to run Lambda functions on your local machine.",

@@ -19,8 +19,11 @@ "keywords": [

"aws-sdk": "^2.1.6",
"chai": "^3.5.0",
"commander": "^2.6.0",
"fs": "^0.0.2",
"mute": "^2.0.6"
"mute": "^2.0.6",
"winston": "^2.2.0"
},
"devDependencies": {
"mocha": "^2.4.5"
"mocha": "^2.4.5",
"sinon": "^1.17.6"
},

@@ -27,0 +30,0 @@ "scripts": {

@@ -28,29 +28,7 @@ # Lambda-local

You can also use Lambda local directly in a script. For instance, it is interesting in a [mocha][1] test suite in combination with [istanbull][2] in order to get test coverage.
```js
const lambdaLocal = require('lambda-local');
You can also use Lambda local directly in a script. For instance, it is interesting in a [MochaJS][1] test suite in order to get test coverage.
var jsonPayload = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
}
See [API](#api) for more infos
lambdaLocal.execute({
event: jsonPayload,
lambdaPath: path.join(__dirname, 'path/to/index.js'),
profilePath: '~/.aws/credentials',
profileName: 'default',
timeoutMs: 3000,
callback: function(err, data) {
if (err) {
console.log(err);
} else {
console.log(data);
}
}
});
```
## About

@@ -64,4 +42,5 @@

* -n, --no-force-callback (optional) Force the function to stop after having called the handler function even if context.done/succeed/fail was not called.
* -p, --profile <aws profile name> (optional) Read the AWS profile to get the credentials from file name.
* -p, --profile-path <aws profile name> (optional) Read the specified AWS credentials file.
* -r, --region <aws region> (optional) Sets the AWS region, defaults to us-east-1.
* -P, --profile-path <aws profile name> (optional) Read the specified AWS credentials file.
* -p, --profile <aws profile name> (optional) Use with **-P**: Read the AWS profile of the file.

@@ -90,3 +69,3 @@ ### Event data

### LambdLocal
### LambdaLocal

@@ -98,11 +77,18 @@ #### `execute(options)`

- `lambdaPath` - requested path to the lambda function,
- `profilePath` - optional path to your AWS credentials file
- `profileName` - optional aws profile name
- `lambdaFunc` - pass the lambda function. You cannot use it at the same time as lambdaPath,
- `profilePath` - optional, path to your AWS credentials file
- `profileName` - optional, aws profile name. Must be used with
- `lambdaHandler` - optional handler name, default to `handler`
- `region` - optional AWS region, default to `us-east-1`
- `callbackWaitsForEmptyEventLoop` - optional, default to `true` which forces the function to stop after having called the handler function even if context.done/succeed/fail was not called.
- `timeoutMs` - optional timeout, default to 3000 ms
- `region` - optional, AWS region, default to `us-east-1`
- `callbackWaitsForEmptyEventLoop` - optional, default to `true`. Setting it to `false` will call the callback when your code do, before finishing lambda-local.
- `timeoutMs` - optional, timeout, default to 3000 ms
- `mute` - optional, allows to mute console.log calls in the lambda function, default false
- `callback` - optional lambda third parameter [callback][3]
- `callback` - optional, lambda third parameter [callback][1]
#### `setLogger(logger)`
If you are using [winston](https://www.npmjs.com/package/winston), this pass a winston logger instead of the console.
#### [Samples](REQUIRE_SAMPLES.md)
## License

@@ -112,5 +98,2 @@

[1]: https://mochajs.org/
[2]: http://gotwarlost.github.io/istanbul/
[3]: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html
[1]: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

@@ -1,41 +0,130 @@

'use strict';
"use strict";
var assert = require('assert');
var path = require('path');
var assert = require("chai").assert;
var path = require("path");
var fs = require("fs");
var functionName = 'handler';
var functionName = "handler";
var timeoutMs = 3000;
var lambdalocal = require('../lib/lambdalocal.js');
var callbackFunc = function(err, data) {
describe('LambdaLocal', function() {
it('err should be null', function() {
assert.equal(err, null);
var sinon = require("sinon");
var winston = require("winston");
winston.level = "error";
describe("- Testing utils.js", function () {
var utils = require("../lib/utils.js");
describe("* getAbsolutePath", function () {
it("should return existing path file", function () {
var f_path = utils.getAbsolutePath("test.js");
assert.doesNotThrow(function(){fs.accessSync(f_path, fs.F_OK)});
});
});
it('data should not be null', function() {
assert.notEqual(data, null);
describe("* generateRandomHex", function () {
it("should not return twice the same value", function () {
var first = utils.generateRandomHex(10);
var second = utils.generateRandomHex(10);
assert.notEqual(first, second);
});
});
});
});
describe("- Testing lambdalocal.js", function () {
describe("* Basic Run", function () {
var done, err;
before(function (cb) {
var lambdalocal = require("../lib/lambdalocal.js");
lambdalocal.setLogger(winston);
lambdalocal.execute({
event: require(path.join(__dirname, "./events/test-event.js")),
lambdaPath: path.join(__dirname, "./functs/test-func.js"),
lambdaHandler: functionName,
callbackWaitsForEmptyEventLoop: false,
timeoutMs: timeoutMs,
callback: function (_err, _done) {
err = _err;
done = _done;
cb();
}
});
});
describe("# LambdaLocal", function () {
it("should return correct testvar", function () {
assert.equal(done.result, "testvar");
});
});
describe('Context object', function() {
it('should contain initialized functionName', function() {
assert.equal(lambdalocal.context.functionName, functionName);
describe("# Context object", function () {
it("should contain initialized functionName", function () {
assert.equal(done.context.functionName, functionName);
});
it("should contain initialized awsRequestId", function () {
assert.equal(done.context.awsRequestId.length, 36);
});
it("should contain initialized getRemainingTimeInMillis", function () {
assert.isAtMost(done.context.getRemainingTimeInMillis(), timeoutMs);
});
it("should contain done function", function () {
assert.isDefined(done.context.done);
});
it("should contain succeed function", function () {
assert.isDefined(done.context.succeed);
});
it("should contain fail function", function () {
assert.isDefined(done.context.fail);
});
});
describe("* Mocked function", function () {
var done, err;
before(function (cb) {
var lambdalocal = require("../lib/lambdalocal.js");
lambdalocal.setLogger(winston);
var lambdaFunc = require("./functs/test-func-mocking.js");
sinon.mock(lambdaFunc).expects("getData").returns("MockedData");
lambdalocal.execute({
event: require(path.join(__dirname, "./events/test-event.js")),
lambdaFunc: lambdaFunc,
lambdaHandler: functionName,
callbackWaitsForEmptyEventLoop: false,
timeoutMs: timeoutMs,
callback: function (_err, _done) {
err = _err;
done = _done;
cb();
}
});
});
describe("# LambdaLocal", function () {
it("should return mocked value", function () {
assert.equal(done, "MockedData");
});
});
});
});
it('should contain initialized awsRequestId', function() {
assert.equal(lambdalocal.context.awsRequestId.length === 36, true);
describe("* AWS Profile Test Run", function () {
var done, err;
before(function (cb) {
var lambdalocal = require("../lib/lambdalocal.js");
lambdalocal.setLogger(winston);
lambdalocal.execute({
event: require(path.join(__dirname, "./events/test-event.js")),
lambdaPath: path.join(__dirname, "./functs/test-func-awsprofile.js"),
lambdaHandler: functionName,
profilePath: path.join(__dirname, "./other/debug.aws"),
callbackWaitsForEmptyEventLoop: false,
timeoutMs: timeoutMs,
callback: function (_err, _done) {
done = _done;
err = _err;
cb();
}
});
});
describe("# AWS credentials", function () {
it("should return correct credentials", function () {
assert.equal(done.key, "AKIAIOSFODNN7EXAMPLE");
assert.equal(done.secret, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
});
});
});
it('should contain initialized getRemainingTimeInMillis', function() {
assert.equal((lambdalocal.context.getRemainingTimeInMillis() <= timeoutMs), true);
});
});
};
lambdalocal.execute({
event: require(path.join(__dirname, './test-event.js')),
lambdaPath: path.join(__dirname, './test-func.js'),
lambdaHandler: functionName,
profilePath: path.join(__dirname, './debug.aws'),
callbackWaitsForEmptyEventLoop: true,
timeoutMs: timeoutMs,
callback: callbackFunc
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc