@middy/dynamodb
Advanced tools
Comparing version 5.0.0-alpha.0 to 5.0.0-alpha.1
import middy from '@middy/core' | ||
import { Options as MiddyOptions } from '@middy/util' | ||
import { Context as LambdaContext } from 'aws-lambda' | ||
import { DynamoDBClient, DynamoDBClientConfig } from '@aws-sdk/client-dynamodb' | ||
import { DynamoDBClient, DynamoDBClientConfig, GetItemCommandInput } from '@aws-sdk/client-dynamodb' | ||
import { NativeAttributeValue } from '@aws-sdk/util-dynamodb' | ||
export type Options<AwsDynamoDBClient = DynamoDBClient> = | ||
export type ParamType<T extends Record<string, NativeAttributeValue>> = GetItemCommandInput & { __returnType?: T } | ||
export declare function dynamoDbReq<T extends Record<string, NativeAttributeValue>> (req: GetItemCommandInput): ParamType<T> | ||
export type DynamoDbOptions<AwsDynamoDBClient = DynamoDBClient> = | ||
Omit<MiddyOptions<AwsDynamoDBClient, DynamoDBClientConfig>, 'fetchData'> | ||
@@ -11,17 +15,33 @@ & | ||
fetchData?: { | ||
// TODO: add more precise type | ||
[key: string]: Record<string, any> | ||
[key: string]: GetItemCommandInput | ParamType<Record<string, NativeAttributeValue>> | ||
} | ||
} | ||
export type Context<TOptions extends Options | undefined> = TOptions extends { | ||
export type Context<TOptions extends DynamoDbOptions | undefined> = TOptions extends { | ||
setToContext: true | ||
} | ||
? LambdaContext & Record<keyof TOptions['fetchData'], any> | ||
? TOptions extends { fetchData: infer TFetchData } | ||
? LambdaContext & { | ||
[Key in keyof TFetchData]: TFetchData[Key] extends ParamType<infer T> | ||
? T | ||
: NativeAttributeValue | ||
} | ||
: never | ||
: LambdaContext | ||
declare function dynamodbMiddleware<TOptions extends Options | undefined> ( | ||
export type Internal<TOptions extends DynamoDbOptions | undefined> = | ||
TOptions extends DynamoDbOptions | ||
? TOptions extends { fetchData: infer TFetchData } | ||
? { | ||
[Key in keyof TFetchData]: TFetchData[Key] extends ParamType<infer T> | ||
? T | ||
: NativeAttributeValue | ||
} | ||
: {} | ||
: {} | ||
declare function dynamodbMiddleware<TOptions extends DynamoDbOptions | undefined> ( | ||
options?: TOptions | ||
): middy.MiddlewareObj<unknown, any, Error, Context<TOptions>> | ||
): middy.MiddlewareObj<unknown, any, Error, Context<TOptions>, Internal<TOptions>> | ||
export default dynamodbMiddleware |
133
index.js
@@ -1,59 +0,82 @@ | ||
import { canPrefetch, createPrefetchClient, createClient, getCache, getInternal, processCache, modifyCache } from '@middy/util'; | ||
import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb'; | ||
import { marshall, unmarshall } from '@aws-sdk/util-dynamodb'; | ||
import { | ||
canPrefetch, | ||
createPrefetchClient, | ||
createClient, | ||
getCache, | ||
getInternal, | ||
processCache, | ||
modifyCache | ||
} from '@middy/util' | ||
import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb' | ||
import { marshall, unmarshall } from '@aws-sdk/util-dynamodb' | ||
const defaults = { | ||
AwsClient: DynamoDBClient, | ||
awsClientOptions: {}, | ||
awsClientAssumeRole: undefined, | ||
awsClientCapture: undefined, | ||
fetchData: {}, | ||
disablePrefetch: false, | ||
cacheKey: 'dynamodb', | ||
cacheExpiry: -1, | ||
setToContext: false | ||
}; | ||
const dynamodbMiddleware = (opts = {})=>{ | ||
const options = { | ||
...defaults, | ||
...opts | ||
}; | ||
for(const internalKey in options.fetchData){ | ||
options.fetchData[internalKey].Key = marshall(options.fetchData[internalKey].Key); | ||
AwsClient: DynamoDBClient, | ||
awsClientOptions: {}, | ||
awsClientAssumeRole: undefined, | ||
awsClientCapture: undefined, | ||
fetchData: {}, | ||
disablePrefetch: false, | ||
cacheKey: 'dynamodb', | ||
cacheKeyExpiry: {}, | ||
cacheExpiry: -1, | ||
setToContext: false | ||
} | ||
const dynamodbMiddleware = (opts = {}) => { | ||
const options = { | ||
...defaults, | ||
...opts | ||
} | ||
// force marshall of Key during cold start | ||
for (const internalKey in options.fetchData) { | ||
options.fetchData[internalKey].Key = marshall( | ||
options.fetchData[internalKey].Key | ||
) | ||
} | ||
const fetch = (request, cachedValues = {}) => { | ||
const values = {} | ||
for (const internalKey in options.fetchData) { | ||
if (cachedValues[internalKey]) continue | ||
const inputParameters = options.fetchData[internalKey] | ||
values[internalKey] = client | ||
.send(new GetItemCommand(inputParameters)) | ||
.then((resp) => unmarshall(resp.Item)) | ||
.catch((e) => { | ||
const value = getCache(options.cacheKey).value ?? {} | ||
value[internalKey] = undefined | ||
modifyCache(options.cacheKey, value) | ||
throw e | ||
}) | ||
} | ||
const fetch = (request, cachedValues = {})=>{ | ||
const values = {}; | ||
for(const internalKey in options.fetchData){ | ||
if (cachedValues[internalKey]) continue; | ||
const inputParameters = options.fetchData[internalKey]; | ||
values[internalKey] = client.send(new GetItemCommand(inputParameters)).then((resp)=>unmarshall(resp.Item)).catch((e)=>{ | ||
const value = getCache(options.cacheKey).value ?? {}; | ||
value[internalKey] = undefined; | ||
modifyCache(options.cacheKey, value); | ||
throw e; | ||
}); | ||
} | ||
return values; | ||
}; | ||
let prefetch, client; | ||
if (canPrefetch(options)) { | ||
client = createPrefetchClient(options); | ||
prefetch = processCache(options, fetch); | ||
return values | ||
} | ||
let client | ||
if (canPrefetch(options)) { | ||
client = createPrefetchClient(options) | ||
processCache(options, fetch) | ||
} | ||
const dynamodbMiddlewareBefore = async (request) => { | ||
if (!client) { | ||
client = await createClient(options, request) | ||
} | ||
const dynamodbMiddlewareBefore = async (request)=>{ | ||
if (!client) { | ||
client = await createClient(options, request); | ||
} | ||
const { value } = prefetch ?? processCache(options, fetch, request); | ||
Object.assign(request.internal, value); | ||
if (options.setToContext) { | ||
const data = await getInternal(Object.keys(options.fetchData), request); | ||
Object.assign(request.context, data); | ||
} | ||
prefetch = null; | ||
}; | ||
return { | ||
before: dynamodbMiddlewareBefore | ||
}; | ||
}; | ||
export default dynamodbMiddleware; | ||
const { value } = processCache(options, fetch, request) | ||
Object.assign(request.internal, value) | ||
if (options.setToContext) { | ||
const data = await getInternal(Object.keys(options.fetchData), request) | ||
Object.assign(request.context, data) | ||
} | ||
} | ||
return { | ||
before: dynamodbMiddlewareBefore | ||
} | ||
} | ||
// used for TS type inference (see index.d.ts) | ||
export function dynamoDbReq (req) { | ||
return req | ||
} | ||
export default dynamodbMiddleware |
{ | ||
"name": "@middy/dynamodb", | ||
"version": "5.0.0-alpha.0", | ||
"version": "5.0.0-alpha.1", | ||
"description": "DynamoDB middleware for the middy framework", | ||
@@ -13,3 +13,2 @@ "type": "module", | ||
}, | ||
"main": "./index.cjs", | ||
"module": "./index.js", | ||
@@ -21,6 +20,2 @@ "exports": { | ||
"default": "./index.js" | ||
}, | ||
"require": { | ||
"types": "./index.d.ts", | ||
"default": "./index.cjs" | ||
} | ||
@@ -32,3 +27,2 @@ } | ||
"index.js", | ||
"index.cjs", | ||
"index.d.ts" | ||
@@ -70,3 +64,3 @@ ], | ||
"dependencies": { | ||
"@middy/util": "5.0.0-alpha.0" | ||
"@middy/util": "5.0.0-alpha.1" | ||
}, | ||
@@ -76,7 +70,7 @@ "devDependencies": { | ||
"@aws-sdk/util-dynamodb": "^3.245.0", | ||
"@middy/core": "5.0.0-alpha.0", | ||
"@middy/core": "5.0.0-alpha.1", | ||
"@types/aws-lambda": "^8.10.101", | ||
"aws-xray-sdk": "^3.3.3" | ||
}, | ||
"gitHead": "08c35e3dba9efdad0b86666ce206ce302cc65d07" | ||
"gitHead": "ebce8d5df8783077fa49ba62ee9be20e8486a7f1" | ||
} |
@@ -22,4 +22,5 @@ <div align="center"> | ||
</a> | ||
<a href="https://lgtm.com/projects/g/middyjs/middy/context:javascript"> | ||
<img src="https://img.shields.io/lgtm/grade/javascript/g/middyjs/middy.svg?logo=lgtm&logoWidth=18" alt="Language grade: JavaScript" style="max-width:100%;"> | ||
<a href="https://github.com/middyjs/middy/actions/workflows/sast.yml"> | ||
<img src="https://github.com/middyjs/middy/actions/workflows/sast.yml/badge.svg | ||
?branch=main&event=push" alt="CodeQL" style="max-width:100%;"> | ||
</a> | ||
@@ -26,0 +27,0 @@ <a href="https://bestpractices.coreinfrastructure.org/projects/5280"> |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
47
3
9500
5
116
+ Added@middy/util@5.0.0-alpha.1(transitive)
- Removed@middy/util@5.0.0-alpha.0(transitive)
Updated@middy/util@5.0.0-alpha.1