@tobinbc/dynamodb-string-adapter v1.2.0
dynamodb-string-adapter
DynamoDB cannot persist empty strings ''. This makes using the javascript aws-sdk documentClient a bit annoying when trying to persist two-way bound data fields e.g. in Angular or React inputs. If instantiating with new AWS.dynamodb.documentClient() a flag can be used to convert empty strings; if using a more integrated service e.g. AppSync / Amplify / API.graphQL, the underlieing documentClient is more difficult to work with.
This Typescript package converts string, number, object, null, undefined to DynamoDB compatible values and vice-versa.
Install
npm i --save @tobinbc/dynamodb-string-adapterVersion updates
- Added Generic Types for return type
- Defaults to Typescript string return to keep API types happy; actually returns TDSAStored to keep DDB happy.
Usage
Defaults
Defaults to storing an Object containing minimal metadata about the stored value (DDB storage = $$$). Assumes string cannot be null.
This is the preferred option - for speed the code has been setup to test for the DSA Type Object first.
import { fieldFromDDB, fieldToDDB } from '@tobinbc/dynamodb-string-adapter'
const input = 'test string';
const ddb = fieldToDDB(input); // => ddb is inferred as type `string` (see below)
ddb => { // => ddb runtime type is `TDSAStored` which can be accepted by AppSync
value: input, // => 'test string'
__type: LOCAL_TYPES.DSA_STORED,
};
const output = fieldFromDDB(ddb) // => 'test string'
...
const input = '';
const ddb = fieldToDDB(input);
ddb => {
(value:null): true,
notNull: true, // => Therefore the output cannot be `null`
__type: LOCAL_TYPES.DSA_STORED,
};
const output = fieldFromDDB(ddb) // => ''Allow null strings:
const input = '';
const ddb = fieldToDDB(input,{notNull:false});
ddb => {
(value:string): 'emptyString',
__type: LOCAL_TYPES.DSA_STORED,
};
const output = fieldFromDDB(ddb) // => ''
...
const input = null;
const ddb = fieldToDDB(input,{notNull:false});
ddb => {
(value:null): true,
notNull: false, // => Therefore the output can be `null`
__type: LOCAL_TYPES.DSA_STORED,
};
const output = fieldFromDDB(ddb) // => nullIf the DDB stored type should remain as a Primitive
A bit of a hack but when using GraphQL / AppSync the generated Typings will require the correctly typed inputs. Therefore Generic Types can be used to keep Typescript happy, and, if actually needed at runtime, a real string can also be returned.
import DSA, { fieldFromDDB, fieldToDDB } from '@tobinbc/dynamodb-string-adapter'
DSA.setGlobalOptions({
store:false,
})
const input = 12345;
const ddb = fieldToDDB<number>(input); // => 12345
const output = fieldFromDDB(ddb) // => 12345
...
const input = ''; // (empty string)
const ddb = fieldToDDB<string>(input); // => 'emptyString'; defaults to <string>
const output = fieldFromDDB(ddb) // => 'emptyString'If your application actually needs to store the value 'emptyString' for any reason
DSA.setGlobalOptions({
yesIReallyWantToStoreThePhraseEmptyString:true,
})Option sets
Perhaps different fields have different possibilities for null strings, so option sets can be added automatically with fieldToDDB and used when decoding within the same instantiation. The sets can be set globally if needed too. The OptionSet is not persisted in DDB so storing the type data in DDB should be the first option. The OptionSetId will be used as a key; the key global shouldn't be used.
import DSA, { fieldFromDDB, fieldToDDB } from '@tobinbc/dynamodb-string-adapter'
DSA.addOptionSet('phone', {
store: false,
});
const address:string = null;
const name:string = '';
const phone:number = 123456
const ddbAddress = fieldToDDB(address,{notNull:false},'address');
const ddbName = fieldToDDB(name); // => ddbName inferred as `string` and is a real string
const ddbPhone = fieldToDDB(name,'phone');
const outAddress = fieldFromDDB(ddbAddress,'address') // => null
const outName = fieldFromDDB(ddbName) // => '' (default `notNull`)
const outPhone = fieldFromDDB(ddbPhone,'phone') // => 123456On encode, the option set will be determined: 1. Options passed in arguments 2. OptionSetId passed in arguments 3. Global defaults
On decode, the option set will be determined: 1. Type persisted in DDB 2. Options passed in arguments 3. OptionSetId passed in arguments 4. Global defaults
Tests
npm run testDisclaimer
So this is actually my first published package; any feedback is well received.