dynamodb-toolbox
dynamodb-toolbox copied to clipboard
Add schema support for maps
Only top level schemas are supported. By adding support for nested maps, we could enforce types and provide a cleaner way to update data maps. This should be optional, falling back to the current dot notation for unmapped structures.
Proposed implementation
const MyModel = new Model('MyModel',{
// Specify table name
table: 'my-dynamodb-table',
// Define partition and sort keys
partitionKey: 'pk',
sortKey: 'sk',
// Define schema
schema: {
pk: { type: 'string', alias: 'id' },
sk: { type: 'string', hidden: true },
someMap: {
type: 'map' ,
schema: { // $ shorthand
title: 'string', // support string-based type declarations
count: { type: 'number', default: 10 }, // support scalars with defaults and other options
someList: { type: 'list' },
someNestedMap: { // Supported nested maps with schemas
type: 'map',
schema: { ... }
}
}
}
}
})
This would enable support for schema validation as well as partial updates.
Any update on this one? Would be such a great feature as otherwise we lose all the awesome aliasing features in the deeper nested maps 😢.
It would be handy to support list schema too. For eg.
someList: { type: 'list', schema: { name: 'string', enrolled: 'boolean' } }
the expected input for this would be:
const list = [{ name: 'foo', enrolled: true}, { name: 'bar', enrolled: false}]
I am happy to create the PR for this. Let me know.
+1 to this feature, typing on maps would be super useful
To add to this being able to alias to a non-nested field would be super useful it doesnt seem like its possible right now?
I have here an example "Giveaway" model that has a winners object with the current winner and past winners (if any). And would like to alias winners.current to "winner", not sure if that is possible:
const giveaway = new Entity({
table,
name: 'Giveaway',
attributes: {
id: { partitionKey: true, prefix: 'Giveaway#' },
sk: { sortKey: true, default: 'Giveaway#', hidden: true },
winner: { type: 'map', dependsOn: 'winners', default: (item) => item.winners.current, save: false },
winners: { type: 'map', default: { current: {}, pastWinners: [] } }
}
})
Whenever I parse an item the winners.current value is correct, however, the default function for winner never gets called so the "winner" object is not populated. I assume I could probably put save to true and it would work via duplicating the value but not ideal.