# nealyip-aws-lambda-helper

> S3, Dynamodb ORM and moment js with timezone npm packages

Latest version **1.2.37** (published 2020-05-10) · 0 weekly downloads

## Install

```sh
npm install nealyip-aws-lambda-helper
pnpm add nealyip-aws-lambda-helper
yarn add nealyip-aws-lambda-helper
bun add nealyip-aws-lambda-helper
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.2.37 |
| Published | 2020-05-10 |
| First published | 2017-08-08 |
| Weekly downloads | 0 |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 578.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | nealyip |

## Links

- npm: https://www.npmjs.com/package/nealyip-aws-lambda-helper
- npm.io page: https://npm.io/package/nealyip-aws-lambda-helper

## Recent versions

- 1.2.37 (latest) — 2020-05-10
- 1.1.5-beta-02 (beta) — 2018-04-23
- 1.2.36 — 2020-04-01
- 1.2.35 — 2020-04-01
- 1.2.34 — 2019-08-14
- 1.2.33 — 2019-07-10
- 1.2.32 — 2019-05-10
- 1.2.31 — 2019-04-16
- 1.2.30 — 2019-04-16
- 1.2.29 — 2019-04-03
- 1.2.28 — 2019-04-03
- 1.2.27 — 2019-01-24
- 1.2.26 — 2019-01-22
- 1.2.25 — 2019-01-14
- 1.2.24 — 2018-12-13
- … 105 more at https://npm.io/package/nealyip-aws-lambda-helper/versions

## README

# README #

S3, Dynamodb ORM and moment js with timezone npm packages

### Update Log ###
v1.2.37 Hint multiValueQueryStringParameters on Response  
v1.2.34 Make getItem honours projectionExpression  
v1.2.33 Make SendMessageRequest fields optional  
v1.2.32 Add SQS Support  
v1.2.31 Enhance SNS Support  
v1.2.30 Add SNS support  
v1.2.29 Support Passphrase for RSA Signing    
v1.2.28 Add PSS padding for RSA Signing  
v1.2.27 Trim cookie name in the cookie parse function.  
v1.2.26 Fix cookie's parse function, use the first seen value. Add multi value cookies parser.  
v1.2.25 Fix wrong output type definition  
v1.2.24 Fix misuse of const instead of import  
v1.2.23 Add browser support  
v1.2.20 Fix wrong AESGCM cipher suite name  
v1.2.19 Export AESCBC in case of need  
v1.2.17 Fix TS 3 reporting error  
v1.2.16 Add multiValueHeaders return for aws api gateway response  
v1.2.15 Add multiValueHeaders definition for AWS lambda input event  
v1.2.14 For response class's ok and fail message parameter, check with instanceof instead of constructor so that any class or function that implements toJSON method can be passed.  
v1.2.13 Add pkcs7 to aes-cbc cipher suite name  
v1.2.12 Add urlencoded property to Encrypted  
v1.2.11 Fix checking aes key on aes-gcm  
v1.2.10 Fix base64 and hex without cipher_suite property  
v1.2.9 Return cipher_suite name for crypto2  
v1.2.8 Add crypto2 to have a better support for AES  
v1.2.7 Add remove key function to updateItem  
v1.2.6 Add Group by for object array  
v1.2.5 Add Array collapse function, to flatten 2D array to 1D    
v1.2.4 Allow sequenceSequentialUncaught  
v1.2.3 Allow Model's key to be zero  
v1.2.2 Allow Model.getItem empty sort key  
v1.2.0 Typescript Version  
v1.1.5-beta-03 Fix wrong getitem output  
v1.1.5-beta-02 Add queryCount for dynamodb, only return count result for query  
v1.1.5-beta-01 Fix typescript warning for files getfiles function  
v1.1.4-beta-9 Add Recursive folder readers  
v1.1.4-beta-7 Fix wrong response event object parameters  
v1.1.4-beta-6 Allow using attribute_not_exists, attribute_exists for updateitem, @todo allow for query and scan   
v1.1.0 Use typescript
v1.0.65 Support begins_with for model  
v1.0.64 Add queryItems and scanItems for model that directly return items array
v1.0.63 Support conditional expression for DB.updateItem   
v1.0.62 Fix reserved words problem on projectExpression  
v1.0.61 Range for month  
v1.0.60 Fix accidentally remove logging   
v1.0.59 Separate CORS from Response to sub class, add XSRF checking, add Custom Error class  
v1.0.58 Add logging for response  
v1.0.57 Fix error if no headers or origin header is ucfirst  
v1.0.56 Update Response class, now require specify the cors whitelist domains, if nothing or empty string is passed, cors is disabled (default)  
and the return header won't include Access-Control-Allow-Origin header.  
checkCORS method can also be called before to check request before the function
v1.0.55 Add arn helper class to resolve arn to lambda function name  
v1.0.54 Cookie reader and writer  
v1.0.53 Add AES key generator  
v1.0.52 Add copy method to storage  
v1.0.51 Add list object by prefix and check is folder existed function to storage  
v1.0.50 Add no cache header to response  
v1.0.49 Use invocationType for lambda invoke  
v1.0.45 Add alias to lambda function  
v1.0.43 Fix error there is only partition key and sort key when using updateItem on Model   

### To use S3 ###

#### Create a file s3example.js ####
```javascript
let Storage = require('nealyip-aws-lambda-helper/storage');

