Last active
October 5, 2021 02:10
-
-
Save mtimbs/bcd3b58ef719409b374d17c7b7033cf4 to your computer and use it in GitHub Desktop.
Recursive Dynamic Update DynamoDB (WIP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NativeAttributeValue } from '@aws-sdk/util-dynamodb/src/models'; | |
import { AttributeValue } from '@aws-sdk/client-dynamodb'; | |
import { marshall } from '@aws-sdk/util-dynamodb'; | |
interface DynamoUpdateParams { | |
UpdateExpression: string; | |
ExpressionAttributeNames: Record<string, string>; | |
ExpressionAttributeValues: Record<string, AttributeValue>; | |
} | |
const attributeExtractor = (item: Record<string, unknown>) => Object.entries(item).reduce((previous, [key, value]): Record<string, string> => | |
({ | |
...previous, | |
...{ [`#${key}`]: key }, | |
...(typeof value === 'object' && value !== null && Object.keys(item).length > 0) && attributeExtractor(value as Record<string, unknown>) | |
}), | |
{}); | |
const valueExtractor = (item: Record<string, NativeAttributeValue>) => Object.entries(item).reduce((previous, [key, value]): Record<string, string> => | |
({ | |
...previous, | |
...(typeof value !== 'object') && marshall({ [`:${key}`]: value }), | |
...(typeof value === 'object' && value !== null && Object.keys(item).length > 0) && valueExtractor(value as Record<string, unknown>) | |
}), | |
{}); | |
const expressionCreator = (item: Record<string, unknown>, prefix: string|null) => | |
Object.entries(item).reduce<string>((carry, [key, value]): string => { | |
const prefixedKey = prefix ? `${prefix}.#${key}` : `#${key}`; | |
if (typeof value === 'object' && value !== null && Object.keys(item).length > 0) { | |
return `${carry}${expressionCreator(value as Record<string, unknown>, prefixedKey)}`; | |
} | |
return `${carry} ${prefixedKey} = :${key},`; | |
}, ''); | |
export const dynamicUpdateExpressionFromObject = <T extends { [K in keyof T]: NativeAttributeValue }>(item: T): DynamoUpdateParams => { | |
const ExpressionAttributeNames: Record<string, string> = attributeExtractor(item); | |
const ExpressionAttributeValues: Record<string, AttributeValue> = valueExtractor(item); | |
const UpdateExpression = `SET${expressionCreator(item, null).slice(0, -1)}`; | |
return { | |
UpdateExpression, | |
ExpressionAttributeNames, | |
ExpressionAttributeValues, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment