From c1b8a42b99a88bf61ec7373084acbd9533ac1cc4 Mon Sep 17 00:00:00 2001 From: Richard Hooker Date: Thu, 16 Jul 2020 11:30:58 +0100 Subject: [PATCH] feat(empty-strings): drop empty string strictness to allow feature BREAKING CHANGE: empty strings are now valid dynamoDB values (see https://aws.amazon.com/about-aws/whats-new/2020/05/amazon-dynamodb-now-supports-empty-values-for-non-key-string-and-binary-attributes-in-dynamodb-tables/ for official statement) and thus they are mapped to and from db. --- src/mapper/for-type/string.mapper.spec.ts | 6 +++++- src/mapper/for-type/string.mapper.ts | 6 +++--- src/mapper/mapper.spec.ts | 7 ++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/mapper/for-type/string.mapper.spec.ts b/src/mapper/for-type/string.mapper.spec.ts index 8ef713d1b..c83ddd90e 100644 --- a/src/mapper/for-type/string.mapper.spec.ts +++ b/src/mapper/for-type/string.mapper.spec.ts @@ -9,7 +9,7 @@ describe('string mapper', () => { it('should work (empty string)', () => { const attributeValue = StringMapper.toDb('') - expect(attributeValue).toBe(null) + expect(attributeValue).toStrictEqual({ S: '' }) }) it('should work (null)', () => { @@ -28,6 +28,10 @@ describe('string mapper', () => { const stringValue = StringMapper.fromDb({ S: 'myStringValue' }) expect(stringValue).toBe('myStringValue') }) + it('should allow empty string values', () => { + const stringValue = StringMapper.fromDb({ S: '' }) + expect(stringValue).toBe('') + }) it('should throw if not a string attribute', () => { expect(() => StringMapper.fromDb({ N: '8' })).toThrow() }) diff --git a/src/mapper/for-type/string.mapper.ts b/src/mapper/for-type/string.mapper.ts index 3e86a251b..8f5dea2d3 100644 --- a/src/mapper/for-type/string.mapper.ts +++ b/src/mapper/for-type/string.mapper.ts @@ -5,7 +5,7 @@ import { StringAttribute } from '../type/attribute.type' import { MapperForType } from './base.mapper' function stringFromDb(attributeValue: StringAttribute): string { - if (attributeValue.S) { + if (attributeValue.S || attributeValue.S === '') { return attributeValue.S } else { throw new Error(`there is no S(tring) value defined on given attribute value: ${JSON.stringify(attributeValue)}`) @@ -13,8 +13,8 @@ function stringFromDb(attributeValue: StringAttribute): string { } function stringToDb(modelValue: string): StringAttribute | null { - // an empty string is not a valid value for string attribute - if (modelValue === '' || modelValue === null || modelValue === undefined) { + // an empty string is valid for a string attribute + if (modelValue === null || modelValue === undefined) { return null } else { return { S: modelValue } diff --git a/src/mapper/mapper.spec.ts b/src/mapper/mapper.spec.ts index 3e1152a3c..e78820735 100644 --- a/src/mapper/mapper.spec.ts +++ b/src/mapper/mapper.spec.ts @@ -67,7 +67,7 @@ describe('Mapper', () => { it('string (empty)', () => { const attrValue = toDbOne('')! - expect(attrValue).toBeNull() + expect(attrValue.S).toStrictEqual('') }) it('number', () => { @@ -801,7 +801,7 @@ describe('Mapper', () => { // OK id: 'myId', - // x -> empty strings are not valid + // x -> empty strings are valid name: '', // x -> empty set is not valid @@ -824,7 +824,8 @@ describe('Mapper', () => { expect(toDbValue.id).toBeDefined() expect(keyOf(toDbValue.id)).toBe('S') - expect(toDbValue.name).toBeUndefined() + expect(toDbValue.name).toBeDefined() + expect(keyOf(toDbValue.name)).toBe('S') expect(toDbValue.roles).toBeUndefined()