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

aws-core-utils

Package Overview
Dependencies
Maintainers
1
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

aws-core-utils - npm Package Compare versions

Comparing version 5.0.26 to 5.1.0

kms-cache.js

66

contexts.js
'use strict';
const regions = require('./regions');
const stages = require('./stages');

@@ -8,2 +9,5 @@ const kinesisCache = require('./kinesis-cache');

const Objects = require('core-functions/objects');
const copy = Objects.copy;
const merge = Objects.merge;
const deep = true;

@@ -31,2 +35,5 @@ /**

/** Configures the given context with the given event, given AWS context and the resolved stage */
configureEventAwsContextAndStage: configureEventAwsContextAndStage,
/** Configures a context with custom settings and/or custom options */

@@ -39,3 +46,3 @@ configureCustomSettings: configureCustomSettings

* handling, logging, custom settings, an optional Kinesis instance, an optional DynamoDB.DocumentClient instance, the
* current region, the resolved stage and the given AWS context based on the given settings and options.
* current region, the given AWS event, given AWS context and the resolved stage based on the given settings and options.
*

@@ -46,6 +53,5 @@ * The distinction between options and settings is that options are meant to contain only non-function properties

*
* Note that if either the given event or AWS context are undefined, then everything other than the region, stage and
* AWS context will be configured. This missing configuration can be configured at a later point in your code by
* invoking {@linkcode stages#configureRegionStageAndAwsContext}. This separation of configuration is primarily useful
* for unit testing.
* Note that if either the given event or AWS context are undefined, then everything other than the event, AWS context &
* stage will be configured. This missing configuration can be configured at a later point in your code by invoking
* {@linkcode configureEventAwsContextAndStage}. This separation of configuration is primarily useful for unit testing.
*

@@ -55,4 +61,4 @@ * @param {Object|StandardContext} context - the context to configure as a standard context

* @param {StandardOptions|undefined} [options] - options to use to configure a standard context
* @param {Object|undefined} [event] - the AWS event, which was passed to your lambda
* @param {Object|undefined} [awsContext] - the AWS context, which was passed to your lambda
* @param {AWSEvent|undefined} [event] - the AWS event, which was passed to your lambda
* @param {AWSContext|undefined} [awsContext] - the AWS context, which was passed to your lambda
* @param {boolean|undefined} [forceConfiguration] - whether or not to force configuration of the given settings and

@@ -68,2 +74,5 @@ * options, which will ONLY override any previously configured stage handling settings on the given context

// Configure the region after configuring logging (failing fast if process.env.AWS_REGION is blank)
regions.configureRegion(context, true);
// Configure the given context with any custom settings and/or custom options

@@ -89,6 +98,37 @@ configureCustomSettings(context, settings ? settings.customSettings : undefined, options ? options.customOptions : undefined);

// Configure the given context with the given AWS event, AWS context and the resolved stage (if any)
if (event || awsContext) {
configureEventAwsContextAndStage(context, event, awsContext);
}
return context;
}
/**
* Configures the given context with the given event, given AWS context and the resolved stage. In order to resolve the
* stage, stage handling settings and logging must already be configured on the given context (see {@linkcode
* stages#configureStageHandling} for details).
* @param {StageHandling|EventAWSContextAndStageAware} context - the context to configure
* @param {AWSEvent} event - the AWS event, which was passed to your lambda
* @param {AWSContext} awsContext - the AWS context, which was passed to your lambda
* @return {EventAWSContextAndStageAware} the given context configured with a stage and the given AWS context
* @throws {Error} if the resolved stage is blank
*/
function configureEventAwsContextAndStage(context, event, awsContext) {
// Configure context.event with the given AWS event
if (event) {
context.event = event;
}
// Configure context.awsContext with the given AWS context
if (awsContext) {
context.awsContext = awsContext;
}
// Resolve the current stage (e.g. dev, qa, prod, ...) if possible and configure context.stage with it, if it is not
// already configured
if (event && awsContext) {
// Configure the given context with the current region, resolved stage and AWS context
stages.configureRegionStageAndAwsContext(context, event, awsContext);
stages.configureStage(context, event, awsContext, true);
}
return context;

@@ -111,15 +151,15 @@ }

function configureCustomSettings(context, settings, options) {
const settingsAvailable = settings && typeof settings == 'object';
const settingsAvailable = settings && typeof settings === 'object';
const optionsAvailable = options && typeof options === 'object';
const customOptions = optionsAvailable ? Objects.copy(options, true) : {};
const customOptions = optionsAvailable ? copy(options, deep) : {};
const customSettings = settingsAvailable ?
optionsAvailable ? Objects.merge(customOptions, settings, false, false) : settings :
optionsAvailable ? merge(customOptions, settings, false, false) : settings :
customOptions;
context.custom = context.custom && typeof context.custom === 'object' ?
Objects.merge(customSettings, context.custom, false, false) : customSettings;
merge(customSettings, context.custom, false, false) : customSettings;
return context;
}

22

dynamodb-doc-client-cache.js
'use strict';
let AWS = require("aws-sdk");
let AWS = require('aws-sdk');

@@ -10,6 +10,5 @@ // Module-scope cache of AWS.DynamoDB.DocumentClient instances by region key

// A map of region key objects by region, which is only needed, because WeakMaps can ONLY have object keys
const regionKeysByRegion = new Map();
const regions = require('./regions');
const getRegion = regions.getRegion;
const getRegionKey = regions.getRegionKey;

@@ -63,3 +62,3 @@ const Objects = require('core-functions/objects');

