@model-ts/dynamodb 4.0.0 → 4.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.
- package/CHANGELOG.md +6 -0
- package/dist/cjs/__test__/rollback.test.d.ts +1 -0
- package/dist/cjs/__test__/rollback.test.js +196 -0
- package/dist/cjs/__test__/rollback.test.js.map +1 -0
- package/dist/cjs/sandbox.d.ts +2 -0
- package/dist/cjs/sandbox.js +128 -1
- package/dist/cjs/sandbox.js.map +1 -1
- package/dist/esm/__test__/rollback.test.d.ts +1 -0
- package/dist/esm/__test__/rollback.test.js +194 -0
- package/dist/esm/__test__/rollback.test.js.map +1 -0
- package/dist/esm/sandbox.d.ts +2 -0
- package/dist/esm/sandbox.js +128 -1
- package/dist/esm/sandbox.js.map +1 -1
- package/package.json +1 -1
- package/src/__test__/rollback.test.ts +279 -0
- package/src/sandbox.ts +171 -1
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const t = tslib_1.__importStar(require("io-ts"));
|
|
5
|
+
const core_1 = require("@model-ts/core");
|
|
6
|
+
const sandbox_1 = require("../sandbox");
|
|
7
|
+
const client_1 = require("../client");
|
|
8
|
+
const provider_1 = require("../provider");
|
|
9
|
+
const client = new client_1.Client({ tableName: "table" });
|
|
10
|
+
const provider = provider_1.getProvider(client);
|
|
11
|
+
const SIMPLE_CODEC = t.type({
|
|
12
|
+
foo: t.string,
|
|
13
|
+
bar: t.number,
|
|
14
|
+
});
|
|
15
|
+
class Simple extends core_1.model("Simple", SIMPLE_CODEC, provider) {
|
|
16
|
+
get PK() {
|
|
17
|
+
return `PK#${this.foo}`;
|
|
18
|
+
}
|
|
19
|
+
get SK() {
|
|
20
|
+
return `SK#${this.bar}`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
describe("rollback", () => {
|
|
24
|
+
let sandbox;
|
|
25
|
+
beforeAll(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
sandbox = yield sandbox_1.createSandbox(client);
|
|
27
|
+
yield sandbox.seed(new Simple({ foo: "seeded1", bar: 1 }), new Simple({ foo: "seeded2", bar: 2 }));
|
|
28
|
+
}));
|
|
29
|
+
afterAll(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
yield sandbox.destroy();
|
|
31
|
+
}));
|
|
32
|
+
test("rolls back newly added items", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
sandbox.startTracking();
|
|
34
|
+
yield new Simple({ foo: "new-item", bar: 99 }).put();
|
|
35
|
+
expect(yield sandbox.get("PK#new-item", "SK#99")).not.toBeNull();
|
|
36
|
+
yield sandbox.rollback();
|
|
37
|
+
expect(yield sandbox.get("PK#new-item", "SK#99")).toBeNull();
|
|
38
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).not.toBeNull();
|
|
39
|
+
expect(yield sandbox.get("PK#seeded2", "SK#2")).not.toBeNull();
|
|
40
|
+
}));
|
|
41
|
+
test("rolls back updated items", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
+
sandbox.startTracking();
|
|
43
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "modified" });
|
|
44
|
+
const modified = yield sandbox.get("PK#seeded1", "SK#1");
|
|
45
|
+
expect(modified.foo).toBe("modified");
|
|
46
|
+
yield sandbox.rollback();
|
|
47
|
+
const restored = yield sandbox.get("PK#seeded1", "SK#1");
|
|
48
|
+
expect(restored.foo).toBe("seeded1");
|
|
49
|
+
}));
|
|
50
|
+
test("rolls back deleted items", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
+
sandbox.startTracking();
|
|
52
|
+
yield Simple.delete({ PK: "PK#seeded1", SK: "SK#1" });
|
|
53
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).toBeNull();
|
|
54
|
+
yield sandbox.rollback();
|
|
55
|
+
const restored = yield sandbox.get("PK#seeded1", "SK#1");
|
|
56
|
+
expect(restored).not.toBeNull();
|
|
57
|
+
expect(restored.foo).toBe("seeded1");
|
|
58
|
+
}));
|
|
59
|
+
test("rolls back soft-deleted items", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
+
sandbox.startTracking();
|
|
61
|
+
const item = new Simple({ foo: "seeded1", bar: 1 });
|
|
62
|
+
// @ts-ignore - _docVersion needed for softDelete encoding
|
|
63
|
+
item._docVersion = 0;
|
|
64
|
+
yield client.softDelete(item);
|
|
65
|
+
// Original should be gone, deleted version should exist
|
|
66
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).toBeNull();
|
|
67
|
+
expect(yield sandbox.get("$$DELETED$$PK#seeded1", "$$DELETED$$SK#1")).not.toBeNull();
|
|
68
|
+
yield sandbox.rollback();
|
|
69
|
+
// Original should be restored, deleted version should be gone
|
|
70
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).not.toBeNull();
|
|
71
|
+
expect(yield sandbox.get("$$DELETED$$PK#seeded1", "$$DELETED$$SK#1")).toBeNull();
|
|
72
|
+
}));
|
|
73
|
+
test("rolls back mixed operations", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
sandbox.startTracking();
|
|
75
|
+
// Add a new item
|
|
76
|
+
yield new Simple({ foo: "brand-new", bar: 50 }).put();
|
|
77
|
+
// Update an existing item
|
|
78
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "changed" });
|
|
79
|
+
// Delete an existing item
|
|
80
|
+
yield Simple.delete({ PK: "PK#seeded2", SK: "SK#2" });
|
|
81
|
+
// Verify all changes took effect
|
|
82
|
+
expect(yield sandbox.get("PK#brand-new", "SK#50")).not.toBeNull();
|
|
83
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("changed");
|
|
84
|
+
expect(yield sandbox.get("PK#seeded2", "SK#2")).toBeNull();
|
|
85
|
+
yield sandbox.rollback();
|
|
86
|
+
// New item should be gone
|
|
87
|
+
expect(yield sandbox.get("PK#brand-new", "SK#50")).toBeNull();
|
|
88
|
+
// Updated item should be restored
|
|
89
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1");
|
|
90
|
+
// Deleted item should be back
|
|
91
|
+
expect(yield sandbox.get("PK#seeded2", "SK#2")).not.toBeNull();
|
|
92
|
+
}));
|
|
93
|
+
test("supports multiple tracking/rollback cycles", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
94
|
+
// Cycle 1
|
|
95
|
+
sandbox.startTracking();
|
|
96
|
+
yield new Simple({ foo: "cycle1", bar: 10 }).put();
|
|
97
|
+
yield sandbox.rollback();
|
|
98
|
+
expect(yield sandbox.get("PK#cycle1", "SK#10")).toBeNull();
|
|
99
|
+
// Cycle 2
|
|
100
|
+
sandbox.startTracking();
|
|
101
|
+
yield new Simple({ foo: "cycle2", bar: 20 }).put();
|
|
102
|
+
yield sandbox.rollback();
|
|
103
|
+
expect(yield sandbox.get("PK#cycle2", "SK#20")).toBeNull();
|
|
104
|
+
// Cycle 3 - modify seeded data
|
|
105
|
+
sandbox.startTracking();
|
|
106
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "cycle3-mod" });
|
|
107
|
+
yield sandbox.rollback();
|
|
108
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1");
|
|
109
|
+
// Seeded data is intact throughout
|
|
110
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).not.toBeNull();
|
|
111
|
+
expect(yield sandbox.get("PK#seeded2", "SK#2")).not.toBeNull();
|
|
112
|
+
}));
|
|
113
|
+
test("does not track writes before startTracking", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
114
|
+
// Write without tracking
|
|
115
|
+
yield new Simple({ foo: "untracked", bar: 77 }).put();
|
|
116
|
+
// Now start tracking and immediately rollback
|
|
117
|
+
sandbox.startTracking();
|
|
118
|
+
yield sandbox.rollback();
|
|
119
|
+
// The untracked write should still be there
|
|
120
|
+
expect(yield sandbox.get("PK#untracked", "SK#77")).not.toBeNull();
|
|
121
|
+
// Clean up manually for subsequent tests
|
|
122
|
+
sandbox.startTracking();
|
|
123
|
+
yield Simple.delete({ PK: "PK#untracked", SK: "SK#77" });
|
|
124
|
+
yield sandbox.rollback();
|
|
125
|
+
}));
|
|
126
|
+
test("tracks the same key modified multiple times", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
127
|
+
sandbox.startTracking();
|
|
128
|
+
// Update the same item twice
|
|
129
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "first-update" });
|
|
130
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "second-update" });
|
|
131
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("second-update");
|
|
132
|
+
yield sandbox.rollback();
|
|
133
|
+
// Should restore to original, not to the intermediate state
|
|
134
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1");
|
|
135
|
+
}));
|
|
136
|
+
});
|
|
137
|
+
describe("rollback with beforeEach/afterEach pattern", () => {
|
|
138
|
+
let sandbox;
|
|
139
|
+
beforeAll(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
140
|
+
sandbox = yield sandbox_1.createSandbox(client);
|
|
141
|
+
yield sandbox.seed(new Simple({ foo: "a", bar: 1 }), new Simple({ foo: "b", bar: 2 }));
|
|
142
|
+
}));
|
|
143
|
+
beforeEach(() => {
|
|
144
|
+
sandbox.startTracking();
|
|
145
|
+
});
|
|
146
|
+
afterEach(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
147
|
+
yield sandbox.rollback();
|
|
148
|
+
}));
|
|
149
|
+
afterAll(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
150
|
+
yield sandbox.destroy();
|
|
151
|
+
}));
|
|
152
|
+
test("test A: add an item", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
153
|
+
yield new Simple({ foo: "from-test-a", bar: 100 }).put();
|
|
154
|
+
expect(yield sandbox.get("PK#from-test-a", "SK#100")).not.toBeNull();
|
|
155
|
+
}));
|
|
156
|
+
test("test B: item from test A does not exist", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
157
|
+
expect(yield sandbox.get("PK#from-test-a", "SK#100")).toBeNull();
|
|
158
|
+
}));
|
|
159
|
+
test("test C: modify seeded data", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
+
yield Simple.updateRaw({ PK: "PK#a", SK: "SK#1" }, { foo: "modified-a" });
|
|
161
|
+
expect((yield sandbox.get("PK#a", "SK#1")).foo).toBe("modified-a");
|
|
162
|
+
}));
|
|
163
|
+
test("test D: seeded data is back to original", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
164
|
+
expect((yield sandbox.get("PK#a", "SK#1")).foo).toBe("a");
|
|
165
|
+
}));
|
|
166
|
+
test("test E: delete seeded data", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
167
|
+
yield Simple.delete({ PK: "PK#b", SK: "SK#2" });
|
|
168
|
+
expect(yield sandbox.get("PK#b", "SK#2")).toBeNull();
|
|
169
|
+
}));
|
|
170
|
+
test("test F: deleted seeded data is back", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
171
|
+
expect(yield sandbox.get("PK#b", "SK#2")).not.toBeNull();
|
|
172
|
+
expect((yield sandbox.get("PK#b", "SK#2")).foo).toBe("b");
|
|
173
|
+
}));
|
|
174
|
+
});
|
|
175
|
+
describe("existing sandbox semantics still work", () => {
|
|
176
|
+
let sandbox;
|
|
177
|
+
beforeEach(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
178
|
+
sandbox = yield sandbox_1.createSandbox(client);
|
|
179
|
+
}));
|
|
180
|
+
afterEach(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
181
|
+
yield sandbox.destroy();
|
|
182
|
+
}));
|
|
183
|
+
test("create and destroy per test still works", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
184
|
+
yield sandbox.seed(new Simple({ foo: "per-test", bar: 1 }));
|
|
185
|
+
const item = yield sandbox.get("PK#per-test", "SK#1");
|
|
186
|
+
expect(item).not.toBeNull();
|
|
187
|
+
expect(item.foo).toBe("per-test");
|
|
188
|
+
}));
|
|
189
|
+
test("snapshot and diff still work", () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
190
|
+
const before = yield sandbox.snapshot();
|
|
191
|
+
yield new Simple({ foo: "diffed", bar: 1 }).put();
|
|
192
|
+
const diffResult = yield sandbox.diff(before);
|
|
193
|
+
expect(diffResult).toContain("PK#diffed");
|
|
194
|
+
}));
|
|
195
|
+
});
|
|
196
|
+
//# sourceMappingURL=rollback.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.test.js","sourceRoot":"","sources":["../../../src/__test__/rollback.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/sandbox.d.ts
CHANGED
package/dist/cjs/sandbox.js
CHANGED
|
@@ -97,9 +97,134 @@ const getTableContents = (tableName) => tslib_1.__awaiter(void 0, void 0, void 0
|
|
|
97
97
|
return acc;
|
|
98
98
|
});
|
|
99
99
|
exports.getTableContents = getTableContents;
|
|
100
|
+
const WRITE_METHODS = new Set([
|
|
101
|
+
"put",
|
|
102
|
+
"update",
|
|
103
|
+
"delete",
|
|
104
|
+
"batchWrite",
|
|
105
|
+
"transactWrite",
|
|
106
|
+
]);
|
|
107
|
+
function createTrackedDocClient(original, tableName) {
|
|
108
|
+
let isTracking = false;
|
|
109
|
+
const trackedKeys = new Map();
|
|
110
|
+
const captureKey = (pk, sk) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
const compositeKey = `${pk}__${sk}`;
|
|
112
|
+
if (trackedKeys.has(compositeKey))
|
|
113
|
+
return;
|
|
114
|
+
const { Item } = yield original
|
|
115
|
+
.get({ TableName: tableName, Key: { PK: pk, SK: sk } })
|
|
116
|
+
.promise();
|
|
117
|
+
trackedKeys.set(compositeKey, { pk, sk, original: Item !== null && Item !== void 0 ? Item : null });
|
|
118
|
+
});
|
|
119
|
+
const captureKeysForOperation = (method, params) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
var _a;
|
|
121
|
+
switch (method) {
|
|
122
|
+
case "put":
|
|
123
|
+
if (params.TableName === tableName && params.Item) {
|
|
124
|
+
yield captureKey(params.Item.PK, params.Item.SK);
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
case "update":
|
|
128
|
+
case "delete":
|
|
129
|
+
if (params.TableName === tableName && params.Key) {
|
|
130
|
+
yield captureKey(params.Key.PK, params.Key.SK);
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
case "batchWrite": {
|
|
134
|
+
const tableItems = ((_a = params.RequestItems) === null || _a === void 0 ? void 0 : _a[tableName]) || [];
|
|
135
|
+
yield Promise.all(tableItems.map((item) => {
|
|
136
|
+
if (item.PutRequest) {
|
|
137
|
+
return captureKey(item.PutRequest.Item.PK, item.PutRequest.Item.SK);
|
|
138
|
+
}
|
|
139
|
+
if (item.DeleteRequest) {
|
|
140
|
+
return captureKey(item.DeleteRequest.Key.PK, item.DeleteRequest.Key.SK);
|
|
141
|
+
}
|
|
142
|
+
}));
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
case "transactWrite": {
|
|
146
|
+
const transactItems = params.TransactItems || [];
|
|
147
|
+
yield Promise.all(transactItems
|
|
148
|
+
.map((item) => {
|
|
149
|
+
var _a, _b, _c;
|
|
150
|
+
if (((_a = item.Put) === null || _a === void 0 ? void 0 : _a.TableName) === tableName) {
|
|
151
|
+
return captureKey(item.Put.Item.PK, item.Put.Item.SK);
|
|
152
|
+
}
|
|
153
|
+
if (((_b = item.Update) === null || _b === void 0 ? void 0 : _b.TableName) === tableName) {
|
|
154
|
+
return captureKey(item.Update.Key.PK, item.Update.Key.SK);
|
|
155
|
+
}
|
|
156
|
+
if (((_c = item.Delete) === null || _c === void 0 ? void 0 : _c.TableName) === tableName) {
|
|
157
|
+
return captureKey(item.Delete.Key.PK, item.Delete.Key.SK);
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
.filter(Boolean));
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
const proxy = new Proxy(original, {
|
|
166
|
+
get(target, prop) {
|
|
167
|
+
const value = target[prop];
|
|
168
|
+
if (value === undefined)
|
|
169
|
+
return undefined;
|
|
170
|
+
if (typeof value === "function") {
|
|
171
|
+
if (isTracking && WRITE_METHODS.has(prop)) {
|
|
172
|
+
return (params) => {
|
|
173
|
+
const request = value.call(target, params);
|
|
174
|
+
const origPromise = request.promise.bind(request);
|
|
175
|
+
request.promise = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
176
|
+
yield captureKeysForOperation(prop, params);
|
|
177
|
+
return origPromise();
|
|
178
|
+
});
|
|
179
|
+
return request;
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return value.bind(target);
|
|
183
|
+
}
|
|
184
|
+
return value;
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
return {
|
|
188
|
+
proxy: proxy,
|
|
189
|
+
startTracking: () => {
|
|
190
|
+
isTracking = true;
|
|
191
|
+
trackedKeys.clear();
|
|
192
|
+
},
|
|
193
|
+
rollback: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
194
|
+
isTracking = false;
|
|
195
|
+
const entries = Array.from(trackedKeys.values());
|
|
196
|
+
const toDelete = entries.filter((e) => e.original === null);
|
|
197
|
+
const toRestore = entries.filter((e) => e.original !== null);
|
|
198
|
+
const deleteChunks = Array_1.chunksOf(25)(toDelete);
|
|
199
|
+
const restoreChunks = Array_1.chunksOf(25)(toRestore);
|
|
200
|
+
yield Promise.all([
|
|
201
|
+
...deleteChunks.map((chunk) => original
|
|
202
|
+
.batchWrite({
|
|
203
|
+
RequestItems: {
|
|
204
|
+
[tableName]: chunk.map(({ pk, sk }) => ({
|
|
205
|
+
DeleteRequest: { Key: { PK: pk, SK: sk } },
|
|
206
|
+
})),
|
|
207
|
+
},
|
|
208
|
+
})
|
|
209
|
+
.promise()),
|
|
210
|
+
...restoreChunks.map((chunk) => original
|
|
211
|
+
.batchWrite({
|
|
212
|
+
RequestItems: {
|
|
213
|
+
[tableName]: chunk.map(({ original: item }) => ({
|
|
214
|
+
PutRequest: { Item: item },
|
|
215
|
+
})),
|
|
216
|
+
},
|
|
217
|
+
})
|
|
218
|
+
.promise()),
|
|
219
|
+
]);
|
|
220
|
+
trackedKeys.clear();
|
|
221
|
+
}),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
100
224
|
const createSandbox = (client) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
101
225
|
const tableName = yield exports.createTable();
|
|
102
|
-
|
|
226
|
+
const tracked = createTrackedDocClient(docClient, tableName);
|
|
227
|
+
client.setDocumentClient(tracked.proxy);
|
|
103
228
|
client.setTableName(tableName);
|
|
104
229
|
return {
|
|
105
230
|
destroy: () => exports.destroyTable(tableName),
|
|
@@ -132,6 +257,8 @@ const createSandbox = (client) => tslib_1.__awaiter(void 0, void 0, void 0, func
|
|
|
132
257
|
const snapshot = yield exports.getTableContents(tableName);
|
|
133
258
|
return diff_1.formatSnapshotDiff(before, snapshot);
|
|
134
259
|
}),
|
|
260
|
+
startTracking: tracked.startTracking,
|
|
261
|
+
rollback: tracked.rollback,
|
|
135
262
|
};
|
|
136
263
|
});
|
|
137
264
|
exports.createSandbox = createSandbox;
|
package/dist/cjs/sandbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/sandbox.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import * as t from "io-ts";
|
|
3
|
+
import { model } from "@model-ts/core";
|
|
4
|
+
import { createSandbox } from "../sandbox";
|
|
5
|
+
import { Client } from "../client";
|
|
6
|
+
import { getProvider } from "../provider";
|
|
7
|
+
const client = new Client({ tableName: "table" });
|
|
8
|
+
const provider = getProvider(client);
|
|
9
|
+
const SIMPLE_CODEC = t.type({
|
|
10
|
+
foo: t.string,
|
|
11
|
+
bar: t.number,
|
|
12
|
+
});
|
|
13
|
+
class Simple extends model("Simple", SIMPLE_CODEC, provider) {
|
|
14
|
+
get PK() {
|
|
15
|
+
return `PK#${this.foo}`;
|
|
16
|
+
}
|
|
17
|
+
get SK() {
|
|
18
|
+
return `SK#${this.bar}`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
describe("rollback", () => {
|
|
22
|
+
let sandbox;
|
|
23
|
+
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
+
sandbox = yield createSandbox(client);
|
|
25
|
+
yield sandbox.seed(new Simple({ foo: "seeded1", bar: 1 }), new Simple({ foo: "seeded2", bar: 2 }));
|
|
26
|
+
}));
|
|
27
|
+
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
+
yield sandbox.destroy();
|
|
29
|
+
}));
|
|
30
|
+
test("rolls back newly added items", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
+
sandbox.startTracking();
|
|
32
|
+
yield new Simple({ foo: "new-item", bar: 99 }).put();
|
|
33
|
+
expect(yield sandbox.get("PK#new-item", "SK#99")).not.toBeNull();
|
|
34
|
+
yield sandbox.rollback();
|
|
35
|
+
expect(yield sandbox.get("PK#new-item", "SK#99")).toBeNull();
|
|
36
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).not.toBeNull();
|
|
37
|
+
expect(yield sandbox.get("PK#seeded2", "SK#2")).not.toBeNull();
|
|
38
|
+
}));
|
|
39
|
+
test("rolls back updated items", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
+
sandbox.startTracking();
|
|
41
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "modified" });
|
|
42
|
+
const modified = yield sandbox.get("PK#seeded1", "SK#1");
|
|
43
|
+
expect(modified.foo).toBe("modified");
|
|
44
|
+
yield sandbox.rollback();
|
|
45
|
+
const restored = yield sandbox.get("PK#seeded1", "SK#1");
|
|
46
|
+
expect(restored.foo).toBe("seeded1");
|
|
47
|
+
}));
|
|
48
|
+
test("rolls back deleted items", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
sandbox.startTracking();
|
|
50
|
+
yield Simple.delete({ PK: "PK#seeded1", SK: "SK#1" });
|
|
51
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).toBeNull();
|
|
52
|
+
yield sandbox.rollback();
|
|
53
|
+
const restored = yield sandbox.get("PK#seeded1", "SK#1");
|
|
54
|
+
expect(restored).not.toBeNull();
|
|
55
|
+
expect(restored.foo).toBe("seeded1");
|
|
56
|
+
}));
|
|
57
|
+
test("rolls back soft-deleted items", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
58
|
+
sandbox.startTracking();
|
|
59
|
+
const item = new Simple({ foo: "seeded1", bar: 1 });
|
|
60
|
+
// @ts-ignore - _docVersion needed for softDelete encoding
|
|
61
|
+
item._docVersion = 0;
|
|
62
|
+
yield client.softDelete(item);
|
|
63
|
+
// Original should be gone, deleted version should exist
|
|
64
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).toBeNull();
|
|
65
|
+
expect(yield sandbox.get("$$DELETED$$PK#seeded1", "$$DELETED$$SK#1")).not.toBeNull();
|
|
66
|
+
yield sandbox.rollback();
|
|
67
|
+
// Original should be restored, deleted version should be gone
|
|
68
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).not.toBeNull();
|
|
69
|
+
expect(yield sandbox.get("$$DELETED$$PK#seeded1", "$$DELETED$$SK#1")).toBeNull();
|
|
70
|
+
}));
|
|
71
|
+
test("rolls back mixed operations", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
+
sandbox.startTracking();
|
|
73
|
+
// Add a new item
|
|
74
|
+
yield new Simple({ foo: "brand-new", bar: 50 }).put();
|
|
75
|
+
// Update an existing item
|
|
76
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "changed" });
|
|
77
|
+
// Delete an existing item
|
|
78
|
+
yield Simple.delete({ PK: "PK#seeded2", SK: "SK#2" });
|
|
79
|
+
// Verify all changes took effect
|
|
80
|
+
expect(yield sandbox.get("PK#brand-new", "SK#50")).not.toBeNull();
|
|
81
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("changed");
|
|
82
|
+
expect(yield sandbox.get("PK#seeded2", "SK#2")).toBeNull();
|
|
83
|
+
yield sandbox.rollback();
|
|
84
|
+
// New item should be gone
|
|
85
|
+
expect(yield sandbox.get("PK#brand-new", "SK#50")).toBeNull();
|
|
86
|
+
// Updated item should be restored
|
|
87
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1");
|
|
88
|
+
// Deleted item should be back
|
|
89
|
+
expect(yield sandbox.get("PK#seeded2", "SK#2")).not.toBeNull();
|
|
90
|
+
}));
|
|
91
|
+
test("supports multiple tracking/rollback cycles", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
// Cycle 1
|
|
93
|
+
sandbox.startTracking();
|
|
94
|
+
yield new Simple({ foo: "cycle1", bar: 10 }).put();
|
|
95
|
+
yield sandbox.rollback();
|
|
96
|
+
expect(yield sandbox.get("PK#cycle1", "SK#10")).toBeNull();
|
|
97
|
+
// Cycle 2
|
|
98
|
+
sandbox.startTracking();
|
|
99
|
+
yield new Simple({ foo: "cycle2", bar: 20 }).put();
|
|
100
|
+
yield sandbox.rollback();
|
|
101
|
+
expect(yield sandbox.get("PK#cycle2", "SK#20")).toBeNull();
|
|
102
|
+
// Cycle 3 - modify seeded data
|
|
103
|
+
sandbox.startTracking();
|
|
104
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "cycle3-mod" });
|
|
105
|
+
yield sandbox.rollback();
|
|
106
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1");
|
|
107
|
+
// Seeded data is intact throughout
|
|
108
|
+
expect(yield sandbox.get("PK#seeded1", "SK#1")).not.toBeNull();
|
|
109
|
+
expect(yield sandbox.get("PK#seeded2", "SK#2")).not.toBeNull();
|
|
110
|
+
}));
|
|
111
|
+
test("does not track writes before startTracking", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
|
+
// Write without tracking
|
|
113
|
+
yield new Simple({ foo: "untracked", bar: 77 }).put();
|
|
114
|
+
// Now start tracking and immediately rollback
|
|
115
|
+
sandbox.startTracking();
|
|
116
|
+
yield sandbox.rollback();
|
|
117
|
+
// The untracked write should still be there
|
|
118
|
+
expect(yield sandbox.get("PK#untracked", "SK#77")).not.toBeNull();
|
|
119
|
+
// Clean up manually for subsequent tests
|
|
120
|
+
sandbox.startTracking();
|
|
121
|
+
yield Simple.delete({ PK: "PK#untracked", SK: "SK#77" });
|
|
122
|
+
yield sandbox.rollback();
|
|
123
|
+
}));
|
|
124
|
+
test("tracks the same key modified multiple times", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
|
+
sandbox.startTracking();
|
|
126
|
+
// Update the same item twice
|
|
127
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "first-update" });
|
|
128
|
+
yield Simple.updateRaw({ PK: "PK#seeded1", SK: "SK#1" }, { foo: "second-update" });
|
|
129
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("second-update");
|
|
130
|
+
yield sandbox.rollback();
|
|
131
|
+
// Should restore to original, not to the intermediate state
|
|
132
|
+
expect((yield sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1");
|
|
133
|
+
}));
|
|
134
|
+
});
|
|
135
|
+
describe("rollback with beforeEach/afterEach pattern", () => {
|
|
136
|
+
let sandbox;
|
|
137
|
+
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
138
|
+
sandbox = yield createSandbox(client);
|
|
139
|
+
yield sandbox.seed(new Simple({ foo: "a", bar: 1 }), new Simple({ foo: "b", bar: 2 }));
|
|
140
|
+
}));
|
|
141
|
+
beforeEach(() => {
|
|
142
|
+
sandbox.startTracking();
|
|
143
|
+
});
|
|
144
|
+
afterEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
145
|
+
yield sandbox.rollback();
|
|
146
|
+
}));
|
|
147
|
+
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
|
+
yield sandbox.destroy();
|
|
149
|
+
}));
|
|
150
|
+
test("test A: add an item", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
151
|
+
yield new Simple({ foo: "from-test-a", bar: 100 }).put();
|
|
152
|
+
expect(yield sandbox.get("PK#from-test-a", "SK#100")).not.toBeNull();
|
|
153
|
+
}));
|
|
154
|
+
test("test B: item from test A does not exist", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
155
|
+
expect(yield sandbox.get("PK#from-test-a", "SK#100")).toBeNull();
|
|
156
|
+
}));
|
|
157
|
+
test("test C: modify seeded data", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
+
yield Simple.updateRaw({ PK: "PK#a", SK: "SK#1" }, { foo: "modified-a" });
|
|
159
|
+
expect((yield sandbox.get("PK#a", "SK#1")).foo).toBe("modified-a");
|
|
160
|
+
}));
|
|
161
|
+
test("test D: seeded data is back to original", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
162
|
+
expect((yield sandbox.get("PK#a", "SK#1")).foo).toBe("a");
|
|
163
|
+
}));
|
|
164
|
+
test("test E: delete seeded data", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
165
|
+
yield Simple.delete({ PK: "PK#b", SK: "SK#2" });
|
|
166
|
+
expect(yield sandbox.get("PK#b", "SK#2")).toBeNull();
|
|
167
|
+
}));
|
|
168
|
+
test("test F: deleted seeded data is back", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
169
|
+
expect(yield sandbox.get("PK#b", "SK#2")).not.toBeNull();
|
|
170
|
+
expect((yield sandbox.get("PK#b", "SK#2")).foo).toBe("b");
|
|
171
|
+
}));
|
|
172
|
+
});
|
|
173
|
+
describe("existing sandbox semantics still work", () => {
|
|
174
|
+
let sandbox;
|
|
175
|
+
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
176
|
+
sandbox = yield createSandbox(client);
|
|
177
|
+
}));
|
|
178
|
+
afterEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
179
|
+
yield sandbox.destroy();
|
|
180
|
+
}));
|
|
181
|
+
test("create and destroy per test still works", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
182
|
+
yield sandbox.seed(new Simple({ foo: "per-test", bar: 1 }));
|
|
183
|
+
const item = yield sandbox.get("PK#per-test", "SK#1");
|
|
184
|
+
expect(item).not.toBeNull();
|
|
185
|
+
expect(item.foo).toBe("per-test");
|
|
186
|
+
}));
|
|
187
|
+
test("snapshot and diff still work", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
188
|
+
const before = yield sandbox.snapshot();
|
|
189
|
+
yield new Simple({ foo: "diffed", bar: 1 }).put();
|
|
190
|
+
const diffResult = yield sandbox.diff(before);
|
|
191
|
+
expect(diffResult).toContain("PK#diffed");
|
|
192
|
+
}));
|
|
193
|
+
});
|
|
194
|
+
//# sourceMappingURL=rollback.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.test.js","sourceRoot":"","sources":["../../../src/__test__/rollback.test.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/sandbox.d.ts
CHANGED
package/dist/esm/sandbox.js
CHANGED
|
@@ -91,9 +91,134 @@ export const getTableContents = (tableName) => __awaiter(void 0, void 0, void 0,
|
|
|
91
91
|
items.forEach((item) => (acc[`${item.PK}__${item.SK}`] = item));
|
|
92
92
|
return acc;
|
|
93
93
|
});
|
|
94
|
+
const WRITE_METHODS = new Set([
|
|
95
|
+
"put",
|
|
96
|
+
"update",
|
|
97
|
+
"delete",
|
|
98
|
+
"batchWrite",
|
|
99
|
+
"transactWrite",
|
|
100
|
+
]);
|
|
101
|
+
function createTrackedDocClient(original, tableName) {
|
|
102
|
+
let isTracking = false;
|
|
103
|
+
const trackedKeys = new Map();
|
|
104
|
+
const captureKey = (pk, sk) => __awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
const compositeKey = `${pk}__${sk}`;
|
|
106
|
+
if (trackedKeys.has(compositeKey))
|
|
107
|
+
return;
|
|
108
|
+
const { Item } = yield original
|
|
109
|
+
.get({ TableName: tableName, Key: { PK: pk, SK: sk } })
|
|
110
|
+
.promise();
|
|
111
|
+
trackedKeys.set(compositeKey, { pk, sk, original: Item !== null && Item !== void 0 ? Item : null });
|
|
112
|
+
});
|
|
113
|
+
const captureKeysForOperation = (method, params) => __awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
var _a;
|
|
115
|
+
switch (method) {
|
|
116
|
+
case "put":
|
|
117
|
+
if (params.TableName === tableName && params.Item) {
|
|
118
|
+
yield captureKey(params.Item.PK, params.Item.SK);
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
case "update":
|
|
122
|
+
case "delete":
|
|
123
|
+
if (params.TableName === tableName && params.Key) {
|
|
124
|
+
yield captureKey(params.Key.PK, params.Key.SK);
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
case "batchWrite": {
|
|
128
|
+
const tableItems = ((_a = params.RequestItems) === null || _a === void 0 ? void 0 : _a[tableName]) || [];
|
|
129
|
+
yield Promise.all(tableItems.map((item) => {
|
|
130
|
+
if (item.PutRequest) {
|
|
131
|
+
return captureKey(item.PutRequest.Item.PK, item.PutRequest.Item.SK);
|
|
132
|
+
}
|
|
133
|
+
if (item.DeleteRequest) {
|
|
134
|
+
return captureKey(item.DeleteRequest.Key.PK, item.DeleteRequest.Key.SK);
|
|
135
|
+
}
|
|
136
|
+
}));
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case "transactWrite": {
|
|
140
|
+
const transactItems = params.TransactItems || [];
|
|
141
|
+
yield Promise.all(transactItems
|
|
142
|
+
.map((item) => {
|
|
143
|
+
var _a, _b, _c;
|
|
144
|
+
if (((_a = item.Put) === null || _a === void 0 ? void 0 : _a.TableName) === tableName) {
|
|
145
|
+
return captureKey(item.Put.Item.PK, item.Put.Item.SK);
|
|
146
|
+
}
|
|
147
|
+
if (((_b = item.Update) === null || _b === void 0 ? void 0 : _b.TableName) === tableName) {
|
|
148
|
+
return captureKey(item.Update.Key.PK, item.Update.Key.SK);
|
|
149
|
+
}
|
|
150
|
+
if (((_c = item.Delete) === null || _c === void 0 ? void 0 : _c.TableName) === tableName) {
|
|
151
|
+
return captureKey(item.Delete.Key.PK, item.Delete.Key.SK);
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
.filter(Boolean));
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
const proxy = new Proxy(original, {
|
|
160
|
+
get(target, prop) {
|
|
161
|
+
const value = target[prop];
|
|
162
|
+
if (value === undefined)
|
|
163
|
+
return undefined;
|
|
164
|
+
if (typeof value === "function") {
|
|
165
|
+
if (isTracking && WRITE_METHODS.has(prop)) {
|
|
166
|
+
return (params) => {
|
|
167
|
+
const request = value.call(target, params);
|
|
168
|
+
const origPromise = request.promise.bind(request);
|
|
169
|
+
request.promise = () => __awaiter(this, void 0, void 0, function* () {
|
|
170
|
+
yield captureKeysForOperation(prop, params);
|
|
171
|
+
return origPromise();
|
|
172
|
+
});
|
|
173
|
+
return request;
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
return value.bind(target);
|
|
177
|
+
}
|
|
178
|
+
return value;
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
proxy: proxy,
|
|
183
|
+
startTracking: () => {
|
|
184
|
+
isTracking = true;
|
|
185
|
+
trackedKeys.clear();
|
|
186
|
+
},
|
|
187
|
+
rollback: () => __awaiter(this, void 0, void 0, function* () {
|
|
188
|
+
isTracking = false;
|
|
189
|
+
const entries = Array.from(trackedKeys.values());
|
|
190
|
+
const toDelete = entries.filter((e) => e.original === null);
|
|
191
|
+
const toRestore = entries.filter((e) => e.original !== null);
|
|
192
|
+
const deleteChunks = chunksOf(25)(toDelete);
|
|
193
|
+
const restoreChunks = chunksOf(25)(toRestore);
|
|
194
|
+
yield Promise.all([
|
|
195
|
+
...deleteChunks.map((chunk) => original
|
|
196
|
+
.batchWrite({
|
|
197
|
+
RequestItems: {
|
|
198
|
+
[tableName]: chunk.map(({ pk, sk }) => ({
|
|
199
|
+
DeleteRequest: { Key: { PK: pk, SK: sk } },
|
|
200
|
+
})),
|
|
201
|
+
},
|
|
202
|
+
})
|
|
203
|
+
.promise()),
|
|
204
|
+
...restoreChunks.map((chunk) => original
|
|
205
|
+
.batchWrite({
|
|
206
|
+
RequestItems: {
|
|
207
|
+
[tableName]: chunk.map(({ original: item }) => ({
|
|
208
|
+
PutRequest: { Item: item },
|
|
209
|
+
})),
|
|
210
|
+
},
|
|
211
|
+
})
|
|
212
|
+
.promise()),
|
|
213
|
+
]);
|
|
214
|
+
trackedKeys.clear();
|
|
215
|
+
}),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
94
218
|
export const createSandbox = (client) => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
219
|
const tableName = yield createTable();
|
|
96
|
-
|
|
220
|
+
const tracked = createTrackedDocClient(docClient, tableName);
|
|
221
|
+
client.setDocumentClient(tracked.proxy);
|
|
97
222
|
client.setTableName(tableName);
|
|
98
223
|
return {
|
|
99
224
|
destroy: () => destroyTable(tableName),
|
|
@@ -126,6 +251,8 @@ export const createSandbox = (client) => __awaiter(void 0, void 0, void 0, funct
|
|
|
126
251
|
const snapshot = yield getTableContents(tableName);
|
|
127
252
|
return formatSnapshotDiff(before, snapshot);
|
|
128
253
|
}),
|
|
254
|
+
startTracking: tracked.startTracking,
|
|
255
|
+
rollback: tracked.rollback,
|
|
129
256
|
};
|
|
130
257
|
});
|
|
131
258
|
//# sourceMappingURL=sandbox.js.map
|
package/dist/esm/sandbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/sandbox.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/sandbox.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import * as t from "io-ts"
|
|
2
|
+
import { model } from "@model-ts/core"
|
|
3
|
+
import { Sandbox, createSandbox } from "../sandbox"
|
|
4
|
+
import { Client } from "../client"
|
|
5
|
+
import { getProvider } from "../provider"
|
|
6
|
+
|
|
7
|
+
const client = new Client({ tableName: "table" })
|
|
8
|
+
const provider = getProvider(client)
|
|
9
|
+
|
|
10
|
+
const SIMPLE_CODEC = t.type({
|
|
11
|
+
foo: t.string,
|
|
12
|
+
bar: t.number,
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
class Simple extends model("Simple", SIMPLE_CODEC, provider) {
|
|
16
|
+
get PK() {
|
|
17
|
+
return `PK#${this.foo}`
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get SK() {
|
|
21
|
+
return `SK#${this.bar}`
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe("rollback", () => {
|
|
26
|
+
let sandbox: Sandbox
|
|
27
|
+
|
|
28
|
+
beforeAll(async () => {
|
|
29
|
+
sandbox = await createSandbox(client)
|
|
30
|
+
await sandbox.seed(
|
|
31
|
+
new Simple({ foo: "seeded1", bar: 1 }),
|
|
32
|
+
new Simple({ foo: "seeded2", bar: 2 })
|
|
33
|
+
)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
afterAll(async () => {
|
|
37
|
+
await sandbox.destroy()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test("rolls back newly added items", async () => {
|
|
41
|
+
sandbox.startTracking()
|
|
42
|
+
|
|
43
|
+
await new Simple({ foo: "new-item", bar: 99 }).put()
|
|
44
|
+
expect(await sandbox.get("PK#new-item", "SK#99")).not.toBeNull()
|
|
45
|
+
|
|
46
|
+
await sandbox.rollback()
|
|
47
|
+
|
|
48
|
+
expect(await sandbox.get("PK#new-item", "SK#99")).toBeNull()
|
|
49
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).not.toBeNull()
|
|
50
|
+
expect(await sandbox.get("PK#seeded2", "SK#2")).not.toBeNull()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test("rolls back updated items", async () => {
|
|
54
|
+
sandbox.startTracking()
|
|
55
|
+
|
|
56
|
+
await Simple.updateRaw(
|
|
57
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
58
|
+
{ foo: "modified" }
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
const modified = await sandbox.get("PK#seeded1", "SK#1")
|
|
62
|
+
expect(modified.foo).toBe("modified")
|
|
63
|
+
|
|
64
|
+
await sandbox.rollback()
|
|
65
|
+
|
|
66
|
+
const restored = await sandbox.get("PK#seeded1", "SK#1")
|
|
67
|
+
expect(restored.foo).toBe("seeded1")
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test("rolls back deleted items", async () => {
|
|
71
|
+
sandbox.startTracking()
|
|
72
|
+
|
|
73
|
+
await Simple.delete({ PK: "PK#seeded1", SK: "SK#1" })
|
|
74
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).toBeNull()
|
|
75
|
+
|
|
76
|
+
await sandbox.rollback()
|
|
77
|
+
|
|
78
|
+
const restored = await sandbox.get("PK#seeded1", "SK#1")
|
|
79
|
+
expect(restored).not.toBeNull()
|
|
80
|
+
expect(restored.foo).toBe("seeded1")
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
test("rolls back soft-deleted items", async () => {
|
|
84
|
+
sandbox.startTracking()
|
|
85
|
+
|
|
86
|
+
const item = new Simple({ foo: "seeded1", bar: 1 })
|
|
87
|
+
// @ts-ignore - _docVersion needed for softDelete encoding
|
|
88
|
+
item._docVersion = 0
|
|
89
|
+
await client.softDelete(item)
|
|
90
|
+
|
|
91
|
+
// Original should be gone, deleted version should exist
|
|
92
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).toBeNull()
|
|
93
|
+
expect(
|
|
94
|
+
await sandbox.get("$$DELETED$$PK#seeded1", "$$DELETED$$SK#1")
|
|
95
|
+
).not.toBeNull()
|
|
96
|
+
|
|
97
|
+
await sandbox.rollback()
|
|
98
|
+
|
|
99
|
+
// Original should be restored, deleted version should be gone
|
|
100
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).not.toBeNull()
|
|
101
|
+
expect(
|
|
102
|
+
await sandbox.get("$$DELETED$$PK#seeded1", "$$DELETED$$SK#1")
|
|
103
|
+
).toBeNull()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test("rolls back mixed operations", async () => {
|
|
107
|
+
sandbox.startTracking()
|
|
108
|
+
|
|
109
|
+
// Add a new item
|
|
110
|
+
await new Simple({ foo: "brand-new", bar: 50 }).put()
|
|
111
|
+
|
|
112
|
+
// Update an existing item
|
|
113
|
+
await Simple.updateRaw(
|
|
114
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
115
|
+
{ foo: "changed" }
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
// Delete an existing item
|
|
119
|
+
await Simple.delete({ PK: "PK#seeded2", SK: "SK#2" })
|
|
120
|
+
|
|
121
|
+
// Verify all changes took effect
|
|
122
|
+
expect(await sandbox.get("PK#brand-new", "SK#50")).not.toBeNull()
|
|
123
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("changed")
|
|
124
|
+
expect(await sandbox.get("PK#seeded2", "SK#2")).toBeNull()
|
|
125
|
+
|
|
126
|
+
await sandbox.rollback()
|
|
127
|
+
|
|
128
|
+
// New item should be gone
|
|
129
|
+
expect(await sandbox.get("PK#brand-new", "SK#50")).toBeNull()
|
|
130
|
+
// Updated item should be restored
|
|
131
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1")
|
|
132
|
+
// Deleted item should be back
|
|
133
|
+
expect(await sandbox.get("PK#seeded2", "SK#2")).not.toBeNull()
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
test("supports multiple tracking/rollback cycles", async () => {
|
|
137
|
+
// Cycle 1
|
|
138
|
+
sandbox.startTracking()
|
|
139
|
+
await new Simple({ foo: "cycle1", bar: 10 }).put()
|
|
140
|
+
await sandbox.rollback()
|
|
141
|
+
expect(await sandbox.get("PK#cycle1", "SK#10")).toBeNull()
|
|
142
|
+
|
|
143
|
+
// Cycle 2
|
|
144
|
+
sandbox.startTracking()
|
|
145
|
+
await new Simple({ foo: "cycle2", bar: 20 }).put()
|
|
146
|
+
await sandbox.rollback()
|
|
147
|
+
expect(await sandbox.get("PK#cycle2", "SK#20")).toBeNull()
|
|
148
|
+
|
|
149
|
+
// Cycle 3 - modify seeded data
|
|
150
|
+
sandbox.startTracking()
|
|
151
|
+
await Simple.updateRaw(
|
|
152
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
153
|
+
{ foo: "cycle3-mod" }
|
|
154
|
+
)
|
|
155
|
+
await sandbox.rollback()
|
|
156
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1")
|
|
157
|
+
|
|
158
|
+
// Seeded data is intact throughout
|
|
159
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).not.toBeNull()
|
|
160
|
+
expect(await sandbox.get("PK#seeded2", "SK#2")).not.toBeNull()
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
test("does not track writes before startTracking", async () => {
|
|
164
|
+
// Write without tracking
|
|
165
|
+
await new Simple({ foo: "untracked", bar: 77 }).put()
|
|
166
|
+
|
|
167
|
+
// Now start tracking and immediately rollback
|
|
168
|
+
sandbox.startTracking()
|
|
169
|
+
await sandbox.rollback()
|
|
170
|
+
|
|
171
|
+
// The untracked write should still be there
|
|
172
|
+
expect(await sandbox.get("PK#untracked", "SK#77")).not.toBeNull()
|
|
173
|
+
|
|
174
|
+
// Clean up manually for subsequent tests
|
|
175
|
+
sandbox.startTracking()
|
|
176
|
+
await Simple.delete({ PK: "PK#untracked", SK: "SK#77" })
|
|
177
|
+
await sandbox.rollback()
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
test("tracks the same key modified multiple times", async () => {
|
|
181
|
+
sandbox.startTracking()
|
|
182
|
+
|
|
183
|
+
// Update the same item twice
|
|
184
|
+
await Simple.updateRaw(
|
|
185
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
186
|
+
{ foo: "first-update" }
|
|
187
|
+
)
|
|
188
|
+
await Simple.updateRaw(
|
|
189
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
190
|
+
{ foo: "second-update" }
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("second-update")
|
|
194
|
+
|
|
195
|
+
await sandbox.rollback()
|
|
196
|
+
|
|
197
|
+
// Should restore to original, not to the intermediate state
|
|
198
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1")
|
|
199
|
+
})
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
describe("rollback with beforeEach/afterEach pattern", () => {
|
|
203
|
+
let sandbox: Sandbox
|
|
204
|
+
|
|
205
|
+
beforeAll(async () => {
|
|
206
|
+
sandbox = await createSandbox(client)
|
|
207
|
+
await sandbox.seed(
|
|
208
|
+
new Simple({ foo: "a", bar: 1 }),
|
|
209
|
+
new Simple({ foo: "b", bar: 2 })
|
|
210
|
+
)
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
beforeEach(() => {
|
|
214
|
+
sandbox.startTracking()
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
afterEach(async () => {
|
|
218
|
+
await sandbox.rollback()
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
afterAll(async () => {
|
|
222
|
+
await sandbox.destroy()
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
test("test A: add an item", async () => {
|
|
226
|
+
await new Simple({ foo: "from-test-a", bar: 100 }).put()
|
|
227
|
+
expect(await sandbox.get("PK#from-test-a", "SK#100")).not.toBeNull()
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
test("test B: item from test A does not exist", async () => {
|
|
231
|
+
expect(await sandbox.get("PK#from-test-a", "SK#100")).toBeNull()
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
test("test C: modify seeded data", async () => {
|
|
235
|
+
await Simple.updateRaw({ PK: "PK#a", SK: "SK#1" }, { foo: "modified-a" })
|
|
236
|
+
expect((await sandbox.get("PK#a", "SK#1")).foo).toBe("modified-a")
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
test("test D: seeded data is back to original", async () => {
|
|
240
|
+
expect((await sandbox.get("PK#a", "SK#1")).foo).toBe("a")
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
test("test E: delete seeded data", async () => {
|
|
244
|
+
await Simple.delete({ PK: "PK#b", SK: "SK#2" })
|
|
245
|
+
expect(await sandbox.get("PK#b", "SK#2")).toBeNull()
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
test("test F: deleted seeded data is back", async () => {
|
|
249
|
+
expect(await sandbox.get("PK#b", "SK#2")).not.toBeNull()
|
|
250
|
+
expect((await sandbox.get("PK#b", "SK#2")).foo).toBe("b")
|
|
251
|
+
})
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
describe("existing sandbox semantics still work", () => {
|
|
255
|
+
let sandbox: Sandbox
|
|
256
|
+
|
|
257
|
+
beforeEach(async () => {
|
|
258
|
+
sandbox = await createSandbox(client)
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
afterEach(async () => {
|
|
262
|
+
await sandbox.destroy()
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
test("create and destroy per test still works", async () => {
|
|
266
|
+
await sandbox.seed(new Simple({ foo: "per-test", bar: 1 }))
|
|
267
|
+
|
|
268
|
+
const item = await sandbox.get("PK#per-test", "SK#1")
|
|
269
|
+
expect(item).not.toBeNull()
|
|
270
|
+
expect(item.foo).toBe("per-test")
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
test("snapshot and diff still work", async () => {
|
|
274
|
+
const before = await sandbox.snapshot()
|
|
275
|
+
await new Simple({ foo: "diffed", bar: 1 }).put()
|
|
276
|
+
const diffResult = await sandbox.diff(before)
|
|
277
|
+
expect(diffResult).toContain("PK#diffed")
|
|
278
|
+
})
|
|
279
|
+
})
|
package/src/sandbox.ts
CHANGED
|
@@ -105,18 +105,186 @@ export const getTableContents = async (
|
|
|
105
105
|
return acc
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
// -------------------------------------------------------------------------------------
|
|
109
|
+
// Tracking
|
|
110
|
+
// -------------------------------------------------------------------------------------
|
|
111
|
+
|
|
112
|
+
interface TrackedEntry {
|
|
113
|
+
pk: string
|
|
114
|
+
sk: string
|
|
115
|
+
original: any | null
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const WRITE_METHODS = new Set([
|
|
119
|
+
"put",
|
|
120
|
+
"update",
|
|
121
|
+
"delete",
|
|
122
|
+
"batchWrite",
|
|
123
|
+
"transactWrite",
|
|
124
|
+
])
|
|
125
|
+
|
|
126
|
+
function createTrackedDocClient(
|
|
127
|
+
original: DynamoDB.DocumentClient,
|
|
128
|
+
tableName: string
|
|
129
|
+
) {
|
|
130
|
+
let isTracking = false
|
|
131
|
+
const trackedKeys = new Map<string, TrackedEntry>()
|
|
132
|
+
|
|
133
|
+
const captureKey = async (pk: string, sk: string) => {
|
|
134
|
+
const compositeKey = `${pk}__${sk}`
|
|
135
|
+
if (trackedKeys.has(compositeKey)) return
|
|
136
|
+
|
|
137
|
+
const { Item } = await original
|
|
138
|
+
.get({ TableName: tableName, Key: { PK: pk, SK: sk } })
|
|
139
|
+
.promise()
|
|
140
|
+
|
|
141
|
+
trackedKeys.set(compositeKey, { pk, sk, original: Item ?? null })
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const captureKeysForOperation = async (method: string, params: any) => {
|
|
145
|
+
switch (method) {
|
|
146
|
+
case "put":
|
|
147
|
+
if (params.TableName === tableName && params.Item) {
|
|
148
|
+
await captureKey(params.Item.PK, params.Item.SK)
|
|
149
|
+
}
|
|
150
|
+
break
|
|
151
|
+
case "update":
|
|
152
|
+
case "delete":
|
|
153
|
+
if (params.TableName === tableName && params.Key) {
|
|
154
|
+
await captureKey(params.Key.PK, params.Key.SK)
|
|
155
|
+
}
|
|
156
|
+
break
|
|
157
|
+
case "batchWrite": {
|
|
158
|
+
const tableItems = params.RequestItems?.[tableName] || []
|
|
159
|
+
await Promise.all(
|
|
160
|
+
tableItems.map((item: any) => {
|
|
161
|
+
if (item.PutRequest) {
|
|
162
|
+
return captureKey(
|
|
163
|
+
item.PutRequest.Item.PK,
|
|
164
|
+
item.PutRequest.Item.SK
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
if (item.DeleteRequest) {
|
|
168
|
+
return captureKey(
|
|
169
|
+
item.DeleteRequest.Key.PK,
|
|
170
|
+
item.DeleteRequest.Key.SK
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
)
|
|
175
|
+
break
|
|
176
|
+
}
|
|
177
|
+
case "transactWrite": {
|
|
178
|
+
const transactItems = params.TransactItems || []
|
|
179
|
+
await Promise.all(
|
|
180
|
+
transactItems
|
|
181
|
+
.map((item: any) => {
|
|
182
|
+
if (item.Put?.TableName === tableName) {
|
|
183
|
+
return captureKey(item.Put.Item.PK, item.Put.Item.SK)
|
|
184
|
+
}
|
|
185
|
+
if (item.Update?.TableName === tableName) {
|
|
186
|
+
return captureKey(item.Update.Key.PK, item.Update.Key.SK)
|
|
187
|
+
}
|
|
188
|
+
if (item.Delete?.TableName === tableName) {
|
|
189
|
+
return captureKey(item.Delete.Key.PK, item.Delete.Key.SK)
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
.filter(Boolean)
|
|
193
|
+
)
|
|
194
|
+
break
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const proxy = new Proxy(original, {
|
|
200
|
+
get(target, prop) {
|
|
201
|
+
const value = (target as any)[prop]
|
|
202
|
+
if (value === undefined) return undefined
|
|
203
|
+
|
|
204
|
+
if (typeof value === "function") {
|
|
205
|
+
if (isTracking && WRITE_METHODS.has(prop as string)) {
|
|
206
|
+
return (params: any) => {
|
|
207
|
+
const request = value.call(target, params)
|
|
208
|
+
const origPromise = request.promise.bind(request)
|
|
209
|
+
request.promise = async () => {
|
|
210
|
+
await captureKeysForOperation(prop as string, params)
|
|
211
|
+
return origPromise()
|
|
212
|
+
}
|
|
213
|
+
return request
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return value.bind(target)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return value
|
|
220
|
+
},
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
proxy: proxy as DynamoDB.DocumentClient,
|
|
225
|
+
startTracking: () => {
|
|
226
|
+
isTracking = true
|
|
227
|
+
trackedKeys.clear()
|
|
228
|
+
},
|
|
229
|
+
rollback: async () => {
|
|
230
|
+
isTracking = false
|
|
231
|
+
|
|
232
|
+
const entries = Array.from(trackedKeys.values())
|
|
233
|
+
const toDelete = entries.filter((e) => e.original === null)
|
|
234
|
+
const toRestore = entries.filter((e) => e.original !== null)
|
|
235
|
+
|
|
236
|
+
const deleteChunks = chunksOf(25)(toDelete)
|
|
237
|
+
const restoreChunks = chunksOf(25)(toRestore)
|
|
238
|
+
|
|
239
|
+
await Promise.all([
|
|
240
|
+
...deleteChunks.map((chunk) =>
|
|
241
|
+
original
|
|
242
|
+
.batchWrite({
|
|
243
|
+
RequestItems: {
|
|
244
|
+
[tableName]: chunk.map(({ pk, sk }) => ({
|
|
245
|
+
DeleteRequest: { Key: { PK: pk, SK: sk } },
|
|
246
|
+
})),
|
|
247
|
+
},
|
|
248
|
+
})
|
|
249
|
+
.promise()
|
|
250
|
+
),
|
|
251
|
+
...restoreChunks.map((chunk) =>
|
|
252
|
+
original
|
|
253
|
+
.batchWrite({
|
|
254
|
+
RequestItems: {
|
|
255
|
+
[tableName]: chunk.map(({ original: item }) => ({
|
|
256
|
+
PutRequest: { Item: item },
|
|
257
|
+
})),
|
|
258
|
+
},
|
|
259
|
+
})
|
|
260
|
+
.promise()
|
|
261
|
+
),
|
|
262
|
+
])
|
|
263
|
+
|
|
264
|
+
trackedKeys.clear()
|
|
265
|
+
},
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// -------------------------------------------------------------------------------------
|
|
270
|
+
// Sandbox
|
|
271
|
+
// -------------------------------------------------------------------------------------
|
|
272
|
+
|
|
108
273
|
export interface Sandbox {
|
|
109
274
|
destroy: () => Promise<void>
|
|
110
275
|
snapshot: () => Promise<{ [key: string]: any }>
|
|
111
276
|
seed: (...args: Array<{ [key: string]: any }>) => Promise<void>
|
|
112
277
|
get: (pk: string, sk: string) => Promise<null | any>
|
|
113
278
|
diff: (before: { [key: string]: any }) => Promise<string>
|
|
279
|
+
startTracking: () => void
|
|
280
|
+
rollback: () => Promise<void>
|
|
114
281
|
}
|
|
115
282
|
|
|
116
283
|
export const createSandbox = async (client: Client): Promise<Sandbox> => {
|
|
117
284
|
const tableName = await createTable()
|
|
118
285
|
|
|
119
|
-
|
|
286
|
+
const tracked = createTrackedDocClient(docClient, tableName)
|
|
287
|
+
client.setDocumentClient(tracked.proxy)
|
|
120
288
|
client.setTableName(tableName)
|
|
121
289
|
|
|
122
290
|
return {
|
|
@@ -155,5 +323,7 @@ export const createSandbox = async (client: Client): Promise<Sandbox> => {
|
|
|
155
323
|
|
|
156
324
|
return formatSnapshotDiff(before, snapshot)
|
|
157
325
|
},
|
|
326
|
+
startTracking: tracked.startTracking,
|
|
327
|
+
rollback: tracked.rollback,
|
|
158
328
|
}
|
|
159
329
|
}
|