Skip to content

Commit f698f93

Browse files
author
sam
authored
fix: add specific commands for V3's DocumentClient (#36)
BREAKING CHANGE: JsonFormat removed from V3 command's type parameters
1 parent 726a67d commit f698f93

20 files changed

+379
-314
lines changed

README.md

+21-10
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Both the AWS SDK v2 and v3 provide a javascript-friendly interface called the `D
9898

9999
#### AWS SDK V2
100100

101-
For the SDK V2 client, cast it to `TypeSafeDynamoDBv2`.
101+
For the SDK V2 client, cast it to `TypeSafeDocumentClientV2`.
102102

103103
See: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html
104104

@@ -115,25 +115,28 @@ const table = new DynamoDB.DocumentClient() as TypeSafeDocumentClientV2<
115115

116116
#### AWS SDK V3
117117

118-
When defining your Command types, specify the `JsonFormat.Document` type parameter to adapt it to the `DocumentClient` interface.
118+
When defining your Command types, use the corresponding `TypeSafe*DocumentCommand` type, for example `TypeSafeGetDocumentCommand` instead of `TypeSafeGetItemCommand`:
119+
120+
- GetItem - `TypeSafeGetDocumentCommand`
121+
- PutItem - `TypeSafePutDocumentCommand`
122+
- DeleteItem - `TypeSafeDeleteDocumentCommand`
123+
- UpdateItem - `TypeSafeUpdateDocumentCommand`
124+
- Query - `TypeSafeQueryDocumentCommand`
125+
- Scan - `TypeSafeScanDocumentCommand`
119126

120127
See: https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_lib_dynamodb.html
121128

122129
```ts
123130
import { JsonFormat } from "typesafe-dynamodb";
124-
import { TypeSafeGetItemCommand } from "typesafe-dynamodb/lib/get-item-command";
125-
126-
const GetItemCommand = TypeSafeGetItemCommand<
127-
MyType,
128-
"key",
129-
"sort",
130-
JsonFormat.Document // specify the format as Document.
131-
>();
131+
import { TypeSafeGetDocumentCommand } from "typesafe-dynamodb/lib/get-document-command";
132+
133+
const MyGetItemCommand = TypeSafeGetDocumentCommand<MyType, "key", "sort">();
132134
```
133135

134136
For the SDK V3 client, cast it to `TypeSafeDynamoDBv3`.
135137

136138
```ts
139+
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
137140
import { DynamoDBDocumentClient, PutCommand } from "@aws-sdk/lib-dynamodb";
138141
import { TypeSafeDocumentClientV3 } from "typesafe-dynamodb/lib/document-client-v3";
139142

