@moicky/dynamodb 3.0.5 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -11,6 +11,7 @@ export declare class Transaction {
|
|
|
11
11
|
private updatedAt;
|
|
12
12
|
private operations;
|
|
13
13
|
private shouldSplitTransactions;
|
|
14
|
+
private hasBeenExecuted;
|
|
14
15
|
constructor({ tableName, createdAt, updatedAt, shouldSplitTransactions, }?: {
|
|
15
16
|
tableName?: string;
|
|
16
17
|
createdAt?: any;
|
|
@@ -19,8 +20,8 @@ export declare class Transaction {
|
|
|
19
20
|
});
|
|
20
21
|
private getItemKey;
|
|
21
22
|
create<T extends ItemWithKey>(item: WithoutReferences<T>, args?: CreateOperation["args"]): CreateOperations<T>;
|
|
22
|
-
update<T extends DynamoDBItemKey>(item: OnlyKey<T
|
|
23
|
-
delete(item: DynamoDBItemKey, args?: DeleteOperation["args"]):
|
|
23
|
+
update<T extends DynamoDBItemKey>(item: T extends any ? OnlyKey<T> : T, args?: UpdateOperation["args"]): UpdateOperations<T>;
|
|
24
|
+
delete(item: DynamoDBItemKey, args?: DeleteOperation["args"]): this;
|
|
24
25
|
addConditionFor<T extends DynamoDBItemKey>(item: T, args?: Partial<ConditionOperation["args"]>): ConditionOperations<T>;
|
|
25
26
|
private handleOperation;
|
|
26
27
|
execute(args?: Partial<Omit<TransactWriteItemsCommandInput, "TransactItems">>): Promise<Record<string, ResponseItem[]>>;
|
|
@@ -12,6 +12,7 @@ class Transaction {
|
|
|
12
12
|
updatedAt;
|
|
13
13
|
operations = {};
|
|
14
14
|
shouldSplitTransactions;
|
|
15
|
+
hasBeenExecuted = false;
|
|
15
16
|
constructor({ tableName, createdAt, updatedAt, shouldSplitTransactions, } = {}) {
|
|
16
17
|
this.tableName = tableName ?? (0, __1.getDefaultTable)();
|
|
17
18
|
this.createdAt = createdAt ?? (0, __1.getItemModificationTimestamp)("createdAt");
|
|
@@ -25,6 +26,9 @@ class Transaction {
|
|
|
25
26
|
return (0, __1.getItemKey)(item, { TableName: tableName || this.tableName });
|
|
26
27
|
}
|
|
27
28
|
create(item, args) {
|
|
29
|
+
if (this.hasBeenExecuted) {
|
|
30
|
+
throw new Error("[@moicky/dynamodb]: Transaction has already been executed");
|
|
31
|
+
}
|
|
28
32
|
const itemKey = this.getItemKey(item, args?.TableName);
|
|
29
33
|
const createOperation = {
|
|
30
34
|
_type: "create",
|
|
@@ -35,26 +39,41 @@ class Transaction {
|
|
|
35
39
|
return new operations_1.CreateOperations(createOperation, this);
|
|
36
40
|
}
|
|
37
41
|
update(item, args) {
|
|
42
|
+
if (this.hasBeenExecuted) {
|
|
43
|
+
throw new Error("[@moicky/dynamodb]: Transaction has already been executed");
|
|
44
|
+
}
|
|
38
45
|
const itemKey = this.getItemKey(item, args?.TableName);
|
|
46
|
+
const actions = [];
|
|
47
|
+
const existingOperation = this.operations[itemKey];
|
|
48
|
+
if (existingOperation && existingOperation._type === "update") {
|
|
49
|
+
actions.push(...existingOperation.actions);
|
|
50
|
+
}
|
|
39
51
|
const updateOperation = {
|
|
40
52
|
_type: "update",
|
|
41
53
|
item,
|
|
42
|
-
actions
|
|
54
|
+
actions,
|
|
43
55
|
args: { TableName: this.tableName, ...args },
|
|
44
56
|
};
|
|
45
57
|
this.operations[itemKey] = updateOperation;
|
|
46
58
|
return new operations_1.UpdateOperations(updateOperation, this);
|
|
47
59
|
}
|
|
48
60
|
delete(item, args) {
|
|
61
|
+
if (this.hasBeenExecuted) {
|
|
62
|
+
throw new Error("[@moicky/dynamodb]: Transaction has already been executed");
|
|
63
|
+
}
|
|
49
64
|
const itemKey = this.getItemKey(item, args?.TableName);
|
|
50
65
|
this.operations[itemKey] = {
|
|
51
66
|
_type: "delete",
|
|
52
67
|
item,
|
|
53
68
|
args: { TableName: this.tableName, ...args },
|
|
54
69
|
};
|
|
70
|
+
return this;
|
|
55
71
|
}
|
|
56
72
|
addConditionFor(item, args) {
|
|
57
|
-
|
|
73
|
+
if (this.hasBeenExecuted) {
|
|
74
|
+
throw new Error("[@moicky/dynamodb]: Transaction has already been executed");
|
|
75
|
+
}
|
|
76
|
+
return new operations_1.ConditionOperations(this, this.operations, item, {
|
|
58
77
|
TableName: this.tableName,
|
|
59
78
|
...args,
|
|
60
79
|
});
|
|
@@ -80,32 +99,49 @@ class Transaction {
|
|
|
80
99
|
};
|
|
81
100
|
const { ExpressionAttributeValues, ExpressionAttributeNames, ...otherArgs } = args;
|
|
82
101
|
const attr = new __1.ExpressionAttributes(ExpressionAttributeValues, ExpressionAttributeNames);
|
|
102
|
+
let hasSetUpdatedAt = false;
|
|
83
103
|
actions.forEach((action) => {
|
|
84
104
|
switch (action._type) {
|
|
85
105
|
case "set":
|
|
86
106
|
attr.appendBoth(action.values);
|
|
107
|
+
if ("updatedAt" in action.values) {
|
|
108
|
+
hasSetUpdatedAt = true;
|
|
109
|
+
}
|
|
87
110
|
expressions.set.push(Object.keys(action.values)
|
|
88
111
|
.map((key) => `${attr.getName(key)} = ${attr.getValue(key)}`)
|
|
89
112
|
.join(", "));
|
|
90
113
|
break;
|
|
91
114
|
case "remove":
|
|
92
115
|
attr.appendNames(action.attributes);
|
|
116
|
+
if (action.attributes.includes("updatedAt")) {
|
|
117
|
+
hasSetUpdatedAt = true;
|
|
118
|
+
}
|
|
93
119
|
expressions.remove.push(action.attributes.map((key) => attr.getName(key)).join(", "));
|
|
94
120
|
break;
|
|
95
121
|
case "add":
|
|
96
122
|
attr.appendBoth(action.values);
|
|
123
|
+
if ("updatedAt" in action.values) {
|
|
124
|
+
hasSetUpdatedAt = true;
|
|
125
|
+
}
|
|
97
126
|
expressions.add.push(Object.keys(action.values)
|
|
98
127
|
.map((key) => `${attr.getName(key)} ${attr.getValue(key)}`)
|
|
99
128
|
.join(", "));
|
|
100
129
|
break;
|
|
101
130
|
case "delete":
|
|
102
131
|
attr.appendBoth(action.values);
|
|
132
|
+
if ("updatedAt" in action.values) {
|
|
133
|
+
hasSetUpdatedAt = true;
|
|
134
|
+
}
|
|
103
135
|
expressions.delete.push(Object.keys(action.values)
|
|
104
136
|
.map((key) => `${attr.getName(key)} ${attr.getValue(key)}`)
|
|
105
137
|
.join(", "));
|
|
106
138
|
break;
|
|
107
139
|
}
|
|
108
140
|
});
|
|
141
|
+
if (!hasSetUpdatedAt) {
|
|
142
|
+
attr.appendBoth({ updatedAt: this.updatedAt });
|
|
143
|
+
expressions.set.push(`${attr.getName("updatedAt")} = ${attr.getValue("updatedAt")}`);
|
|
144
|
+
}
|
|
109
145
|
const joinedExpressions = Object.entries(expressions)
|
|
110
146
|
.filter(([, value]) => value?.length)
|
|
111
147
|
.reduce((acc, [t, v]) => [...acc, `${t.toUpperCase()} ${v.join(", ")}`], [])
|
|
@@ -132,6 +168,10 @@ class Transaction {
|
|
|
132
168
|
async execute(args) {
|
|
133
169
|
args = (0, __1.withDefaults)(args, "transactWriteItems");
|
|
134
170
|
return new Promise(async (resolve, reject) => {
|
|
171
|
+
if (this.hasBeenExecuted) {
|
|
172
|
+
reject(new Error("[@moicky/dynamodb]: Transaction has already been executed"));
|
|
173
|
+
}
|
|
174
|
+
this.hasBeenExecuted = true;
|
|
135
175
|
const operations = Object.values(this.operations);
|
|
136
176
|
if (operations.length === 0 ||
|
|
137
177
|
(operations.length > OPERATIONS_LIMIT &&
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TransactWriteItemsCommandInput } from "@aws-sdk/client-dynamodb";
|
|
1
2
|
import { Transaction } from ".";
|
|
2
3
|
import { DynamoDBItem } from "../types";
|
|
3
4
|
import { DynamoDBReference } from "./references/types";
|
|
@@ -7,6 +8,9 @@ export declare class CreateOperations<U extends ItemWithKey> {
|
|
|
7
8
|
private transaction;
|
|
8
9
|
constructor(operation: CreateOperation, transaction: Transaction);
|
|
9
10
|
setReferences(refs: SetReferencesParams<U>): void;
|
|
11
|
+
execute(args?: Partial<Omit<TransactWriteItemsCommandInput, "TransactItems">>): Promise<Record<string, (Pick<import("@aws-sdk/client-dynamodb").ItemCollectionMetrics, "SizeEstimateRangeGB"> & {
|
|
12
|
+
Key: Record<string, any>;
|
|
13
|
+
})[]>>;
|
|
10
14
|
}
|
|
11
15
|
export declare class UpdateOperations<U extends DynamoDBItem> {
|
|
12
16
|
private operation;
|
|
@@ -15,25 +19,32 @@ export declare class UpdateOperations<U extends DynamoDBItem> {
|
|
|
15
19
|
setReferences(refs: SetReferencesParams<U>): void;
|
|
16
20
|
set(values: WithoutKey<Partial<U>> & NestedParams): this;
|
|
17
21
|
adjustNumber(values: Prettify<StrictDeepNumberUpdates<U>>): this;
|
|
18
|
-
removeAttributes(...attributes: string
|
|
22
|
+
removeAttributes(...attributes: Array<Exclude<Extract<keyof U, string>, keyof DynamoDBItemKey> | `${string}.${string}` | `${string}.${string}.${string}`>): UpdateOperations<U>;
|
|
19
23
|
addItemsToSet(values: Prettify<DeepSetUpdates<U>>): this;
|
|
20
24
|
deleteItemsFromSet(values: Prettify<DeepSetUpdates<U>>): this;
|
|
21
25
|
onCondition({ expression, values, }: {
|
|
22
26
|
expression: string;
|
|
23
27
|
values: Partial<U> & Record<string, any>;
|
|
24
28
|
}): void;
|
|
29
|
+
execute(args?: Partial<Omit<TransactWriteItemsCommandInput, "TransactItems">>): Promise<Record<string, (Pick<import("@aws-sdk/client-dynamodb").ItemCollectionMetrics, "SizeEstimateRangeGB"> & {
|
|
30
|
+
Key: Record<string, any>;
|
|
31
|
+
})[]>>;
|
|
25
32
|
}
|
|
26
33
|
export declare class ConditionOperations<U extends DynamoDBItem> {
|
|
34
|
+
private transaction;
|
|
27
35
|
private operations;
|
|
28
36
|
private item;
|
|
29
37
|
private args;
|
|
30
|
-
constructor(operations: Transaction["operations"], item: DynamoDBItemKey, args: Partial<ConditionOperation["args"]> & {
|
|
38
|
+
constructor(transaction: Transaction, operations: Transaction["operations"], item: DynamoDBItemKey, args: Partial<ConditionOperation["args"]> & {
|
|
31
39
|
TableName: string;
|
|
32
40
|
});
|
|
33
41
|
matches({ expression, values, }: {
|
|
34
42
|
expression: string;
|
|
35
43
|
values: Partial<U> & Record<string, any>;
|
|
36
44
|
}): void;
|
|
45
|
+
execute(args?: Partial<Omit<TransactWriteItemsCommandInput, "TransactItems">>): Promise<Record<string, (Pick<import("@aws-sdk/client-dynamodb").ItemCollectionMetrics, "SizeEstimateRangeGB"> & {
|
|
46
|
+
Key: Record<string, any>;
|
|
47
|
+
})[]>>;
|
|
37
48
|
}
|
|
38
49
|
type SetReferencesParams<U extends DynamoDBItem> = TypedParams<U, DynamoDBReference, DynamoDBItemKey> & TypedParams<U, Set<DynamoDBReference>, DynamoDBItemKey[] | Set<DynamoDBItemKey>> & NestedParams<DynamoDBItemKey | DynamoDBItemKey[] | Set<DynamoDBItemKey>>;
|
|
39
50
|
export {};
|
|
@@ -19,7 +19,7 @@ class CreateOperations {
|
|
|
19
19
|
onAttribute: attributeName,
|
|
20
20
|
};
|
|
21
21
|
const refData = ref instanceof Set
|
|
22
|
-
?
|
|
22
|
+
? Array.from(ref).map((references) => (0, references_1.createReference)({ references, ...refArgs }, this.transaction))
|
|
23
23
|
: (0, references_1.createReference)({ references: ref, ...refArgs }, this.transaction);
|
|
24
24
|
const parts = attributeName.split(".");
|
|
25
25
|
parts.reduce((acc, part, index) => {
|
|
@@ -33,6 +33,9 @@ class CreateOperations {
|
|
|
33
33
|
}, this.operation.item);
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
|
+
execute(args) {
|
|
37
|
+
return this.transaction.execute(args);
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
exports.CreateOperations = CreateOperations;
|
|
38
41
|
class UpdateOperations {
|
|
@@ -54,7 +57,7 @@ class UpdateOperations {
|
|
|
54
57
|
_type: "set",
|
|
55
58
|
values: {
|
|
56
59
|
[attributeName]: ref instanceof Set
|
|
57
|
-
?
|
|
60
|
+
? Array.from(ref).map((references) => (0, references_1.createReference)({ references, ...refArgs }, this.transaction))
|
|
58
61
|
: (0, references_1.createReference)({ references: ref, ...refArgs }, this.transaction),
|
|
59
62
|
},
|
|
60
63
|
});
|
|
@@ -75,7 +78,10 @@ class UpdateOperations {
|
|
|
75
78
|
removeAttributes(...attributes) {
|
|
76
79
|
if (attributes.length === 0)
|
|
77
80
|
return this;
|
|
78
|
-
this.operation.actions.push({
|
|
81
|
+
this.operation.actions.push({
|
|
82
|
+
_type: "remove",
|
|
83
|
+
attributes: attributes.map(String),
|
|
84
|
+
});
|
|
79
85
|
return this;
|
|
80
86
|
}
|
|
81
87
|
addItemsToSet(values) {
|
|
@@ -109,13 +115,18 @@ class UpdateOperations {
|
|
|
109
115
|
}, {}),
|
|
110
116
|
};
|
|
111
117
|
}
|
|
118
|
+
execute(args) {
|
|
119
|
+
return this.transaction.execute(args);
|
|
120
|
+
}
|
|
112
121
|
}
|
|
113
122
|
exports.UpdateOperations = UpdateOperations;
|
|
114
123
|
class ConditionOperations {
|
|
124
|
+
transaction;
|
|
115
125
|
operations;
|
|
116
126
|
item;
|
|
117
127
|
args;
|
|
118
|
-
constructor(operations, item, args) {
|
|
128
|
+
constructor(transaction, operations, item, args) {
|
|
129
|
+
this.transaction = transaction;
|
|
119
130
|
this.operations = operations;
|
|
120
131
|
this.item = item;
|
|
121
132
|
this.args = args;
|
|
@@ -136,6 +147,9 @@ class ConditionOperations {
|
|
|
136
147
|
},
|
|
137
148
|
};
|
|
138
149
|
}
|
|
150
|
+
execute(args) {
|
|
151
|
+
return this.transaction.execute(args);
|
|
152
|
+
}
|
|
139
153
|
}
|
|
140
154
|
exports.ConditionOperations = ConditionOperations;
|
|
141
155
|
const arraysToSets = (values) => {
|
|
@@ -39,13 +39,15 @@ const getRefsToResolve = (item) => {
|
|
|
39
39
|
for (const value of Object.values(item)) {
|
|
40
40
|
if (typeof value === "object") {
|
|
41
41
|
if (value instanceof Set || Array.isArray(value)) {
|
|
42
|
-
refs.push(...
|
|
42
|
+
refs.push(...Array.from(value)
|
|
43
|
+
.map((v) => getRefsToResolve(v))
|
|
44
|
+
.flat());
|
|
43
45
|
}
|
|
44
46
|
else if (value?._type === "dynamodb:reference") {
|
|
45
47
|
refs.push(value?._target);
|
|
46
48
|
}
|
|
47
49
|
else {
|
|
48
|
-
refs.push(...getRefsToResolve(value));
|
|
50
|
+
refs.push(...getRefsToResolve(value).flat());
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
}
|
|
@@ -62,7 +64,7 @@ const injectRefs = (item, refs) => {
|
|
|
62
64
|
for (const [key, value] of Object.entries(item)) {
|
|
63
65
|
if (typeof value === "object") {
|
|
64
66
|
if (value instanceof Set || Array.isArray(value)) {
|
|
65
|
-
item[key] = new Set(
|
|
67
|
+
item[key] = new Set(Array.from(value).map((v) => injectRefs(v, refs)));
|
|
66
68
|
}
|
|
67
69
|
else if (value?._type === "dynamodb:reference") {
|
|
68
70
|
item[key] = refs[itemToStringKey(value._target)];
|