aws-core-utils
Advanced tools
Comparing version 5.0.17 to 6.0.0
'use strict'; | ||
const contexts = require('./contexts'); | ||
require("core-functions/promises"); | ||
const Promises = require('core-functions/promises'); | ||
const Objects = require('core-functions/objects'); | ||
@@ -12,2 +12,4 @@ const appErrors = require('core-functions/app-errors'); | ||
const logging = require('logging-utils'); | ||
const LogLevel = logging.LogLevel; | ||
const log = logging.log; | ||
@@ -63,7 +65,7 @@ /** | ||
* | ||
* @param {Object|StandardContext|undefined} [moduleScopeContext] - an optional module-scope context from which to copy an initial standard context | ||
* @param {StandardSettings|undefined} [moduleScopeSettings] - optional module-scoped settings from which to copy initial settings to use to configure a standard context | ||
* @param {StandardOptions|undefined} [moduleScopeOptions] - optional module-scoped options from which to copy initial options to use to configure a standard context | ||
* @param {function(event: AwsEvent, context: StandardContext)} fn - your function that must accept the AWS event and a standard context and ideally return a Promise | ||
* @param {string|undefined} [logRequestResponseAtLogLevel] - an optional log level at which to log the request (i.e. | ||
* @param {Object|StandardContext|undefined} [initContext] - an optional module-scope context from which to copy an initial standard context | ||
* @param {StandardSettings|undefined} [initSettings] - optional module-scoped settings from which to copy initial settings to use to configure a standard context | ||
* @param {StandardOptions|undefined} [initOptions] - optional module-scoped options from which to copy initial options to use to configure a standard context | ||
* @param {function(event: AWSEvent, context: StandardContext)} fn - your function that must accept the AWS event and a standard context and ideally return a Promise | ||
* @param {LogLevel|string|undefined} [logRequestResponseAtLogLevel] - an optional log level at which to log the request (i.e. | ||
* AWS event) and response; if log level is undefined or invalid, then logs neither | ||
@@ -79,3 +81,3 @@ * @param {number[]|undefined} [allowedHttpStatusCodes] - an optional array of HTTP status codes that are allowed to be | ||
*/ | ||
function generateHandlerFunction(moduleScopeContext, moduleScopeSettings, moduleScopeOptions, fn, logRequestResponseAtLogLevel, allowedHttpStatusCodes, invalidRequestMsg, failureMsg, successMsg) { | ||
function generateHandlerFunction(initContext, initSettings, initOptions, fn, logRequestResponseAtLogLevel, allowedHttpStatusCodes, invalidRequestMsg, failureMsg, successMsg) { | ||
/** | ||
@@ -88,6 +90,6 @@ * An API-Gateway exposed Lambda handler function. | ||
function handler(event, awsContext, callback) { | ||
const context = moduleScopeContext && typeof moduleScopeContext === 'object' ? Objects.copy(moduleScopeContext, true) : {}; | ||
const context = initContext && typeof initContext === 'object' ? Objects.copy(initContext, {deep: true}) : {}; | ||
try { | ||
const settings = moduleScopeSettings && typeof moduleScopeSettings === 'object' ? Objects.copy(moduleScopeSettings, true) : undefined; | ||
const options = moduleScopeOptions && typeof moduleScopeOptions === 'object' ? Objects.copy(moduleScopeOptions, true) : undefined; | ||
const settings = initSettings && typeof initSettings === 'object' ? Objects.copy(initSettings, {deep: true}) : undefined; | ||
const options = initOptions && typeof initOptions === 'object' ? Objects.copy(initOptions, {deep: true}) : undefined; | ||
@@ -98,9 +100,13 @@ // Configure the context as a standard context | ||
// Optionally log the request | ||
log('Request: ', event, logRequestResponseAtLogLevel, context); | ||
if (logRequestResponseAtLogLevel && logging.isValidLogLevel(logRequestResponseAtLogLevel)) { | ||
context.log(logRequestResponseAtLogLevel, 'Request:', JSON.stringify(event)); | ||
} | ||
// Execute the given function | ||
Promise.try(() => fn(event, context)) | ||
Promises.try(() => fn(event, context)) | ||
.then(response => { | ||
// Optionally log the response | ||
log('Response: ', response, logRequestResponseAtLogLevel, context); | ||
if (logRequestResponseAtLogLevel && logging.isValidLogLevel(logRequestResponseAtLogLevel)) { | ||
context.log(logRequestResponseAtLogLevel, 'Response:', JSON.stringify(response)); | ||
} | ||
@@ -127,3 +133,3 @@ // Log the given success message (if any) | ||
} catch (err) { | ||
(context.error ? context.error : console.error)(isNotBlank(failureMsg) ? failureMsg : 'Failed to execute Lambda', err.stack); | ||
log(context, LogLevel.ERROR, isNotBlank(failureMsg) ? failureMsg : 'Failed to execute Lambda', err.stack); | ||
// Fail the Lambda callback | ||
@@ -135,28 +141,2 @@ failCallback(callback, err, awsContext, undefined, undefined, allowedHttpStatusCodes); | ||
return handler; | ||
} | ||
function log(prefix, object, logLevel, context) { | ||
if (isNotBlank(logLevel)) { | ||
const msg = `${isNotBlank(prefix) ? prefix : ''}${JSON.stringify(object)}`; | ||
switch (logLevel.toLowerCase()) { | ||
case logging.INFO: | ||
context.info(msg); | ||
break; | ||
case logging.DEBUG: | ||
context.debug(msg); | ||
break; | ||
case logging.TRACE: | ||
context.trace(msg); | ||
break; | ||
case logging.WARN: | ||
context.warn(msg); | ||
break; | ||
case logging.ERROR: | ||
context.error(msg); | ||
break; | ||
default: | ||
context.warn(`Unexpected log level (${logLevel})`); | ||
break; | ||
} | ||
} | ||
} | ||
} |
11
arns.js
@@ -83,13 +83,2 @@ 'use strict'; | ||
/** | ||
* ARN resource-related components | ||
* @typedef {Object} ArnResources | ||
* @property {string} resourceType - a resource type (for DynamoDB stream eventSourceARN's this contains "table") | ||
* @property {string} resource - a resource name (for DynamoDB stream eventSourceARN's this is the table name) | ||
* @property {string} subResourceType - a sub-resource type (for DynamoDB stream eventSourceARN's this contains "stream") | ||
* @property {string} subResource - a sub-resource name (for DynamoDB stream eventSourceARN's this is the stream timestamp) | ||
* @property {string} aliasOrVersion - a Lambda alias or version number | ||
* @property {string[]} others - any other components after a Lambda alias or version number | ||
*/ | ||
/** | ||
* Attempts to extract any and all resource-related components from the given ARN (if defined) and returns them as | ||
@@ -96,0 +85,0 @@ * an object containing resourceType, resource, aliasOrVersion and others (just in case there were even more components |
@@ -13,3 +13,5 @@ "use strict"; | ||
module.exports = { | ||
// General error checks | ||
isUnavailable: isUnavailable, | ||
// Specific error checks | ||
isConditionalCheckFailed: isConditionalCheckFailed, | ||
@@ -19,6 +21,11 @@ isProvisionedThroughputExceeded: isProvisionedThroughputExceeded, | ||
isLimitExceededException: isLimitExceededException, | ||
isItemCollectionSizeLimitExceededException: isItemCollectionSizeLimitExceededException, | ||
// Summarized multiple error checks | ||
isThrottled: isThrottled, | ||
isLimitExceeded: isLimitExceeded, | ||
isRetryable: isRetryable, | ||
// Other specific error checks | ||
isExpiredCredentialsError: isExpiredCredentialsError, | ||
isNetworkingError: isNetworkingError, | ||
// S3 not found | ||
wasS3ObjectNotFound: wasS3ObjectNotFound | ||
@@ -47,2 +54,19 @@ }; | ||
function isItemCollectionSizeLimitExceededException(err) { | ||
return err.code === 'ItemCollectionSizeLimitExceededException'; | ||
} | ||
function isLimitExceeded(err) { | ||
switch (err.code) { | ||
// DynamoDB-specific? | ||
case 'ItemCollectionSizeLimitExceededException': | ||
case 'LimitExceededException': | ||
// not DynamoDB-specific? | ||
case 'RequestLimitExceeded': | ||
return true; | ||
default: | ||
return false; | ||
} | ||
} | ||
function isThrottled(err) { | ||
@@ -53,12 +77,9 @@ switch (err.code) { | ||
case 'ThrottlingException': | ||
case 'ItemCollectionSizeLimitExceededException': | ||
case 'LimitExceededException': | ||
// S3-specific? | ||
//case 'ServiceUnavailable': // actually 503 error | ||
//case 'SlowDown': // actually 503 error | ||
case 'SlowDown': // actually 503 error | ||
// not DynamoDB-specific? | ||
case 'Throttling': | ||
case 'RequestLimitExceeded': | ||
case 'RequestThrottled': | ||
@@ -72,6 +93,4 @@ return true; | ||
function isRetryable(err) { | ||
if (isNetworkingError(err)) return true; | ||
if (isExpiredCredentialsError(err)) return true; | ||
if (isThrottled(err)) return true; | ||
return err.statusCode >= 500; | ||
return err.statusCode >= 500 || isNetworkingError(err) || isExpiredCredentialsError(err) || isThrottled(err) || | ||
isLimitExceeded(err) || err.retryable; | ||
//return isThrottled(err) || err.code === 'ItemCollectionSizeLimitExceededException' || | ||
@@ -78,0 +97,0 @@ // err.code === 'UnrecognizedClientException' || err.retryable; |
@@ -107,12 +107,12 @@ 'use strict'; | ||
const customOptions = optionsAvailable ? Objects.copy(options, true) : {}; | ||
const customOptions = optionsAvailable ? Objects.copy(options, {deep: true}) : {}; | ||
const customSettings = settingsAvailable ? | ||
optionsAvailable ? Objects.merge(customOptions, settings, false, false) : settings : | ||
optionsAvailable ? Objects.merge(customOptions, settings) : settings : | ||
customOptions; | ||
context.custom = context.custom && typeof context.custom === 'object' ? | ||
Objects.merge(customSettings, context.custom, false, false) : customSettings; | ||
Objects.merge(customSettings, context.custom) : customSettings; | ||
return context; | ||
} |
@@ -56,3 +56,3 @@ 'use strict'; | ||
// If no options were specified, then use an empty object | ||
const options = dynamoDBDocClientOptions ? Objects.copy(dynamoDBDocClientOptions, true) : {}; | ||
const options = dynamoDBDocClientOptions ? Objects.copy(dynamoDBDocClientOptions, {deep: true}) : {}; | ||
@@ -59,0 +59,0 @@ // If no region was specified in the given dynamoDBDocClient options, then set it to the current region |
'use strict'; | ||
/** | ||
* Defaults used by this module, which can be overridden to alter the default behaviour. | ||
* @namespace {DynamoDBUtilsDefaults} defaults | ||
*/ | ||
const defaults = { | ||
emptyStringReplacement: ' ' | ||
}; | ||
/** | ||
* Utilities for working with AWS DynamoDB. | ||
@@ -12,5 +20,6 @@ * @module aws-core-utils/dynamodb-utils | ||
toValueFromAttributeTypeAndValue: toValueFromAttributeTypeAndValue, | ||
toNumber: toNumber, | ||
toKeyValueStrings: toKeyValueStrings, | ||
toKeyValuePairs: toKeyValuePairs | ||
toKeyValuePairs: toKeyValuePairs, | ||
toStorableObject: toStorableObject, | ||
defaults: defaults | ||
}; | ||
@@ -21,2 +30,5 @@ | ||
const Numbers = require('core-functions/numbers'); | ||
const toNumberOrIntegerLike = Numbers.toNumberOrIntegerLike; | ||
/** | ||
@@ -70,3 +82,3 @@ * Attempts to convert the given DynamoDB map object containing keys and Attribute values into a JavaScript object. | ||
case 'N': | ||
return toNumber(value); | ||
return toNumberOrIntegerLike(value); | ||
case 'BOOL': | ||
@@ -83,3 +95,3 @@ return value === true || value === 'true'; | ||
case 'NS': | ||
return value.map(v => toNumber(v)); | ||
return value.map(v => toNumberOrIntegerLike(v)); | ||
case 'B': | ||
@@ -94,24 +106,2 @@ case 'BS': | ||
/** | ||
* Attempts to convert the given value into a number, but keeps any integer string, which cannot be converted to a | ||
* number without losing precision. | ||
* @param {string} value - the value to convert | ||
* @returns {number|string} the number parsed from the value | ||
*/ | ||
function toNumber(value) { | ||
if (value) { | ||
const typeOfValue = typeof value; | ||
if (typeOfValue === 'string' && value.indexOf('.') === -1) { | ||
// No decimal point, so try for an integer first | ||
const n = Number.parseInt(value); | ||
// Check if have enough precision to hold the given integer value ... otherwise rather keep the original string value | ||
return `${n}` === value ? n : Number.isNaN(n) ? NaN : value; | ||
} else if (typeOfValue === 'number') { | ||
return value; | ||
} | ||
return Number.parseFloat(value); | ||
} | ||
return NaN; | ||
} | ||
/** | ||
* Extracts an array of colon-separated key name and value strings from the given DynamoDB map object. | ||
@@ -122,9 +112,4 @@ * @param {Object} dynamoDBMap - a DynamoDB map object | ||
function toKeyValueStrings(dynamoDBMap) { | ||
if (!dynamoDBMap || typeof dynamoDBMap !== 'object') { | ||
return []; | ||
} | ||
return Object.getOwnPropertyNames(dynamoDBMap).map(key => { | ||
const value = toValueFromAttributeValue(dynamoDBMap[key]); | ||
return `${key}:${stringify(value)}`; | ||
}); | ||
return dynamoDBMap && typeof dynamoDBMap === 'object' ? | ||
Object.getOwnPropertyNames(dynamoDBMap).map(key => `${key}:${stringify(toValueFromAttributeValue(dynamoDBMap[key]))}`) : []; | ||
} | ||
@@ -136,9 +121,30 @@ | ||
* @param {Object} dynamoDBMap - a DynamoDB map object | ||
* @returns {string[]} an array of key name and value pairs | ||
* @returns {KeyValuePair[]} an array of key value pairs | ||
*/ | ||
function toKeyValuePairs(dynamoDBMap) { | ||
if (!dynamoDBMap || typeof dynamoDBMap !== 'object') { | ||
return []; | ||
} | ||
return Object.getOwnPropertyNames(dynamoDBMap).map(key => [key, toValueFromAttributeValue(dynamoDBMap[key])]); | ||
return dynamoDBMap && typeof dynamoDBMap === 'object' ? | ||
Object.getOwnPropertyNames(dynamoDBMap).map(key => [key, toValueFromAttributeValue(dynamoDBMap[key])]) : []; | ||
} | ||
/** | ||
* Transforms the given object into an object that can be safely stored to DynamoDB with all of its empty strings | ||
* replaced with Defaults.emptyStringReplacement and with no undefined properties. | ||
* @param {Object} object - an object to be stored in DynamoDB | ||
* @returns {Object} an object that can be safely stored in DynamoDB | ||
*/ | ||
function toStorableObject(object) { | ||
// Round-trip to JSON and back to eliminate all undefined properties and replace all empty strings | ||
return JSON.parse(JSON.stringify(object, emptyStringReplacer)); | ||
} | ||
//noinspection JSUnusedLocalSymbols | ||
/** | ||
* A replacer function to be used with JSON.stringify, which replaces all empty string values with Defaults.emptyStringReplacement. | ||
* @param {string} key - the key of the property being stringified (initially an empty key representing the object being stringified) | ||
* @param {*} value - the value being stringified | ||
* @returns {string} the non-empty string replacement value | ||
*/ | ||
function emptyStringReplacer(key, value) { | ||
// DynamoDB does NOT accept any empty strings including ones inside arrays, so no special case for arrays is necessary | ||
return value === '' ? defaults.emptyStringReplacement : value; | ||
} |
@@ -53,3 +53,3 @@ 'use strict'; | ||
// If no options were specified, then use an empty object | ||
const options = kinesisOptions ? Objects.copy(kinesisOptions, true) : {}; | ||
const options = kinesisOptions ? Objects.copy(kinesisOptions, {deep: true}) : {}; | ||
@@ -56,0 +56,0 @@ // If no region was specified in the given kinesis options, then set it to the current region |
{ | ||
"name": "aws-core-utils", | ||
"version": "5.0.17", | ||
"version": "6.0.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.14", | ||
"logging-utils": "^3.0.12", | ||
"core-functions": "^3.0.0", | ||
"logging-utils": "^4.0.0", | ||
"deep-equal": "^1.0.1" | ||
@@ -18,0 +18,0 @@ }, |
@@ -1,2 +0,2 @@ | ||
# aws-core-utils v5.0.17 | ||
# aws-core-utils v6.0.0 | ||
@@ -134,6 +134,6 @@ Core utilities for working with Amazon Web Services (AWS), including ARNs, regions, stages, Lambdas, AWS errors, stream events, Kinesis, DynamoDB.DocumentClients, etc. | ||
// If you need the logic of the configureCustomSettings function, which is used by configureStandardContext, for other purposes | ||
const myCustomSettings = {myCustomSetting1: 1, myCustomSetting2: 2, myCustomFunction: () => {}}; // | ||
const myCustomSettings = {myCustomSetting1: 1, myCustomSetting2: 2, myCustomFunction: () => {}}; | ||
const myCustomOptions = require('my-custom-options.json'); | ||
contexts.configureCustomSettings(context, myCustomSettings, myCustomOptions); | ||
console.log(`context.custom = ${JSON.stringify(context.custom)}`); | ||
console.log(`context.custom = ${JSON.stringify(context.custom)}; myCustomFunction = ${JSON.stringify(context.custom.myCustomFunction)} `); | ||
``` | ||
@@ -148,3 +148,3 @@ | ||
const logging = require('logging-utils'); | ||
logging.configureDefaultLogging(context); // or your own custom logging configuration (see logging-utils README.md) | ||
logging.configureLogging(context); // or your own custom logging configuration (see logging-utils README.md) | ||
@@ -188,3 +188,3 @@ // Define the DynamoDB.DocumentClient's constructor options that you want to use, e.g. | ||
const logging = require('logging-utils'); | ||
logging.configureDefaultLogging(context); // or your own custom logging configuration (see logging-utils README.md) | ||
logging.configureLogging(context); // or your own custom logging configuration (see logging-utils README.md) | ||
@@ -394,2 +394,37 @@ // Define the Kinesis constructor options that you want to use, e.g. | ||
### 6.0.0 | ||
- Updated `core-functions` dependency to version 3.0.0 | ||
- Updated `logging-utils` dependency to version 4.0.0 | ||
- Changes to `api-lambdas.js` module: | ||
- Removed `log` function (replaced use with new `log` function & `log` method in `logging-utils`) | ||
- Changes to `arns.js` module: | ||
- Moved `ArnResources` typedef to `type-defs.js` | ||
- Changes to `aws-errors.js` module: | ||
- Added `isItemCollectionSizeLimitExceededException` function | ||
- Added `isLimitExceeded` function | ||
- Removed limit exceeded cases from `isThrottled` function (not backward-compatible) | ||
- Added S3 `SlowDown` case to `isThrottled` function | ||
- Added `isLimitExceeded` & `err.retryable` checks to `isRetryable` function | ||
- Changes to `dynamodb-utils.js` module: | ||
- Removed `toNumber` function (replaced use with new `toNumberOrIntegerLike` function in `core-functions/numbers.js`) | ||
- Added new `toStorableObject` function | ||
- Added new `defaults` static property with `emptyStringReplacement` property | ||
- Changes to `stages.js` module: | ||
- Replaced all setting names constants (e.g. CUSTOM_TO_STAGE_SETTING) with use of a new module-scope `settingNames` | ||
object property that holds all the standard stage handling settings names (e.g. settingNames.customToStage) | ||
- Added new `extractNameAndStageFromStreamName` & `extractNameAndStageFromResourceName` settings | ||
- Added `extractNameAndStageFromQualifiedStreamName` & `extractNameAndStageFromQualifiedResourceName` functions | ||
- Added `extractNameAndStageFromSuffixedStreamName` & `extractNameAndStageFromSuffixedResourceName` functions | ||
- Added `_extractNameAndStageFromQualifiedName` & `_extractNameAndStageFromSuffixedName` functions | ||
- Changed `extractStageFromQualifiedStreamName` to attempt fallback with `_extractNameAndStageFromQualifiedName` | ||
- Changed `extractStageFromQualifiedResourceName` to attempt fallback with `_extractNameAndStageFromQualifiedName` | ||
- Changes to `stream-events.js` module: | ||
- Added `MAX_PARTITION_KEY_SIZE` constant | ||
- Added `DynamoDBEventName` enum | ||
- Added `getEventID`, `getEventName`, `getEventSource` & `getEventSourceARN` functions | ||
- Added `getKinesisShardId`, `getKinesisShardIdFromEventID`, `getKinesisShardIdAndEventNoFromEventID` & `getKinesisSequenceNumber` functions | ||
- Added `getDynamoDBSequenceNumber` function | ||
- Added additional validation checks to `validateStreamEventRecord`, `validateKinesisStreamEventRecord` & `validateDynamoDBStreamEventRecord` functions | ||
- Added many new typedefs to `type-defs.js` | ||
### 5.0.17 | ||
@@ -396,0 +431,0 @@ - Fixed critical module-scope defects in `generateHandlerFunction` function in `api-lambdas` module |
225
stages.js
'use strict'; | ||
// Stage handling setting names | ||
const ENV_STAGE_NAME_SETTING = 'envStageName'; | ||
/** | ||
* The names of all of the standard stage handling settings. | ||
* @namespace | ||
*/ | ||
const settingNames = { | ||
envStageName: 'envStageName', | ||
customToStage: 'customToStage', | ||
convertAliasToStage: 'convertAliasToStage', | ||
streamNameStageSeparator: 'streamNameStageSeparator', | ||
injectStageIntoStreamName: 'injectStageIntoStreamName', | ||
extractStageFromStreamName: 'extractStageFromStreamName', | ||
extractNameAndStageFromStreamName: 'extractNameAndStageFromStreamName', | ||
resourceNameStageSeparator: 'resourceNameStageSeparator', | ||
injectStageIntoResourceName: 'injectStageIntoResourceName', | ||
extractStageFromResourceName: 'extractStageFromResourceName', | ||
extractNameAndStageFromResourceName: 'extractNameAndStageFromResourceName', | ||
injectInCase: 'injectInCase', | ||
extractInCase: 'extractInCase' | ||
}; | ||
const CUSTOM_TO_STAGE_SETTING = 'customToStage'; | ||
const CONVERT_ALIAS_TO_STAGE_SETTING = 'convertAliasToStage'; | ||
const STREAM_NAME_STAGE_SEPARATOR_SETTING = 'streamNameStageSeparator'; | ||
const INJECT_STAGE_INTO_STREAM_NAME_SETTING = 'injectStageIntoStreamName'; | ||
const EXTRACT_STAGE_FROM_STREAM_NAME_SETTING = 'extractStageFromStreamName'; | ||
const RESOURCE_NAME_STAGE_SEPARATOR_SETTING = 'resourceNameStageSeparator'; | ||
const INJECT_STAGE_INTO_RESOURCE_NAME_SETTING = 'injectStageIntoResourceName'; | ||
const EXTRACT_STAGE_FROM_RESOURCE_NAME_SETTING = 'extractStageFromResourceName'; | ||
const INJECT_IN_CASE_SETTING = 'injectInCase'; | ||
const EXTRACT_IN_CASE_SETTING = 'extractInCase'; | ||
/** | ||
@@ -31,2 +34,3 @@ * Stage handling utilities (primarily for AWS Lambda usage), which include the following: | ||
module.exports = { | ||
settingNames: settingNames, | ||
// Stage handling configuration | ||
@@ -52,2 +56,3 @@ isStageHandlingConfigured: isStageHandlingConfigured, | ||
extractStageFromQualifiedStreamName: extractStageFromQualifiedStreamName, | ||
extractNameAndStageFromQualifiedStreamName: extractNameAndStageFromQualifiedStreamName, | ||
@@ -57,2 +62,3 @@ // Resource name qualification | ||
extractStageFromQualifiedResourceName: extractStageFromQualifiedResourceName, | ||
extractNameAndStageFromQualifiedResourceName: extractNameAndStageFromQualifiedResourceName, | ||
@@ -70,5 +76,7 @@ /** | ||
extractStageFromSuffixedStreamName: extractStageFromSuffixedStreamName, | ||
extractNameAndStageFromSuffixedStreamName: extractNameAndStageFromSuffixedStreamName, | ||
// Stage-suffixed resource name qualification | ||
toStageSuffixedResourceName: toStageSuffixedResourceName, | ||
extractStageFromSuffixedResourceName: extractStageFromSuffixedResourceName, | ||
extractNameAndStageFromSuffixedResourceName: extractNameAndStageFromSuffixedResourceName, | ||
// Generic utils | ||
@@ -117,3 +125,3 @@ toStageSuffixedName: toStageSuffixedName, | ||
* | ||
* @param {Object|StandardContext|StageHandling|Logging} context - the context onto which to configure stage handling settings | ||
* @param {Object|StandardContext|StageHandling|Logger} context - the context onto which to configure stage handling settings | ||
* @param {StageHandlingSettings} [context.stageHandling] - previously configured stage handling settings on the context (if any) | ||
@@ -163,3 +171,3 @@ * @param {StageHandlingSettings} settings - the new stage handling settings to use | ||
* | ||
* @param {Object|StandardContext|StageHandling|Logging} context - the context onto which to configure the default stage handling settings | ||
* @param {Object|StandardContext|StageHandling|Logger} context - the context onto which to configure the default stage handling settings | ||
* @param {StageHandlingSettings} [context.stageHandling] - previously configured stage handling settings on the context (if any) | ||
@@ -192,6 +200,6 @@ * @param {StageHandlingOptions|undefined} [options] - optional stage handling options to use to override the default options | ||
function getDefaultStageHandlingSettings(options) { | ||
const settings = options && typeof options === 'object' ? Objects.copy(options, true) : {}; | ||
const settings = options && typeof options === 'object' ? Objects.copy(options, {deep: true}) : {}; | ||
const defaultOptions = loadDefaultStageHandlingOptions(); | ||
Objects.merge(defaultOptions, settings, false, false); | ||
Objects.merge(defaultOptions, settings); | ||
@@ -204,7 +212,9 @@ const defaultSettings = { | ||
extractStageFromStreamName: extractStageFromSuffixedStreamName, | ||
extractNameAndStageFromStreamName: extractNameAndStageFromSuffixedStreamName, | ||
injectStageIntoResourceName: toStageSuffixedResourceName, | ||
extractStageFromResourceName: extractStageFromSuffixedResourceName, | ||
extractNameAndStageFromResourceName: extractNameAndStageFromSuffixedResourceName | ||
}; | ||
return Objects.merge(defaultSettings, settings, false, false); | ||
return Objects.merge(defaultSettings, settings); | ||
} | ||
@@ -229,3 +239,3 @@ | ||
}; | ||
return Objects.merge(defaults, defaultOptions, false, false); | ||
return Objects.merge(defaults, defaultOptions); | ||
} | ||
@@ -265,3 +275,3 @@ | ||
* | ||
* @param {Object|StandardContext|StageHandling|Logging} context - the context to configure | ||
* @param {Object|StandardContext|StageHandling|Logger} context - the context to configure | ||
* @param {StageHandlingSettings|undefined} [settings] - optional stage handling settings to use to configure stage handling | ||
@@ -288,3 +298,3 @@ * @param {StageHandlingOptions|undefined} [options] - optional stage handling options to use to override default options | ||
const stageHandlingSettings = settingsAvailable ? | ||
Objects.merge(defaultSettings, settings, false, false) : defaultSettings; | ||
Objects.merge(defaultSettings, settings) : defaultSettings; | ||
@@ -296,3 +306,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`); | ||
} | ||
@@ -306,3 +316,3 @@ return context; | ||
* | ||
* @param {Object|StandardContext|Logging} context - the context onto which to configure the given stage handling dependencies | ||
* @param {Object|StandardContext|Logger} context - the context onto which to configure the given stage handling dependencies | ||
* @param {Object|StandardSettings|undefined} [otherSettings] - optional other configuration settings to use | ||
@@ -314,3 +324,3 @@ * @param {LoggingSettings|undefined} [otherSettings.loggingSettings] - optional logging settings to use to configure logging | ||
* will override any previously configured dependencies' settings on the given context | ||
* @returns {Logging|StandardContext} the context object configured with stage handling dependencies (i.e. logging functionality) | ||
* @returns {Logger|StandardContext} the context object configured with stage handling dependencies (i.e. logging functionality) | ||
*/ | ||
@@ -320,3 +330,3 @@ function configureDependencies(context, otherSettings, otherOptions, forceConfiguration) { | ||
logging.configureLogging(context, otherSettings ? otherSettings.loggingSettings : undefined, | ||
otherOptions ? otherOptions.loggingOptions : undefined, undefined, forceConfiguration); | ||
otherOptions ? otherOptions.loggingOptions : undefined, forceConfiguration); | ||
} | ||
@@ -378,3 +388,3 @@ | ||
// Resolve extractInCase | ||
const extractInCase = getStageHandlingSetting(context, EXTRACT_IN_CASE_SETTING); | ||
const extractInCase = getStageHandlingSetting(context, settingNames.extractInCase); | ||
@@ -388,3 +398,3 @@ // Attempt 1 | ||
// Attempt 2 | ||
const envStageName = getStageHandlingSetting(context, ENV_STAGE_NAME_SETTING); | ||
const envStageName = getStageHandlingSetting(context, settingNames.envStageName); | ||
@@ -402,3 +412,3 @@ if (isNotBlank(envStageName)) { | ||
// Attempt 3 | ||
const customToStage = getStageHandlingFunction(context, CUSTOM_TO_STAGE_SETTING); | ||
const customToStage = getStageHandlingFunction(context, settingNames.customToStage); | ||
@@ -422,3 +432,3 @@ if (customToStage) { | ||
// Check have all the pieces needed to extract an alias and apply the given convertAliasToStage function to it | ||
const convertAliasToStage = getStageHandlingFunction(context, CONVERT_ALIAS_TO_STAGE_SETTING); | ||
const convertAliasToStage = getStageHandlingFunction(context, settingNames.convertAliasToStage); | ||
@@ -459,3 +469,3 @@ if (convertAliasToStage && awsContext && isNotBlank(awsContext.functionVersion) && isNotBlank(awsContext.invokedFunctionArn)) { | ||
// Check have all the pieces needed to extract a stream name and apply the given extractStageFromStreamName function to it | ||
const extractStageFromStreamName = getStageHandlingFunction(context, EXTRACT_STAGE_FROM_STREAM_NAME_SETTING); | ||
const extractStageFromStreamName = getStageHandlingFunction(context, settingNames.extractStageFromStreamName); | ||
if (extractStageFromStreamName && event && event.Records) { | ||
@@ -468,3 +478,3 @@ stages = streamEvents.getKinesisEventSourceStreamNames(event) | ||
// Check have all the pieces needed to extract a table name and apply the given extractStageFromResourceName function to it | ||
const extractStageFromTableName = getStageHandlingFunction(context, EXTRACT_STAGE_FROM_RESOURCE_NAME_SETTING); | ||
const extractStageFromTableName = getStageHandlingFunction(context, settingNames.extractStageFromResourceName); | ||
if (extractStageFromTableName && event && event.Records) { | ||
@@ -481,3 +491,3 @@ stages = streamEvents.getDynamoDBEventSourceTableNames(event) | ||
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 | ||
@@ -545,3 +555,3 @@ } | ||
function toStageQualifiedStreamName(unqualifiedStreamName, stage, context) { | ||
return _toStageQualifiedName(unqualifiedStreamName, stage, INJECT_STAGE_INTO_STREAM_NAME_SETTING, context); | ||
return _toStageQualifiedName(unqualifiedStreamName, stage, settingNames.injectStageIntoStreamName, context); | ||
} | ||
@@ -561,5 +571,24 @@ | ||
function extractStageFromQualifiedStreamName(qualifiedStreamName, context) { | ||
return _extractStageFromQualifiedName(qualifiedStreamName, EXTRACT_STAGE_FROM_STREAM_NAME_SETTING, context); | ||
const stage = _extractStageFromQualifiedName(qualifiedStreamName, settingNames.extractStageFromStreamName, context); | ||
return isNotBlank(stage) ? stage : | ||
_extractNameAndStageFromQualifiedName(qualifiedStreamName, settingNames.extractNameAndStageFromStreamName, context)[1]; | ||
} | ||
/** | ||
* Extracts the unqualified stream name and the stage from the given stage-qualified stream name (if non-blank and an | ||
* extractNameAndStageFromStreamName function is configured); otherwise returns the given stream name and an empty stage | ||
* string. | ||
* | ||
* This function uses the configured extractNameAndStageFromStreamName function (if any) on the given context to | ||
* determine its actual behaviour. | ||
* | ||
* @param {string} qualifiedStreamName - the stage-qualified stream name | ||
* @param {StageHandling|Object} context - the context to use with stage handling settings and logging functionality | ||
* @returns {[string,string]} an array containing: the unqualified name and the stage (if extracted); otherwise the | ||
* given name and an empty stage string | ||
*/ | ||
function extractNameAndStageFromQualifiedStreamName(qualifiedStreamName, context) { | ||
return _extractNameAndStageFromQualifiedName(qualifiedStreamName, settingNames.extractNameAndStageFromStreamName, context); | ||
} | ||
// ===================================================================================================================== | ||
@@ -580,3 +609,3 @@ // Stream name qualification (default) | ||
function toStageSuffixedStreamName(unsuffixedStreamName, stage, context) { | ||
return _toStageSuffixedName(unsuffixedStreamName, stage, STREAM_NAME_STAGE_SEPARATOR_SETTING, context); | ||
return _toStageSuffixedName(unsuffixedStreamName, stage, settingNames.streamNameStageSeparator, context); | ||
} | ||
@@ -595,5 +624,24 @@ | ||
function extractStageFromSuffixedStreamName(stageSuffixedStreamName, context) { | ||
return _extractStageFromSuffixedName(stageSuffixedStreamName, STREAM_NAME_STAGE_SEPARATOR_SETTING, context); | ||
return _extractStageFromSuffixedName(stageSuffixedStreamName, settingNames.streamNameStageSeparator, context); | ||
} | ||
/** | ||
* A default extractNameAndStageFromStreamName function that extracts the unqualified name and stage from the given | ||
* stage-suffixed stream name. | ||
* | ||
* The unqualified name prefix is extracted from the given stream name by taking everything before the last occurrence | ||
* of the configured streamNameStageSeparator (if any). | ||
* | ||
* The stage suffix is extracted from the given stream name by taking everything after the last occurrence of the configured | ||
* streamNameStageSeparator (if any). | ||
* | ||
* @param {string} stageSuffixedStreamName - the stage-suffixed name of the stream | ||
* @param {StageHandling|Object} context - the context to use with stage handling settings and logging functionality | ||
* @returns {[string,string]} an array containing: the unqualified name and the stage (if extracted); otherwise the | ||
* given name and an empty stage string | ||
*/ | ||
function extractNameAndStageFromSuffixedStreamName(stageSuffixedStreamName, context) { | ||
return _extractNameAndStageFromSuffixedName(stageSuffixedStreamName, settingNames.streamNameStageSeparator, context); | ||
} | ||
// ===================================================================================================================== | ||
@@ -617,3 +665,3 @@ // Resource name qualification | ||
function toStageQualifiedResourceName(unqualifiedResourceName, stage, context) { | ||
return _toStageQualifiedName(unqualifiedResourceName, stage, INJECT_STAGE_INTO_RESOURCE_NAME_SETTING, context); | ||
return _toStageQualifiedName(unqualifiedResourceName, stage, settingNames.injectStageIntoResourceName, context); | ||
} | ||
@@ -633,5 +681,25 @@ | ||
function extractStageFromQualifiedResourceName(qualifiedResourceName, context) { | ||
return _extractStageFromQualifiedName(qualifiedResourceName, EXTRACT_STAGE_FROM_RESOURCE_NAME_SETTING, context); | ||
const stage = _extractStageFromQualifiedName(qualifiedResourceName, settingNames.extractStageFromResourceName, context); | ||
return isNotBlank(stage) ? stage : | ||
_extractNameAndStageFromQualifiedName(qualifiedResourceName, settingNames.extractNameAndStageFromResourceName, context)[1]; | ||
} | ||
/** | ||
* Extracts the unqualified resource name and the stage from the given stage-qualified resource name (if non-blank and | ||
* an extractNameAndStageFromResourceName function is configured); otherwise returns the given resource name and an | ||
* empty stage string. | ||
* | ||
* This function uses the configured extractNameAndStageFromResourceName function (if any) on the given context to | ||
* determine its actual behaviour. | ||
* | ||
* @param {string} qualifiedResourceName - the stage-qualified resource name | ||
* @param {StageHandling|Object} context - the context to use with stage handling settings and logging functionality | ||
* @returns {[string,string]} an array containing: the unqualified name and the stage (if extracted); otherwise the | ||
* given name and an empty stage string | ||
*/ | ||
function extractNameAndStageFromQualifiedResourceName(qualifiedResourceName, context) { | ||
return _extractNameAndStageFromQualifiedName(qualifiedResourceName, settingNames.extractNameAndStageFromResourceName, context); | ||
} | ||
// ===================================================================================================================== | ||
@@ -651,3 +719,3 @@ // Resource name qualification (default) | ||
function toStageSuffixedResourceName(unsuffixedResourceName, stage, context) { | ||
return _toStageSuffixedName(unsuffixedResourceName, stage, RESOURCE_NAME_STAGE_SEPARATOR_SETTING, context); | ||
return _toStageSuffixedName(unsuffixedResourceName, stage, settingNames.resourceNameStageSeparator, context); | ||
} | ||
@@ -665,5 +733,24 @@ | ||
function extractStageFromSuffixedResourceName(stageSuffixedResourceName, context) { | ||
return _extractStageFromSuffixedName(stageSuffixedResourceName, RESOURCE_NAME_STAGE_SEPARATOR_SETTING, context) | ||
return _extractStageFromSuffixedName(stageSuffixedResourceName, settingNames.resourceNameStageSeparator, context) | ||
} | ||
/** | ||
* A default extractNameAndStageFromResourceName function that extracts the unqualified name and stage from the given | ||
* stage-suffixed resource name. | ||
* | ||
* The unqualified name prefix is extracted from the given resource name by taking everything before the last occurrence | ||
* of the configured resourceNameStageSeparator (if any). | ||
* | ||
* The stage suffix is extracted from the given resource name by taking everything after the last occurrence of the | ||
* configured resourceNameStageSeparator (if any). | ||
* | ||
* @param {string} stageSuffixedResourceName - the stage-suffixed name of the resource | ||
* @param {StageHandling|Object} context - the context to use with stage handling settings and logging functionality | ||
* @returns {[string,string]} an array containing: the unqualified name and the stage (if extracted); otherwise the | ||
* given name and an empty stage string | ||
*/ | ||
function extractNameAndStageFromSuffixedResourceName(stageSuffixedResourceName, context) { | ||
return _extractNameAndStageFromSuffixedName(stageSuffixedResourceName, settingNames.resourceNameStageSeparator, context); | ||
} | ||
// ===================================================================================================================== | ||
@@ -687,2 +774,3 @@ // Generic name qualification | ||
if (isNotBlank(qualifiedName)) { | ||
qualifiedName = trim(qualifiedName); | ||
configureDefaultStageHandling(context); | ||
@@ -692,4 +780,3 @@ | ||
const extractStageFromName = getStageHandlingFunction(context, extractStageFromNameSettingName); | ||
return extractStageFromName ? extractStageFromName(trim(qualifiedName), context) : ''; | ||
return extractStageFromName ? trimOrEmpty(extractStageFromName(qualifiedName, context)) : ''; | ||
} | ||
@@ -699,2 +786,27 @@ return ''; | ||
function _extractNameAndStageFromQualifiedName(qualifiedName, extractNameAndStageFromNameSettingName, context) { | ||
qualifiedName = trimOrEmpty(qualifiedName); | ||
if (isNotBlank(qualifiedName)) { | ||
configureDefaultStageHandling(context); | ||
// Resolve extractNameAndStageFromName function to use | ||
const extractNameAndStageFromName = getStageHandlingFunction(context, extractNameAndStageFromNameSettingName); | ||
if (extractNameAndStageFromName) { | ||
const nameAndStage = extractNameAndStageFromName(qualifiedName, context); | ||
if (Array.isArray(nameAndStage)) { | ||
if (nameAndStage.length !== 2) { | ||
const extractFnName = extractNameAndStageFromName.name ? extractNameAndStageFromName.name : 'extractNameAndStageFromName'; | ||
context.warn(`Extracted name and stage ${stringify(nameAndStage)} contains ${nameAndStage.length} elements, but ${extractFnName} function should return an array with a resolved name & stage`); | ||
} | ||
return [trimOrEmpty(nameAndStage[0]), trimOrEmpty(nameAndStage[1])]; | ||
} | ||
if (nameAndStage) { | ||
const extractFnName = extractNameAndStageFromName.name ? extractNameAndStageFromName.name : 'extractNameAndStageFromName'; | ||
context.warn(`Ignoring extracted name and stage (${stringify(nameAndStage)}), since ${extractFnName} function MUST return an array with a resolved name & stage`); | ||
} | ||
} | ||
} | ||
return [qualifiedName, '']; | ||
} | ||
// ===================================================================================================================== | ||
@@ -712,3 +824,3 @@ // Generic name qualification (default) | ||
// Resolve injectInCase | ||
const injectInCase = getStageHandlingSetting(context, INJECT_IN_CASE_SETTING); | ||
const injectInCase = getStageHandlingSetting(context, settingNames.injectInCase); | ||
@@ -728,3 +840,3 @@ return toStageSuffixedName(unsuffixedName, separator, stage, injectInCase); | ||
// Resolve extractInCase | ||
const extractInCase = getStageHandlingSetting(context, EXTRACT_IN_CASE_SETTING); | ||
const extractInCase = getStageHandlingSetting(context, settingNames.extractInCase); | ||
@@ -738,2 +850,21 @@ // Extract stage using separator and convert to case specified by extractInCase | ||
function _extractNameAndStageFromSuffixedName(stageSuffixedName, separatorSettingName, context) { | ||
if (isNotBlank(stageSuffixedName)) { | ||
configureDefaultStageHandling(context); | ||
// Resolve separator | ||
const separator = getStageHandlingSetting(context, separatorSettingName); | ||
// Resolve extractInCase | ||
const extractInCase = getStageHandlingSetting(context, settingNames.extractInCase); | ||
// Extract stage using separator and convert to case specified by extractInCase | ||
const suffixStartPos = stageSuffixedName.lastIndexOf(separator); | ||
return suffixStartPos !== -1 ? | ||
[trimOrEmpty(stageSuffixedName.substring(0, suffixStartPos)), trimOrEmpty(toCase(stageSuffixedName.substring(suffixStartPos + 1), extractInCase))] : | ||
[trimOrEmpty(stageSuffixedName), '']; | ||
} | ||
return [trimOrEmpty(stageSuffixedName), '']; | ||
} | ||
/** | ||
@@ -740,0 +871,0 @@ * Returns a stage-suffixed version of the given unsuffixed name with an appended stage suffix, which will contain the |
'use strict'; | ||
// Constants | ||
const MAX_PARTITION_KEY_SIZE = 256; | ||
const arns = require('./arns'); | ||
const Strings = require('core-functions/strings'); | ||
const isNotBlank = Strings.isNotBlank; | ||
const stringify = Strings.stringify; | ||
/** | ||
* Utilities for extracting information from AWS Kinesis and AWS DynamoDB stream events. | ||
* Valid event names for a DynamoDB stream event. | ||
* @enum {string} | ||
* @readonly | ||
*/ | ||
const DynamoDBEventName = { | ||
INSERT: 'INSERT', | ||
MODIFY: 'MODIFY', | ||
REMOVE: 'REMOVE' | ||
}; | ||
/** | ||
* Utilities for validating and extracting information from AWS Kinesis and AWS DynamoDB stream events. | ||
* @module aws-core-utils/stream-events | ||
@@ -14,2 +27,16 @@ * @author Byron du Preez | ||
module.exports = { | ||
MAX_PARTITION_KEY_SIZE: MAX_PARTITION_KEY_SIZE, | ||
/** Valid event names for a DynamoDB stream event */ | ||
DynamoDBEventName: DynamoDBEventName, | ||
/** Returns the event id from the given stream event record */ | ||
getEventID: getEventID, | ||
/** Returns the event name from the given stream event record */ | ||
getEventName: getEventName, | ||
/** Returns the event source from the given stream event record */ | ||
getEventSource: getEventSource, | ||
/** Returns the event source ARN from the given stream event record */ | ||
getEventSourceARN: getEventSourceARN, | ||
/** Returns the event source ARNs of the given stream event's records */ | ||
@@ -24,3 +51,12 @@ getEventSourceARNs: getEventSourceARNs, | ||
getKinesisEventSourceStreamName: getKinesisEventSourceStreamName, | ||
/** Extracts and returns the shard id from the given Kinesis stream event record */ | ||
getKinesisShardId: getKinesisShardId, | ||
/** Extracts and returns the shard id from the given Kinesis eventID */ | ||
getKinesisShardIdFromEventID: getKinesisShardIdFromEventID, | ||
/** Extracts and returns the shard id and event number from the given Kinesis eventID */ | ||
getKinesisShardIdAndEventNoFromEventID: getKinesisShardIdAndEventNoFromEventID, | ||
/** Returns the sequence number from the given Kinesis stream event record */ | ||
getKinesisSequenceNumber: getKinesisSequenceNumber, | ||
/** Extracts and returns the table names from the given DynamoDB stream event records' eventSourceARNs */ | ||
@@ -33,2 +69,5 @@ getDynamoDBEventSourceTableNames: getDynamoDBEventSourceTableNames, | ||
/** Returns the sequence number from the given DynamoDB stream event record */ | ||
getDynamoDBSequenceNumber: getDynamoDBSequenceNumber, | ||
/** Validates the given stream event record and raises an error if the record is invalid or not a Kinesis or DynamoDB stream event record */ | ||
@@ -46,8 +85,44 @@ validateStreamEventRecord: validateStreamEventRecord, | ||
/** | ||
* Returns the event id from the given stream event record. | ||
* @param {AnyStreamEventRecord|*} record - a stream event record | ||
* @returns {string} the event id (if any) or an empty string | ||
*/ | ||
function getEventID(record) { | ||
return record && record.eventID ? record.eventID : ''; | ||
} | ||
/** | ||
* Returns the event name from the given stream event record. | ||
* @param {AnyStreamEventRecord|*} record - a stream event record | ||
* @returns {string} the event name (if any) or an empty string | ||
*/ | ||
function getEventName(record) { | ||
return record && record.eventName ? record.eventName : ''; | ||
} | ||
/** | ||
* Returns the event source from the given stream event record. | ||
* @param {AnyStreamEventRecord|*} record - a stream event record | ||
* @returns {string} the event source (if any) or an empty string | ||
*/ | ||
function getEventSource(record) { | ||
return record && record.eventSource ? record.eventSource : ''; | ||
} | ||
/** | ||
* Returns the event source ARN from the given stream event record. | ||
* @param {AnyStreamEventRecord|*} record - a stream event record | ||
* @returns {string} the event source ARN (if any) or an empty string | ||
*/ | ||
function getEventSourceARN(record) { | ||
return record && record.eventSourceARN ? record.eventSourceARN : ''; | ||
} | ||
/** | ||
* Returns the event source ARNs of the given stream event's records (if any); otherwise returns an empty array. | ||
* @param event - a Kinesis or DynamoDB stream event | ||
* @param {AnyStreamEvent|*} event - a Kinesis or DynamoDB stream event | ||
* @returns {string[]} an array of event source ARNs (one for each stream event record) | ||
*/ | ||
function getEventSourceARNs(event) { | ||
return event && event.Records ? event.Records.map(r => r.eventSourceARN) : []; | ||
return event && Array.isArray(event.Records) ? event.Records.map(getEventSourceARN) : []; | ||
} | ||
@@ -57,7 +132,7 @@ | ||
* Returns the event sources of the given stream event's records (if any); otherwise returns an empty array. | ||
* @param event - a Kinesis or DynamoDB stream event | ||
* @param {AnyStreamEvent|*} event - a Kinesis or DynamoDB stream event | ||
* @returns {string[]} an array of event sources (one for each stream event record) | ||
*/ | ||
function getEventSources(event) { | ||
return event && event.Records ? event.Records.map(r => r.eventSource) : []; | ||
return event && Array.isArray(event.Records) ? event.Records.map(getEventSource) : []; | ||
} | ||
@@ -68,7 +143,7 @@ | ||
* returns an empty array. | ||
* @param event - a Kinesis stream event | ||
* @param {KinesisEvent|*} event - a Kinesis stream event | ||
* @returns {string[]} an array of event source stream names (one for each stream event record) | ||
*/ | ||
function getKinesisEventSourceStreamNames(event) { | ||
return event && event.Records ? event.Records.map(getKinesisEventSourceStreamName) : []; | ||
return event && Array.isArray(event.Records) ? event.Records.map(getKinesisEventSourceStreamName) : []; | ||
} | ||
@@ -79,10 +154,56 @@ | ||
* an empty string. | ||
* @param record - a Kinesis stream event record | ||
* @param {KinesisEventRecord|*} record - a Kinesis stream event record | ||
* @returns {string} the stream name (if any) or an empty string | ||
*/ | ||
function getKinesisEventSourceStreamName(record) { | ||
return record && isNotBlank(record.eventSourceARN) ? arns.getArnResources(record.eventSourceARN).resource : ''; | ||
return record && record.eventSourceARN ? arns.getArnResources(record.eventSourceARN).resource : ''; | ||
} | ||
/** | ||
* Extracts the shard id from the given Kinesis record's eventID. | ||
* @param {KinesisEventRecord|*} record - a Kinesis stream event record | ||
* @returns {string} the shard id (if any) or an empty string | ||
*/ | ||
function getKinesisShardId(record) { | ||
return record && record.eventID ? getKinesisShardIdFromEventID(record.eventID) : ''; | ||
} | ||
/** | ||
* Extracts the shard id from the given Kinesis eventID. | ||
* @param {string} eventID - an eventID from an AWS Kinesis stream event record. | ||
* @return {string|undefined} the shard id (if any) or an empty string | ||
*/ | ||
function getKinesisShardIdFromEventID(eventID) { | ||
if (eventID) { | ||
const sepPos = eventID.indexOf(':'); | ||
return sepPos !== -1 ? eventID.substring(0, sepPos) : ''; | ||
} | ||
return ''; | ||
} | ||
/** | ||
* Extracts the shard id and event number from the given Kinesis eventID. | ||
* @param {string} eventID - an eventID from an AWS Kinesis stream event record. | ||
* @return {[string,string]} an array containing: the shard id (if any) or an empty string; and the event number (if any) | ||
* or an empty string | ||
*/ | ||
function getKinesisShardIdAndEventNoFromEventID(eventID) { | ||
if (eventID) { | ||
const sepPos = eventID.indexOf(':'); | ||
return sepPos !== -1 ? | ||
[eventID.substring(0, sepPos), eventID.substring(sepPos + 1), ] : ['', '']; | ||
} | ||
return ['', '']; | ||
} | ||
/** | ||
* Gets the sequence number from the given Kinesis stream event record. | ||
* @param {KinesisEventRecord|*} record - a Kinesis stream event record | ||
* @returns {string} the sequence number (if any) or an empty string | ||
*/ | ||
function getKinesisSequenceNumber(record) { | ||
return record && record.kinesis && record.kinesis.sequenceNumber ? record.kinesis.sequenceNumber : ''; | ||
} | ||
/** | ||
* Extracts and returns an arrays containing the table name followed by the stream timestamp/suffix from the given | ||
@@ -95,3 +216,3 @@ * DynamoDB stream event record's eventSourceARN (if any); otherwise returns an array of 2 empty strings. | ||
* | ||
* @param record - a DynamoDB stream event record | ||
* @param {DynamoDBEventRecord|*} record - a DynamoDB stream event record | ||
* @returns {[string, string]} an array containing the table name (if any or empty) followed by an empty string followed | ||
@@ -101,3 +222,3 @@ * by the stream timestamp/suffix (if any or empty) | ||
function getDynamoDBEventSourceTableNameAndStreamTimestamp(record) { | ||
if (record && isNotBlank(record.eventSourceARN)) { | ||
if (record && record.eventSourceARN) { | ||
const resources = arns.getArnResources(record.eventSourceARN); | ||
@@ -112,7 +233,7 @@ return [resources.resource, resources.subResource]; | ||
* otherwise returns an empty array. | ||
* @param event - a DynamoDB stream event | ||
* @param {DynamoDBEvent|*} event - a DynamoDB stream event | ||
* @returns {string[]} an array of event source table names (one for each stream event record) | ||
*/ | ||
function getDynamoDBEventSourceTableNames(event) { | ||
return event && event.Records ? event.Records.map(getDynamoDBEventSourceTableName) : []; | ||
return event && Array.isArray(event.Records) ? event.Records.map(getDynamoDBEventSourceTableName) : []; | ||
} | ||
@@ -123,26 +244,30 @@ | ||
* returns an empty string. | ||
* @param record - a DynamoDB stream event record | ||
* @param {DynamoDBEventRecord|*} record - a DynamoDB stream event record | ||
* @returns {string} the table name (if any) or an empty string (if none) | ||
*/ | ||
function getDynamoDBEventSourceTableName(record) { | ||
return record && isNotBlank(record.eventSourceARN) ? arns.getArnResources(record.eventSourceARN).resource : ''; | ||
return record && record.eventSourceARN ? arns.getArnResources(record.eventSourceARN).resource : ''; | ||
} | ||
/** | ||
* Returns the sequence number from the given DynamoDB stream event record. | ||
* @param {DynamoDBEventRecord|*} record - a DynamoDB stream event record | ||
* @returns {string} the sequence number (if any) or an empty string | ||
*/ | ||
function getDynamoDBSequenceNumber(record) { | ||
return record && record.dynamodb && record.dynamodb.SequenceNumber ? record.dynamodb.SequenceNumber : ''; | ||
} | ||
/** | ||
* Validates the given stream event record and raises an error if the record fails to meet any of the following criteria: | ||
* 1. It must be defined; | ||
* 2. It must contain a defined eventSource; | ||
* 3. It must be either a Kinesis or DynamoDB stream event record; and | ||
* 4. It must contain the required properties expected of its type (based on its eventSource). | ||
* 1. It must be a valid stream event record according to {@linkcode _validateStreamEventRecord}; | ||
* 2. It must be either a Kinesis or DynamoDB stream event record; and | ||
* 3. It must contain the required properties expected of its type (based on its eventSource). | ||
* | ||
* @param {Object} record - a Kinesis or DynamoDB stream event record | ||
* @param {AnyStreamEventRecord|*} record - a Kinesis or DynamoDB stream event record | ||
* @throws {Error} if the record is invalid | ||
*/ | ||
function validateStreamEventRecord(record) { | ||
if (!record) { | ||
throw new Error(`Missing entire stream event record (${record})`); | ||
} | ||
if (!record.eventSource) { | ||
throw new Error(`Missing eventSource property for stream event record (${stringify(record)})`); | ||
} | ||
_validateStreamEventRecord(record); | ||
switch (record.eventSource) { | ||
@@ -160,3 +285,3 @@ case "aws:kinesis": | ||
default: | ||
// Only support Kinesis and DynamoDB stream event records for now | ||
// Only support Kinesis and DynamoDB stream event records | ||
throw new Error(`Unexpected eventSource (${record.eventSource}) on stream event record (${stringify(record)})`); | ||
@@ -167,20 +292,41 @@ } | ||
/** | ||
* Validates the given stream event record and raises an error if the record fails to meet any of the following criteria: | ||
* 1. It must be a non-null object | ||
* 2. It must contain a defined eventID; | ||
* 3. It must contain a defined eventSourceARN; | ||
* 4. It must contain a defined eventSource; | ||
* | ||
* @param {AnyStreamEventRecord|*} record - a Kinesis or DynamoDB stream event record | ||
* @throws {Error} if the record is invalid | ||
*/ | ||
function _validateStreamEventRecord(record) { | ||
if (!record || typeof record !== 'object') { | ||
throw new Error(`Invalid stream event record (${record}) - record must be a non-null object`); | ||
} | ||
if (!record.eventID) { | ||
throw new Error(`Missing eventID property for stream event record (${stringify(record)})`); | ||
} | ||
if (!record.eventSourceARN) { | ||
throw new Error(`Missing eventSourceARN property for stream event record (${stringify(record)})`); | ||
} | ||
if (!record.eventSource) { | ||
throw new Error(`Missing eventSource property for stream event record (${stringify(record)})`); | ||
} | ||
if (!record.eventName) { | ||
throw new Error(`Missing eventName property for stream event record (${stringify(record)})`); | ||
} | ||
} | ||
/** | ||
* Validates the given Kinesis stream event record and raises an error if the record fails to meet any of the following criteria: | ||
* 1. It must be defined; | ||
* 1. It must be a valid stream event record according to {@linkcode _validateStreamEventRecord}; | ||
* 2. It must be a Kinesis stream event record (i.e. must contain an eventSource of "aws:kinesis"); and | ||
* 3. It must contain kinesis and kinesis.data properties. | ||
* | ||
* @param {Object} record - a Kinesis stream event record | ||
* @param {string} [record.eventSource] - a stream event record's eventSource | ||
* @param {Object} [record.kinesis] - a Kinesis stream event record's kinesis object | ||
* @param {string} [record.kinesis.data] - a Kinesis stream event record's kinesis data | ||
* @param {KinesisEventRecord|*} record - a Kinesis stream event record | ||
* @throws {Error} if the record is invalid | ||
*/ | ||
function validateKinesisStreamEventRecord(record) { | ||
if (!record) { | ||
throw new Error(`Missing entire Kinesis stream event record (${record})`); | ||
} | ||
if (!record.eventSource) { | ||
throw new Error(`Missing eventSource property for Kinesis stream event record (${stringify(record)})`); | ||
} | ||
_validateStreamEventRecord(record); | ||
if (record.eventSource !== "aws:kinesis") { | ||
@@ -192,2 +338,7 @@ throw new Error(`Unexpected eventSource (${record.eventSource}) on Kinesis stream event record (${stringify(record)})`) | ||
/** | ||
* Validates the given Kinesis stream event record. | ||
* @param {KinesisEventRecord|*} record - a Kinesis stream event record | ||
* @private | ||
*/ | ||
function _validateKinesisStreamEventRecord(record) { | ||
@@ -200,2 +351,8 @@ if (!record.kinesis) { | ||
} | ||
if (!record.kinesis.partitionKey) { | ||
throw new Error(`Missing partitionKey property for Kinesis stream event record (${stringify(record)})`); | ||
} | ||
if (!record.kinesis.sequenceNumber) { | ||
throw new Error(`Missing sequenceNumber property for Kinesis stream event record (${stringify(record)})`); | ||
} | ||
} | ||
@@ -205,3 +362,3 @@ | ||
* Validates the given DynamoDB stream event record and raises an error if the record fails to meet any of the following criteria: | ||
* 1. It must be defined; | ||
* 1. It must be a valid stream event record according to {@linkcode _validateStreamEventRecord}; | ||
* 2. It must be a DynamoDB stream event record (i.e. must contain an eventSource of "aws:dynamodb"); | ||
@@ -211,18 +368,8 @@ * 3. It must contain dynamodb, dynamodb.Keys and dynamodb.StreamViewType properties; and | ||
* | ||
* @param {Object} record - a DynamoDB stream event record | ||
* @param {string} [record.eventSource] - a stream event record's eventSource | ||
* @param {Object} [record.dynamodb] - a DynamoDB stream event record's dynamodb object | ||
* @param {Object} [record.dynamodb.Keys] - a DynamoDB stream event record's Keys object | ||
* @param {string} [record.dynamodb.StreamViewType] - a DynamoDB stream event record's stream view type | ||
* @param {Object} [record.dynamodb.NewImage] - a DynamoDB stream event record's new image object | ||
* @param {Object} [record.dynamodb.OldImage] - a DynamoDB stream event record's old image object | ||
* @param {DynamoDBEventRecord|*} record - a DynamoDB stream event record | ||
* @throws {Error} if the record is invalid | ||
*/ | ||
function validateDynamoDBStreamEventRecord(record) { | ||
if (!record) { | ||
throw new Error(`Missing entire DynamoDB stream event record (${record})`); | ||
} | ||
if (!record.eventSource) { | ||
throw new Error(`Missing eventSource property for DynamoDB stream event record (${stringify(record)})`); | ||
} | ||
_validateStreamEventRecord(record); | ||
if (record.eventSource !== "aws:dynamodb") { | ||
@@ -234,3 +381,21 @@ throw new Error(`Unexpected eventSource (${record.eventSource}) on DynamoDB stream event record (${stringify(record)})`) | ||
/** | ||
* Returns true if the given DynamoDB event name OR given DynamoDB stream event record's eventName is valid; false otherwise | ||
* @param {string|DynamoDBEventRecord} recordOrEventName - a DynamoDB event name OR DynamoDB stream event record | ||
* @returns {boolean} true if valid; false otherwise | ||
*/ | ||
function isDynamoDBEventNameValid(recordOrEventName) { | ||
const eventName = recordOrEventName.eventName ? recordOrEventName.eventName : recordOrEventName; | ||
return eventName === DynamoDBEventName.INSERT || eventName === DynamoDBEventName.MODIFY || eventName === DynamoDBEventName.REMOVE; | ||
} | ||
/** | ||
* Validates the given DynamoDB stream event record. | ||
* @param {DynamoDBEventRecord|*} record - a DynamoDB stream event record | ||
* @private | ||
*/ | ||
function _validateDynamoDBStreamEventRecord(record) { | ||
if (!isDynamoDBEventNameValid(record)) { | ||
throw new Error(`Invalid eventName property (${record.eventName}) for DynamoDB stream event record (${stringify(record)})`); | ||
} | ||
if (!record.dynamodb) { | ||
@@ -242,2 +407,5 @@ throw new Error(`Missing dynamodb property for DynamoDB stream event record (${stringify(record)})`); | ||
} | ||
if (!record.dynamodb.SequenceNumber) { | ||
throw new Error(`Missing SequenceNumber property for DynamoDB stream event record (${stringify(record)})`); | ||
} | ||
if (!record.dynamodb.StreamViewType) { | ||
@@ -251,3 +419,3 @@ throw new Error(`Missing StreamViewType property for DynamoDB stream event record (${stringify(record)})`); | ||
case 'NEW_IMAGE': | ||
if (!record.dynamodb.NewImage) { | ||
if (!record.dynamodb.NewImage && record.eventName !== 'REMOVE') { | ||
throw new Error(`Missing NewImage property for DynamoDB stream event record (${stringify(record)})`); | ||
@@ -258,3 +426,3 @@ } | ||
case 'OLD_IMAGE': | ||
if (!record.dynamodb.OldImage) { | ||
if (!record.dynamodb.OldImage && record.eventName !== 'INSERT') { | ||
throw new Error(`Missing OldImage property for DynamoDB stream event record (${stringify(record)})`); | ||
@@ -265,3 +433,3 @@ } | ||
case 'NEW_AND_OLD_IMAGES': | ||
if (!record.dynamodb.NewImage && !record.dynamodb.OldImage) { | ||
if ((!record.dynamodb.NewImage && record.eventName !== 'REMOVE') || (!record.dynamodb.OldImage && record.eventName !== 'INSERT')) { | ||
throw new Error(`Missing both NewImage and OldImage properties for DynamoDB stream event record (${stringify(record)})`); | ||
@@ -274,20 +442,2 @@ } | ||
} | ||
} | ||
// /** | ||
// * Returns short descriptive key information for the given Kinesis or DynamoDB stream record, which includes the | ||
// * record's partition key and the first & last 5 characters of its sequence number, for logging purposes. | ||
// * @param {Object} record - a Kinesis or DynamoDB stream record | ||
// * @return {string} short descriptive key information for the given record | ||
// */ | ||
// function toStreamEventRecordTruncatedKeyInfo(record) { | ||
// if (!record) return stringify(record); | ||
// if (record.kinesis) { | ||
// let seqNo = record.kinesis.sequenceNumber; | ||
// let seqNoFragment = seqNo ? seqNo.substring(0, 5) + "..." + seqNo.substring(seqNo.length - 5) : ''; | ||
// return `${record.kinesis.partitionKey} ${seqNoFragment}`; | ||
// } else if (record.dynamodb) { | ||
// // TO DO | ||
// } | ||
// } | ||
} |
@@ -18,3 +18,3 @@ 'use strict'; | ||
require('core-functions/promises'); | ||
const Promises = require('core-functions/promises'); | ||
@@ -25,2 +25,3 @@ const Strings = require('core-functions/strings'); | ||
const logging = require('logging-utils'); | ||
const LogLevel = logging.LogLevel; | ||
@@ -41,3 +42,3 @@ const stages = require("../stages"); | ||
context.info(`Simulating doing something useful with event ${JSON.stringify(event)}`); | ||
return Promise.delay(ms) | ||
return Promises.delay(ms) | ||
.then(() => { | ||
@@ -89,6 +90,6 @@ return rejectedError ? Promise.reject(rejectedError) : Promise.resolve(resolvedResponse); | ||
const handler = apiLambdas.generateHandlerFunction(context, undefined, require('./sample-standard-options.json'), | ||
fn, logging.INFO); //, undefined, 'Invalid do something request', 'Failed to do something useful', 'Did something useful'); | ||
fn, LogLevel.INFO); //, undefined, 'Invalid do something request', 'Failed to do something useful', 'Did something useful'); | ||
// Wrap the callback-based AWS Lambda handler function as a Promise returning function purely for testing purposes | ||
const handlerWithPromise = Promise.wrap(handler); | ||
const handlerWithPromise = Promises.wrap(handler); | ||
@@ -139,6 +140,6 @@ // Invoke the handler function | ||
const handler = apiLambdas.generateHandlerFunction(context, undefined, require('./sample-standard-options.json'), | ||
fn, logging.DEBUG, undefined, 'Invalid do something request', 'Failed to do something useful', 'Did something useful'); | ||
fn, LogLevel.DEBUG, undefined, 'Invalid do something request', 'Failed to do something useful', 'Did something useful'); | ||
// Wrap the callback-based AWS Lambda handler function as a Promise returning function purely for testing purposes | ||
const handlerWithPromise = Promise.wrap(handler); | ||
const handlerWithPromise = Promises.wrap(handler); | ||
@@ -198,6 +199,6 @@ // Invoke the handler function | ||
const handler = apiLambdas.generateHandlerFunction(context, undefined, require('./sample-standard-options.json'), | ||
fn, logging.TRACE, undefined, 'Invalid do something request', 'Failed to do something useful', 'Did something useful'); | ||
fn, LogLevel.TRACE, undefined, 'Invalid do something request', 'Failed to do something useful', 'Did something useful'); | ||
// Wrap the callback-based AWS Lambda handler function as a Promise returning function purely for testing purposes | ||
const handlerWithPromise = Promise.wrap(handler); | ||
const handlerWithPromise = Promises.wrap(handler); | ||
@@ -204,0 +205,0 @@ // Invoke the handler function |
@@ -8,2 +8,5 @@ 'use strict'; | ||
const logging = require('logging-utils'); | ||
const LogLevel = logging.LogLevel; | ||
const strings = require('core-functions/strings'); | ||
@@ -247,3 +250,3 @@ const stringify = strings.stringify; | ||
t.ok(context.stageHandling, 'context.stageHandling must be defined'); | ||
t.equal(context.logLevel, 'info', 'context.logLevel must be "info"'); | ||
t.equal(context.logLevel, LogLevel.INFO, `context.logLevel must be "${LogLevel.INFO}"`); | ||
t.ok(typeof context.error === 'function', 'context.error must be defined'); | ||
@@ -274,3 +277,3 @@ t.ok(typeof context.warn === 'function', 'context.warn must be defined'); | ||
t.ok(context.stageHandling, 'context.stageHandling must be defined'); | ||
t.equal(context.logLevel, 'trace', 'context.logLevel must be "trace"'); | ||
t.equal(context.logLevel, LogLevel.TRACE, `context.logLevel must be "${LogLevel.TRACE}"`); | ||
t.ok(typeof context.error === 'function', 'context.error must be defined'); | ||
@@ -305,3 +308,3 @@ t.ok(typeof context.warn === 'function', 'context.warn must be defined'); | ||
t.equal(context.stageHandling.streamNameStageSeparator, '-', 'context.stageHandling must be "-"'); | ||
t.equal(context.logLevel, 'error', 'context.logLevel must be "error"'); | ||
t.equal(context.logLevel, LogLevel.ERROR, `context.logLevel must be "${LogLevel.ERROR}"`); | ||
t.ok(typeof context.error === 'function', 'context.error must be defined'); | ||
@@ -338,3 +341,3 @@ t.ok(typeof context.warn === 'function', 'context.warn must be defined'); | ||
t.equal(context.stageHandling.streamNameStageSeparator, '-', 'context.stageHandling must be "-"'); | ||
t.equal(context.logLevel, 'error', 'context.logLevel must be "error"'); | ||
t.equal(context.logLevel, LogLevel.ERROR, `context.logLevel must be "${LogLevel.ERROR}"`); | ||
t.ok(typeof context.error === 'function', 'context.error must be defined'); | ||
@@ -381,3 +384,3 @@ t.ok(typeof context.warn === 'function', 'context.warn must be defined'); | ||
t.equal(context.stageHandling.streamNameStageSeparator, '-', 'context.stageHandling must be "-"'); | ||
t.equal(context.logLevel, 'error', 'context.logLevel must be "error"'); | ||
t.equal(context.logLevel, LogLevel.ERROR, `context.logLevel must be "${LogLevel.ERROR}"`); | ||
t.ok(typeof context.error === 'function', 'context.error must be defined'); | ||
@@ -384,0 +387,0 @@ t.ok(typeof context.warn === 'function', 'context.warn must be defined'); |
@@ -25,2 +25,3 @@ 'use strict'; | ||
const logging = require('logging-utils'); | ||
const LogLevel = logging.LogLevel; | ||
@@ -40,3 +41,3 @@ const Strings = require('core-functions/strings'); | ||
const context = {}; | ||
logging.configureLoggingWithSettings(context, logging.TRACE); | ||
logging.configureLogging(context, {logLevel: LogLevel.TRACE}); | ||
@@ -159,3 +160,3 @@ // Set current region | ||
const context = {}; | ||
logging.configureLoggingWithSettings(context, logging.DEBUG); | ||
logging.configureLogging(context, {logLevel: LogLevel.DEBUG}); | ||
@@ -162,0 +163,0 @@ process.env.AWS_REGION = 'us-west-1'; |
@@ -15,5 +15,6 @@ 'use strict'; | ||
const toValueFromAttributeTypeAndValue = dynamoDBUtils.toValueFromAttributeTypeAndValue; | ||
const toNumber = dynamoDBUtils.toNumber; | ||
const toKeyValueStrings = dynamoDBUtils.toKeyValueStrings; | ||
const toKeyValuePairs = dynamoDBUtils.toKeyValuePairs; | ||
const toStorableObject = dynamoDBUtils.toStorableObject; | ||
const defaults = dynamoDBUtils.defaults; | ||
@@ -23,42 +24,27 @@ const strings = require('core-functions/strings'); | ||
test('toNumber', t => { | ||
// A simple integer | ||
t.equal(toNumber('103'), 103, `toNumber('103') must be ${103}`); | ||
// A simple float | ||
t.equal(toNumber('3.1415679'), 3.1415679, `toNumber('3.1415679') must be ${3.1415679}`); | ||
const putRequest = { | ||
TableName : 'Table', | ||
Item: { | ||
hashKey: 'hashkey', | ||
numAttribute: 1, | ||
boolAttribute: true, | ||
list1: [1, 'two', false, '', null], | ||
empty1: '', | ||
undefined1: undefined, | ||
map1: { | ||
foo: 'bar', | ||
empty2: '', | ||
undefined2: undefined, | ||
map2: { | ||
abc: 'abc', | ||
empty3: '', | ||
undefined3: undefined, | ||
spaces: ' ', | ||
null2: null | ||
} | ||
}, | ||
null1: null | ||
} | ||
}; | ||
// +/- 2 to the power of 53 should still give numbers, since have about 54 bits of precisions for integers | ||
t.equal(toNumber('9007199254740992'), 9007199254740992, `toNumber('9007199254740992') must be ${9007199254740992}`); | ||
t.equal(toNumber('-9007199254740992'), -9007199254740992, `toNumber('-9007199254740992') must be ${-9007199254740992}`); | ||
// +/- 2 to the power of 54 is still ok | ||
t.equal(toNumber('18014398509481984'), 18014398509481984, `toNumber('18014398509481984') must be ${18014398509481984}`); | ||
t.equal(toNumber('-18014398509481984'), -18014398509481984, `toNumber('-18014398509481984') must be ${-18014398509481984}`); | ||
// +/- 2 to the power of 55 is too big | ||
t.notEqual(toNumber('36028797018963968'), 36028797018963968, `toNumber('36028797018963968') must NOT be ${36028797018963968}`); | ||
t.notEqual(toNumber('-36028797018963968'), -36028797018963968, `toNumber('-36028797018963968') must NOT be ${-36028797018963968}`); | ||
t.equal(toNumber('36028797018963968'), '36028797018963968', `toNumber('36028797018963968') must be '36028797018963968'`); | ||
t.equal(toNumber('-36028797018963968'), '-36028797018963968', `toNumber('-36028797018963968') must be '-36028797018963968'`); | ||
// +/- 2 to the power of 56 is too big | ||
t.notEqual(toNumber('72057594037927936'), 72057594037927936, `toNumber('72057594037927936') must NOT be ${72057594037927936}`); | ||
t.notEqual(toNumber('-72057594037927936'), -72057594037927936, `toNumber('-72057594037927936') must NOT be ${-72057594037927936}`); | ||
t.equal(toNumber('72057594037927936'), '72057594037927936', `toNumber('72057594037927936') must be '72057594037927936'`); | ||
t.equal(toNumber('-72057594037927936'), '-72057594037927936', `toNumber('-72057594037927936') must be '-72057594037927936'`); | ||
// Too big to hold in an integer | ||
t.equal(toNumber('9223372036854775807'), '9223372036854775807', `toNumber('9223372036854775807') must be '9223372036854775807'`); | ||
t.equal(toNumber('-9223372036854775808'), '-9223372036854775808', `toNumber('-9223372036854775808') must be '-9223372036854775808'`); | ||
t.ok(Number.isNaN(toNumber('')), `toNumber('') must be NaN`); | ||
t.ok(Number.isNaN(toNumber('abc')), `toNumber('abc') must be NaN`); | ||
t.ok(Number.isNaN(toNumber(undefined)), `toNumber(undefined) must be NaN`); | ||
t.ok(Number.isNaN(toNumber(null)), `toNumber(null) must be NaN`); | ||
t.ok(Number.isNaN(toNumber({})), `toNumber({}) must be NaN`); | ||
t.ok(Number.isNaN(toNumber([])), `toNumber([]) must be NaN`); | ||
t.end(); | ||
}); | ||
test('toValueFromAttributeTypeAndValue', t => { | ||
@@ -173,1 +159,82 @@ t.equal(toValueFromAttributeTypeAndValue('NULL', true), null, `toValueFromAttributeTypeAndValue('NULL', true) must be null`); | ||
}); | ||
test('toStorableObject with default emptyStringReplacement', t => { | ||
let emptyStringReplacement = defaults.emptyStringReplacement; // 'EMPTY_STRING'; | ||
//Defaults.emptyStringReplacement = emptyStringReplacement; | ||
const item = toStorableObject(putRequest.Item); | ||
console.log(`toStorableObject(putRequest.Item) = ${stringify(item)}`); | ||
const oldItem = putRequest.Item; | ||
// Check empty strings were replaced | ||
t.equal(item.empty1, emptyStringReplacement, `item.empty1 must be ${emptyStringReplacement}`); | ||
t.equal(item.map1.empty2, emptyStringReplacement, `item.map1.empty2 must be ${emptyStringReplacement}`); | ||
t.equal(item.map1.map2.empty3, emptyStringReplacement, `item.map1.map2.empty3 must be ${emptyStringReplacement}`); | ||
t.equal(item.list1[3], emptyStringReplacement, `item.list1[3] must be ${emptyStringReplacement}`); | ||
// Check non-empty strings are still intact | ||
t.equal(item.hashKey, oldItem.hashKey, `item.hashKey must be ${oldItem.hashKey}`); | ||
t.equal(item.map1.foo, oldItem.map1.foo, `item.map1.foo must be ${oldItem.map1.foo}`); | ||
t.equal(item.map1.map2.abc, oldItem.map1.map2.abc, `item.map1.map2.abc must be ${oldItem.map1.map2.abc}`); | ||
t.equal(item.map1.map2.spaces, oldItem.map1.map2.spaces, `item.map1.map2.spaces must be ${oldItem.map1.map2.spaces}`); | ||
t.equal(item.list1[1], oldItem.list1[1], `item.list1[1] must be ${oldItem.list1[1]}`); | ||
const itemKeys = Object.getOwnPropertyNames(item); | ||
const map1Keys = Object.getOwnPropertyNames(item.map1); | ||
const map2Keys = Object.getOwnPropertyNames(item.map1.map2); | ||
// Ensure that no undefined properties exist | ||
t.equal(itemKeys.indexOf('undefined1'), -1, `item.undefined1 must NOT exist`); | ||
t.equal(map1Keys.indexOf('undefined2'), -1, `item.map1.undefined2 must NOT exist`); | ||
t.equal(map2Keys.indexOf('undefined3'), -1, `item.map1.map2.undefined3 must NOT exist`); | ||
// Ensure that null properties are intact | ||
t.notEqual(itemKeys.indexOf('null1'), -1, `item.null1 must exist`); | ||
t.equal(item.null1, null, `item.null1 must be null`); | ||
t.equal(item.map1.map2.null2, null, `item.map1.map2.null2 must be null`); | ||
t.equal(item.list1[4], null, `item.list1[4] must be null`); | ||
t.end(); | ||
}); | ||
test('toStorableObject with overridden Defaults.emptyStringReplacement', t => { | ||
let emptyStringReplacement = 'EMPTY_STRING'; | ||
// Override the default empty string replacement | ||
defaults.emptyStringReplacement = emptyStringReplacement; | ||
const item = toStorableObject(putRequest.Item); | ||
console.log(`toStorableObject(putRequest.Item) = ${stringify(item)}`); | ||
const oldItem = putRequest.Item; | ||
// Check empty strings were replaced | ||
t.equal(item.empty1, emptyStringReplacement, `item.empty1 must be ${emptyStringReplacement}`); | ||
t.equal(item.map1.empty2, emptyStringReplacement, `item.map1.empty2 must be ${emptyStringReplacement}`); | ||
t.equal(item.map1.map2.empty3, emptyStringReplacement, `item.map1.map2.empty3 must be ${emptyStringReplacement}`); | ||
t.equal(item.list1[3], emptyStringReplacement, `item.list1[3] must be ${emptyStringReplacement}`); | ||
// Check non-empty strings are still intact | ||
t.equal(item.hashKey, oldItem.hashKey, `item.hashKey must be ${oldItem.hashKey}`); | ||
t.equal(item.map1.foo, oldItem.map1.foo, `item.map1.foo must be ${oldItem.map1.foo}`); | ||
t.equal(item.map1.map2.abc, oldItem.map1.map2.abc, `item.map1.map2.abc must be ${oldItem.map1.map2.abc}`); | ||
t.equal(item.map1.map2.spaces, oldItem.map1.map2.spaces, `item.map1.map2.spaces must be ${oldItem.map1.map2.spaces}`); | ||
t.equal(item.list1[1], oldItem.list1[1], `item.list1[1] must be ${oldItem.list1[1]}`); | ||
const itemKeys = Object.getOwnPropertyNames(item); | ||
const map1Keys = Object.getOwnPropertyNames(item.map1); | ||
const map2Keys = Object.getOwnPropertyNames(item.map1.map2); | ||
// Ensure that no undefined properties exist | ||
t.equal(itemKeys.indexOf('undefined1'), -1, `item.undefined1 must NOT exist`); | ||
t.equal(map1Keys.indexOf('undefined2'), -1, `item.map1.undefined2 must NOT exist`); | ||
t.equal(map2Keys.indexOf('undefined3'), -1, `item.map1.map2.undefined3 must NOT exist`); | ||
// Ensure that null properties are intact | ||
t.notEqual(itemKeys.indexOf('null1'), -1, `item.null1 must exist`); | ||
t.equal(item.null1, null, `item.null1 must be null`); | ||
t.equal(item.map1.map2.null2, null, `item.map1.map2.null2 must be null`); | ||
t.equal(item.list1[4], null, `item.list1[4] must be null`); | ||
t.end(); | ||
}); |
@@ -25,2 +25,3 @@ 'use strict'; | ||
const logging = require('logging-utils'); | ||
const LogLevel = logging.LogLevel; | ||
@@ -40,3 +41,3 @@ const Strings = require('core-functions/strings'); | ||
const context = {}; | ||
logging.configureLoggingWithSettings(context, logging.TRACE); | ||
logging.configureLogging(context, {logLevel: LogLevel.TRACE}); | ||
@@ -159,3 +160,3 @@ // Set current region | ||
const context = {}; | ||
logging.configureLoggingWithSettings(context, logging.DEBUG); | ||
logging.configureLogging(context, {logLevel: LogLevel.DEBUG}); | ||
@@ -162,0 +163,0 @@ process.env.AWS_REGION = 'us-west-1'; |
{ | ||
"name": "aws-core-utils-tests", | ||
"description": "Unit tests for aws-core-utils modules", | ||
"version": "5.0.17", | ||
"version": "6.0.0", | ||
"author": "Byron du Preez", | ||
"license": "Apache-2.0", | ||
"private": true, | ||
"engines": { | ||
@@ -8,0 +9,0 @@ "node": ">=4.3.2" |
{ | ||
"loggingOptions": { | ||
"logLevel": "trace", | ||
"logLevel": "TRACE", | ||
"useLevelPrefixes": true, | ||
"envLogLevelName": "LOG_LEVEL", | ||
"useConsoleTrace": false | ||
@@ -6,0 +7,0 @@ }, |
@@ -12,2 +12,6 @@ 'use strict'; | ||
const streamEvents = require('../stream-events'); | ||
const getEventID = streamEvents.getEventID; | ||
const getEventSource = streamEvents.getEventSource; | ||
const getEventSourceARN = streamEvents.getEventSourceARN; | ||
//const getEventSources = streamEvents.getEventSources; | ||
const getEventSourceARNs = streamEvents.getEventSourceARNs; | ||
@@ -18,5 +22,13 @@ | ||
//const getDynamoDBEventSourceTableName = streamEvents.getDynamoDBEventSourceTableName; | ||
//const getDynamoDBEventSourceTableNameAndStreamTimestamp = streamEvents.getDynamoDBEventSourceTableNameAndStreamTimestamp; | ||
const getKinesisShardId = streamEvents.getKinesisShardId; | ||
const getKinesisShardIdFromEventID = streamEvents.getKinesisShardIdFromEventID; | ||
const getKinesisShardIdAndEventNoFromEventID = streamEvents.getKinesisShardIdAndEventNoFromEventID; | ||
const getKinesisSequenceNumber = streamEvents.getKinesisSequenceNumber; | ||
// const getDynamoDBEventSourceTableName = streamEvents.getDynamoDBEventSourceTableName; | ||
// const getDynamoDBEventSourceTableNameAndStreamTimestamp = streamEvents.getDynamoDBEventSourceTableNameAndStreamTimestamp; | ||
const getDynamoDBSequenceNumber = streamEvents.getDynamoDBSequenceNumber; | ||
const validateStreamEventRecord = streamEvents.validateStreamEventRecord; | ||
@@ -35,2 +47,55 @@ const validateKinesisStreamEventRecord = streamEvents.validateKinesisStreamEventRecord; | ||
// ===================================================================================================================== | ||
// getEventID, getEventSource, getEventSourceARN, getKinesisSequenceNumber & getDynamoDBSequenceNumber | ||
// ===================================================================================================================== | ||
test('getEventID, getEventSource, getEventSourceARN, getKinesisSequenceNumber & getDynamoDBSequenceNumber', t => { | ||
// With garbage | ||
t.equal(getEventID(undefined), '', `getEventID(undefined) must be ''`); | ||
t.equal(getEventSource(undefined), '', `getEventSource(undefined) must be ''`); | ||
t.equal(getEventSourceARN(undefined), '', `getEventSourceARN(undefined) must be ''`); | ||
t.equal(getKinesisSequenceNumber(undefined), '', `getKinesisSequenceNumber(undefined) must be ''`); | ||
t.equal(getDynamoDBSequenceNumber(undefined), '', `getDynamoDBSequenceNumber(undefined) must be ''`); | ||
t.equal(getEventID(null), '', `getEventID(null) must be ''`); | ||
t.equal(getEventSource(null), '', `getEventSource(null) must be ''`); | ||
t.equal(getEventSourceARN(null), '', `getEventSourceARN(null) must be ''`); | ||
t.equal(getKinesisSequenceNumber(null), '', `getKinesisSequenceNumber(null) must be ''`); | ||
t.equal(getDynamoDBSequenceNumber(null), '', `getDynamoDBSequenceNumber(null) must be ''`); | ||
t.equal(getEventID({}), '', `getEventID({}) must be ''`); | ||
t.equal(getEventSource({}), '', `getEventSource({}) must be ''`); | ||
t.equal(getEventSourceARN({}), '', `getEventSourceARN({}) must be ''`); | ||
t.equal(getKinesisSequenceNumber({}), '', `getKinesisSequenceNumber({}) must be ''`); | ||
t.equal(getDynamoDBSequenceNumber({}), '', `getDynamoDBSequenceNumber({}) must be ''`); | ||
t.equal(getEventID('junk'), '', `getEventID('junk') must be ''`); | ||
t.equal(getEventSource('junk'), '', `getEventSource('junk') must be ''`); | ||
t.equal(getEventSourceARN('junk'), '', `getEventSourceARN('junk') must be ''`); | ||
t.equal(getKinesisSequenceNumber('junk'), '', `getKinesisSequenceNumber('junk') must be ''`); | ||
t.equal(getDynamoDBSequenceNumber('junk'), '', `getDynamoDBSequenceNumber('junk') must be ''`); | ||
// With a Kinesis stream event record | ||
const kinesisEventSourceArn = samples.sampleKinesisEventSourceArn('eventSourceArnRegion', 'TestStream_QA'); | ||
const kinesisRecord = samples.sampleKinesisRecord(undefined, undefined, kinesisEventSourceArn, 'eventAwsRegion'); | ||
t.equal(getEventID(kinesisRecord), kinesisRecord.eventID, `getEventID(kinesisRecord) must be '${kinesisRecord.eventID}'`); | ||
t.equal(getEventSource(kinesisRecord), kinesisRecord.eventSource, `getEventSource(kinesisRecord) must be '${kinesisRecord.eventSource}'`); | ||
t.equal(getEventSourceARN(kinesisRecord), kinesisRecord.eventSourceARN, `getEventSourceARN(kinesisRecord) must be '${kinesisRecord.eventSourceARN}'`); | ||
t.equal(getKinesisSequenceNumber(kinesisRecord), kinesisRecord.kinesis.sequenceNumber, `getKinesisSequenceNumber(kinesisRecord) must be '${kinesisRecord.kinesis.sequenceNumber}'`); | ||
t.equal(getDynamoDBSequenceNumber(kinesisRecord), '', `getDynamoDBSequenceNumber(kinesisRecord) must be ''`); | ||
// With a DynamoDB stream event record | ||
const dynamoDBEventSourceArn = samples.sampleDynamoDBEventSourceArn('eventSourceArnRegion', 'TestStream_UAT'); | ||
const dynamoDBRecord = samples.awsDynamoDBUpdateSampleEvent(dynamoDBEventSourceArn).Records[0]; | ||
t.equal(getEventID(dynamoDBRecord), dynamoDBRecord.eventID, `getEventID(dynamoDBRecord) must be '${dynamoDBRecord.eventID}'`); | ||
t.equal(getEventSource(dynamoDBRecord), dynamoDBRecord.eventSource, `getEventSource(dynamoDBRecord) must be '${dynamoDBRecord.eventSource}'`); | ||
t.equal(getEventSourceARN(dynamoDBRecord), dynamoDBRecord.eventSourceARN, `getEventSourceARN(dynamoDBRecord) must be '${dynamoDBRecord.eventSourceARN}'`); | ||
t.equal(getDynamoDBSequenceNumber(dynamoDBRecord), dynamoDBRecord.dynamodb.SequenceNumber, `getDynamoDBSequenceNumber(dynamoDBRecord) must be '${stringify(dynamoDBRecord.dynamodb.SequenceNumber)}'`); | ||
t.equal(getKinesisSequenceNumber(dynamoDBRecord), '', `getKinesisSequenceNumber(dynamoDBRecord) must be ''`); | ||
t.end(); | ||
}); | ||
// ===================================================================================================================== | ||
// getEventSourceARNs | ||
@@ -42,3 +107,3 @@ // ===================================================================================================================== | ||
const eventSourceArns = streamNames.map(streamName => | ||
isNotBlank(streamName) ? samples.sampleKinesisEventSourceArn('eventSourceArnRegion', trim(streamName)) : trim(streamName)); | ||
isNotBlank(streamName) ? samples.sampleKinesisEventSourceArn('eventSourceArnRegion', trimOrEmpty(streamName)) : trimOrEmpty(streamName)); | ||
const records = eventSourceArns.map(eventSourceArn => | ||
@@ -155,2 +220,97 @@ samples.sampleKinesisRecord(undefined, undefined, eventSourceArn, 'eventAwsRegion')); | ||
// ===================================================================================================================== | ||
// getKinesisShardIdFromEventID | ||
// ===================================================================================================================== | ||
test('getKinesisShardIdFromEventID', t => { | ||
// Other cases | ||
t.equal(getKinesisShardIdFromEventID(undefined), '', `eventID (undefined) shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID(null), '', `eventID (null) shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID(''), '', `eventID '' shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID(':'), '', `eventID ':' shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID('shardId-'), '', `eventID 'shardId-' shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID('shardId-:'), 'shardId-', `eventID 'shardId-:' shardId must be 'shardId-'`); | ||
t.equal(getKinesisShardIdFromEventID('shardId-0:'), 'shardId-0', `eventID 'shardId-0:' shardId must be 'shardId-0'`); | ||
t.equal(getKinesisShardIdFromEventID('shardId-012:'), 'shardId-012', `eventID 'shardId-012:' shardId must be 'shardId-012'`); | ||
// More real eventIDs | ||
let eventID = 'shardId-000000000000:49545115243490985018280067714973144582180062593244200961'; | ||
let expected = 'shardId-000000000000'; | ||
t.equal(getKinesisShardIdFromEventID(eventID), expected, `eventID '${eventID}' shardId must be '${expected}'`); | ||
eventID = 'shardId-123456789012:49545115243490985018280067714973144582180062593244200961'; | ||
expected = 'shardId-123456789012'; | ||
t.equal(getKinesisShardIdFromEventID(eventID), expected, `eventID '${eventID}' shardId must be '${expected}'`); | ||
t.end(); | ||
}); | ||
// ===================================================================================================================== | ||
// getKinesisShardId | ||
// ===================================================================================================================== | ||
test('getKinesisShardId', t => { | ||
function toRecord(eventID) { | ||
return {eventID: eventID}; | ||
} | ||
// Other cases | ||
t.equal(getKinesisShardId(undefined), '', `record (undefined) shardId must be ''`); | ||
t.equal(getKinesisShardId({}), '', `record ({}) shardId must be ''`); | ||
t.equal(getKinesisShardId(toRecord(undefined)), '', `record ${JSON.stringify(toRecord(undefined))} shardId must be ''`); | ||
t.equal(getKinesisShardId(toRecord(null)), '', `record ${JSON.stringify(toRecord(null))} shardId must be ''`); | ||
t.equal(getKinesisShardId(toRecord('')), '', `record ${JSON.stringify(toRecord(''))} shardId must be ''`); | ||
t.equal(getKinesisShardId(toRecord(':')), '', `record ${JSON.stringify(toRecord(':'))} shardId must be ''`); | ||
t.equal(getKinesisShardId(toRecord('shardId-')), '', `record ${JSON.stringify(toRecord('shardId-'))} shardId must be ''`); | ||
t.equal(getKinesisShardId(toRecord('shardId-:')), 'shardId-', `record ${JSON.stringify(toRecord('shardId-:'))} shardId must be 'shardId-'`); | ||
t.equal(getKinesisShardId(toRecord('shardId-0:')), 'shardId-0', `record ${JSON.stringify(toRecord('shardId-0:'))} shardId must be 'shardId-0'`); | ||
t.equal(getKinesisShardId(toRecord('shardId-012:')), 'shardId-012', `record ${JSON.stringify(toRecord('shardId-012:'))} shardId must be 'shardId-012'`); | ||
// More real eventIDs | ||
let eventID = 'shardId-000000000000:49545115243490985018280067714973144582180062593244200961'; | ||
let expected = 'shardId-000000000000'; | ||
t.equal(getKinesisShardId(toRecord(eventID)), expected, `record ${JSON.stringify(toRecord(eventID))} shardId must be '${expected}'`); | ||
eventID = 'shardId-123456789012:49545115243490985018280067714973144582180062593244200961'; | ||
expected = 'shardId-123456789012'; | ||
t.equal(getKinesisShardId(toRecord(eventID)), expected, `record ${JSON.stringify(toRecord(eventID))} shardId must be '${expected}'`); | ||
t.end(); | ||
}); | ||
// ===================================================================================================================== | ||
// getKinesisShardIdAndEventNoFromEventID | ||
// ===================================================================================================================== | ||
test('getKinesisShardIdAndEventNoFromEventID', t => { | ||
// Other cases | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID(undefined), ['', ''], `eventID (undefined) shardId & eventNo must be ['','']`); | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID(null), ['', ''], `eventID (null) shardId & eventNo must be ['','']`); | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID(''), ['', ''], `eventID '' shardId & eventNo must be ['','']`); | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID(':'), ['', ''], `eventID ':' shardId & eventNo must be ['','']`); | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID('shardId-'), ['', ''], `eventID 'shardId-' shardId & eventNo must be ['','']`); | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID('shardId-:'), ['shardId-', ''], `eventID 'shardId-:' shardId & eventNo must be ['shardId-','']`); | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID('shardId-0:'), ['shardId-0', ''], `eventID 'shardId-0:' shardId & eventNo must be ['shardId-0','']`); | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID('shardId-012:456'), ['shardId-012', '456'], `eventID 'shardId-012:456' shardId & eventNo must be ['shardId-012','456']`); | ||
t.equal(getKinesisShardIdFromEventID(undefined), '', `eventID (undefined) shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID(null), '', `eventID (null) shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID(''), '', `eventID '' shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID(':'), '', `eventID ':' shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID('shardId-'), '', `eventID 'shardId-' shardId must be ''`); | ||
t.equal(getKinesisShardIdFromEventID('shardId-:'), 'shardId-', `eventID 'shardId-:' shardId must be 'shardId-'`); | ||
t.equal(getKinesisShardIdFromEventID('shardId-0:'), 'shardId-0', `eventID 'shardId-0:' shardId must be 'shardId-0'`); | ||
t.equal(getKinesisShardIdFromEventID('shardId-012:'), 'shardId-012', `eventID 'shardId-012:' shardId must be 'shardId-012'`); | ||
// More real eventIDs | ||
let eventID = 'shardId-000000000000:49545115243490985018280067714973144582180062593244200961'; | ||
let expected = ['shardId-000000000000', '49545115243490985018280067714973144582180062593244200961']; | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID(eventID), expected, `eventID '${expected}' shardId & eventNo must be ${stringify(expected)}`); | ||
eventID = 'shardId-123456789012:49545115243490985018280067714973144582180062593244200962'; | ||
expected = ['shardId-123456789012', '49545115243490985018280067714973144582180062593244200962']; | ||
t.deepEqual(getKinesisShardIdAndEventNoFromEventID(eventID), expected, `eventID '${expected}' shardId & eventNo must be ${stringify(expected)}`); | ||
t.end(); | ||
}); | ||
// ===================================================================================================================== | ||
// validateStreamEventRecord | ||
@@ -195,3 +355,3 @@ // ===================================================================================================================== | ||
// "valid" Kinesis records | ||
check({eventSource: 'aws:kinesis', kinesis: {data: "dummy_data"}}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:kinesis', kinesis: {partitionKey: 'shardId-000:123', data: "dummy_data", sequenceNumber: '123'}, eventName: 'aws:kinesis:record'}, true); | ||
@@ -209,18 +369,18 @@ // valid Kinesis records | ||
// invalid DynamoDB stream event records | ||
check({eventSource: 'aws:dynamodb'}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OTHER"}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {StreamViewType: "KEYS_ONLY"}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE"}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", NewImage: {}}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE"}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", OldImage: {}}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES"}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OTHER"}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {StreamViewType: "KEYS_ONLY"}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE"}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", NewImage: {}}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE"}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", OldImage: {}}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES"}}, false); | ||
// "valid" DynamoDB stream event records | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "KEYS_ONLY"}}, true); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", OldImage: {}}}, true); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", NewImage: {}}}, true); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, NewImage: {}}}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "KEYS_ONLY", SequenceNumber: '123'}, eventName: 'MODIFY'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", OldImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", NewImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, NewImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, true); | ||
@@ -271,5 +431,6 @@ // valid DynamoDB stream event records | ||
check({eventSource: 'aws:kinesis', kinesis: {}}, false); | ||
check({eventSource: 'aws:kinesis', kinesis: {data: "dummy_data"}}, false); | ||
// "valid" Kinesis records | ||
check({eventSource: 'aws:kinesis', kinesis: {data: "dummy_data"}}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:kinesis', kinesis: {partitionKey: 'shardId-000-123', data: "dummy_data", sequenceNumber: '123'}, eventName: 'aws:kinesis:record'}, true); | ||
@@ -286,6 +447,6 @@ // valid Kinesis records | ||
// invalid - since DynamoDB stream event records | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "KEYS_ONLY"}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", OldImage: {}}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", NewImage: {}}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, NewImage: {}}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "KEYS_ONLY", SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", OldImage: {}, SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", NewImage: {}, SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, NewImage: {}, SequenceNumber: '123'}}, false); | ||
@@ -332,21 +493,74 @@ // invalid - since DynamoDB stream event records | ||
check({eventSource: 'aws:other'}, false); | ||
check({eventID: 'eventID'}, false); | ||
check({eventSourceARN: 'eventSourceARN'}, false); | ||
check({eventID: 'eventID', eventSource: 'aws:other'}, false); | ||
check({eventSourceARN: 'eventSourceARN', eventSource: 'aws:other'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:other'}, false); | ||
// invalid Kinesis stream event records | ||
check({eventSource: 'aws:kinesis'}, false); | ||
check({eventID: 'eventID', eventSource: 'aws:kinesis'}, false); | ||
check({eventSourceARN: 'eventSourceARN', eventSource: 'aws:kinesis'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:kinesis'}, false); | ||
// invalid DynamoDB stream event records | ||
check({eventSource: 'aws:dynamodb'}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OTHER"}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {StreamViewType: "KEYS_ONLY"}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE"}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", NewImage: {}}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE"}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", OldImage: {}}}, false); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES"}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OTHER", SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {StreamViewType: "KEYS_ONLY", SequenceNumber: '123'}, eventName: 'INSERT'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {StreamViewType: "KEYS_ONLY", SequenceNumber: '123'}, eventName: 'MODIFY'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {StreamViewType: "KEYS_ONLY", SequenceNumber: '123'}, eventName: 'REMOVE'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", SequenceNumber: '123'}, eventName: 'MODIFY'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", SequenceNumber: '123'}, eventName: 'REMOVE'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", NewImage: {}, SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", NewImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", NewImage: {}, SequenceNumber: '123'}, eventName: 'REMOVE'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", SequenceNumber: '123'}, eventName: 'INSERT'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", SequenceNumber: '123'}, eventName: 'MODIFY'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", OldImage: {}, SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", OldImage: {}, SequenceNumber: '123'}, eventName: 'INSERT'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", OldImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", SequenceNumber: '123'}, eventName: 'INSERT'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", SequenceNumber: '123'}, eventName: 'MODIFY'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", SequenceNumber: '123'}, eventName: 'REMOVE'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, SequenceNumber: '123'}, eventName: 'INSERT'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", NewImage: {}, SequenceNumber: '123'}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", NewImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", NewImage: {}, SequenceNumber: '123'}, eventName: 'REMOVE'}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, NewImage: {}, SequenceNumber: '123'}}, false); | ||
// "valid" DynamoDB stream event records | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "KEYS_ONLY"}}, true); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", OldImage: {}}}, true); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", NewImage: {}}}, true); | ||
check({eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, NewImage: {}}}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "KEYS_ONLY", SequenceNumber: '123'}, eventName: 'INSERT'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "KEYS_ONLY", SequenceNumber: '123'}, eventName: 'MODIFY'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "KEYS_ONLY", SequenceNumber: '123'}, eventName: 'REMOVE'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", SequenceNumber: '123'}, eventName: 'INSERT'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", NewImage: {}, SequenceNumber: '123'}, eventName: 'INSERT'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", OldImage: {}, SequenceNumber: '123'}, eventName: 'INSERT'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", OldImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "OLD_IMAGE", OldImage: {}, SequenceNumber: '123'}, eventName: 'REMOVE'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", SequenceNumber: '123'}, eventName: 'REMOVE'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", NewImage: {}, SequenceNumber: '123'}, eventName: 'INSERT'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", NewImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_IMAGE", NewImage: {}, SequenceNumber: '123'}, eventName: 'REMOVE'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, SequenceNumber: '123'}, eventName: 'REMOVE'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", NewImage: {}, SequenceNumber: '123'}, eventName: 'INSERT'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, NewImage: {}, SequenceNumber: '123'}, eventName: 'INSERT'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, NewImage: {}, SequenceNumber: '123'}, eventName: 'MODIFY'}, true); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:dynamodb', dynamodb: {Keys: {}, StreamViewType: "NEW_AND_OLD_IMAGES", OldImage: {}, NewImage: {}, SequenceNumber: '123'}, eventName: 'REMOVE'}, true); | ||
// valid DynamoDB stream event records | ||
@@ -359,3 +573,3 @@ const awsDynamoDBUpdateSampleEvent = samples.awsDynamoDBUpdateSampleEvent("identityArn", "eventSourceArn"); | ||
// invalid - since Kinesis records | ||
check({eventSource: 'aws:kinesis', kinesis: {data: "dummy_data"}}, false); | ||
check({eventID: 'eventID', eventSourceARN: 'eventSourceARN', eventSource: 'aws:kinesis', kinesis: {data: "dummy_data"}}, false); | ||
@@ -362,0 +576,0 @@ // invalid - since Kinesis records |
182
type-defs.js
@@ -8,7 +8,3 @@ 'use strict'; | ||
/** | ||
* @typedef {Object} AwsEvent - an AWS event passed to your Lambda handler function | ||
*/ | ||
/** | ||
* @typedef {Object} AwsContext - an AWS context passed to your Lambda handler function | ||
* @typedef {Object} AWSContext - an AWS context passed to your Lambda handler function | ||
* @property {uuid} awsRequestId - a unique identifier assigned to the current invocation of your handler function by AWS Lambda | ||
@@ -19,3 +15,3 @@ * @property {function(): number} getRemainingTimeInMillis - gets the remaining time to execute in milliseconds | ||
/** | ||
* @typedef {function(event: AwsEvent, awsContext: AwsContext, callback: Callback)} AwsLambdaHandlerFunction - a handler | ||
* @typedef {function(event: AWSEvent, awsContext: AWSContext, callback: Callback)} AwsLambdaHandlerFunction - a handler | ||
* function for your AWS Lambda | ||
@@ -33,3 +29,3 @@ */ | ||
* @property {string|undefined} [stage] - the configured stage to use | ||
* @property {AwsContext|undefined} [awsContext] - the AWS context passed to your Lambda function on invocation | ||
* @property {AWSContext|undefined} [awsContext] - the AWS context passed to your Lambda function on invocation | ||
*/ | ||
@@ -84,3 +80,3 @@ | ||
* @property {string} region - the name of the AWS region to use | ||
* @property {AwsContext} awsContext - the AWS context passed to your Lambda function on invocation | ||
* @property {AWSContext} awsContext - the AWS context passed to your Lambda function on invocation | ||
*/ | ||
@@ -106,3 +102,3 @@ | ||
/** | ||
* @typedef {Logging} StageHandling - an object configured with stage handling and logging functionality | ||
* @typedef {Logger} StageHandling - an object configured with stage handling and logging functionality | ||
* @property {StageHandlingSettings} stageHandling - an object configured with stage handling settings and functionality to use | ||
@@ -145,4 +141,5 @@ */ | ||
* settings determine how {@linkcode stages.js#resolveStage}, {@linkcode stages.js#toStageQualifiedStreamName}, | ||
* {@linkcode stages.js#extractStageFromQualifiedStreamName}, {@linkcode stages.js#toStageQualifiedResourceName}, | ||
* {@linkcode stages.js#extractStageFromQualifiedStreamName} and other internal functions will behave when invoked. | ||
* {@linkcode stages.js#extractStageFromQualifiedStreamName}, {@linkcode stages.js#extractNameAndStageFromQualifiedStreamName}, | ||
* {@linkcode stages.js#toStageQualifiedResourceName}, {@linkcode stages.js#extractStageFromQualifiedResourceName}, | ||
* {@linkcode stages.js#extractNameAndStageFromQualifiedResourceName} and other internal functions will behave when invoked. | ||
* | ||
@@ -157,8 +154,10 @@ * They can also be used to pass any additional custom configuration options and settings that you need through to any | ||
* @property {ExtractStageFromStreamName|undefined} [extractStageFromStreamName] - an optional function that extracts a stage from a stage-qualified stream name | ||
* @property {ExtractNameAndStageFromStreamName|undefined} [extractNameAndStageFromStreamName] - an optional function that extracts the unqualified name and stage from a stage-qualified stream name | ||
* @property {InjectStageIntoResourceName|undefined} [injectStageIntoResourceName] - an optional function that returns a stage-qualified resource name | ||
* @property {ExtractStageFromResourceName|undefined} [extractStageFromResourceName] - an optional function that extracts a stage from a stage-qualified resource name | ||
* @property {ExtractNameAndStageFromResourceName|undefined} [extractNameAndStageFromResourceName] - an optional function that extracts the unqualified name and stage from a stage-qualified resource name | ||
*/ | ||
/** | ||
* @typedef {function(event: AwsEvent, awsContext: AwsContext, context: StageHandling): (string|undefined)} CustomToStage - | ||
* @typedef {function(event: AWSEvent, awsContext: AWSContext, context: StageHandling): (string|undefined)} CustomToStage - | ||
* a custom function that accepts: an AWS event; an AWS context; and a context, and somehow extracts a usable stage from | ||
@@ -169,3 +168,3 @@ * the AWS event and/or AWS context. | ||
/** | ||
* @typedef {function(alias: string, event: AwsEvent, awsContext: AwsContext, context: StageHandling): (string|undefined)} ConvertAliasToStage - | ||
* @typedef {function(alias: string, event: AWSEvent, awsContext: AWSContext, context: StageHandling): (string|undefined)} ConvertAliasToStage - | ||
* a function that accepts: an extracted AWS Lambda alias (if any); an AWS event; an AWS context; and a context, and | ||
@@ -187,2 +186,8 @@ * converts the alias into a stage | ||
/** | ||
* @typedef {function(qualifiedStreamName: string, context: StageHandling):[string,string]} ExtractNameAndStageFromStreamName - | ||
* a function that accepts: a stage-qualified stream name; and a context, and extracts the unqualified name and stage | ||
* from the stream name | ||
*/ | ||
/** | ||
* @typedef {function(unqualifiedResourceName: string, stage: string, context: StageHandling):(string|undefined)} InjectStageIntoResourceName - | ||
@@ -198,1 +203,152 @@ * a function that accepts: an unqualified resource name; a stage; and a context, and returns a stage-qualified resource | ||
/** | ||
* @typedef {function(qualifiedResourceName: string, context: StageHandling):[string,string]} ExtractNameAndStageFromResourceName - | ||
* a function that accepts: a stage-qualified resource name; and a context, and extracts the unqualified name and stage | ||
* from the resource name | ||
*/ | ||
/** | ||
* ARN resource-related components | ||
* @typedef {Object} ArnResources | ||
* @property {string} resourceType - a resource type (for DynamoDB stream eventSourceARN's this contains "table") | ||
* @property {string} resource - a resource name (for DynamoDB stream eventSourceARN's this is the table name) | ||
* @property {string} subResourceType - a sub-resource type (for DynamoDB stream eventSourceARN's this contains "stream") | ||
* @property {string} subResource - a sub-resource name (for DynamoDB stream eventSourceARN's this is the stream timestamp) | ||
* @property {string} aliasOrVersion - a Lambda alias or version number | ||
* @property {string[]} others - any other components after a Lambda alias or version number | ||
*/ | ||
/** | ||
* @typedef {Object} AWSEvent - represents an AWS event typically passed to your Lambda handler function | ||
* @see KinesisEvent | ||
* @see DynamoDBEvent | ||
* @see S3Event | ||
* @see SESEvent | ||
* @see SNSEvent | ||
*/ | ||
/** | ||
* @typedef {KinesisEvent|DynamoDBEvent|S3Event|SESEvent|SNSEvent} AnyAWSEvent - represents any AWS event (currently supported) | ||
*/ | ||
/** | ||
* @typedef {AWSEvent} StreamEvent - represents an AWS stream event | ||
* @property {StreamEventRecord[]} Records - the records of the AWS stream event | ||
* @see KinesisEvent | ||
* @see DynamoDBEvent | ||
*/ | ||
/** | ||
* @typedef {KinesisEvent|DynamoDBEvent} AnyStreamEvent - represents an AWS Kinesis or DynamoDB stream event | ||
/** | ||
* @typedef {StreamEvent} KinesisEvent - represents an AWS Kinesis stream event | ||
* @property {KinesisEventRecord[]} Records - the records of the AWS Kinesis stream event | ||
*/ | ||
/** | ||
* @typedef {StreamEvent} DynamoDBEvent - represents an AWS DynamoDB stream event | ||
* @property {DynamoDBEventRecord[]} Records - the records of the AWS DynamoDB stream event | ||
*/ | ||
/** | ||
* @typedef {AWSEvent} S3Event - represents an AWS S3 (Simple Storage Service) event | ||
* @property {S3EventRecord[]} Records - the records of the AWS S3 event | ||
*/ | ||
/** | ||
* @typedef {AWSEvent} SESEvent - represents an AWS SES (Simple Email Service) event | ||
* @property {SESEventRecord[]} Records - the records of the AWS SES event | ||
*/ | ||
/** | ||
* @typedef {AWSEvent} SNSEvent - represents an AWS SNS (Simple Notification Service) event | ||
* @property {string} EventSource - the event source of the AWS event record | ||
* @property {SNSEventRecord[]} Records - the records of the AWS SNS event | ||
*/ | ||
/** | ||
* @typedef {Object} AWSEventRecord - represents an AWS event record | ||
* @see KinesisEventRecord | ||
* @see DynamoDBEventRecord | ||
* @see S3EventRecord | ||
* @see SESEventRecord | ||
* @see SNSEventRecord | ||
*/ | ||
/** | ||
* @typedef {KinesisEventRecord|DynamoDBEventRecord|S3EventRecord|SESEventRecord|SNSEventRecord} AnyAWSEventRecord - represents any AWS event record (currently supported) | ||
*/ | ||
/** | ||
* @typedef {AWSEventRecord} StreamEventRecord - represents an AWS stream event record | ||
* @property {string} eventID - the event ID, which should uniquely identify the record | ||
* @property {string} eventSource - the event source, which should be either 'aws:kinesis' or 'aws:dynamodb' | ||
* @property {string} eventSourceARN - the event source ARN (Amazon Resource Number), which identifies the event source stream or table | ||
* @property {string} eventVersion - the version of the event | ||
* @property {string} awsRegion - the AWS region in which the event took place | ||
* @property {string} eventName - the "name" of the event - for Kinesis this will be 'aws:kinesis:record'; for DynamoDB this will be 'INSERT', 'MODIFY' or 'REMOVE' | ||
* @see KinesisEventRecord | ||
* @see DynamoDBEventRecord | ||
*/ | ||
/** | ||
* @typedef {KinesisEventRecord|DynamoDBEventRecord} AnyStreamEventRecord - represents any AWS stream event record (currently supported) | ||
*/ | ||
/** | ||
* @typedef {StreamEventRecord} KinesisEventRecord - represents an AWS Kinesis stream event record | ||
* @property {KinesisProperty} kinesis - the kinesis property contains the data and details of the Kinesis event record | ||
* @property {string} invokeIdentityArn - the invoke identity ARN (Amazon Resource Number) | ||
* @see KinesisEvent | ||
*/ | ||
/** | ||
* @typedef {Object} KinesisProperty - represents the kinesis property of an AWS Kinesis stream event record | ||
* @property {string} partitionKey - the partition key of the Kinesis event record | ||
* @property {string} data - the actual data of a Kinesis event record in base 64 format | ||
* @property {string} sequenceNumber - the sequence number of the Kinesis event record | ||
* @property {string} kinesisSchemaVersion - the schema version of the Kinesis event record | ||
*/ | ||
/** | ||
* @typedef {StreamEventRecord} DynamoDBEventRecord - represents an AWS DynamoDB stream event record | ||
* @property {DynamodbProperty} dynamodb - the dynamodb property contains the details of the DynamoDB record that was inserted, modified or removed | ||
* @see DynamoDBEvent | ||
*/ | ||
/** | ||
* @typedef {Object} DynamodbProperty - represents the dynamodb property of an AWS DynamoDB stream event record | ||
* @property {Object} Keys - the keys of the DynamoDB record (in DynamoDB attribute value format) | ||
* @property {Object} [NewImage] - the new image of the DynamoDB record (in DynamoDB attribute value format) | ||
* @property {Object} [OldImage] - the old image of the DynamoDB record (in DynamoDB attribute value format) | ||
* @property {string} SequenceNumber - the sequence number of the event | ||
* @property {string} SizeBytes - the size of the event in bytes | ||
* @property {string} StreamViewType - the type of stream view, which defines whether NewImage and OldImage should be | ||
* present or not, and which should be 'KEYS_ONLY', 'NEW_IMAGE', 'OLD_IMAGE' or 'NEW_AND_OLD_IMAGES' | ||
*/ | ||
/** | ||
* @typedef {AWSEventRecord} S3EventRecord - represents an AWS S3 event record | ||
* @property {string} eventSource - the event source of the AWS S3 event record | ||
* @see S3Event | ||
*/ | ||
/** | ||
* @typedef {AWSEventRecord} SESEventRecord - represents an AWS SES event record | ||
* @property {string} eventSource - the event source of the AWS SES event record | ||
* @see SESEvent | ||
*/ | ||
/** | ||
* @typedef {AWSEventRecord} SNSEventRecord - represents an AWS SNS event record | ||
* @property {string} EventSource - the event source of the AWS SNS event record | ||
* @see SNSEvent | ||
*/ | ||
/** | ||
* @typedef {Object} DynamoDBUtilsDefaults - Defaults used by the dynamodb-utils module, which can be overridden to | ||
* alter the default behaviour | ||
* @property {string} emptyStringReplacement - a non-empty string to use as a replacement for empty strings, which | ||
* cannot be stored to DynamoDB (defaults to ' ', i.e. a single space) | ||
*/ |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
425721
31
6045
668
+ Addedcore-functions@3.0.25(transitive)
+ Addedlogging-utils@4.0.25(transitive)
- Removedcore-functions@2.0.18(transitive)
- Removedlogging-utils@3.0.18(transitive)
Updatedcore-functions@^3.0.0
Updatedlogging-utils@^4.0.0