andrew-templeton / cfn-lambda Goto Github PK
View Code? Open in Web Editor NEWCloudFormation custom resource helper for Lambda Node.js runtime
License: MIT License
CloudFormation custom resource helper for Lambda Node.js runtime
License: MIT License
I've created a CircleCI custom resource using this library and it works pretty well, thank you :)
The only issue I have is that the library logs the event including the ApiToken
property I pass to the custom resource. I would like to avoid logging sensitive data, or at least sanitize it.
I can probably monkey patch console.log
but that seems very ugly.
I can create a pull request for this issue my self, but would like to decide first on a solution.
Possible solutions:
I think a combination of 1+4 would probably cover most use cases.
I would like to add the aws:cloudformation:stack-name, aws:cloudformation:stack-id, and aws:cloudformation:logical-id tags to the custom resource I am creating. I can retrieve these values from the StackId and LogicalResourceId keys in the event object passed into the lambda request, however, these values are not visible within the scope of the Create, Update, or Delete handlers. Is this a feature that can be added?
I’m attempting to deploy the project https://github.com/mazerte/aws-cloudformation-elastic-transcoder-pipeline using cfn-lambda deploy, and I get the error "InvalidParameterValueException: The runtime parameter of nodejs is no longer supported for creating or updating AWS Lambda functions. We recommend you use the new runtime (nodejs6.10) while creating or updating functions.". It looks like cfn-lambda is the one specifying the runtime parameter of the AWS Lambda function to create.
The debug log generated is:
0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/Cellar/node/7.5.0/bin/node',
1 verbose cli '/usr/local/bin/npm',
1 verbose cli 'run',
1 verbose cli 'cfn-lambda-deploy' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'precfn-lambda-deploy',
4 verbose run-script 'cfn-lambda-deploy',
4 verbose run-script 'postcfn-lambda-deploy' ]
5 info lifecycle [email protected]~precfn-lambda-deploy: [email protected]
6 silly lifecycle [email protected]~precfn-lambda-deploy: no script for precfn-lambda-deploy, continuing
7 info lifecycle [email protected]~cfn-lambda-deploy: [email protected]
8 verbose lifecycle [email protected]~cfn-lambda-deploy: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]~cfn-lambda-deploy: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/jason/Code/rearc-maltese/vendor/aws-cloudformation-elastic-transcoder-pipeline/node_modules/.bin:/Users/jason/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
10 verbose lifecycle [email protected]~cfn-lambda-deploy: CWD: /Users/jason/Code/rearc-maltese/vendor/aws-cloudformation-elastic-transcoder-pipeline
11 silly lifecycle [email protected]~cfn-lambda-deploy: Args: [ '-c', 'node_modules/cfn-lambda/bin/cfn-lambda deploy' ]
12 silly lifecycle [email protected]~cfn-lambda-deploy: Returned: code: 1 signal: null
13 info lifecycle [email protected]~cfn-lambda-deploy: Failed to exec cfn-lambda-deploy script
14 verbose stack Error: [email protected] cfn-lambda-deploy: `node_modules/cfn-lambda/bin/cfn-lambda deploy`
14 verbose stack Exit status 1
14 verbose stack at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:279:16)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at EventEmitter.emit (events.js:192:7)
14 verbose stack at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at ChildProcess.emit (events.js:192:7)
14 verbose stack at maybeClose (internal/child_process.js:890:16)
14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
15 verbose pkgid [email protected]
16 verbose cwd /Users/jason/Code/rearc-maltese/vendor/aws-cloudformation-elastic-transcoder-pipeline
17 error Darwin 15.6.0
18 error argv "/usr/local/Cellar/node/7.5.0/bin/node" "/usr/local/bin/npm" "run" "cfn-lambda-deploy"
19 error node v7.5.0
20 error npm v4.1.2
21 error code ELIFECYCLE
22 error [email protected] cfn-lambda-deploy: `node_modules/cfn-lambda/bin/cfn-lambda deploy`
22 error Exit status 1
23 error Failed at the [email protected] cfn-lambda-deploy script 'node_modules/cfn-lambda/bin/cfn-lambda deploy'.
23 error Make sure you have the latest version of node.js and npm installed.
23 error If you do, this is most likely a problem with the aws-cloudformation-elastic-transcoder-pipeline package,
23 error not with npm itself.
23 error Tell the author that this fails on your system:
23 error node_modules/cfn-lambda/bin/cfn-lambda deploy
23 error You can get information on how to open an issue for this project with:
23 error npm bugs aws-cloudformation-elastic-transcoder-pipeline
23 error Or if that isn't available, you can get their info via:
23 error npm owner ls aws-cloudformation-elastic-transcoder-pipeline
23 error There is likely additional logging output above.
24 verbose exit [ 1, true ]
Like this, tested and works:
/*
npm install archiver --save
npm install async --save
npm install string-format --save
*/
const real_exec = require('child_process').exec,
async = require('async'),
format = require('string-format'),
path = require('path'),
os = require('os'),
fs = require('fs'),
archiver = require('archiver');
function exec(cmd, options, cb){
return real_exec(cmd, options, function(_error, _stdout, _stderr) {
console.log(cmd);
console.log(_stderr);
return cb(_error, _stdout, _stderr);
});
}
const aws_cmds = {
'get-user': 'aws iam get-user \
--output json \
--region "{REGION}"',
'create-role': 'aws iam create-role \
--role-name "{FULL_NAME}" \
--assume-role-policy-document "{TRUST_ARG}"',
'update-assume-role-policy': 'aws iam update-assume-role-policy \
--role-name "{FULL_NAME}" \
--policy-document "{TRUST_ARG}"',
'put-role-policy': 'aws iam put-role-policy \
--role-name "{FULL_NAME}" \
--policy-name "{FULL_NAME}_policy" \
--policy-document "{POLICY_ARG}"',
'lambda create-function': 'aws --region "{REGION}" lambda create-function \
--function-name "{FULL_NAME}" \
--runtime nodejs \
--role "{ROLE_ARN}" \
--handler \'index.handler\' \
--description "{LAMBDA_DESC}" \
--timeout 300 \
--memory-size 128 \
--zip-file "{ZIP_ARG}"',
'lambda update-function-configuration': 'aws --region "{REGION}" lambda update-function-configuration \
--function-name "{FULL_NAME}" \
--role "{ROLE_ARN}" \
--handler \'index.handler\' \
--description "{LAMBDA_DESC}" \
--timeout 300 \
--memory-size 128',
'lambda update-function-code': 'aws --region "{REGION}" lambda update-function-code \
--function-name "{FULL_NAME}" \
--zip-file "{ZIP_ARG}"'
};
var command_opts = {},
default_region = 'us-east-1',
regions = ['us-east-1', 'us-west-2', 'eu-west-1', 'ap-northeast-1'],
resource_dir = path.join(__dirname, '..', '..');
resource_info = require(path.join(__dirname, '..', '..', 'package.json'));
resource_info['version'] = resource_info['version'].replace(/\./g, '-');
var FULL_NAME = format("{name}-{version}", resource_info);
var ZIP_LOCATION = path.join(os.tmpdir(), FULL_NAME + '.zip');
var command_vars = {
'ZIP_LOCATION': ZIP_LOCATION,
'ZIP_ARG': 'fileb://' + ZIP_LOCATION,
'FULL_NAME': FULL_NAME,
'POLICY_ARG': 'file://' + path.join(resource_dir, 'execution-policy.json'),
'TRUST_ARG': 'file://' + path.join(__dirname, 'lib', 'lambda.trust.json'),
'REGION': default_region,
'LAMBDA_DESC': format('CloudFormation Custom Resource service for Custom::{name}', resource_info)
};
var output = fs.createWriteStream(ZIP_LOCATION);
var archive = archiver('zip', {store: true});
output.on('close', start_deploy);
archive.on('error', function(err){
throw err;
});
console.log(format('Zipping Lambda bundle to {}...', ZIP_LOCATION));
archive.directory(resource_dir, '');
archive.pipe(output);
archive.finalize();
console.log('~~~~ Deploying Lambda to all regions (' + regions.join(' ') + '). You may see CREATE errors ~~~~');
console.log('~~~~ This is fine, it simply means that the deployment script will run UPDATEs ~~~~');
function start_deploy() {
exec(format(aws_cmds['get-user'], command_vars), command_opts, handle_roles);
}
function handle_roles(error, stdout, stderr) {
var user_info = JSON.parse(stdout);
var account_re = /arn:aws:iam::(.*?):user.*/
command_vars['ACCOUNT_NUMBER'] = user_info['User']['Arn'].replace(account_re, '$1');
command_vars['ROLE_ARN'] = format('arn:aws:iam::{ACCOUNT_NUMBER}:role/{FULL_NAME}', command_vars);
async.waterfall([
function(callback) {
exec(format(aws_cmds['create-role'], command_vars), command_opts, function(_error, _stdout, _stderr) {
callback(null, _error, _stdout, _stderr);
})
},
function(error, stdout, stderr, callback) {
exec(format(aws_cmds['update-assume-role-policy'], command_vars), command_opts, function(_error, _stdout, _stderr) {
callback(null, _error, _stdout, _stderr);
console.log('Upserted Role!');
})
},
function(error, stdout, stderr, callback) {
exec(format(aws_cmds['put-role-policy'], command_vars), command_opts, function(_error, _stdout, _stderr) {
console.log('Added Policy!');
console.log("Sleeping 5 seconds for policy to propagate.");
setTimeout(function() {
callback(null, _error, _stdout, _stderr);
}, 5000);
});
}],
handle_regions); // waterfall 1
}
function handle_regions(err, error, stdout, stderr) {
console.log('Beginning deploy of Lambdas to Regions: ' + regions.join(' '));
async.eachSeries(regions, handle_region, function () {
console.log('~~~~ All done! Lambdas are deployed globally and ready for use by CloudFormation. ~~~~');
console.log('~~~~ They are accessible to your CloudFormation at: ~~~~');
console.log(format('aws:arn:<region>:{ACCOUNT_NUMBER}:function:{FULL_NAME}', command_vars));
});
}
function handle_region(region, region_callback) {
console.log('Deploying Lambda to: ' + region);
command_vars['REGION'] = region;
async.waterfall([
function(callback) {
exec(format(aws_cmds['lambda create-function'], command_vars), command_opts, function(_error, _stdout, _stderr) {
callback(null, _error, _stdout, _stderr);
});
},
function(error, stdout, stderr, callback) {
exec(format(aws_cmds['lambda update-function-configuration'], command_vars), command_opts, function(_error, _stdout, _stderr) {
callback(null, _error, _stdout, _stderr);
})
},
function(error, stdout, stderr, callback) {
exec(format(aws_cmds['lambda update-function-code'], command_vars), command_opts, function(_error, _stdout, _stderr) {
callback(null, _error, _stdout, _stderr);
});
}
],
function (err, error, stdout, stderr) {
console.log('Upserted lambda');
region_callback();
}
);
}
Attempted Pull request but was denied...
Use case: would like lambda to work with aws china.
Following code should fix issue... alter regex to work with arn:aws-cn:lambda:cn-north-1:000000:function:new-function
Change to index.js
function getEnvironment(context) { var parsedArn = context.invokedFunctionArn.match(/^arn:aws.*:lambda:(\w+-\w+-\d+):(\d+):function:(.*)$/); return { LambdaArn: parsedArn[0], Region: parsedArn[1], AccountId: parsedArn[2], LambdaName: parsedArn[3] }; }
I have an asyncCreate() with LongRunning.PingInSeconds=120
https://github.com/andrew-templeton/cfn-lambda/blob/development/index.js#L180
First time it wait for 120 sec and invokes lambda and exits.
The invocation works. I reply NotDone() and it gets the message so, as follows
INFO Got NotDone signal callback from implementation of cfn-lambda resource, engaging another tick in the cycle.
But after that it sets timeout again for 120 sec. But this doesn't work. It doesn't comeback after 120 sec. The code inside setTimeout()
doesn't execute.
| 2020-08-18T00:58:01.902+05:30 | 2020-08-17T19:28:01.902Z xxx INFO Terminating this lambda and allowing lambda recursion to take over.
| 2020-08-18T00:58:01.935+05:30 | END RequestId: xxxxx
| 2020-08-18T00:58:01.935+05:30 | REPORT RequestId: xxx Duration: 124947.01 ms Billed Duration: 125000 ms Memory Size: 128 MB Max Memory Used: 117 MB Init Duration: 1322.69 ms
XRAY TraceId: xxx SegmentId: xxx Sampled: true
Logs from 1st (and only poll):
LongRunningRequestContext found, proceeding with ping cycle logic:
INFO Inside LongRunning request ping cycle and not timed out, diverting Create to handler with notDone callback supplied.
Got NotDone signal callback from implementation of cfn-lambda resource, engaging another tick in the cycle.
Long running configurations found and initialization sent SUCCESS, continuing with recurse operation:
In 120 seconds, will recurse with event:
2020-08-18T00:58:02.495+05:30 | END RequestId: xxx |
---|---|
2020-08-18T00:58:02.495+05:30 |
| 2020-08-18T00:58:01.902+05:30 | 2020-08-17T19:28:01.902Z xxx INFO Terminating this lambda and allowing lambda recursion to take over.
We use both GitHub's built in vulnerability scanner as well as a third-party one snyk.io and there seems to be a few issues with the latest version.
https://app.snyk.io/test/npm/cfn-lambda/2.1.3
Is there a specific reason you are including aws-sdk
into this bundle? Is it not good enough to lock the API versions in the code and then let it inherit the module from AWS lambda natively? Seems like that would clear up a number of issues.
Please release new version of cfn-lambda to get the latest version of async
I encountered an error .
TypeError: Object.keys called on non-object
at Function.keys (native)
at JSONDeepEquals (/var/task/node_modules/cfn-lambda/src/JSONDeepEquals.js:13:19)
at /var/task/node_modules/cfn-lambda/src/JSONDeepEquals.js:21:16
at Array.every (native)
at JSONDeepEquals (/var/task/node_modules/cfn-lambda/src/JSONDeepEquals.js:20:34)
at /var/task/node_modules/cfn-lambda/src/JSONDeepEquals.js:29:9
at Array.every (native)
at JSONDeepEquals (/var/task/node_modules/cfn-lambda/src/JSONDeepEquals.js:24:40)
at CfnLambda (/var/task/node_modules/cfn-lambda/index.js:172:11)
with these parameters.
var Params = {
"arr": [
"str"
]
};
var OldParams= {
"arr": [
"str"
]
};
console.log(JSONDeepEquals(Params, OldParams));
Perhaps , I think that because node version is v0.10.36.
On node v5.6.0 environment , Object.keys('string')
is no problem.
But, on v0.10.36 environment , error occurs .
I suggest that you change the order of processing .
if (Object(a) !== a) {
return a === b;
}
var ka = Object.keys(a).sort();
var kb = Object.keys(b).sort();
First, thanks for a great boilerplate for Custom Resources.
We've been using this a fair bit to create a number of minor CRs.
I wonder if someone wouldn't mind providing an example of how I could do the following.
I'm looking to build a CR that creates a very specific (hardcoded) type of CloudFront Distro as well as adds an entry to a DynamoDB table.
I already have a CR created and working that only does the DDB update. What I'm struggle to understand is how to CRUD a CloudFront Distro but restrict the values it takes in from CloudFormation.
Essentially the values it would take in...
Source: domain1.com
Target: domain2.com
Then it would create a CF distro that uses the Source as the Alias
.
The Node.js 6.10 runtime is now deprectated for new lambda functions.
So when I tried to use your launcher page for cfn-lex-bot, I get the following error in Cloudformation:
Hi, are there any plans to support sdk v3? I am getting invoke errors when using new LambdaClient for SDK V3 client/lambda but works fine with SDK V2. Also, is this library being actively maintained? I haven't seen update since July, 2022
Uncaught Exception {
"errorType": "TypeError",
"errorMessage": "resourceDefinition.LongRunning.LambdaApi.invoke is not a function",
"stack": [
"TypeError: resourceDefinition.LongRunning.LambdaApi.invoke is not a function",
" at Timeout._onTimeout (/var/task/node_modules/cfn-lambda/index.js:189:50)",
" at listOnTimeout (node:internal/timers:569:17)",
" at process.processTimers (node:internal/timers:512:7)"
]
}
Lex resources like intent and slot types can have large number of property values that could make olddata more than 4k(current custom resource response object size limit). Such old resource property values are making update to fail due to large response size to responseURL.
Assume the following code for a custom resource function:
const CfnLambdaFactory = require('cfn-lambda');
exports.handler = CfnLambdaFactory({
AsyncCreate: /* Valid async create handler */,
AsyncUpdate: /* Valid async update handler */,
AsyncDelete: /* Valid async delete handler */,
Schema: /* Valid schema */
});
If this is executed for the first time, everything is fine. But, when executing it again, and there is a cached execution environment in AWS' Lambda execution environment already, the second execution will log warnings like this:
2021-04-21T11:26:02.545Z 9c68dea6-3a26-4ca5-88a7-cdb011eb06fe INFO WARNING: Both Create and AsyncCreate handlers defined. Ignoring AsyncCreate
2021-04-21T11:26:02.545Z 9c68dea6-3a26-4ca5-88a7-cdb011eb06fe INFO WARNING: Both Update and AsyncUpdate handlers defined. Ignoring AsyncUpdate
2021-04-21T11:26:02.545Z 9c68dea6-3a26-4ca5-88a7-cdb011eb06fe INFO WARNING: Both Delete and AsyncDelete handlers defined. Ignoring AsyncDelete
These warnings are misleading: There's nothing wrong really with the resource definition, but rather due to the caching the resource definition is now wrong. The first execution has added the Create
, Update
, and Delete
definitions to it.
For quick reference:
Lines 34 to 50 in 8bad51a
I could see these options to fix this:
delete
the AsyncCreate
, AsyncUpdate
, and AsyncDelete
properties after adding the wrappers. This would change a parameter though, so as developer I would not expect this unless there's a huge warning somewhere in the docs. But ...return function CfnLambda
, so that these only get executed on the first call.WDYT?
Also: Regardless of which fix is chosen, it would be nice to move from console.log('WARNING: ...')
to console.warn('...')
:)
Can we use the same service token generated by the lambda function for creating more than more than one intent?
Brainstorming a bit: I think the long-running lambda configuration could be simplified by leveraging the waitFor
method in the AWS JavaScript SDK, which implements the 'waiters' API defined in the AWS API JSON documents. For example, the CloudFront DistributionDeployed
waiter (distributionDeployed
in the JavaScript SDK) is defined to periodically call the underlying GetDistribution
(cloudFront.getDistribution
in the JavaScript SDK) operation every 60 seconds (at most 25 times), returning successfully only when the response path of Distribution.Status
is equal to Deployed
. It should be possible to pass these existing waiter names into cfn-lambda and re-use waitFor
directly, rather than re-implement each waiter from scratch in a custom format. Here's some sample code:
// `client` is the selected AWS service client instance
// `lambda` is an AWS Lambda client instance
// `event`, `context` are the parameters received by the lambda handler function
// `state` is the waiter state name
event.waiting = true; // use this flag to skip create/delete/update action and continue waiting
client.waitFor(state, params, (err, data) => {
if (err) error();
else success();
});
setTimeout(() => {
console.log("Timeout reached, re-executing function");
lambda.invoke({
FunctionName: context.invokedFunctionArn,
InvocationType: 'Event',
Payload: JSON.stringify(event)
}, (err, data) => {
if (err) error();
else context.done();
});
}, context.getRemainingTimeInMillis() - 1000);
I have this working in a custom resource I've prototyped without cfn-lambda, and I think it could help simplify the long-running lambda feature in this project quite a bit. Think it's worth developing further into a PR, or are there any things you anticipate wouldn't work correctly with this approach?
on deploy.js#L149
function(err, data) {
if (err !== null) {
callback(null, false); <---L149
}
else {
console.log(format('Created Function "{}" on {}!', FULL_NAME, region));
callback(null, true);
}
});
When createFunction() throws error , proceed updateFunction().
Getting 7 test failures on project when running "npm test" (not familiar enough with the test harness to know if these are problem or not).
75 passing (4s)
7 failing
1) SDKAlias Param Manipulation should force booleans along the forceBools path sets:
TypeError: Cannot read property 'Long' of undefined
at src/SDKAlias.js:9:8269
at Array.reduce (native)
at src/SDKAlias.js:9:8048
at Array.forEach (native)
at forcePaths (src/SDKAlias.js:9:7779)
at forceBoolean (src/SDKAlias.js:9:9943)
at usableParams (src/SDKAlias.js:9:4208)
at SimpleAlias (src/SDKAlias.js:9:1871)
at src/SDKAlias.js:9:930
at Context.<anonymous> (test/sdk.alias.js:172:7)
2) SDKAlias Param Manipulation should force numbers along the forceNums path sets:
TypeError: Cannot read property 'Long' of undefined
at src/SDKAlias.js:9:8269
at Array.reduce (native)
at src/SDKAlias.js:9:8048
at Array.forEach (native)
at forcePaths (src/SDKAlias.js:9:7779)
at forceNum (src/SDKAlias.js:9:9547)
at usableParams (src/SDKAlias.js:9:4582)
at SimpleAlias (src/SDKAlias.js:9:1871)
at src/SDKAlias.js:9:930
at Context.<anonymous> (test/sdk.alias.js:229:7)
3) SDKAlias Physical ID Generation should work with string mappable physicalId with no returned values:
TypeError: Cannot read property 'UseMeAsId' of undefined
at src/SDKAlias.js:9:7636
at src/SDKAlias.js:9:2802
at Object.test (test/sdk.alias.js:429:13)
at SimpleAlias (src/SDKAlias.js:9:2370)
at src/SDKAlias.js:9:625
at Context.<anonymous> (test/sdk.alias.js:438:7)
4) Update Should work with unchanged PhysicalResourceId:
Uncaught TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at JSONDeepEquals (src/JSONDeepEquals.js:9:460)
at CfnLambda (index.js:9:10486)
at test/update.js:42:7
at Server.<anonymous> (test-helpers/https/server.js:9:1794)
at emitListeningNT (net.js:1288:10)
at _combinedTickCallback (internal/process/next_tick.js:71:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
5) Update Should work with a provided PhysicalResourceId:
Uncaught TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at JSONDeepEquals (src/JSONDeepEquals.js:9:460)
at CfnLambda (index.js:9:10486)
at test/update.js:67:7
at Server.<anonymous> (test-helpers/https/server.js:9:1794)
at emitListeningNT (net.js:1288:10)
at _combinedTickCallback (internal/process/next_tick.js:71:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
6) Update Should work with a provided Data set:
Uncaught TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at JSONDeepEquals (src/JSONDeepEquals.js:9:460)
at CfnLambda (index.js:9:10486)
at test/update.js:94:7
at Server.<anonymous> (test-helpers/https/server.js:9:1794)
at emitListeningNT (net.js:1288:10)
at _combinedTickCallback (internal/process/next_tick.js:71:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
7) Update Should fail with correct messaging:
Uncaught TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at JSONDeepEquals (src/JSONDeepEquals.js:9:460)
at CfnLambda (index.js:9:10486)
at test/update.js:200:7
at Server.<anonymous> (test-helpers/https/server.js:9:1794)
at emitListeningNT (net.js:1288:10)
at _combinedTickCallback (internal/process/next_tick.js:71:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
=============================================================================
Writing coverage object [/Users/robweaver/Projects/cfn-lambda.orig/coverage/coverage.json]
Writing coverage reports at [/Users/robweaver/Projects/cfn-lambda.orig/coverage]
=============================================================================
=============================== Coverage summary ===============================
Statements : 57.67% ( 346/600 )
Branches : 56.66% ( 183/323 )
Functions : 53.23% ( 66/124 )
Lines : 58.05% ( 346/596 )
================================================================================
npm ERR! Test failed. See above for more details.
I'll admit to not having tested, but your code looks to have the same issue as cfn-response at https://github.com/andrew-templeton/cfn-lambda/blob/development/index.js#L235, in that you leave out parsedUrl.query
from the PUT request URL.
Have you tried against AWS recently?
First, thank you for this great library!
Currently the index.js
exports the deploy
function which in its turn requires the aws-sdk
.
This creates quite a (unnecessarily) big package to deploy and confuses dependency resolution tools (like Webpack).
Is there a way to just use the handler factory without requiring the aws-sdk
?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.