class S3Example extends Storage {
    constructor(){
        super();
        this.key = 'path/to/example.json';
    }
}

module.exports = S3Example;
```
#### then from the index.js ####
```javascript
const S3Example = require('./s3example');

new S3Example().put('content here')
.catch(err=>console.log(err));

new S3Example().get()
.then(res => console.log(res));
```

### To use dynamodb ###

#### create a file called dbexample.js ####

```javascript
const Model = require('nealyip-aws-lambda-helper/model');

class DBExample extends Model{
    constructor(){
        super();
        this.tableName    = 'test.batch';
        this.partitionKey = 'batch_id';
        this.sortKey      = 'user_id';
    }
}

module.exports = DBExample;
```

#### then from the index.js ####

```javascript
(new DBExample).scan()
.then(res => console.log(res.Items));

(new DBExample).createItem(
{
    'id':1,
    'name':2,
    'value':3
}
).then(res=> console.log('success'), err=>console.log(err));
```
#### updateItem ####
For updateItem, you must provide the partition key and sort key (if there exists).  

#### updateItem conditionally ####
```javascript
// Error will be thrown if the condition does not match
(new DBExample).updateItem(
{
    'id':1,
    'name':2,
    'value':3
},
[['name', '=', '2'], ['value', 'begins_with', '4']]
).then(res=> console.log('success'), err=>console.log(err));
```

#### updateItem for number increment ####
```javascript
(new DBExample).updateItem(
{
    'batch_id':1
},
[],
{
    'value' : 5
}
).then(res=> console.log('success'), err=>console.log(err));
```
Increment in conjunction with conditions  
```javascript
(new DBExample).updateItem(
{
    'batch_id':1
},
[['gender', '=', 'F']],
{
    'value' : 5
}
).then(res=> console.log('success'), err=>console.log(err));
```
#### updateItem with removing keys ####
```javascript
(new DBExample).updateItem(
{
    'batch_id':1
},
[],
{},
['keytoremove1', 'keytoremove2']
).then(res=> console.log('success'), err=>console.log(err));
```

#### query with index ####

dbexample.js
```javascript
const Model = require('nealyip-aws-lambda-helper/model');

class DBExample extends Model{
    constructor(){
        super();
        this.tableName            = 'test.batch';
        this.partitionKey         = 'batch_id';
        this.sortKey              = 'user_id';
        this.indexName            = 'abc-index';
        this.projectionExpression = 'abc,def,ghi';
    }
}

