Skip to content

Commit d6400ff

Browse files
committed
📝 doc
Signed-off-by: moznion <moznion@mail.moznion.net>
1 parent db82b25 commit d6400ff

File tree

1 file changed

+126
-32
lines changed

1 file changed

+126
-32
lines changed

README.md

Lines changed: 126 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
# ts-dynamodb-attributes-transformer [![.github/workflows/check.yml](https://github.com/moznion/ts-dynamodb-attributes-transformer/actions/workflows/check.yml/badge.svg)](https://github.com/moznion/ts-dynamodb-attributes-transformer/actions/workflows/check.yml) [![npm version](https://badge.fury.io/js/@moznion%2Fts-dynamodb-attributes-transformer.svg)](https://badge.fury.io/js/@moznion%2Fts-dynamodb-attributes-transformer)
22

3-
Code transformer plugin powered by [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) that transforms TypeScript object to Amazon DynamoDB attributes.
3+
Code transformer plugin powered by [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) that transforms TypeScript object from/to Amazon DynamoDB attributes.
44

5-
## How it works
5+
## Description
66

7-
This plugin replaces the TypeScript function invocation of `dynamodbRecord<T>(obj: T)` with `Record<keyof T, AttributeValue>` value that is defined in aws-sdk-js-v3 according to the type `T` and the contents of the object. In short, this plugin generates the DynamoDB attribute code for every property of type `T`.
7+
This plugin replaces the TypeScript function invocation with the generated object code. In short, this plugin generates the code for every property of type `T`.
8+
9+
10+
### `dynamodbRecord<T>(obj: T): Record<keyof T, AttributeValue>`
11+
12+
This plugin replaces `dynamodbRecord<T>(obj: T)` invocation with `Record<keyof T, AttributeValue>` value that is defined in aws-sdk-js-v3 according to the type `T` and the contents of the object.
813

914
This plugin powers the users can do drop-in replacements for the existing `Record<keyof T, AttributeValue>` value and/or the generator with `dynamodbRecord<T>(obj: T)` function.
1015

11-
Manual making the translation layer between the object and DynamoDB's Record is no longer needed!
16+
### `fromDynamodbRecord<T>(attrs: Record<string, AttributeValue>): T`
17+
18+
This replaces `fromDynamodbRecord<T>(attrs: Record<string, AttributeValue>)` invocation with the object which has type `T`. This method is responsible to translate the DynamoDB attributes to the actual TypeScript object, i.e. unmarshalling.
1219

1320
## Motivations
1421