if (!region) {
const currentRegion = regions.getRegion();
const currentRegion = getRegion();
options.region = currentRegion;

@@ -129,3 +128,3 @@ region = currentRegion;

function getDynamoDBDocClient(region) {
const regionKey = getRegionKey(region ? region : regions.getRegion());
const regionKey = getRegionKey(region);
return dynamoDBDocClientByRegionKey.get(regionKey);

@@ -143,15 +142,6 @@ }

function getDynamoDBDocClientOptionsUsed(region) {
const regionKey = getRegionKey(region ? region : regions.getRegion());
const regionKey = getRegionKey(region);
return dynamoDBDocClientOptionsByRegionKey.get(regionKey);
}
function getRegionKey(region) {
let regionKey = regionKeysByRegion.get(region);
if (!regionKey) {
regionKey = {region: region};
regionKeysByRegion.set(region, regionKey);
}
return regionKey;
}
/**

@@ -158,0 +148,0 @@ * Creates and caches a new AWS DynamoDB.DocumentClient instance with the given DynamoDB.DocumentClient constructor

'use strict';
let AWS = require("aws-sdk");
let AWS = require('aws-sdk');

@@ -10,8 +10,9 @@ // Module-scope cache of AWS.Kinesis instances by region key

// A map of region key objects by region, which is only needed, because WeakMaps can ONLY have object keys
const regionKeysByRegion = new Map();
const regions = require('./regions');
const getRegion = regions.getRegion;
const getRegionKey = regions.getRegionKey;
const Objects = require('core-functions/objects');
const copy = Objects.copy;
const deep = true;

@@ -54,3 +55,3 @@ const Strings = require('core-functions/strings');

// If no options were specified, then use an empty object
const options = kinesisOptions ? Objects.copy(kinesisOptions, true) : {};
const options = kinesisOptions ? copy(kinesisOptions, deep) : {};

@@ -60,3 +61,3 @@ // If no region was specified in the given kinesis options, then set it to the current region

if (!region) {
const currentRegion = regions.getRegion();
const currentRegion = getRegion();
options.region = currentRegion;

@@ -122,3 +123,3 @@ region = currentRegion;

function getKinesis(region) {
const regionKey = getRegionKey(region ? region : regions.getRegion());
const regionKey = getRegionKey(region);
return kinesisByRegionKey.get(regionKey);

@@ -135,15 +136,6 @@ }

function getKinesisOptionsUsed(region) {
const regionKey = getRegionKey(region ? region : regions.getRegion());
const regionKey = getRegionKey(region);
return kinesisOptionsByRegionKey.get(regionKey);
}
function getRegionKey(region) {
let regionKey = regionKeysByRegion.get(region);
if (!regionKey) {
regionKey = {region: region};
regionKeysByRegion.set(region, regionKey);
}
return regionKey;
}
/**

@@ -150,0 +142,0 @@ * Creates and caches a new AWS Kinesis instance with the given Kinesis constructor options for either the region

{
"name": "aws-core-utils",
"version": "5.0.26",
"version": "5.1.0",
"description": "Core utilities for working with Amazon Web Services (AWS), including ARNs, regions, stages, Lambdas, AWS errors, stream events, Kinesis, DynamoDB.DocumentClients, etc.",

@@ -14,4 +14,4 @@ "author": "Byron du Preez",

"dependencies": {
"core-functions": "2.0.16",
"logging-utils": "3.0.16",
"core-functions": "2.0.17",
"logging-utils": "3.0.17",
"deep-equal": "1.0.1"

@@ -21,3 +21,3 @@ },

"aws-sdk": "2.54.0",
"aws-core-test-utils": "1.0.7",
"aws-core-test-utils": "1.0.9",
"tape": "^4.7.0",

@@ -24,0 +24,0 @@ "uuid": "3.1.0"

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

# aws-core-utils v5.0.26
# aws-core-utils v5.1.0

@@ -11,29 +11,37 @@ Core utilities for working with Amazon Web Services (AWS), including ARNs, regions, stages, Lambdas, AWS errors, stream events, Kinesis, DynamoDB.DocumentClients, etc.

- arns.js
- Utilities for working with Amazon Resource Names (ARNs)
- Utilities for working with Amazon Resource Names (ARNs)
- aws-errors.js
- Utilities for working with AWS errors
- Utilities for working with AWS errors
- contexts.js
- Utilities for configuring contexts for AWS Gateway exposed and other types of Lambdas
- Utilities for configuring contexts for AWS Gateway exposed and other types of Lambdas
- dynamodb-doc-client-cache.js
- A module-scope cache of AWS.DynamoDB.DocumentClient instances by region for Lambda.
- A module-scope cache of AWS.DynamoDB.DocumentClient instances by region for Lambda.
- dynamodb-doc-client-utils.js
- Utilities for working with AWS DynamoDB.DocumentClient.
- Utilities for working with AWS DynamoDB.DocumentClient.
- dynamodb-utils.js
- Utilities for working with AWS DynamoDB.
- Utilities for working with AWS DynamoDB.
- kinesis-cache.js
- A module-scope cache of AWS.Kinesis instances by region for Lambda.
- A module-scope cache of AWS.Kinesis instances by region for Lambda.
- kms-cache.js
- A module-scope cache of AWS.KMS instances by region for Lambda usage.
- kms-utils.js
- Utilities to simplify working with AWS.KMS instances.
- lambda-cache.js
- A module-scope cache of AWS.Lambda instances by region for use within Lambda functions.
- lambda-utils.js
- Utilities to simplify working with an AWS.Lambda instance
- lambdas.js
- Utilities for working with AWS Lambda, which enable extraction of function names, versions and, most importantly,
aliases from AWS contexts and their invoked function ARNs.
- Utility for failing non-API Gateway Lambda's callbacks with standard AppError errors if mapping of errors to HTTP status codes is needed
- Utilities for working with AWS Lambda, which enable extraction of function names, versions and, most importantly,
aliases from AWS contexts and their invoked function ARNs.
- Utility for failing non-API Gateway Lambda's callbacks with standard AppError errors if mapping of errors to HTTP status codes is needed
- regions.js
- Utilities for resolving the AWS region from various sources (primarily for AWS Lambda usage).
- Utilities for resolving the AWS region from various sources (primarily for AWS Lambda usage).
- stages.js
- Utilities for resolving or deriving the current stage (e.g. dev, qa, prod) from various sources
(primarily for AWS Lambda usage).
- Utilities for configuration of stage handling.
- Configurable and default functions for generating stage-qualified stream and resource names.
- Configurable and default functions for extracting stages from stage-qualified stream and resource names.
- Utilities for resolving or deriving the current stage (e.g. dev, qa, prod) from various sources
(primarily for AWS Lambda usage).
- Utilities for configuration of stage handling.
- Configurable and default functions for generating stage-qualified stream and resource names.
- Configurable and default functions for extracting stages from stage-qualified stream and resource names.
- stream-events.js
- Utilities for extracting information from AWS Kinesis and AWS DynamoDB stream events.
- Utilities for extracting information from AWS Kinesis and AWS DynamoDB stream events.

@@ -220,3 +228,135 @@ This module is exported as a [Node.js](https://nodejs.org/) module.

```
* To use the KMS cache to configure and cache an AWS KMS instance per region
```js
const kmsCache = require('aws-core-utils/kms-cache');
// Preamble to create a context and configure logging on the context
const context = {};
const logging = require('logging-utils');
logging.configureDefaultLogging(context); // or your own custom logging configuration (see logging-utils README.md)
// Define the KMS constructor options that you want to use, e.g.
const kmsOptions = {
// See http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/KMS.html#constructor-property for full details
maxRetries: 0
// ...
};
// To create and cache a new AWS KMS instance with the given KMS constructor options for either the current
// region or the region specified in the given options OR reuse a previously cached KMS instance (if any) that is
// compatible with the given options
const kms = kmsCache.setKMS(kmsOptions, context);
// To configure a new AWS.KMS instance (or re-use a cached instance) on a context
kmsCache.configureKMS(context, kmsOptions);
console.log(context.kms);
// To get a previously set or configured AWS KMS instance for the current AWS region
const kms1 = kmsCache.getKMS();
// ... or for a specified region
const kms2 = kmsCache.getKMS('us-west-2');
// To get the original options that were used to construct a cached AWS KMS instance for the current or specified AWS region
const optionsUsed1 = kmsCache.getKMSOptionsUsed();
const optionsUsed2 = kmsCache.getKMSOptionsUsed('us-west-1');
// To delete and remove a cached KMS instance from the cache
const deleted = kmsCache.deleteKMS('eu-west-1');
```
* To use the AWS.KMS utilities
```js
const kmsUtils = require('aws-core-utils/kms-utils');
const kms = new AWS.KMS({region: 'eu-west-1'}); // or better yet use kms-cache module as above
// Preamble to create a context and configure logging on the context
const logging = require('logging-utils');
const logger = logging.configureLogging({}); // or your own custom logging configuration (see logging-utils README.md)
const accountId = 'XXXXXXXXXXXX'; // use your AWS account ID
const kmsKeyAlias = 'aws/lambda'; // or use your own key alias
const keyId = `arn:aws:kms:us-west-2:${accountId}:alias/${kmsKeyAlias}`;
// To encrypt plaintext using KMS:
const plaintext = 'Shhhhhhhhhhhhhhh'; // use your own plaintext
kmsUtils.encryptKey(kms, keyId, plaintext, logger)
.then(ciphertextBase64 => console.log(JSON.stringify(ciphertextBase64)));
// To decrypt ciphertext using KMS:
const ciphertextBase64 = '...'; // use your own ciphertext
kmsUtils.decryptKey(kms, ciphertextBase64, logger)
.then(plaintext => console.log(JSON.stringify(plaintext)));
// To encrypt plaintext using KMS:
const encryptParams = {KeyId: keyId, Plaintext: plaintext};
kmsUtils.encrypt(kms, encryptParams, logger)
.then(result => console.log(JSON.stringify(result)));
// To decrypt ciphertext using KMS:
const decryptParams = {CiphertextBlob: new Buffer(ciphertextBase64, 'base64')};
kmsUtils.decrypt(kms, decryptParams, logger)
.then(result => console.log(JSON.stringify(result)));
```
* To use the Lambda cache to configure and cache an AWS Lambda instance per region
```js
const lambdaCache = require('aws-core-utils/lambda-cache');
// Preamble to create a context and configure logging on the context
const context = {};
const logging = require('logging-utils');
logging.configureLogging(context); // or your own custom logging configuration (see logging-utils README.md)
// Define the Lambda constructor options that you want to use, e.g.
const lambdaOptions = {
// See http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html#constructor-property for full details
maxRetries: 0
// ...
};
// To create and cache a new AWS Lambda instance with the given Lambda constructor options for either the current
// region or the region specified in the given options OR reuse a previously cached Lambda instance (if any) that is
// compatible with the given options
const lambda = lambdaCache.setLambda(lambdaOptions, context);
// To configure a new AWS.Lambda instance (or re-use a cached instance) on a context
lambdaCache.configureLambda(context, lambdaOptions);
console.log(context.lambda);
// To get a previously set or configured AWS Lambda instance for the current AWS region
const lambda1 = lambdaCache.getLambda();
// ... or for a specified region
const lambda2 = lambdaCache.getLambda('us-west-2');
// To get the original options that were used to construct a cached AWS Lambda instance for the current or specified AWS region
const optionsUsed1 = lambdaCache.getLambdaOptionsUsed();
const optionsUsed2 = lambdaCache.getLambdaOptionsUsed('us-west-1');
// To delete and remove a cached Lambda instance from the cache
const deleted = lambdaCache.deleteLambda('eu-west-1');
```
* To use the AWS.Lambda utilities
```js
const lambdaUtils = require('aws-core-utils/lambda-utils');
const lambda = new AWS.Lambda({region: 'eu-west-1'}); // or better yet use lambda-cache module as above
// To list the event source mappings on your Lambda function
const params = {FunctionName: 'my-lambda-function'};
lambdaUtils.listEventSourceMappings(lambda, params, context)
.then(result => console.log(JSON.stringify(result)));
// To update an event source mapping on your Lambda function
const params2 = {FunctionName: 'my-lambda-function', UUID: uuid, BatchSize: 99};
lambdaUtils.updateEventSourceMapping(lambda, params2, context)
.then(result => console.log(JSON.stringify(result)));
// To disable an event source mapping on your Lambda function
lambdaUtils.disableEventSourceMapping(lambda, 'my-lambda-function', uuid, context)
.then(result => console.log(JSON.stringify(result)));
```
* To use the Lambda utilities

@@ -396,2 +536,5 @@ ```js

### 5.1.0
- Backport of major changes/additions from 6.1.0 & from earlier 6.x releases
### 5.0.26

@@ -398,0 +541,0 @@ - Moved test devDependencies to package.json & removed test/package.json

'use strict';
// A map of region key objects by region, which is only needed, because WeakMaps can ONLY have object keys
const regionKeysByRegion = new Map();
// noinspection JSUnusedGlobalSymbols
/**

@@ -10,2 +14,3 @@ * Utilities for resolving the AWS region from various sources (primarily for AWS Lambda usage).

getRegion: getRegion,
setRegion: setRegion,
getDefaultRegion: getDefaultRegion,

@@ -16,4 +21,8 @@ //getRegionOrDefault: getRegionOrDefault,

getEventSourceArnRegions: getEventSourceArnRegions,
/** @deprecated simply use `getRegion` directly instead when the region is required */
configureRegion: configureRegion,
//resolveRegion: resolveRegion,
getRegionKey: getRegionKey,
ONLY_FOR_TESTING: {

@@ -33,25 +42,22 @@ getRegionRaw: getRegionRaw,

const arns = require('./arns');
// const getArnComponent = arns.getArnComponent;
// const getArnPartition = arns.getArnPartition;
// const getArnService = arns.getArnService;
const getArnRegion = arns.getArnRegion;
// const getArnAccountId = arns.getArnAccountId;
// const getArnResources = arns.getArnResources;
/**
* Gets the region in which this function is running from the AWS_REGION environment variable (if it exists, which
* should always be true for a live AWS Lambda); otherwise logs a warning and returns an empty string.
* Gets the region in which this function is running from the `AWS_REGION` environment variable and returns it as is if
* it's neither "undefined" nor "null"; otherwise logs a warning and returns undefined if it's "undefined" or "null" (or
* undefined).
*
* This is the best option to use to get the region within AWS Lambda code (and the only option to use at module-level
* scope), since these environment variables will be set by AWS Lambda.
* The `AWS_REGION` environment variable is the best option to use to get the region within AWS Lambda code (and the
* only option to use at module-level scope), since these environment variables will be set by AWS Lambda.
*
* An optional hidden 'failFast' boolean argument, which defaults to false, can be passed as true to raise an error if
* the AWS_REGION env variable is not available
* An optional "hidden" 'failFast' boolean argument, which defaults to false, can be passed as true to raise an error if
* the AWS_REGION env variable is not available or unusable
*
* @returns {string} the AWS region (if it exists); otherwise an empty string.
* @returns {string|undefined} the AWS region (if it exists); otherwise undefined.
*/
function getRegion() {
const region = trimOrEmpty(process.env.AWS_REGION);
const awsRegion = trim(process.env.AWS_REGION);
const region = awsRegion !== "undefined" && awsRegion !== "null" ? awsRegion : undefined;
if (!region) {
const errorMsg = 'Failed to get AWS_REGION from env - for unit testing either call setRegionIfNotBlank(...) in your tests or set your AWS_REGION env variable';
const errorMsg = `Failed to get usable region from AWS_REGION env variable (${awsRegion}) - for unit testing call setRegion beforehand`;
const failFast = arguments.length > 0 && arguments[0] === true;

@@ -68,2 +74,21 @@ if (failFast) {

/**
* Sets the `AWS_REGION` environment variable to the given region (if it's NOT undefined, "undefined", null or "null");
* otherwise deletes `process.env.AWS_REGION`, which effectively "sets" it to undefined. NB: `delete` is used to avoid
* the undesirable behaviour where setting `process.env.AWS_REGION` to undefined or null results in it containing the
* string "undefined" or "null" respectively. NB: This only sets the region temporarily on the current process and
* should largely only be used for testing purposes.
* @param {string|undefined|null} awsRegion - the region to set on or delete from process.env.AWS_REGION
*/
function setRegion(awsRegion) {
const region = trim(awsRegion);
if (region === undefined || region === null || region === 'undefined' || region === 'null') {
// If the given region is undefined or null, then must delete process.env.AWS_REGION rather than setting it to
// undefined or null, which incorrectly sets it to the strings "undefined" or "null" respectively
delete process.env.AWS_REGION;
} else {
process.env.AWS_REGION = region;
}
}
/**
* Gets the region from the AWS_DEFAULT_REGION environment variable; otherwise returns an empty string.

@@ -79,7 +104,7 @@ * @returns {string} the AWS default region (if it exists); otherwise an empty string

* NB: This only sets the region temporarily on the current process and should probably only be used for testing purposes.
* @deprecated use `setRegion` instead
* @returns {boolean} true if set; false otherwise.
*/
function setRegionIfNotSet(awsRegion) {
// Replaces an undefined or null awsRegion with '', otherwise it will become 'undefined' or 'null' on process.env
const newRegion = trimOrEmpty(awsRegion);
const newRegion = trim(awsRegion);

@@ -89,14 +114,8 @@ // Check if AWS region is already set or not

if (isBlank(region)) {
// Attempt to set the AWS_REGION
try {
process.env.AWS_REGION = newRegion;
return true;
} catch (err) {
console.error(`Failed to set AWS_REGION env variable to (${newRegion}) - ${err}`, err.stack);
}
} else {
if (process.env.AWS_REGION !== newRegion) {
console.log(`Ignoring attempt to change ALREADY set AWS_REGION env variable (${process.env.AWS_REGION}) to (${newRegion})`);
}
setRegion(newRegion);
return true;
}
if (process.env.AWS_REGION !== newRegion) {
console.log(`Ignoring attempt to change ALREADY set AWS_REGION env variable (${process.env.AWS_REGION}) to (${newRegion})`);
}
return false;

@@ -144,54 +163,2 @@ }

// /**
// * Extracts a region from the following resources in the following order:
// * 1. Using {@linkcode getRegion}
// * 2. The region extracted from the given AWS context's invokedFunctionArn (if any)
// * 3. The first non-blank awsRegion (if any) extracted from the event's records
// * 4. The first non-blank eventSourceARN region (if any) extracted from the event's records
// *
// * The detailed process followed is as follows:
// * 1. Attempts to get the region using {@linkcode getRegion} (i.e. from AWS-specific environment variables).
// *
// * 2. Extracts and returns the region from the given awsContext's invokedFunctionArn, if it contains an
// * invokedFunctionArn in the form of "arn:aws:lambda:<region>:<accountId>:function:<functionName>[:functionAlias]".
// *
// * 3. Returns the first non-blank awsRegion (if any) extracted from the event's records, if any of them contain an awsRegion property.
// *
// * 4. Returns the first non-blank eventSourceARN region (if any) extracted from the event's records, if any of them contain an
// *
// * Extracts and returns the region from the given event's eventSourceARN, if it contains an eventSourceARN
// * in the form of "arn:aws:kinesis:<region>:<accountId>:stream/<streamName>".
// *
// * 5. Gives up and returns an empty string.
// *
// * @param {Object} event the Kinesis event to be checked
// * @param {Object} awsContext the AWS context
// * @return {string} the region if found; otherwise an empty string
// */
// function resolveRegion(event, awsContext) {
// // Attempt 1
// let region = getRegion();
// if (isNotBlank(region)) {
// return region;
// }
// // Attempt 2
// region = getInvokedFunctionArnRegion(awsContext);
// if (isNotBlank(region)) {
// return region;
// }
// // Attempt 3
// region = getEventAwsRegions(event).find(r => isNotBlank(r));
// if (isNotBlank(region)) {
// return region;
// }
// // Attempt 4
// region = getEventSourceArnRegions(event).find(r => isNotBlank(r));
// if (isNotBlank(region)) {
// return region;
// }
// // Give up
// return '';
// }
/**

@@ -223,5 +190,6 @@ * Gets the region in which this function is running from the AWS_REGION environment variable (if it exists); otherwise

/**
* Returns the context.region if it is already configured on the given context, otherwise gets the current AWS_REGION
* and then, if its not blank, sets it on the context as context.region; otherwise either raises an error if failFast is
* explicitly true or logs a warning.
* Keeps context.region as is if it's already configured on the given context, otherwise gets the current region from
* process.env.AWS_REGION and if it's not blank, sets it on the context as context.region; otherwise either throws an
* error if failFast is explicitly true.
* @deprecated simply use `getRegion` directly instead when the region is required
* @param {Object|RegionAware} context - a context on which to set the region

@@ -238,4 +206,21 @@ * @param {boolean|undefined} [failFast] - an optional flag that is only used when AWS_REGION is needed and blank and

}
(context.info || console.log)(`Using region (${getRegion()}) & context.region (${context.region})`);
return context;
}
/**
* Returns the region key object for the given region name.
* @param {string|undefined} [region] - the name of the region (defaults to current region if not defined)
* @param {boolean|undefined} [failFast] - an optional flag that is only used when AWS_REGION is needed and blank and
* that determines whether the error will be raised (if failFast is explicitly true) or simply logged as a warning
* @returns {{region: string}} a region key object
*/
function getRegionKey(region, failFast) {
const regionName = region ? region : getRegion(failFast === true);
let regionKey = regionKeysByRegion.get(regionName);
if (!regionKey) {
regionKey = {region: regionName};
regionKeysByRegion.set(regionName, regionKey);
}
return regionKey;
}

@@ -20,2 +20,3 @@ 'use strict';

// noinspection JSUnusedGlobalSymbols
/**

@@ -47,2 +48,3 @@ * Stage handling utilities (primarily for AWS Lambda usage), which include the following:

configureStage: configureStage,
/** @deprecated Use configureStage instead & either regions.getRegion or regions.configureRegion & configure context.awsContext elsewhere (e.g. contexts.configureEventAwsContextAndStage) */
configureRegionStageAndAwsContext: configureRegionStageAndAwsContext,

@@ -89,2 +91,5 @@

const Objects = require('core-functions/objects');
const copy = Objects.copy;
const merge = Objects.merge;
const deep = true;

@@ -189,6 +194,6 @@ const streamEvents = require('./stream-events');

function getDefaultStageHandlingSettings(options) {
const settings = options && typeof options === 'object' ? Objects.copy(options, true) : {};
const settings = options && typeof options === 'object' ? copy(options, deep) : {};
const defaultOptions = loadDefaultStageHandlingOptions();
Objects.merge(defaultOptions, settings, false, false);
merge(defaultOptions, settings, false, false);

@@ -205,3 +210,3 @@ const defaultSettings = {

};
return Objects.merge(defaultSettings, settings, false, false);
return merge(defaultSettings, settings, false, false);
}

@@ -226,3 +231,3 @@

};
return Objects.merge(defaults, defaultOptions, false, false);
return merge(defaults, defaultOptions, false, false);
}

@@ -284,3 +289,3 @@

const stageHandlingSettings = settingsAvailable ?
Objects.merge(defaultSettings, settings, false, false) : defaultSettings;
merge(defaultSettings, settings, false, false) : defaultSettings;

@@ -292,3 +297,3 @@ // Configure stage handling with the given or derived stage handling settings

if (!settingsAvailable && !optionsAvailable && (forceConfiguration || !stageHandlingWasConfigured)) {
context.warn(`Stage handling was configured without settings or options - used default stage handling configuration (${stringify(stageHandlingSettings)})`);
context.warn(`Stage handling was configured without settings or options - used default configuration`);
}

@@ -468,3 +473,3 @@ return context;

if (distinctStages > 1) {
context.warn(`WARNING - Ignoring arbitrary first stage (${stage}), since found MULTIPLE distinct stages ${stringify(distinctStages)} on event (${stringify(event)})!`);
context.warn(`Ignoring arbitrary first stage (${stage}), since found MULTIPLE distinct stages ${stringify(distinctStages)} on event (${stringify(event)})!`);
stage = ''; // too many choices, so choose none

@@ -779,2 +784,3 @@ }

}
context.info(`Using stage (${context.stage})`);
return context;

@@ -787,2 +793,3 @@ }

* {@linkcode stages#configureStageHandling} for details).
* @deprecated Use module:./contexts#configureEventAwsContextAndStage instead & either regions.getRegion or regions.configureRegion
* @param {StageHandling|RegionStageAWSContextAware} context - the context to configure

@@ -795,2 +802,5 @@ * @param {Object} event - the AWS event, which was passed to your lambda

function configureRegionStageAndAwsContext(context, event, awsContext) {
// Configure context.event with the given AWS event
context.event = event;
// Configure context.awsContext with the given AWS context, if not already configured

@@ -807,4 +817,3 @@ if (!context.awsContext) {

context.info(`Using region (${context.region}) and stage (${context.stage})`);
return context;
}

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

const awsRegion = 'us-west-1';
// Test subject

@@ -244,2 +246,3 @@ const contexts = require('../contexts');

regions.setRegion(awsRegion);
contexts.configureStandardContext(context, undefined, undefined, undefined, undefined, false);

@@ -258,3 +261,3 @@

t.notOk(context.dynamoDBDocClient, 'context.dynamoDBDocClient must not be defined');
t.notOk(context.region, 'context.region must not be defined');
t.equal(context.region, awsRegion, `context.region must be ${awsRegion}`);
t.notOk(context.stage, 'context.stage must not be defined');

@@ -272,2 +275,3 @@ t.notOk(context.awsContext, 'context.awsContext must not be defined');

regions.setRegion(awsRegion);
contexts.configureStandardContext(context, undefined, standardOptions, undefined, undefined, false);

@@ -289,3 +293,3 @@

t.ok(context.dynamoDBDocClient, 'context.dynamoDBDocClient must be defined');
t.notOk(context.region, 'context.region must not be defined');
t.equal(context.region, awsRegion, `context.region must not be ${awsRegion}`);
t.notOk(context.stage, 'context.stage must not be defined');

@@ -303,2 +307,3 @@ t.notOk(context.awsContext, 'context.awsContext must not be defined');

regions.setRegion(awsRegion);
contexts.configureStandardContext(context, standardSettings, undefined, undefined, undefined, false);

@@ -323,3 +328,3 @@

t.ok(context.dynamoDBDocClient, 'context.dynamoDBDocClient must be defined');
t.notOk(context.region, 'context.region must not be defined');
t.equal(context.region, awsRegion, `context.region must not be ${awsRegion}`);
t.notOk(context.stage, 'context.stage must not be defined');

@@ -337,2 +342,3 @@ t.notOk(context.awsContext, 'context.awsContext must not be defined');

regions.setRegion(awsRegion);
contexts.configureStandardContext(context, standardSettings, standardOptions, undefined, undefined, false);

@@ -357,3 +363,3 @@

t.ok(context.dynamoDBDocClient, 'context.dynamoDBDocClient must be defined');
t.notOk(context.region, 'context.region must not be defined');
t.equal(context.region, awsRegion, `context.region must not be ${awsRegion}`);
t.notOk(context.stage, 'context.stage must not be defined');

@@ -415,1 +421,38 @@ t.notOk(context.awsContext, 'context.awsContext must not be defined');

// =====================================================================================================================
// configureEventAwsContextAndStage
// =====================================================================================================================
test('configureEventAwsContextAndStage', t => {
try {
setRegionStageAndDeleteCachedInstances('us-west-1', "dev99");
const expectedStage = 'DEV99';
let context = {};
// Generate a sample AWS event
const event = sampleAwsEvent('TestStream_DEV2', 'partitionKey', '', false);
// Generate a sample AWS context
const awsContext = sampleAwsContext('1.0.1', 'dev1');
// Initial configuration WITHOUT event & AWS context
contexts.configureStandardContext(context, standardSettings, standardOptions, undefined, undefined, false);
t.notOk(context.event, 'context.event must not be defined');
t.notOk(context.awsContext, 'context.awsContext must not be defined');
t.notOk(context.stage, 'context.stage must not be defined');
// Complete configuration (later)
contexts.configureEventAwsContextAndStage(context, event, awsContext);
t.equal(context.event, event, 'context.event must be event');
t.equal(context.awsContext, awsContext, 'context.awsContext must be awsContext');
t.equal(context.stage, expectedStage, `context.stage must be ${expectedStage}`);
} finally {
process.env.AWS_REGION = undefined;
process.env.STAGE = undefined;
}
t.end();
});

@@ -10,10 +10,8 @@ 'use strict';

const uuid = require("uuid");
// The test subject
const regions = require('../regions');
const getRegion = regions.getRegion;
const setRegion = regions.setRegion;
const getRegionRaw = regions.ONLY_FOR_TESTING.getRegionRaw;
// const getDefaultRegion = regions.getDefaultRegion;
// const resolveRegion = regions.resolveRegion;
const setRegionIfNotSet = regions.ONLY_FOR_TESTING.setRegionIfNotSet;

@@ -23,11 +21,8 @@

const isBlank = Strings.isBlank;
// const isNotBlank = Strings.isNotBlank;
// const trim = Strings.trim;
// const trimOrEmpty = Strings.trimOrEmpty;
// =====================================================================================================================
// Tests for getRegion
// Tests for getRegion & setRegion
// =====================================================================================================================
test('getRegion and setRegionIfNotSet', t => {
test('getRegion and setRegion', t => {

@@ -38,39 +33,42 @@ // Attempt to preserve the original AWS_REGION setting (unfortunately cannot preserve undefined or null)

// check orig
if (isBlank(origRegion)) {
if (origRegion === undefined) {
t.equal(origRegion, process.env.AWS_REGION, `original raw must be '${process.env.AWS_REGION}'`);
t.equal(getRegion(), '', `original must be empty string '${process.env.AWS_REGION}'`);
t.equal(getRegion(), undefined, `original must be empty string '${process.env.AWS_REGION}'`);
} else if (isBlank(origRegion)) {
t.equal(origRegion, process.env.AWS_REGION, `original raw must be '${process.env.AWS_REGION}'`);
t.equal(getRegion(), '', `original must be undefined '${process.env.AWS_REGION}'`);
}
// Must use empty string to "clear" property.env variable - undefined & null don't work (e.g. it sets it to 'undefined' or 'null')
const unset = '';
// Must use delete to "clear" property.env variable - since setting to undefined & null don't work as intended
try {
// "Clear" AWS_REGION to empty string
//console.log(`BEFORE reset process.env.AWS_REGION = (${process.env.AWS_REGION})`);
process.env.AWS_REGION = unset;
//console.log(`AFTER reset process.env.AWS_REGION = '${process.env.AWS_REGION}' (orig was ${origRegion})`);
t.equal(process.env.AWS_REGION, unset, `process.env.AWS_REGION must be '${unset}' after reset`);
// Clear AWS_REGION to undefined (by deleting it)
delete process.env.AWS_REGION;
t.equal(process.env.AWS_REGION, undefined, `process.env.AWS_REGION must be '${undefined}' after delete`);
// check get when not set
t.equal(getRegion(), unset, `must be '${unset}'`);
t.equal(getRegion(), undefined, `getRegion() must be '${undefined}'`);
t.throws(() => getRegion(true), undefined, `getRegion(true) must throw'`);
// check will set, when not set
const expected = 'TEST_REGION_1';
t.ok(setRegionIfNotSet(expected), `must set successfully`);
t.equal(getRegion(), expected, `must be ${expected}`);
setRegion(expected);
t.equal(getRegion(), expected, `setRegion('TEST_REGION_1') then getRegion() must be ${expected}`);
t.equal(process.env.AWS_REGION, expected, `process.env.AWS_REGION must be ${expected}`);
// check was NOT set, when already set set
t.notOk(setRegionIfNotSet('TEST_REGION_3'), `must NOT set successfully`);
t.equal(getRegion(), expected, `must still be ${expected}`);
// check changed, when another set
const expected2 = 'TEST_REGION_3';
setRegion(expected2);
t.equal(getRegion(), expected2, `setRegion('TEST_REGION_3') then getRegion() must now be ${expected2}`);
t.equal(process.env.AWS_REGION, expected2, `process.env.AWS_REGION must be ${expected2}`);
} finally {
// "Restore" original aws region
//console.log(`BEFORE restore process.env.AWS_REGION = '${process.env.AWS_REGION}' (orig was ${origRegion})`);
process.env.AWS_REGION = isBlank(origRegion) ? unset : origRegion;
//console.log(`AFTER restore process.env.AWS_REGION = '${process.env.AWS_REGION}' (orig was ${origRegion})`);
setRegion(origRegion);
// Check "restore" worked
if (isBlank(origRegion)) {
t.equal(getRegion(), unset, `must be "restored" to '${unset}' (orig was ${origRegion})`);
if (origRegion === undefined) {
t.equal(getRegion(), undefined, `getRegion() must be "restored" to undefined' (orig was ${origRegion})`);
} else if (isBlank(origRegion)) {
t.equal(getRegion(), '', `getRegion() must be "restored" to empty string (orig was '${origRegion}')`);
} else {
t.equal(getRegion(), origRegion, `must be restored to ${origRegion}`);
t.equal(getRegion(), origRegion, `getRegion() must be restored to ${origRegion}`);
}

@@ -81,33 +79,53 @@ t.end();

//TODO add tests for other methods
// =====================================================================================================================
// Tests for resolveRegion
// Tests for getRegion and setRegionIfNotSet
// =====================================================================================================================
// test('resolveRegion with event.awsRegion defined and no event.eventSourceArn and no awsContext.invokedFunctionArn', t => {
// // Create an event
// const streamName = sampleStreamName('', '');
// ;
// // Configure different regions to each of the 3 sources
// // const eventSourceArnRegion = 'ES_ARN_REGION';
// // const eventAwsRegion = 'EVENT_AWS_REGION';
// // const invokedFunctionArnRegion = 'IF_ARN_REGION';
//
// const eventSourceArn = sampleEventSourceArn(streamName); //, eventSourceArnRegion);
// //const record = sampleKinesisRecord(eventSourceArn, eventAwsRegion);
// //const event = sampleKinesisEventWithRecord(record);
// const event = sampleKinesisEventWithSampleRecord(eventSourceArn); //, eventAwsRegion);
//
// // Create an AWS context
// const functionName = sampleFunctionName;
// const functionVersion = latestFunctionVersion;
//
// const functionAlias = '';
// const invokedFunctionArn = sampleInvokedFunctionArn(sampleFunctionName, functionAlias); //, invokedFunctionArnRegion);
// const awsContext = sampleAwsContext(invokedFunctionArn, functionName, functionVersion);
//
// const region = regions.resolveRegion(event, awsContext);
// t.equal(region, EVENT_AWS_REGION);
//
// t.end();
// });
test('getRegion and setRegionIfNotSet', t => {
// Attempt to preserve the original AWS_REGION setting (unfortunately cannot preserve undefined or null)
const origRegion = getRegionRaw();
// check orig
if (origRegion === undefined) {
t.equal(origRegion, process.env.AWS_REGION, `original raw must be '${process.env.AWS_REGION}'`);
t.equal(getRegion(), undefined, `original must be empty string '${process.env.AWS_REGION}'`);
} else if (isBlank(origRegion)) {
t.equal(origRegion, process.env.AWS_REGION, `original raw must be '${process.env.AWS_REGION}'`);
t.equal(getRegion(), '', `original must be undefined '${process.env.AWS_REGION}'`);
}
// Must use delete to "clear" property.env variable - since setting to undefined & null don't work as intended
try {
// Clear AWS_REGION to undefined (by deleting it)
delete process.env.AWS_REGION;
t.equal(process.env.AWS_REGION, undefined, `process.env.AWS_REGION must be '${undefined}' after delete`);
// check get when not set
t.equal(getRegion(), undefined, `getRegion() must be '${undefined}'`);
t.throws(() => getRegion(true), undefined, `getRegion(true) must throw'`);
// check will set, when not set
const expected = 'TEST_REGION_1';
t.ok(setRegionIfNotSet(expected), `setRegionIfNotSet('TEST_REGION_1') must set successfully`);
t.equal(getRegion(), expected, `getRegion() must be ${expected}`);
t.equal(process.env.AWS_REGION, expected, `process.env.AWS_REGION must be ${expected}`);
// check was NOT set, when already set set
t.notOk(setRegionIfNotSet('TEST_REGION_3'), `setRegionIfNotSet('TEST_REGION_3') must NOT set successfully`);
t.equal(getRegion(), expected, `getRegion() must still be ${expected}`);
} finally {
// "Restore" original aws region
setRegion(origRegion);
// Check "restore" worked
if (origRegion === undefined) {
t.equal(getRegion(), undefined, `getRegion() must be "restored" to undefined' (orig was ${origRegion})`);
} else if (isBlank(origRegion)) {
t.equal(getRegion(), '', `getRegion() must be "restored" to empty string (orig was '${origRegion}')`);
} else {
t.equal(getRegion(), origRegion, `getRegion() must be restored to ${origRegion}`);
}
t.end();
}
});

@@ -143,3 +143,3 @@ 'use strict';

logGroupName: `/aws/lambda/${functionName}`,
logStreamName: `2016/10/14/[$LATEST]${uuid1.replace(/-/g, "")}`,
logStreamName: logStreamName,
functionName: functionName,

@@ -146,0 +146,0 @@ memoryLimitInMB: 128,

@@ -275,3 +275,92 @@ 'use strict';

// ---------------------------------------------------------------------------------------------------------------------
// AWS.KMS
// ---------------------------------------------------------------------------------------------------------------------
/**
* @typedef {Object} KMSAware - a object configured with an AWS.KMS instance
* @property {AWS.KMS} kms - an instance of AWS.KMS to use
*/
/**
* @typedef {Object} KMSEncryptParams - the parameters to pass to an AWS.KMS `encrypt` call
* @property {string} KeyId - the identifier of the CMK to use for encryption. You can use the key ID or Amazon Resource Name (ARN) of the CMK, or the name or ARN of an alias that refers to the CMK.
* @property {string|Buffer} Plaintext - the data to encrypt (plaintext)
* @property {Object.<string, string>|undefined} [EncryptionContext] - name-value pair that specifies the encryption context to be used for authenticated encryption. If used here, the same value must be supplied to the Decrypt API or decryption will fail. For more information, see http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html.
* @property {string[]|undefined} [GrantTokens] - A list of grant tokens. For more information, see Grant Tokens in the AWS Key Management Service Developer Guide (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token)
*/
/**
* @typedef {Object} KMSEncryptResult - a KMS encrypt result
* @property {string|Buffer|TypedArray|Blob} CiphertextBlob - the encrypted plaintext (ciphertext). If you are using the CLI, the value is Base64 encoded. Otherwise, it is not encoded.
* @property {string} KeyId - the ARN of the CMK that was used to encrypt the data, e.g. "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
*/
/**
* @typedef {Object} KMSDecryptParams - the parameters to pass to an AWS.KMS `decrypt` call
* @property {string|Buffer|TypedArray|Blob} CiphertextBlob - the ciphertext to be decrypted. The blob includes metadata.
* @property {Object.<string, string>|undefined} [EncryptionContext] - the encryption context. If this was specified in the Encrypt function, it must be specified here or the decryption operation will fail
* @property {string[]|undefined} [GrantTokens] - A list of grant tokens
*/
/**
* @typedef {Object} KMSDecryptResult - a KMS decrypt result
* @property {string|Buffer|TypedArray|Blob} Plaintext - decrypted plaintext data. This value may not be returned if the customer master key is not available or if you didn't have permission to use it.
* @property {string} KeyId - the ARN of the key used to perform the decryption. This value is returned if no errors are encountered during the operation.
*/
// ---------------------------------------------------------------------------------------------------------------------
// AWS.Lambda
// ---------------------------------------------------------------------------------------------------------------------
/**
* @typedef {AWS.Lambda} AwsLambda - an AWS.Lambda instance with optional extra async versions of its methods that return promises instead of taking callbacks
* @property {function(params: ListEventSourceMappingsParams): Promise.<EventSourceMapping[]>} [listEventSourceMappingsAsync] - an async version of its `listEventSourceMappings` method
* @property {function(params: UpdateEventSourceMappingParams): Promise.<*>} [updateEventSourceMappingAsync] - an async version of its `updateEventSourceMapping` method
*/
/**
* @typedef {Object} LambdaAware - a object configured with an AWS.Lambda instance
* @property {AWS.Lambda|AwsLambda} lambda - an instance of AWS.Lambda to use
*/
/**
* @typedef {"Creating"|"Enabled"|"Disabled"|"Enabling"|"Disabling"|"Updating"|"Deleting"} EventSourceMappingState
*/
/**
* @typedef {Object} EventSourceMapping - an event source mapping
* @property {string} UUID
* @property {string} BatchSize
* @property {string} EventSourceArn
* @property {string} FunctionArn
* @property {string} LastModified
* @property {string} LastProcessingResult
* @property {EventSourceMappingState} State
* @property {string} StateTransitionReason
*/
/**
* @typedef {Object} ListEventSourceMappingsParams
* @property {string} FunctionName
* @property {string|undefined} [EventSourceArn]
* @property {string|undefined} [Marker]
* @property {number|undefined} [MaxItems]
*/
/**
* @typedef {Object} UpdateEventSourceMappingParams
* @property {string} FunctionName - the Lambda function to which you want the stream records sent
* @property {string} UUID - the event source mapping identifier
* @property {boolean|undefined} [Enabled]
* @property {number|undefined} [BatchSize]
*/
/**
* @typedef {StandardContext} ListEventSourceMappingsResult - the result returned by a call to AWS.Lambda listEventSourceMappings
* @property {string} NextMarker
* @property {EventSourceMapping[]} EventSourceMappings
*/
// ---------------------------------------------------------------------------------------------------------------------
// End of BACKPORT copy from latest `aws-core-utils/type-defs`
// ---------------------------------------------------------------------------------------------------------------------

Sorry, the diff of this file is too big to display

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