@@ -144,6 +147,14 @@ const docClient = DynamoDBDocumentClient.from(
144147
) as TypeSafeDocumentClientV3<MyType, "key", "sort">;
145148
```
146149

150+
And then call `.send` with an instance of your TypeSafe Command:
151+
152+
```ts
153+
docClient.send(new MyGetItemCommand({
154+
..
155+
}));
156+
```
157+
147158
## Features
148159

149160
### Type-aware Input and Output

src/delete-document-command.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { DeleteCommand as _DeleteCommand } from "@aws-sdk/lib-dynamodb";
2+
import type { DeleteCommand } from "./delete-item";
3+
import type { JsonFormat } from "./json-format";
4+
5+
export function TypeSafeDeleteDocumentCommand<
6+
Item extends object,
7+
PartitionKey extends keyof Item,
8+
RangeKey extends keyof Item | undefined
9+
>(): DeleteCommand<Item, PartitionKey, RangeKey, JsonFormat.Document> {
10+
return _DeleteCommand as any;
11+
}

src/delete-item-command.ts

+5-59
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,11 @@
1-
import {
2-
DynamoDBClientResolvedConfig,
3-
DeleteItemCommand as _DeleteItemCommand,
4-
ReturnValue as DynamoDBReturnValue,
5-
} from "@aws-sdk/client-dynamodb";
6-
import type { Command } from "@aws-sdk/smithy-client";
7-
import { DeleteItemInput, DeleteItemOutput } from "./delete-item";
8-
import { MetadataBearer } from "@aws-sdk/types";
9-
import { TableKey } from "./key";
10-
import { JsonFormat } from "./json-format";
11-
12-
export interface DeleteItemCommand<
13-
Item extends object,
14-
PartitionKey extends keyof Item,
15-
RangeKey extends keyof Item | undefined,
16-
Key extends TableKey<Item, PartitionKey, RangeKey, Format>,
17-
ConditionExpression extends string | undefined,
18-
ReturnValue extends DynamoDBReturnValue,
19-
Format extends JsonFormat
20-
> extends Command<
21-
DeleteItemInput<
22-
Item,
23-
PartitionKey,
24-
RangeKey,
25-
Key,
26-
ConditionExpression,
27-
ReturnValue,
28-
Format
29-
>,
30-
DeleteItemOutput<Item, ReturnValue, Format> & MetadataBearer,
31-
DynamoDBClientResolvedConfig
32-
> {
33-
_brand: "DeleteItemCommand";
34-
}
1+
import { DeleteItemCommand as _DeleteItemCommand } from "@aws-sdk/client-dynamodb";
2+
import type { DeleteCommand } from "./delete-item";
3+
import type { JsonFormat } from "./json-format";
354

365
export function TypeSafeDeleteItemCommand<
376
Item extends object,
387
PartitionKey extends keyof Item,
39-
RangeKey extends keyof Item | undefined,
40-
Format extends JsonFormat = JsonFormat.Default
41-
>(): new <
42-
Key extends TableKey<Item, PartitionKey, RangeKey, Format>,
43-
ConditionExpression extends string | undefined = undefined,
44-
ReturnValue extends DynamoDBReturnValue = "NONE"
45-
>(
46-
input: DeleteItemInput<
47-
Item,
48-
PartitionKey,
49-
RangeKey,
50-
Key,
51-
ConditionExpression,
52-
ReturnValue,
53-
Format
54-
>
55-
) => DeleteItemCommand<
56-
Item,
57-
PartitionKey,
58-
RangeKey,
59-
Key,
60-
ConditionExpression,
61-
ReturnValue,
62-
Format
63-
> {
8+
RangeKey extends keyof Item | undefined
9+
>(): DeleteCommand<Item, PartitionKey, RangeKey, JsonFormat.AttributeValue> {
6410
return _DeleteItemCommand as any;
6511
}

src/delete-item.ts

+44-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import type { DynamoDB } from "aws-sdk";
2-
import {
2+
import type {
33
ExpressionAttributeNames,
44
ExpressionAttributeValues,
55
} from "./expression-attributes";
6-
import { FormatObject, JsonFormat } from "./json-format";
7-
import { TableKey } from "./key";
6+
import type { FormatObject, JsonFormat } from "./json-format";
7+
import type { TableKey } from "./key";
8+
import type {
9+
DynamoDBClientResolvedConfig,
10+
ReturnValue as DynamoDBReturnValue,
11+
} from "@aws-sdk/client-dynamodb";
12+
import type { Command } from "@aws-sdk/smithy-client";
13+
import type { MetadataBearer } from "@aws-sdk/types";
814

915
export type DeleteItemInput<
1016
Item extends object,
@@ -43,3 +49,38 @@ export interface DeleteItemOutput<
4349
? Partial<FormatObject<Item, Format>>
4450
: Partial<FormatObject<Item, Format>>;
4551
}
52+
53+
export type DeleteCommand<
54+
Item extends object,
55+
PartitionKey extends keyof Item,
56+
RangeKey extends keyof Item | undefined,
57+
Format extends JsonFormat
58+
> = new <
59+
Key extends TableKey<Item, PartitionKey, RangeKey, Format>,
60+
ConditionExpression extends string | undefined = undefined,
61+
ReturnValue extends DynamoDBReturnValue = "NONE"
62+
>(
63+
input: DeleteItemInput<
64+
Item,
65+
PartitionKey,
66+
RangeKey,
67+
Key,
68+
ConditionExpression,
69+
ReturnValue,
70+
Format
71+
>
72+
) => Command<
73+
DeleteItemInput<
74+
Item,
75+
PartitionKey,
76+
RangeKey,
77+
Key,
78+
ConditionExpression,
79+
ReturnValue,
80+
Format
81+
>,
82+
DeleteItemOutput<Item, ReturnValue, Format> & MetadataBearer,
83+
DynamoDBClientResolvedConfig
84+
> & {
85+
_brand: "DeleteItemCommand";
86+
};

src/get-command.ts

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
DynamoDBClientResolvedConfig,
3+
GetItemCommand as _GetItemCommand,
4+
} from "@aws-sdk/client-dynamodb";
5+
import type { Command } from "@aws-sdk/smithy-client";
6+
import { TableKey } from "./key";
7+
import { GetItemInput, GetItemOutput } from "./get-item";
8+
import { MetadataBearer } from "@aws-sdk/types";
9+
import { JsonFormat } from "./json-format";
10+
11+
export type GetCommand<
12+
Item extends object,
13+
PartitionKey extends keyof Item,
14+
RangeKey extends keyof Item | undefined,
15+
Format extends JsonFormat
16+
> = new <
17+
Key extends TableKey<Item, PartitionKey, RangeKey, Format>,
18+
AttributesToGet extends keyof Item | undefined,
19+
ProjectionExpression extends string | undefined
20+
>(
21+
input: GetItemInput<
22+
Item,
23+
PartitionKey,
24+
RangeKey,
25+
Key,
26+
AttributesToGet,
27+
ProjectionExpression,
28+
Format
29+
>
30+
) => Command<
31+
GetItemInput<
32+
Item,
33+
PartitionKey,
34+
RangeKey,
35+
Key,
36+
AttributesToGet,
37+
ProjectionExpression,
38+
Format
39+
>,
40+
GetItemOutput<
41+
Item,
42+
PartitionKey,
43+
RangeKey,
44+
Key,
45+
AttributesToGet,
46+
ProjectionExpression,
47+
Format
48+
> &
49+
MetadataBearer,
50+
DynamoDBClientResolvedConfig
51+
> & {
52+
_brand: "GetItemCommand";
53+
};

src/get-document-command.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { GetCommand as _GetCommand } from "@aws-sdk/lib-dynamodb";
2+
import type { JsonFormat } from "./json-format";
3+
import type { GetCommand } from "./get-command";
4+
5+
export function TypeSafeGetDocumentCommand<
6+
Item extends object,
7+
PartitionKey extends keyof Item,
8+
RangeKey extends keyof Item | undefined
9+
>(): GetCommand<Item, PartitionKey, RangeKey, JsonFormat.Document> {
10+
return _GetCommand as any;
11+
}

src/get-item-command.ts

+6-68
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,11 @@
1-
import {
2-
DynamoDBClientResolvedConfig,
3-
GetItemCommand as _GetItemCommand,
4-
} from "@aws-sdk/client-dynamodb";
5-
import type { Command } from "@aws-sdk/smithy-client";
6-
import { TableKey } from "./key";
7-
import { GetItemInput, GetItemOutput } from "./get-item";
8-
import { MetadataBearer } from "@aws-sdk/types";
9-
import { JsonFormat } from "./json-format";
1+
import { GetCommand as _GetCommand } from "@aws-sdk/lib-dynamodb";
2+
import type { JsonFormat } from "./json-format";
3+
import type { GetCommand } from "./get-command";
104

115
export function TypeSafeGetItemCommand<
126
Item extends object,
137
PartitionKey extends keyof Item,
14-
RangeKey extends keyof Item | undefined,
15-
Format extends JsonFormat = JsonFormat.Default
16-
>(): new <
17-
Key extends TableKey<Item, PartitionKey, RangeKey, Format>,
18-
AttributesToGet extends keyof Item | undefined,
19-
ProjectionExpression extends string | undefined
20-
>(
21-
input: GetItemInput<
22-
Item,
23-
PartitionKey,
24-
RangeKey,
25-
Key,
26-
AttributesToGet,
27-
ProjectionExpression,
28-
Format
29-
>
30-
) => GetItemCommand<
31-
Item,
32-
PartitionKey,
33-
RangeKey,
34-
Key,
35-
AttributesToGet,
36-
ProjectionExpression,
37-
Format
38-
> {
39-
return _GetItemCommand as any;
40-
}
41-
42-
interface GetItemCommand<
43-
Item extends object,
44-
PartitionKey extends keyof Item,
45-
RangeKey extends keyof Item | undefined,
46-
Key extends TableKey<Item, PartitionKey, RangeKey, Format>,
47-
AttributesToGet extends keyof Item | undefined,
48-
ProjectionExpression extends string | undefined,
49-
Format extends JsonFormat
50-
> extends Command<
51-
GetItemInput<
52-
Item,
53-
PartitionKey,
54-
RangeKey,
55-
Key,
56-
AttributesToGet,
57-
ProjectionExpression,
58-
Format
59-
>,
60-
GetItemOutput<
61-
Item,
62-
PartitionKey,
63-
RangeKey,
64-
Key,
65-
AttributesToGet,
66-
ProjectionExpression,
67-
Format
68-
> &
69-
MetadataBearer,
70-
DynamoDBClientResolvedConfig
71-
> {
72-
_brand: "GetItemCommand";
8+
RangeKey extends keyof Item | undefined
9+
>(): GetCommand<Item, PartitionKey, RangeKey, JsonFormat.AttributeValue> {
10+
return _GetCommand as any;
7311
}

src/put-document-command.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { PutCommand as _PutCommand } from "@aws-sdk/lib-dynamodb";
2+
import type { JsonFormat } from "./json-format";
3+
import type { PutCommand } from "./put-item";
4+
5+
export function TypeSafePutDocumentCommand<Item extends object>(): PutCommand<
6+
Item,
7+
JsonFormat.Document
8+
> {
9+
return _PutCommand as any;
10+
}

0 commit comments

Comments
 (0)