-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
…namodb (#19)
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +0,0 @@ | ||
export * from "./attribute-value"; | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { | ||
marshallOptions, | ||
unmarshallOptions, | ||
marshall as _marshall, | ||
unmarshall as _unmarshall, | ||
} from "@aws-sdk/util-dynamodb"; | ||
import { | ||
AttributeMap, | ||
B, | ||
L, | ||
M, | ||
N, | ||
NativeBinaryAttribute, | ||
S, | ||
ToAttributeMap, | ||
} from "./attribute-value"; | ||
|
||
export const marshall: < | ||
Item extends object, | ||
MarshallOptions extends marshallOptions | undefined | ||
>( | ||
item: Item, | ||
options?: MarshallOptions | ||
) => ToAttributeMap<Item> = _marshall; | ||
|
||
export const unmarshall: < | ||
Item extends AttributeMap, | ||
UnmarshallOptions extends unmarshallOptions | undefined | ||
>( | ||
item: Item, | ||
options?: UnmarshallOptions | ||
) => { | ||
[prop in keyof Item]: Unmarshall<Item[prop], UnmarshallOptions>; | ||
} = _unmarshall as any; | ||
|
||
export interface NumberValue<N extends number> { | ||
value: `${N}`; | ||
} | ||
|
||
export type Unmarshall< | ||
T, | ||
UnmarshallOptions extends unmarshallOptions | undefined | ||
> = T extends S<infer s> | ||
? s | ||
: T extends B | ||
? NativeBinaryAttribute | ||
: T extends N<infer n> | ||
? Exclude<UnmarshallOptions, undefined>["wrapNumbers"] extends true | ||
? NumberValue<n> | ||
: n | ||
: T extends Date | ||
? string | ||
: T extends L<infer Items> | ||
? { | ||
[i in keyof Items]: i extends "length" | ||
? Items[i] | ||
: Unmarshall<Items[i], UnmarshallOptions>; | ||
} | ||
: T extends M<infer Attributes> | ||
? { | ||
[prop in keyof Attributes]: Unmarshall< | ||
Attributes[prop], | ||
UnmarshallOptions | ||
>; | ||
} | ||
: never; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import "jest"; | ||
|
||
import { marshall, unmarshall } from "../src/marshall"; | ||
|
||
const myObject = { | ||
key: "key", | ||
sort: 123, | ||
binary: new Uint16Array([1]), | ||
buffer: Buffer.from("buffer", "utf8"), | ||
optional: 456, | ||
list: ["hello", "world"], | ||
record: { | ||
key: "nested key", | ||
sort: 789, | ||
}, | ||
} as const; | ||
|
||
test("should marshall MyItem to ToAttributeMap<MyItem>", () => { | ||
const marshalled = marshall(myObject); | ||
|
||
marshalled.key.S; | ||
marshalled.sort.N; | ||
marshalled.binary?.B; | ||
marshalled.buffer?.B; | ||
marshalled.optional?.N; | ||
marshalled.list?.L[0].S; | ||
marshalled.list?.L[1].S; | ||
// @ts-expect-error | ||
marshalled.list?.L[2]?.S; | ||
marshalled.record.M.key.S; | ||
marshalled.record.M.sort.N; | ||
}); | ||
|
||
test("should unmarshall MyItem from ToAttributeMap<MyItem>", () => { | ||
const marshalled = marshall(myObject); | ||
const unmarshalled = unmarshall(marshalled); | ||
|
||
expect(unmarshalled).toEqual(myObject); | ||
|
||
unmarshalled.key; | ||
unmarshalled.sort; | ||
unmarshalled.binary; | ||
unmarshalled.buffer; | ||
unmarshalled.optional.toString(10); // is a number | ||
unmarshalled.list?.[0]; | ||
unmarshalled.list?.[1]; | ||
// @ts-expect-error | ||
unmarshalled.list?.[2]; | ||
unmarshalled.record.key; | ||
unmarshalled.record.sort.toString(10); // is a number | ||
}); | ||
|
||
test("unmarshall should map numbers to string when wrapNumbers: true", () => { | ||
const marshalled = marshall(myObject); | ||
const unmarshalled = unmarshall(marshalled, { | ||
wrapNumbers: true, | ||
}); | ||
|
||
const expected: typeof unmarshalled = { | ||
...myObject, | ||
sort: { | ||
value: "123", | ||
}, | ||
optional: { | ||
value: "456", | ||
}, | ||
record: { | ||
key: "nested key", | ||
sort: { | ||
value: "789", | ||
}, | ||
}, | ||
}; | ||
expect(unmarshalled).toEqual(expected); | ||
|
||
unmarshalled.key; | ||
unmarshalled.sort.value; // wrapped NumberValue | ||
unmarshalled.binary; | ||
unmarshalled.buffer; | ||
unmarshalled.optional?.value; // wrapped NumberValue | ||
unmarshalled.list?.[0]; | ||
unmarshalled.list?.[1]; | ||
// @ts-expect-error | ||
unmarshalled.list?.[2]; | ||
unmarshalled.record.key; | ||
unmarshalled.record.sort; | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.