@smallwins/lambda
Advanced tools
Comparing version 4.11.0 to 4.15.0
{ | ||
"name": "@smallwins/lambda", | ||
"version": "4.11.0", | ||
"version": "4.15.0", | ||
"description": "Author your AWS Lambda functions as node style errbacks.", | ||
@@ -12,2 +12,3 @@ "main": "index", | ||
"invoke": "./scripts/invoke.js", | ||
"local": "./scripts/local.js", | ||
"deps": "./scripts/deps.js" | ||
@@ -20,2 +21,3 @@ }, | ||
"lambda-invoke": "./scripts/invoke.js", | ||
"lambda-local": "./scripts/local.js", | ||
"lambda-deps": "./scripts/deps.js" | ||
@@ -22,0 +24,0 @@ }, |
@@ -42,5 +42,5 @@ [ ![Codeship Status for smallwins/lambda](https://codeship.com/projects/2e4082e0-d808-0133-2035-1eae90b9310e/status?branch=master)](https://codeship.com/projects/143109) | ||
A huge amount of vanilla Lambda code is working around quirky parameter validation. API Gateway gives you control over the parameters you can expect but this still means one or more of: headers, querystring paramters, form body, or url parameters. Event source style Lambdasare not much better because you get different payloads depending on the source. In the example above we are validating one query string parameter `x`. Imagine a big payload! 😮 | ||
A huge amount of vanilla Lambda code is working around quirky parameter validation. API Gateway gives you control over the parameters you can expect but this still means one or more of: headers, querystring paramters, form body, or url parameters. Event source style Lambdasare not much better because you still get different payloads depending on the source. In the example above we are validating *one* query string parameter `x`. Imagine a big payload! 😮 | ||
Builtin `Error` needs manual serialization (and you still lose the stack trace). The latter part of the code uses the funky AWS `context` object. | ||
Worse still, writing a good program we want to use JavaScript's builtin `Error` but it still needs manual serialization (and you still lose the stack trace). The latter part of this vanilla code uses the funky AWS `context` object. | ||
@@ -71,7 +71,7 @@ We can do better: | ||
`@smallwins/validate` cleans up parameter validation. The callback style above enjoys symmetry with the rest of Node and will automatically serialize `Error`s into JSON friendly objects including any stack trace. All you need to do is wrap a vanilla Node errback function in `lambda` which returns your function with an AWS Lambda friendly signature. | ||
`@smallwins/validate` cleans up parameter validation. The callback style above enjoys symmetry with the rest of Node and will automatically serialize `Error`s into JSON friendly objects including any stack trace. All you need to do is wrap a your node style function in `lambda` which returns your function with an AWS Lambda friendly signature. | ||
#### :loop::loop::loop: easily chain dependant actions ala middleware :loop::loop::loop: | ||
Building on this foundation we can compose multiple errbacks into a Lambda. Lets compose a Lambda that: | ||
Building on this foundation we can compose multiple functions into a single Lambda. It is very common to want to run functions in series. Lets compose a Lambda that: | ||
@@ -138,10 +138,10 @@ - Validates parameters | ||
- `lambda(...fns)` create a lambda that returns a serialized json result `{ok:true|false}` | ||
- `lambda([fns], callback)` create a lambda and handle result with your own errback formatter | ||
- `lambda.local(fn, fakeEvent, (err, result)=>)` run a lamda locally offline by faking the event obj | ||
- `lambda.sources.dynamo.all(...fns)` | ||
- `lambda.sources.dynamo.save(...fns)` | ||
- `lambda.sources.dynamo.insert(...fns)` | ||
- `lambda.sources.dynamo.modify(...fns)` | ||
- `lambda.sources.dynamo.remove(...fns)` | ||
- `lambda(...fns)` create a Lambda that returns a serialized json result `{ok:true|false}` | ||
- `lambda([fns], callback)` create a Lambda and handle result with your own errback formatter | ||
- `lambda.local(fn, fakeEvent, (err, result)=>)` run a Lambda locally offline by faking the event obj | ||
- `lambda.sources.dynamo.all(...fns)` run on INSERT, MODIFY and REMOVE | ||
- `lambda.sources.dynamo.save(...fns)` run on INSERT and MODIFY | ||
- `lambda.sources.dynamo.insert(...fns)` run on INSERT only | ||
- `lambda.sources.dynamo.modify(...fns)` run on MODIFY only | ||
- `lambda.sources.dynamo.remove(...fns)` run on REMOVE only | ||
@@ -160,3 +160,3 @@ A handler looks something like this | ||
Good error handling makes your programs far easier to maintain. (This is a good guide.)[https://www.joyent.com/developers/node/design/errors]. When using `@smallwins/lambda` always use `Error` type as the first parameter to callback: | ||
Good error handling makes programs easier to maintain. [This is a great guide digging in more.](https://www.joyent.com/developers/node/design/errors). When using `@smallwins/lambda` always use `Error` type as the first parameter to the callback: | ||
@@ -180,3 +180,3 @@ ```javascript | ||
`@smallwins/lambda` serializes error into Slack RPC style JSON making them easy to work from API Gateway: | ||
`@smallwins/lambda` serializes errors into Slack RPC style JSON. Easier to work from API Gateway: | ||
@@ -222,2 +222,3 @@ ```javascript | ||
"invoke":"AWS_PROFILE=smallwins lambda-invoke", | ||
"local":"AWS_PROFILE=smallwins lambda-local", | ||
"deps":"AWS_PROFILE=smallwins lambda-deps" | ||
@@ -231,4 +232,5 @@ } | ||
- :point_right: <kbd>npm run deploy src/lambdas/signup brian</kbd> deploys the lambda with the alias `brian` | ||
- :point_right:<kbd>npm run invoke src/lambdas/login brian '{"email":"b@brian.io", "pswd":"..."}'</kbd> to invoke a lambda | ||
- :point_right:<kbd>npm run deps src/lambdas/*</kbd> for a report of all your lambda deps | ||
- :point_right: <kbd>npm run invoke src/lambdas/login brian '{"email":"b@brian.io", "pswd":"..."}'</kbd> to remote invoke a deployed lambda | ||
- :point_right: <kbd>npm run local src/lambdas/login brian '{"email":"b@brian.io", "pswd":"..."}'</kbd> to locally invoke a lambda | ||
- :point_right: <kbd>npm run deps src/lambdas/*</kbd> for a report of all your lambda deps | ||
@@ -245,1 +247,2 @@ The `./scripts/invoke.js` is also a module and can be useful for testing. | ||
Of course you can also mock invoke a Lambda locally with `lambda.local`. |
@@ -10,2 +10,3 @@ #!/usr/bin/env node | ||
console.log(chalk.green(' λ ') + chalk.grey.dim('analyzing local dependencies')) | ||
dirs.forEach(dir=> { | ||
@@ -12,0 +13,0 @@ var pkg = join(dir, 'package.json') |
#!/usr/bin/env node | ||
var async = require('async') | ||
var aws = require('aws-sdk') | ||
@@ -7,13 +7,64 @@ var region = process.env.AWS_REGION || 'us-east-1' | ||
var chalk = require('chalk') | ||
var startsWith = require('lodash').startsWith | ||
var lodash = require('lodash') | ||
var startsWith = lodash.startsWith | ||
var padEnd = lodash.padEnd | ||
var padStart = lodash.padStart | ||
var filtering = process.argv[2] || '' | ||
function log(txt) { | ||
function info(txt) { | ||
console.log(chalk.green(' λ ') + chalk.cyan.underline.dim(txt)) | ||
} | ||
lambda.listFunctions({}, (err, fns)=> { | ||
console.log(chalk.green(' λ ') + chalk.dim.grey('listing deployed lambdas' )) | ||
var names = fns.Functions.map(f=> f.FunctionName).sort().filter(name=> startsWith(name, filtering)) | ||
names.forEach(log) | ||
console.log(chalk.green(' λ ')) | ||
function list(callback) { | ||
lambda.listFunctions({}, (err, fns)=> { | ||
console.log(chalk.green(' λ ') + chalk.grey.dim('listing deployed lambdas')) | ||
var name = f=> f.FunctionName | ||
var start = name=> startsWith(name, filtering) | ||
var names = fns.Functions.map(name).filter(start).sort() | ||
callback(err, names) | ||
}) | ||
} | ||
function aliases(names, callback) { | ||
var handlers = names.map(name=> { | ||
return function getAliasesFor(callback) { | ||
var params = { | ||
FunctionName: name, | ||
} | ||
lambda.listAliases(params, (err, na)=> { | ||
var readable = na.Aliases.map(a=> { | ||
return { | ||
name:a.Name, | ||
version:a.FunctionVersion | ||
} | ||
}) | ||
callback(err, {name:name, aliases:readable}) | ||
}) | ||
} | ||
}) | ||
/* | ||
function done(err, result) { | ||
if (err) { | ||
callback(err) | ||
} | ||
else { | ||
callback(null, result) | ||
} | ||
}*/ | ||
async.parallel(handlers, callback) | ||
} | ||
async.waterfall([list, aliases], function complete(err, result) { | ||
result.forEach(row=> { | ||
info(row.name) | ||
row.aliases.forEach(a=> { | ||
var latest = a.version === '$LATEST' | ||
var ver = padStart(a.version, 25, '.') | ||
var ca = chalk.green(' λ ') | ||
var cb = chalk.grey(' - ' + padEnd(a.name, 10, '.')) | ||
var cc = latest? chalk.dim.grey(ver) : chalk.dim.yellow(ver) | ||
console.log(ca + cb + cc) | ||
}) | ||
console.log(chalk.green(' λ ')) | ||
}) | ||
}) |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
33847
19
904
241
10