diff --git a/src/index.test.ts b/src/index.test.ts index 9a61856..3f3bfae 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1,5 +1,4 @@ -import AWS from 'aws-sdk'; - +import { DocumentClient } from 'aws-sdk/clients/dynamodb'; import type { DynoexprOutput } from './dynoexpr'; import dynoexpr from '.'; @@ -23,13 +22,13 @@ describe('high level API', () => { it('accepts a type to be applied to the output', () => { expect.assertions(1); - const params = dynoexpr({ + const params = dynoexpr({ TableName: 'Table', Key: 123, UpdateSet: { color: 'pink' }, }); - assertType(); + assertType(); expect(params.Key).toBe(123); }); }); diff --git a/src/operations/single.test.ts b/src/operations/single.test.ts index 216130f..d24e3d2 100644 --- a/src/operations/single.test.ts +++ b/src/operations/single.test.ts @@ -1,13 +1,10 @@ -import AWS from 'aws-sdk'; - import type { DynoexprInput, DynoexprOutput } from '../dynoexpr'; import { + createDynamoDbSet, getSingleTableExpressions, convertValuesToDynamoDbSet, } from './single'; -const docClient = new AWS.DynamoDB.DocumentClient(); - describe('single table operations', () => { it('applies consecutive expression getters to a parameters object', () => { const params: DynoexprInput = { @@ -154,6 +151,53 @@ describe('single table operations', () => { expect(result).toStrictEqual(expected); }); + it('creates DynamoDBSet instances for strings', () => { + const params = ['hello', 'world']; + const result = createDynamoDbSet(params); + expect(result.type).toBe('String'); + expect(result.values).toHaveLength(params.length); + expect(result.values).toContain('hello'); + expect(result.values).toContain('world'); + }); + + it('creates DynamoDBSet instances for numbers', () => { + const params = [42, 1, 2]; + const result = createDynamoDbSet(params); + expect(result.type).toBe('Number'); + expect(result.values).toHaveLength(params.length); + expect(result.values).toContain(42); + expect(result.values).toContain(1); + expect(result.values).toContain(2); + }); + + it('creates DynamoDBSet instances for binary types', () => { + const params = [ + Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]), + Buffer.from([0x61, 0x62, 0x63]), + ]; + const result = createDynamoDbSet(params); + expect(result.type).toBe('Binary'); + expect(result.values).toHaveLength(params.length); + expect(result.values).toContainEqual(params[0]); + expect(result.values).toContain(params[1]); + }); + + it('does not throw an error with mixed set types if validation is not explicitly enabled', () => { + const params = ['hello', 42]; + const result = createDynamoDbSet(params); + expect(result.type).toBe('String'); + expect(result.values).toHaveLength(params.length); + expect(result.values).toContain('hello'); + expect(result.values).toContain(42); + }); + + it('throws an error with mixed set types if validation is enabled', () => { + const params = ['hello', 42]; + const expression = () => createDynamoDbSet(params, { validate: true }); + const expectedErrorMessage = 'String Set contains Number value'; + expect(expression).toThrow(expectedErrorMessage); + }); + it('converts Sets to DynamoDbSet if present in ExpressionsAttributeValues', () => { const values = { a: 1, @@ -170,8 +214,8 @@ describe('single table operations', () => { b: 'foo', c: [1, 2, 3], d: { foo: 'bar' }, - e: docClient.createSet([1, 2]), - f: docClient.createSet(['foo', 'bar']), + e: createDynamoDbSet([1, 2]), + f: createDynamoDbSet(['foo', 'bar']), }; expect(result).toStrictEqual(expected); }); diff --git a/src/operations/single.ts b/src/operations/single.ts index a849207..18bf667 100644 --- a/src/operations/single.ts +++ b/src/operations/single.ts @@ -1,4 +1,4 @@ -import AWS from 'aws-sdk'; +import { DocumentClient } from 'aws-sdk/clients/dynamodb'; import type { DynoexprInput, DynamoDbValue, DynoexprOutput } from '../dynoexpr'; import { getConditionExpression } from '../expressions/condition'; @@ -10,7 +10,8 @@ import { getKeyConditionExpression } from '../expressions/key-condition'; import { trimEmptyExpressionAttributes } from './helpers'; -const docClient = new AWS.DynamoDB.DocumentClient(); +export const createDynamoDbSet = + DocumentClient.prototype.createSet.bind(undefined); type ConvertValuesToDynamoDbSetFn = ( attributeValues: Record @@ -20,7 +21,7 @@ export const convertValuesToDynamoDbSet: ConvertValuesToDynamoDbSetFn = ( ) => Object.entries(attributeValues).reduce((acc, [key, value]) => { if (value instanceof Set) { - acc[key] = docClient.createSet(Array.from(value)); + acc[key] = createDynamoDbSet(Array.from(value)); } else { acc[key] = value as DynamoDbValue; }