module.exports = DBExample;
```

```javascript

(new DBExample).query([['abc', '>', '1234'],['def', '=', '4444'],['ghi', 'between', ['2222','4444']]])
.then(res => console.log(res.Items));


```

### To invoke lambda function ###

#### create a file called funa.js ####


```javascript
class Funa extends Lambda {
    constructor() {
        super();
        this.function = 'some-function-example';
        // this.region = 'some region' // you can also specify the region for the function whenever the target is in a different region
    }
}
module.exports = Funa;
```
```
The function name will auto be prepended with the ENV variable plus a hyphen side
eg, dev-some-function-example
If you want to override this, simply override the func getter
```

```javascript

class Funa extends Lambda {
    constructor() {
        super();
        this.function = 'some-function-example';
    }
    get func(){
        return this.function;
    }
}
```

To invoke the function simply call the invoke method

```javascript
let a = new Funa();
a.invoke({
    a:1,
    b:2
});
// or 
a.invokeAsync({
    a:1,
    b:2
});
```

### To use Crypto ###
```javascript
const Crypto = require('nealyip-aws-lambda-helper/crypto');
// generate key and save
console.log(Crypto.genKey());

//encrypt data
let enc = new Crypto(key).encrypt('data');

// decrypt data
new Crypto(key).decrypt(enc);
```

// sha256 hash
new Crypto(key).hash('string')

### To use Crypto2 ###
Encrypt with AES-GCM  
```javascript
const crypto2 = require('nealyip-aws-lambda-helper/crypto2');

const encryptKey = Buffer.from('abcdefghijklmnop');
const aesgcm = new crypto2.AESGCM(encryptKey);
const plainText = Buffer.from('\u6211');
const aad = Buffer.from('something to be verified');

const result = aesgcm.encrypt(plainText, aad);
console.log(result.hex); // An object containing nonce, tag, cipher_text and cipher_suite in hex
console.log(result.base64); // An object containing nonce, tag, cipher_text and cipher_suite in base64
console.log(result.urlencoded); // A url-encoded string containing nonce, tag, cipher_text and cipher_suite
```

Decrypt with AES-GCM
```javascript
const crypto2 = require('nealyip-aws-lambda-helper/crypto2');

const encryptKey = Buffer.from('abcdefghijklmnopabcdefghijklmnop');
const aesgcm = new crypto2.AESGCM(encryptKey);
const aad = Buffer.from('something to be verified');

const encrypted = {
    nonce: Buffer.from('ffd2eed848a2416f32915fae', 'hex'),
    cipher_text: Buffer.from('d344db', 'hex'),
    tag: Buffer.from('085eda92945103915be8c5ae57d0a835', 'hex')
};
const result = aesgcm.decrypt(encrypted, aad);
```

Encrypt with AES-CBC With RSA-SHA256 
```javascript
const crypto2 = require('nealyip-aws-lambda-helper/crypto2');

const fun = async () => {    
    const privateKey = Buffer.from(await getFile('./test/keys/rsa_private.pem'));
    const encryptKey = Buffer.from('abcdefghijklmnopabcdefghijklmnop');
    const plainText = Buffer.from('\u6211');
    const publicKey = Buffer.from(await getFile('./test/keys/rsa_public.pem'));
    
    const signatureAlgorithm = new crypto2.RSAWithSha(privateKey, publicKey);
    const aescbc = new crypto2.AESCBCWithSignature(encryptKey, signatureAlgorithm);
    return aescbc.encrypt(plainText);
};
fun().then(result => {
    console.log(result.hex);    
    console.log(result.base64);    
}).catch(console.error);
````

Encrypt with AES-CBC With HMAC-SHA256 
```javascript
const crypto2 = require('nealyip-aws-lambda-helper/crypto2');
  
const signKey = Buffer.from('hello');
const encryptKey = Buffer.from('abcdefghijklmnop');
const plainText = Buffer.from('\u6211');

const signatureAlgorithm = new crypto2.HMACWithSha(signKey);
const aescbc = new crypto2.AESCBCWithSignature(encryptKey, signatureAlgorithm);
const result = aescbc.encrypt(plainText);

console.log(result.hex);
console.log(result.base64);
````

Decrypt with AES-CBC With RSA-SHA256 
```javascript
const crypto2 = require('nealyip-aws-lambda-helper/crypto2');
  
const fun = async () => {
    const encrypted = {
        nonce: Buffer.from('jGzj5DV2feQXKiRl3eGIWA==', 'base64'),
        cipher_text: Buffer.from('bgtz/EFaBmRVauBDi0Vk1g==', 'base64'),
        tag: Buffer.from('cMDdfPrkGdOX5pAmDazMJZGa53nwP7mUR475KECY06m4BCvgtJr6rVUrR6NTHM404M6Wz7+tshCBrEQYrVdByrlx8BbIWb7KU7h08QVLMBgVpbTRNExeXhRWzr6WeZniANNJ6dECqp9hbmnS7xpKGkR4ge1p8lyhNxIlmIikX4I/Z3yOy38KhT/13f1HtnHTpODlvnaZUVATx0W1eyHney9Itg/xxiBbdv6j7aFgRkDcdvIFMJbu0ZYYspsCas1rOmuK0tTMYmbjXsv1WwOzfNS9bSQQim36op08WXy62txdaR9OlHM8Lu8/3F9al7YWxaIHMq8XE2fvzM1Cw8om/Q==', 'base64')
    };
    const privateKey = Buffer.from('');
    const encryptKey = Buffer.from('abcdefghijklmnopabcdefghijklmnop');
    const publicKey = Buffer.from(await getFile('./test/keys/rsa_public.pem'));

    const signatureAlgorithm = new crypto2.RSAWithSha(privateKey, publicKey);
    const aescbc = new crypto2.AESCBCWithSignature(encryptKey, signatureAlgorithm);
    
    return aescbc.decrypt(encrypted);
};
fun().then(result => {
    console.log(result.toString('utf-8'))
});
````

### To use https client ###
```javascript
const https = require('./https');

https.json({
        url   : 'https://www.example.com/auth',
        method: 'post',
        data  : {
            user    : 'helloabc',
            password: 'abcdefgh'
        }
    })
    .then(res => res.body)
    .then(res => JSON.parse(res).token)
    .then(token => https.json({
            url: 'https://www.example.com/dosth',
            method: 'get',
            headers : {
                Authorization: 'Bearer ' + token
            }
        }
    ))
    .then(res => res.body)
    .then(console.log, err => console.log('Error: ' + err.message));
```

### To use php uniqid ###

```javascript
const helpers = require('nealyip-aws-lambda-helper/helpers');

console.log(helpers.uniqid());
```

### To add / deduct and return utc time ###
```javascript
const helpers = require('./helpers');

console.log(helpers.utcAdd(2, 'minute'));
console.log(helpers.utcAdd(2, 'day'));
console.log(helpers.utcAdd(2, 'second'));
console.log(helpers.utcAdd(2, 'hour'));
console.log(helpers.utcAdd(2, 'month'));
``` 

### To get current utc time ###

```javascript
let helpers = require('nealyip-aws-lambda-helper/helpers');

console.log(helpers.utcNow()); //2017-11-01T12:20:20.000Z
```

### To check is the given time past ###
```javascript
let helpers = require('nealyip-aws-lambda-helper/helpers');

console.log(helpers.isPast('2017-11-01T19:14:00.000+0800'));
```

### To convert from timezone / to utc from a given timezone ###

```javascript
let helpers = require('nealyip-aws-lambda-helper/helpers');

console.log('toUTC', helpers.toUTC('2017-11-01 00:12', 'Asia/Hong_Kong'));

console.log('toUTC', helpers.toUTC('2017-11-01 13:12', 'Asia/Hong_Kong'));
```

