Open djorg83 opened 5 years ago
First I tried extending the @attribute
annotation to always pass in the unwrapNumbers: true
option. But this doesn't work because these options are not passed into the marshaller.
export function unwrappedAttribute(parameters?: Partial<SchemaType>): PropertyAnnotation {
return attribute(Object.assign({ unwrapNumbers: true }, parameters || {}));
}
Then I tried making my own @number
annotation which has a type of Custom
and it's own marshall
and unmarshall
functions. But this only works for top level attributes. The auto-marshaller handles any attributes that are nested documents, and doesn't use the provided marshall
and unmarshall
options even if the nested attributes are annotated with these options.
export function number(parameters?: Partial<SchemaType>): PropertyAnnotation {
const marshall = (input: any): AttributeValue => {
return { N: input };
};
const unmarshall = (item: AttributeValue): number => {
if (typeof item.N === 'number') {
return Number(item.N);
}
return null;
};
return attribute(
Object.assign({ type: 'Custom', marshall, unmarshall }, parameters || {})
);
}
The only way I've been able to work around this problem is by passing objects returned from the data mapper through my own unwrapNumbers
function.
export function unwrapNumbers(value: any): any {
if (value == null || value instanceof Date) {
return value;
}
if (NumberValue.isNumberValue(value)) {
return value.valueOf();
}
if (Array.isArray(value)) {
return value.map((i) => unwrapNumbers(i));
}
if (typeof value === 'object') {
return Object.keys(value).reduce((map, key) => {
return Object.assign(map, { [key]: unwrapNumbers(value[key]) });
}, {});
}
return value;
}
// find one
const car: Car = await mapper.get(item).then(unwrapNumbers);
// find all
const cars = [];
for await (const item of mapper.scan(Car)) {
cars.push(unwrapNumbers(item));
}
unwrapNumbers: true
.It looks like this repo is in fact dead. The primary contributor no longer works for Amazon. His linkedin profile shows that he switched jobs in July, which is also the time of the last commit to this repository. I'm going to see if I can find out if anyone else at Amazon plans to pick this up.
Ugh, can this please get merged!?
Thank you @djorg83 ! I had to improve your script, the reduce method was killing my instances.
export function unwrapNumbers(value: any): any {
if (value == null || value instanceof Date) {
return value;
}
if (NumberValue.isNumberValue(value)) {
return value.valueOf();
}
if (Array.isArray(value)) {
return value.map((i) => unwrapNumbers(i));
}
if (typeof value === 'object') {
for (const key in value) {
if (value.hasOwnProperty(key)) {
value[key] = unwrapNumbers(value[key]);
}
}
}
return value;
}
We have been using this ODM in production, but seeing it wasn't supported anymore we decided to fork this package and our fork is called nova-odm.
What we have done so far:
The overall goal is to keep it interface-compatible with this project (since we generally like this API), but keep it up-to-date and supported. The switch is rather easy due to interface compatibility, you just need to replace depencendies and imports like this:
@aws/dynamodb-data-mapper -> @nova-odm/mapper
@aws/dynamodb-data-mapper-annotations -> @nova-odm/annotations
@aws/dynamodb-expressions -> @nova-odm/expressions
Feel free to raise issues and send us PRs.
If I pass the option of
{ unwrapNumbers: true }
it is not sent to the auto-marshaller when unmarshalling an item.Is this project dead? This commit was made over a year ago and has not been released yet. The current version 0.7.3 does not pass in the marshaller options like the documentation suggests.
From Docs
What I'm trying to do
According to the docs, the above should unwrap numbers into primitives and not a NumberValue. But I've confirmed via debugging that the unwrapNumbers option is not being sent because release 0.7.3 is missing this commit.