1522
- To do automatic generation of the [DynamoDB attribute data type](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html) code that is recognizable by [aws-sdk-js-v3](https://github.com/aws/aws-sdk-js-v3), with type safety.
23+
- Manual making the translation layer between the object and DynamoDB's Record is no longer needed!
1624
- Performance. This uses TypeScript Compiler API, so it generates/determine the DynamoDB attribute code at the compiling timing. This means the logic doesn't have to do a reflection on the fly so this contributes to a good performance.
1725

1826
### Benchmark
@@ -30,6 +38,8 @@ Please see also [benchmark](./examples/benchmark) project.
3038

3139
## Synopsis
3240

41+
### Marshalling into DynamoDB record from the Typescript Object
42+
3343
```ts
3444
import { AttributeValue } from '@aws-sdk/client-dynamodb';
3545
import { dynamodbRecord } from '@moznion/ts-dynamodb-attributes-transformer';
@@ -63,32 +73,32 @@ const record: Record<keyof User, AttributeValue> = dynamodbRecord<User>({
6373
Then this plugin transforms the above TypeScript code like the following JavaScript code:
6474

6575
```js
66-
const record = function (arg) {
67-
return {
68-
id: {
69-
N: arg.id.toString()
70-
},
71-
name: {
72-
S: arg.name
73-
},
74-
tags: {
75-
M: function () {
76-
var m;
77-
m = {}
78-
for (const kv of arg.tags) {
79-
m[kv[0]] = { S: kv[1] }
80-
}
81-
return m;
82-
}()
76+
const record = (function (arg) {
77+
return {
78+
id: {
79+
N: arg.id.toString()
80+
},
81+
name: {
82+
S: arg.name
83+
},
84+
tags: {
85+
M: (function () {
86+
var m;
87+
m = {}
88+
for (const kv of arg.tags) {
89+
m[kv[0]] = { S: kv[1] }
8390
}
84-
};
85-
}({
86-
id: 12345,
87-
name: 'John Doe',
88-
tags: new Map([
89-
['foo', 'bar'],
90-
['buz', 'qux'],
91-
]),
91+
return m;
92+
})()
93+
}
94+
};
95+
})({
96+
id: 12345,
97+
name: 'John Doe',
98+
tags: new Map([
99+
['foo', 'bar'],
100+
['buz', 'qux'],
101+
]),
92102
});
93103
/*
94104
* This record is equal to the following object:
@@ -106,14 +116,98 @@ const record = function (arg) {
106116
*/
107117
```
108118

119+
### Unmarshalling into TypeScript object from DynamoDB record
120+
121+
```ts
122+
import { fromDynamodbRecord } from '@moznion/ts-dynamodb-attributes-transformer';
123+
124+
interface User {
125+
readonly id?: number;
126+
readonly name?: string;
127+
readonly tags: Map<string, string>;
128+
}
129+
130+
const user: User = fromDynamodbRecord<User>({
131+
id: {
132+
N: '12345',
133+
},
134+
name: {
135+
S: 'John Doe',
136+
},
137+
tags: {
138+
M: {
139+
foo: {
140+
S: 'bar',
141+
},
142+
buz: {
143+
S: 'qux',
144+
},
145+
},
146+
},
147+
});
148+
```
149+
150+
Then this plugin transforms the above TypeScript code like the following JavaScript code:
151+
152+
```js
153+
const record = (function (arg) {
154+
return {
155+
id: (function () {
156+
const numStr = arg.id.N;
157+
return numStr === undefined ? undefined : Number(numStr);
158+
})(),
159+
name: arg.name.S,
160+
tags: (function () {
161+
var m, r;
162+
m = new Map();
163+
r = arg['tags']?.M;
164+
for (const k in r) {
165+
m.set(k, r[k]?.S);
166+
}
167+
return m;
168+
})(),
169+
};
170+
})({
171+
id: {
172+
N: '12345',
173+
},
174+
name: {
175+
S: 'John Doe',
176+
},
177+
tags: {
178+
M: {
179+
foo: {
180+
S: 'bar',
181+
},
182+
buz: {
183+
S: 'qux',
184+
},
185+
},
186+
},
187+
});
188+
189+
/*
190+
* This object is equal to the following:
191+
*
192+
* {
193+
* id: 12345,
194+
* name: "John Doe",
195+
* tags: {
196+
* foo: { S: "bar" },
197+
* buz: { S: "qux" },
198+
* }
199+
* }
200+
*/
201+
```
202+
109203
## How to use this transformer
110204
111-
This plugin exports a function that has the signature `dynamodbRecord<T extends object>(item: T): Record<keyof T, AttributeValue>`.
205+
This plugin exports the functions that have the signature `function dynamodbRecord<T extends object>(item: T, shouldLenientTypeCheck?: boolean): Record<keyof T, AttributeValue>` and `function fromDynamodbRecord<T extends object>(attrs: Record<string, AttributeValue>, shouldLenientTypeCheck?: boolean): T`.
112206

113-
This function is a marker to indicate to the transformer to replace this function invocation with the generated DynamoDB record code. Therefore, there are some restrictions:
207+
These functions are the markers to indicate to the transformer to replace the function invocation with the generated code. Therefore, there are some restrictions:
114208

115209
- Type parameter `T` is mandatory parameter (i.e. this mustn't be omitted). A transformer analyzes the type of the given `T` to collect the property information.
116-
- Type `T` must be class or interface.
210+
- Type `T` must be class or interface. If it needs to do unmarshalling, this type `T` must be a derived type of the **interface**.
117211

118212
### Examples
119213

0 commit comments

Comments
 (0)