### To use moment with timestamp ###

```javascript
let moment = require('nealyip-aws-lambda-helper/moment-with-timezone.min');

console.log(moment().tz('Asia/Tokyo').format('YYYYMMDD HH:mm:ss'));
```

### To generate a list for a given month ###
```javascript
let helpers = require('nealyip-aws-lambda-helper/helpers');


console.log(helpers.rangeForMonth('2017-11')); // ['2017-11-01', '2017-11-02',...... '2017-11-30']

```

### To use response for lambda proxy integration ###

```javascript
const Response = require('nealyip-aws-lambda-helper/response');
exports.handler = (event, context, callback) => {
    let response = new Response(event, callback, 'POST');
    
    response.ok({
        data : '1234'
    });
}
```
Tips: response.checkInput() can be used to check event input and reject the request for invalid input

### To use ResponseWithCORSXSRF ###
```javascript
const Response = require('nealyip-aws-lambda-helper/response-with-cors-xsrf.js');
const CustomError = require('nealyip-aws-lambda-helper/error').CustomError;

exports.handler = (event, context, callback) => {
    let response = new Response(event, callback, 'POST');
    
    response.checkInput()
    .then(() => {
        // do something
    })
    .then(() => response.ok({
        data : '1234'
    }))
    .catch(error => response.fail({error: error.message}, error instanceof CustomError ? error.httpCode : 500));
}
```
Tips: You can extend the Response class and checkInput() method for any custom validation

#### Send response cookie ####
```javascript
const Response = require('nealyip-aws-lambda-helper/response');
exports.handler = (event, context, callback) => {
    let response = new Response(event, callback, 'POST');
    
    response.ok({
        data : '1234'
    }, 'SESSIONID=abcd; path=/; HttpOnly');
}
```
Multiple cookie was supported by AWS on oct 2018
```javascript
const Response = require('nealyip-aws-lambda-helper/response');
exports.handler = (event, context, callback) => {
    let response = new Response(event, callback, 'POST');
    
    response.ok({
        data : '1234'
    }, ['SESSIONID=abcd; path=/; HttpOnly', 'CSRF_TOKEN=12345; path=/;']);
}
```

### To use cookie reader ###
```javascript
const cookie = require('nealyip-aws-lambda-helper/cookie');
try{
    let result = cookie.parse('SESSIONID=abcd; some=cookie; another=cookie');
    console.log(result['SESSIONID']);
} catch (e) {
    console.log(e.message);
}
```

### To use arn helper class ###

#### To find the lambda function for an arn ####
```javascript
const ARNHelper = require('nealyip-aws-lambda-helper/arn-helper');

new ARNHelper('some arn')
    .functionName()
    .then(fn => console.log(`the lambda function for ${arn} is ${fn}`));
```
#### To get all resources from API gateway ####
```javascript
const ARNHelper = require('nealyip-aws-lambda-helper/arn-helper');

new ARNHelper()
    .getAllResources()
    .then(console.log); // {items : [{},{}]}

```

### How do I get set up? ###
```
npm install --save nealyip-aws-lambda-helper
```

You are required to provide 2 env variables
```
S3BUCKET : your-bucket
ENV : dev
```

The ENV is the dynamodb prefix
for example
if the dynamodb is dev.test.batch
then the ENV will be dev
and the model table name
this.tableName    = 'test.batch';

### Contribution guidelines ###

To build the moment-with-timezone.js
```npm
npm install
npm run build-prod
npm publish
```

To build the dist
```npm
npm run build-ts
```

To publish release  
inside dist folder  
```npm
npm publish
```

```npm
npm publish --tag beta
npm dist-tag ls
```
Fix wrong dist-tag  
```npm
npm dist-tag  add  nealyip-aws-lambda-helper@1.0.65 latest
```

### Who do I talk to? ###

* Repo owner or admin
* Other community or team contact

---
_Source: https://npm.io/package/nealyip-aws-lambda-helper · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
