@model-ts/dynamodb 3.0.0 → 3.0.1
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__/pagination.test.d.ts +1 -0
- package/dist/cjs/__test__/pagination.test.js +241 -0
- package/dist/cjs/__test__/pagination.test.js.map +1 -0
- package/dist/cjs/pagination.d.ts +1 -1
- package/dist/cjs/pagination.js +4 -6
- package/dist/cjs/pagination.js.map +1 -1
- package/dist/esm/__test__/pagination.test.d.ts +1 -0
- package/dist/esm/__test__/pagination.test.js +238 -0
- package/dist/esm/__test__/pagination.test.js.map +1 -0
- package/dist/esm/pagination.d.ts +1 -1
- package/dist/esm/pagination.js +4 -6
- package/dist/esm/pagination.js.map +1 -1
- package/package.json +1 -1
- package/src/__test__/pagination.test.ts +300 -0
- package/src/pagination.ts +5 -9
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
5
|
+
const pagination_1 = require("../pagination");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
7
|
+
describe("encodeDDBCursor", () => {
|
|
8
|
+
describe("basic encoding without encryption", () => {
|
|
9
|
+
it("should encode basic PK and SK", () => {
|
|
10
|
+
const result = pagination_1.encodeDDBCursor({
|
|
11
|
+
PK: "USER#123",
|
|
12
|
+
SK: "PROFILE#456",
|
|
13
|
+
});
|
|
14
|
+
expect(result).toMatchInlineSnapshot(`"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiJ9"`);
|
|
15
|
+
});
|
|
16
|
+
it("should encode with GSI2 values", () => {
|
|
17
|
+
const result = pagination_1.encodeDDBCursor({
|
|
18
|
+
PK: "USER#123",
|
|
19
|
+
SK: "PROFILE#456",
|
|
20
|
+
GSI2PK: "GSI2PK#user123",
|
|
21
|
+
GSI2SK: "GSI2SK#profile456",
|
|
22
|
+
});
|
|
23
|
+
expect(result).toMatchInlineSnapshot(`"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYifQ=="`);
|
|
24
|
+
});
|
|
25
|
+
it("should encode with multiple GSI values", () => {
|
|
26
|
+
const result = pagination_1.encodeDDBCursor({
|
|
27
|
+
PK: "USER#123",
|
|
28
|
+
SK: "PROFILE#456",
|
|
29
|
+
GSI2PK: "GSI2PK#user123",
|
|
30
|
+
GSI2SK: "GSI2SK#profile456",
|
|
31
|
+
GSI3PK: "GSI3PK#fixed",
|
|
32
|
+
GSI3SK: "GSI3SK#value",
|
|
33
|
+
});
|
|
34
|
+
expect(result).toMatchInlineSnapshot(`"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYiLCJHU0kzUEsiOiJHU0kzUEsjZml4ZWQiLCJHU0kzU0siOiJHU0kzU0sjdmFsdWUifQ=="`);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe("encoding with encryption", () => {
|
|
38
|
+
const encryptionKey = crypto_1.default.randomBytes(32);
|
|
39
|
+
it("should encrypt the cursor when encryption key is provided", () => {
|
|
40
|
+
const result = pagination_1.encodeDDBCursor({
|
|
41
|
+
PK: "USER#123",
|
|
42
|
+
SK: "PROFILE#456",
|
|
43
|
+
}, encryptionKey);
|
|
44
|
+
// The result should be encrypted and different from the unencrypted version
|
|
45
|
+
expect(result).not.toBe("eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiJ9");
|
|
46
|
+
expect(result).toMatch(/^[A-Za-z0-9+/=]+$/); // Base64 format
|
|
47
|
+
});
|
|
48
|
+
it("should produce consistent encrypted results for same input", () => {
|
|
49
|
+
const input = {
|
|
50
|
+
PK: "USER#123",
|
|
51
|
+
SK: "PROFILE#456",
|
|
52
|
+
};
|
|
53
|
+
const result1 = pagination_1.encodeDDBCursor(input, encryptionKey);
|
|
54
|
+
const result2 = pagination_1.encodeDDBCursor(input, encryptionKey);
|
|
55
|
+
expect(result1).toBe(result2);
|
|
56
|
+
});
|
|
57
|
+
it("should encrypt with GSI values", () => {
|
|
58
|
+
const result = pagination_1.encodeDDBCursor({
|
|
59
|
+
PK: "USER#123",
|
|
60
|
+
SK: "PROFILE#456",
|
|
61
|
+
GSI2PK: "GSI2PK#user123",
|
|
62
|
+
GSI2SK: "GSI2SK#profile456",
|
|
63
|
+
}, encryptionKey);
|
|
64
|
+
expect(result).toMatch(/^[A-Za-z0-9+/=]+$/);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe("decodeDDBCursor", () => {
|
|
69
|
+
describe("basic decoding without encryption", () => {
|
|
70
|
+
it("should decode basic PK and SK", () => {
|
|
71
|
+
const encoded = "eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiJ9";
|
|
72
|
+
const result = pagination_1.decodeDDBCursor(encoded);
|
|
73
|
+
expect(result).toMatchInlineSnapshot(`
|
|
74
|
+
Object {
|
|
75
|
+
"PK": "USER#123",
|
|
76
|
+
"SK": "PROFILE#456",
|
|
77
|
+
}
|
|
78
|
+
`);
|
|
79
|
+
});
|
|
80
|
+
it("should decode with GSI2 values", () => {
|
|
81
|
+
const encoded = "eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYifQ==";
|
|
82
|
+
const result = pagination_1.decodeDDBCursor(encoded, "GSI2");
|
|
83
|
+
expect(result).toMatchInlineSnapshot(`
|
|
84
|
+
Object {
|
|
85
|
+
"GSI2PK": "GSI2PK#user123",
|
|
86
|
+
"GSI2SK": "GSI2SK#profile456",
|
|
87
|
+
"PK": "USER#123",
|
|
88
|
+
"SK": "PROFILE#456",
|
|
89
|
+
}
|
|
90
|
+
`);
|
|
91
|
+
});
|
|
92
|
+
it("should decode with GSI3 values", () => {
|
|
93
|
+
const encoded = "eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYiLCJHU0kzUEsiOiJHU0kzUEsjZml4ZWQiLCJHU0kzU0siOiJHU0kzU0sjdmFsdWUifQ==";
|
|
94
|
+
const result = pagination_1.decodeDDBCursor(encoded, "GSI3");
|
|
95
|
+
expect(result).toMatchInlineSnapshot(`
|
|
96
|
+
Object {
|
|
97
|
+
"GSI3PK": "GSI3PK#fixed",
|
|
98
|
+
"GSI3SK": "GSI3SK#value",
|
|
99
|
+
"PK": "USER#123",
|
|
100
|
+
"SK": "PROFILE#456",
|
|
101
|
+
}
|
|
102
|
+
`);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe("decoding with encryption", () => {
|
|
106
|
+
const encryptionKey = crypto_1.default.randomBytes(32);
|
|
107
|
+
it("should decode encrypted cursor", () => {
|
|
108
|
+
const input = {
|
|
109
|
+
PK: "USER#123",
|
|
110
|
+
SK: "PROFILE#456",
|
|
111
|
+
};
|
|
112
|
+
const encoded = pagination_1.encodeDDBCursor(input, encryptionKey);
|
|
113
|
+
const result = pagination_1.decodeDDBCursor(encoded, undefined, encryptionKey);
|
|
114
|
+
expect(result).toMatchInlineSnapshot(`
|
|
115
|
+
Object {
|
|
116
|
+
"PK": "USER#123",
|
|
117
|
+
"SK": "PROFILE#456",
|
|
118
|
+
}
|
|
119
|
+
`);
|
|
120
|
+
});
|
|
121
|
+
it("should decode encrypted cursor with GSI values", () => {
|
|
122
|
+
const input = {
|
|
123
|
+
PK: "USER#123",
|
|
124
|
+
SK: "PROFILE#456",
|
|
125
|
+
GSI2PK: "GSI2PK#user123",
|
|
126
|
+
GSI2SK: "GSI2SK#profile456",
|
|
127
|
+
};
|
|
128
|
+
const encoded = pagination_1.encodeDDBCursor(input, encryptionKey);
|
|
129
|
+
const result = pagination_1.decodeDDBCursor(encoded, "GSI2", encryptionKey);
|
|
130
|
+
expect(result).toMatchInlineSnapshot(`
|
|
131
|
+
Object {
|
|
132
|
+
"GSI2PK": "GSI2PK#user123",
|
|
133
|
+
"GSI2SK": "GSI2SK#profile456",
|
|
134
|
+
"PK": "USER#123",
|
|
135
|
+
"SK": "PROFILE#456",
|
|
136
|
+
}
|
|
137
|
+
`);
|
|
138
|
+
});
|
|
139
|
+
it("should throw PaginationError when decryption fails", () => {
|
|
140
|
+
const wrongKey = crypto_1.default.randomBytes(32);
|
|
141
|
+
const input = {
|
|
142
|
+
PK: "USER#123",
|
|
143
|
+
SK: "PROFILE#456",
|
|
144
|
+
};
|
|
145
|
+
const encoded = pagination_1.encodeDDBCursor(input, encryptionKey);
|
|
146
|
+
expect(() => {
|
|
147
|
+
pagination_1.decodeDDBCursor(encoded, undefined, wrongKey);
|
|
148
|
+
}).toThrow(errors_1.PaginationError);
|
|
149
|
+
expect(() => {
|
|
150
|
+
pagination_1.decodeDDBCursor(encoded, undefined, wrongKey);
|
|
151
|
+
}).toThrow("Couldn't decode cursor");
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
describe("error handling", () => {
|
|
155
|
+
it("should throw PaginationError for invalid base64", () => {
|
|
156
|
+
expect(() => {
|
|
157
|
+
pagination_1.decodeDDBCursor("invalid-base64");
|
|
158
|
+
}).toThrow(errors_1.PaginationError);
|
|
159
|
+
expect(() => {
|
|
160
|
+
pagination_1.decodeDDBCursor("invalid-base64");
|
|
161
|
+
}).toThrow("Couldn't decode cursor");
|
|
162
|
+
});
|
|
163
|
+
it("should throw PaginationError for invalid JSON", () => {
|
|
164
|
+
const invalidJson = Buffer.from("invalid json").toString("base64");
|
|
165
|
+
expect(() => {
|
|
166
|
+
pagination_1.decodeDDBCursor(invalidJson);
|
|
167
|
+
}).toThrow(errors_1.PaginationError);
|
|
168
|
+
});
|
|
169
|
+
it("should throw PaginationError when PK is missing", () => {
|
|
170
|
+
const invalidData = Buffer.from(JSON.stringify({ SK: "PROFILE#456" })).toString("base64");
|
|
171
|
+
expect(() => {
|
|
172
|
+
pagination_1.decodeDDBCursor(invalidData);
|
|
173
|
+
}).toThrow(errors_1.PaginationError);
|
|
174
|
+
});
|
|
175
|
+
it("should throw PaginationError when SK is missing", () => {
|
|
176
|
+
const invalidData = Buffer.from(JSON.stringify({ PK: "USER#123" })).toString("base64");
|
|
177
|
+
expect(() => {
|
|
178
|
+
pagination_1.decodeDDBCursor(invalidData);
|
|
179
|
+
}).toThrow(errors_1.PaginationError);
|
|
180
|
+
});
|
|
181
|
+
it("should throw PaginationError when PK is not a string", () => {
|
|
182
|
+
const invalidData = Buffer.from(JSON.stringify({ PK: 123, SK: "PROFILE#456" })).toString("base64");
|
|
183
|
+
expect(() => {
|
|
184
|
+
pagination_1.decodeDDBCursor(invalidData);
|
|
185
|
+
}).toThrow(errors_1.PaginationError);
|
|
186
|
+
});
|
|
187
|
+
it("should throw PaginationError when SK is not a string", () => {
|
|
188
|
+
const invalidData = Buffer.from(JSON.stringify({ PK: "USER#123", SK: 456 })).toString("base64");
|
|
189
|
+
expect(() => {
|
|
190
|
+
pagination_1.decodeDDBCursor(invalidData);
|
|
191
|
+
}).toThrow(errors_1.PaginationError);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
describe("round-trip encoding and decoding", () => {
|
|
195
|
+
it("should round-trip basic values", () => {
|
|
196
|
+
const input = {
|
|
197
|
+
PK: "USER#123",
|
|
198
|
+
SK: "PROFILE#456",
|
|
199
|
+
};
|
|
200
|
+
const encoded = pagination_1.encodeDDBCursor(input);
|
|
201
|
+
const decoded = pagination_1.decodeDDBCursor(encoded);
|
|
202
|
+
expect(decoded).toEqual(input);
|
|
203
|
+
});
|
|
204
|
+
it("should round-trip with GSI values", () => {
|
|
205
|
+
const input = {
|
|
206
|
+
PK: "USER#123",
|
|
207
|
+
SK: "PROFILE#456",
|
|
208
|
+
GSI2PK: "GSI2PK#user123",
|
|
209
|
+
GSI2SK: "GSI2SK#profile456",
|
|
210
|
+
GSI3PK: "GSI3PK#fixed",
|
|
211
|
+
GSI3SK: "GSI3SK#value",
|
|
212
|
+
};
|
|
213
|
+
const encoded = pagination_1.encodeDDBCursor(input);
|
|
214
|
+
const decoded = pagination_1.decodeDDBCursor(encoded, "GSI2");
|
|
215
|
+
expect(decoded).toEqual({
|
|
216
|
+
PK: input.PK,
|
|
217
|
+
SK: input.SK,
|
|
218
|
+
GSI2PK: input.GSI2PK,
|
|
219
|
+
GSI2SK: input.GSI2SK,
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
it("should round-trip with encryption", () => {
|
|
223
|
+
const encryptionKey = crypto_1.default.randomBytes(32);
|
|
224
|
+
const input = {
|
|
225
|
+
PK: "USER#123",
|
|
226
|
+
SK: "PROFILE#456",
|
|
227
|
+
GSI2PK: "GSI2PK#user123",
|
|
228
|
+
GSI2SK: "GSI2SK#profile456",
|
|
229
|
+
};
|
|
230
|
+
const encoded = pagination_1.encodeDDBCursor(input, encryptionKey);
|
|
231
|
+
const decoded = pagination_1.decodeDDBCursor(encoded, "GSI2", encryptionKey);
|
|
232
|
+
expect(decoded).toEqual({
|
|
233
|
+
PK: input.PK,
|
|
234
|
+
SK: input.SK,
|
|
235
|
+
GSI2PK: input.GSI2PK,
|
|
236
|
+
GSI2SK: input.GSI2SK,
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
//# sourceMappingURL=pagination.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.test.js","sourceRoot":"","sources":["../../../src/__test__/pagination.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/pagination.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export declare function decodePagination(pagination: PaginationInput, pagination
|
|
|
39
39
|
limit: number;
|
|
40
40
|
direction: PaginationDirection;
|
|
41
41
|
};
|
|
42
|
-
export declare const encodeDDBCursor: (
|
|
42
|
+
export declare const encodeDDBCursor: (item: {
|
|
43
43
|
PK: string;
|
|
44
44
|
SK: string;
|
|
45
45
|
} & {
|
package/dist/cjs/pagination.js
CHANGED
|
@@ -68,12 +68,10 @@ const decryptCursor = (key, encryptedCursor) => {
|
|
|
68
68
|
return null;
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
|
-
const encodeDDBCursor = (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
SK },
|
|
75
|
-
[`${GSI}PK`]: values[`${GSI}PK`],
|
|
76
|
-
[`${GSI}SK`]: values[`${GSI}SK`],
|
|
71
|
+
const encodeDDBCursor = (item, encryptionKey) => {
|
|
72
|
+
const cursor = Buffer.from(JSON.stringify(Object.assign({ PK: item.PK, SK: item.SK }, gsi_1.GSI_NAMES.map((GSI) => ({
|
|
73
|
+
[`${GSI}PK`]: item[`${GSI}PK`],
|
|
74
|
+
[`${GSI}SK`]: item[`${GSI}SK`],
|
|
77
75
|
})).reduce((acc, cur) => Object.assign(acc, cur), {})))).toString("base64");
|
|
78
76
|
if (encryptionKey)
|
|
79
77
|
return encryptCursor(encryptionKey, cursor);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/pagination.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/pagination.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import { encodeDDBCursor, decodeDDBCursor } from "../pagination";
|
|
3
|
+
import { PaginationError } from "../errors";
|
|
4
|
+
describe("encodeDDBCursor", () => {
|
|
5
|
+
describe("basic encoding without encryption", () => {
|
|
6
|
+
it("should encode basic PK and SK", () => {
|
|
7
|
+
const result = encodeDDBCursor({
|
|
8
|
+
PK: "USER#123",
|
|
9
|
+
SK: "PROFILE#456",
|
|
10
|
+
});
|
|
11
|
+
expect(result).toMatchInlineSnapshot(`"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiJ9"`);
|
|
12
|
+
});
|
|
13
|
+
it("should encode with GSI2 values", () => {
|
|
14
|
+
const result = encodeDDBCursor({
|
|
15
|
+
PK: "USER#123",
|
|
16
|
+
SK: "PROFILE#456",
|
|
17
|
+
GSI2PK: "GSI2PK#user123",
|
|
18
|
+
GSI2SK: "GSI2SK#profile456",
|
|
19
|
+
});
|
|
20
|
+
expect(result).toMatchInlineSnapshot(`"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYifQ=="`);
|
|
21
|
+
});
|
|
22
|
+
it("should encode with multiple GSI values", () => {
|
|
23
|
+
const result = encodeDDBCursor({
|
|
24
|
+
PK: "USER#123",
|
|
25
|
+
SK: "PROFILE#456",
|
|
26
|
+
GSI2PK: "GSI2PK#user123",
|
|
27
|
+
GSI2SK: "GSI2SK#profile456",
|
|
28
|
+
GSI3PK: "GSI3PK#fixed",
|
|
29
|
+
GSI3SK: "GSI3SK#value",
|
|
30
|
+
});
|
|
31
|
+
expect(result).toMatchInlineSnapshot(`"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYiLCJHU0kzUEsiOiJHU0kzUEsjZml4ZWQiLCJHU0kzU0siOiJHU0kzU0sjdmFsdWUifQ=="`);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe("encoding with encryption", () => {
|
|
35
|
+
const encryptionKey = crypto.randomBytes(32);
|
|
36
|
+
it("should encrypt the cursor when encryption key is provided", () => {
|
|
37
|
+
const result = encodeDDBCursor({
|
|
38
|
+
PK: "USER#123",
|
|
39
|
+
SK: "PROFILE#456",
|
|
40
|
+
}, encryptionKey);
|
|
41
|
+
// The result should be encrypted and different from the unencrypted version
|
|
42
|
+
expect(result).not.toBe("eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiJ9");
|
|
43
|
+
expect(result).toMatch(/^[A-Za-z0-9+/=]+$/); // Base64 format
|
|
44
|
+
});
|
|
45
|
+
it("should produce consistent encrypted results for same input", () => {
|
|
46
|
+
const input = {
|
|
47
|
+
PK: "USER#123",
|
|
48
|
+
SK: "PROFILE#456",
|
|
49
|
+
};
|
|
50
|
+
const result1 = encodeDDBCursor(input, encryptionKey);
|
|
51
|
+
const result2 = encodeDDBCursor(input, encryptionKey);
|
|
52
|
+
expect(result1).toBe(result2);
|
|
53
|
+
});
|
|
54
|
+
it("should encrypt with GSI values", () => {
|
|
55
|
+
const result = encodeDDBCursor({
|
|
56
|
+
PK: "USER#123",
|
|
57
|
+
SK: "PROFILE#456",
|
|
58
|
+
GSI2PK: "GSI2PK#user123",
|
|
59
|
+
GSI2SK: "GSI2SK#profile456",
|
|
60
|
+
}, encryptionKey);
|
|
61
|
+
expect(result).toMatch(/^[A-Za-z0-9+/=]+$/);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe("decodeDDBCursor", () => {
|
|
66
|
+
describe("basic decoding without encryption", () => {
|
|
67
|
+
it("should decode basic PK and SK", () => {
|
|
68
|
+
const encoded = "eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiJ9";
|
|
69
|
+
const result = decodeDDBCursor(encoded);
|
|
70
|
+
expect(result).toMatchInlineSnapshot(`
|
|
71
|
+
Object {
|
|
72
|
+
"PK": "USER#123",
|
|
73
|
+
"SK": "PROFILE#456",
|
|
74
|
+
}
|
|
75
|
+
`);
|
|
76
|
+
});
|
|
77
|
+
it("should decode with GSI2 values", () => {
|
|
78
|
+
const encoded = "eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYifQ==";
|
|
79
|
+
const result = decodeDDBCursor(encoded, "GSI2");
|
|
80
|
+
expect(result).toMatchInlineSnapshot(`
|
|
81
|
+
Object {
|
|
82
|
+
"GSI2PK": "GSI2PK#user123",
|
|
83
|
+
"GSI2SK": "GSI2SK#profile456",
|
|
84
|
+
"PK": "USER#123",
|
|
85
|
+
"SK": "PROFILE#456",
|
|
86
|
+
}
|
|
87
|
+
`);
|
|
88
|
+
});
|
|
89
|
+
it("should decode with GSI3 values", () => {
|
|
90
|
+
const encoded = "eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYiLCJHU0kzUEsiOiJHU0kzUEsjZml4ZWQiLCJHU0kzU0siOiJHU0kzU0sjdmFsdWUifQ==";
|
|
91
|
+
const result = decodeDDBCursor(encoded, "GSI3");
|
|
92
|
+
expect(result).toMatchInlineSnapshot(`
|
|
93
|
+
Object {
|
|
94
|
+
"GSI3PK": "GSI3PK#fixed",
|
|
95
|
+
"GSI3SK": "GSI3SK#value",
|
|
96
|
+
"PK": "USER#123",
|
|
97
|
+
"SK": "PROFILE#456",
|
|
98
|
+
}
|
|
99
|
+
`);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe("decoding with encryption", () => {
|
|
103
|
+
const encryptionKey = crypto.randomBytes(32);
|
|
104
|
+
it("should decode encrypted cursor", () => {
|
|
105
|
+
const input = {
|
|
106
|
+
PK: "USER#123",
|
|
107
|
+
SK: "PROFILE#456",
|
|
108
|
+
};
|
|
109
|
+
const encoded = encodeDDBCursor(input, encryptionKey);
|
|
110
|
+
const result = decodeDDBCursor(encoded, undefined, encryptionKey);
|
|
111
|
+
expect(result).toMatchInlineSnapshot(`
|
|
112
|
+
Object {
|
|
113
|
+
"PK": "USER#123",
|
|
114
|
+
"SK": "PROFILE#456",
|
|
115
|
+
}
|
|
116
|
+
`);
|
|
117
|
+
});
|
|
118
|
+
it("should decode encrypted cursor with GSI values", () => {
|
|
119
|
+
const input = {
|
|
120
|
+
PK: "USER#123",
|
|
121
|
+
SK: "PROFILE#456",
|
|
122
|
+
GSI2PK: "GSI2PK#user123",
|
|
123
|
+
GSI2SK: "GSI2SK#profile456",
|
|
124
|
+
};
|
|
125
|
+
const encoded = encodeDDBCursor(input, encryptionKey);
|
|
126
|
+
const result = decodeDDBCursor(encoded, "GSI2", encryptionKey);
|
|
127
|
+
expect(result).toMatchInlineSnapshot(`
|
|
128
|
+
Object {
|
|
129
|
+
"GSI2PK": "GSI2PK#user123",
|
|
130
|
+
"GSI2SK": "GSI2SK#profile456",
|
|
131
|
+
"PK": "USER#123",
|
|
132
|
+
"SK": "PROFILE#456",
|
|
133
|
+
}
|
|
134
|
+
`);
|
|
135
|
+
});
|
|
136
|
+
it("should throw PaginationError when decryption fails", () => {
|
|
137
|
+
const wrongKey = crypto.randomBytes(32);
|
|
138
|
+
const input = {
|
|
139
|
+
PK: "USER#123",
|
|
140
|
+
SK: "PROFILE#456",
|
|
141
|
+
};
|
|
142
|
+
const encoded = encodeDDBCursor(input, encryptionKey);
|
|
143
|
+
expect(() => {
|
|
144
|
+
decodeDDBCursor(encoded, undefined, wrongKey);
|
|
145
|
+
}).toThrow(PaginationError);
|
|
146
|
+
expect(() => {
|
|
147
|
+
decodeDDBCursor(encoded, undefined, wrongKey);
|
|
148
|
+
}).toThrow("Couldn't decode cursor");
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
describe("error handling", () => {
|
|
152
|
+
it("should throw PaginationError for invalid base64", () => {
|
|
153
|
+
expect(() => {
|
|
154
|
+
decodeDDBCursor("invalid-base64");
|
|
155
|
+
}).toThrow(PaginationError);
|
|
156
|
+
expect(() => {
|
|
157
|
+
decodeDDBCursor("invalid-base64");
|
|
158
|
+
}).toThrow("Couldn't decode cursor");
|
|
159
|
+
});
|
|
160
|
+
it("should throw PaginationError for invalid JSON", () => {
|
|
161
|
+
const invalidJson = Buffer.from("invalid json").toString("base64");
|
|
162
|
+
expect(() => {
|
|
163
|
+
decodeDDBCursor(invalidJson);
|
|
164
|
+
}).toThrow(PaginationError);
|
|
165
|
+
});
|
|
166
|
+
it("should throw PaginationError when PK is missing", () => {
|
|
167
|
+
const invalidData = Buffer.from(JSON.stringify({ SK: "PROFILE#456" })).toString("base64");
|
|
168
|
+
expect(() => {
|
|
169
|
+
decodeDDBCursor(invalidData);
|
|
170
|
+
}).toThrow(PaginationError);
|
|
171
|
+
});
|
|
172
|
+
it("should throw PaginationError when SK is missing", () => {
|
|
173
|
+
const invalidData = Buffer.from(JSON.stringify({ PK: "USER#123" })).toString("base64");
|
|
174
|
+
expect(() => {
|
|
175
|
+
decodeDDBCursor(invalidData);
|
|
176
|
+
}).toThrow(PaginationError);
|
|
177
|
+
});
|
|
178
|
+
it("should throw PaginationError when PK is not a string", () => {
|
|
179
|
+
const invalidData = Buffer.from(JSON.stringify({ PK: 123, SK: "PROFILE#456" })).toString("base64");
|
|
180
|
+
expect(() => {
|
|
181
|
+
decodeDDBCursor(invalidData);
|
|
182
|
+
}).toThrow(PaginationError);
|
|
183
|
+
});
|
|
184
|
+
it("should throw PaginationError when SK is not a string", () => {
|
|
185
|
+
const invalidData = Buffer.from(JSON.stringify({ PK: "USER#123", SK: 456 })).toString("base64");
|
|
186
|
+
expect(() => {
|
|
187
|
+
decodeDDBCursor(invalidData);
|
|
188
|
+
}).toThrow(PaginationError);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
describe("round-trip encoding and decoding", () => {
|
|
192
|
+
it("should round-trip basic values", () => {
|
|
193
|
+
const input = {
|
|
194
|
+
PK: "USER#123",
|
|
195
|
+
SK: "PROFILE#456",
|
|
196
|
+
};
|
|
197
|
+
const encoded = encodeDDBCursor(input);
|
|
198
|
+
const decoded = decodeDDBCursor(encoded);
|
|
199
|
+
expect(decoded).toEqual(input);
|
|
200
|
+
});
|
|
201
|
+
it("should round-trip with GSI values", () => {
|
|
202
|
+
const input = {
|
|
203
|
+
PK: "USER#123",
|
|
204
|
+
SK: "PROFILE#456",
|
|
205
|
+
GSI2PK: "GSI2PK#user123",
|
|
206
|
+
GSI2SK: "GSI2SK#profile456",
|
|
207
|
+
GSI3PK: "GSI3PK#fixed",
|
|
208
|
+
GSI3SK: "GSI3SK#value",
|
|
209
|
+
};
|
|
210
|
+
const encoded = encodeDDBCursor(input);
|
|
211
|
+
const decoded = decodeDDBCursor(encoded, "GSI2");
|
|
212
|
+
expect(decoded).toEqual({
|
|
213
|
+
PK: input.PK,
|
|
214
|
+
SK: input.SK,
|
|
215
|
+
GSI2PK: input.GSI2PK,
|
|
216
|
+
GSI2SK: input.GSI2SK,
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
it("should round-trip with encryption", () => {
|
|
220
|
+
const encryptionKey = crypto.randomBytes(32);
|
|
221
|
+
const input = {
|
|
222
|
+
PK: "USER#123",
|
|
223
|
+
SK: "PROFILE#456",
|
|
224
|
+
GSI2PK: "GSI2PK#user123",
|
|
225
|
+
GSI2SK: "GSI2SK#profile456",
|
|
226
|
+
};
|
|
227
|
+
const encoded = encodeDDBCursor(input, encryptionKey);
|
|
228
|
+
const decoded = decodeDDBCursor(encoded, "GSI2", encryptionKey);
|
|
229
|
+
expect(decoded).toEqual({
|
|
230
|
+
PK: input.PK,
|
|
231
|
+
SK: input.SK,
|
|
232
|
+
GSI2PK: input.GSI2PK,
|
|
233
|
+
GSI2SK: input.GSI2SK,
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
//# sourceMappingURL=pagination.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.test.js","sourceRoot":"","sources":["../../../src/__test__/pagination.test.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/pagination.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export declare function decodePagination(pagination: PaginationInput, pagination
|
|
|
39
39
|
limit: number;
|
|
40
40
|
direction: PaginationDirection;
|
|
41
41
|
};
|
|
42
|
-
export declare const encodeDDBCursor: (
|
|
42
|
+
export declare const encodeDDBCursor: (item: {
|
|
43
43
|
PK: string;
|
|
44
44
|
SK: string;
|
|
45
45
|
} & {
|
package/dist/esm/pagination.js
CHANGED
|
@@ -64,12 +64,10 @@ const decryptCursor = (key, encryptedCursor) => {
|
|
|
64
64
|
return null;
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
|
-
export const encodeDDBCursor = (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
SK },
|
|
71
|
-
[`${GSI}PK`]: values[`${GSI}PK`],
|
|
72
|
-
[`${GSI}SK`]: values[`${GSI}SK`],
|
|
67
|
+
export const encodeDDBCursor = (item, encryptionKey) => {
|
|
68
|
+
const cursor = Buffer.from(JSON.stringify(Object.assign({ PK: item.PK, SK: item.SK }, GSI_NAMES.map((GSI) => ({
|
|
69
|
+
[`${GSI}PK`]: item[`${GSI}PK`],
|
|
70
|
+
[`${GSI}SK`]: item[`${GSI}SK`],
|
|
73
71
|
})).reduce((acc, cur) => Object.assign(acc, cur), {})))).toString("base64");
|
|
74
72
|
if (encryptionKey)
|
|
75
73
|
return encryptCursor(encryptionKey, cursor);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/pagination.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/pagination.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import crypto from "crypto"
|
|
2
|
+
import { encodeDDBCursor, decodeDDBCursor } from "../pagination"
|
|
3
|
+
import { PaginationError } from "../errors"
|
|
4
|
+
|
|
5
|
+
describe("encodeDDBCursor", () => {
|
|
6
|
+
describe("basic encoding without encryption", () => {
|
|
7
|
+
it("should encode basic PK and SK", () => {
|
|
8
|
+
const result = encodeDDBCursor({
|
|
9
|
+
PK: "USER#123",
|
|
10
|
+
SK: "PROFILE#456",
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
expect(result).toMatchInlineSnapshot(
|
|
14
|
+
`"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiJ9"`
|
|
15
|
+
)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it("should encode with GSI2 values", () => {
|
|
19
|
+
const result = encodeDDBCursor({
|
|
20
|
+
PK: "USER#123",
|
|
21
|
+
SK: "PROFILE#456",
|
|
22
|
+
GSI2PK: "GSI2PK#user123",
|
|
23
|
+
GSI2SK: "GSI2SK#profile456",
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
expect(result).toMatchInlineSnapshot(
|
|
27
|
+
`"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYifQ=="`
|
|
28
|
+
)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it("should encode with multiple GSI values", () => {
|
|
32
|
+
const result = encodeDDBCursor({
|
|
33
|
+
PK: "USER#123",
|
|
34
|
+
SK: "PROFILE#456",
|
|
35
|
+
GSI2PK: "GSI2PK#user123",
|
|
36
|
+
GSI2SK: "GSI2SK#profile456",
|
|
37
|
+
GSI3PK: "GSI3PK#fixed",
|
|
38
|
+
GSI3SK: "GSI3SK#value",
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
expect(result).toMatchInlineSnapshot(
|
|
42
|
+
`"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYiLCJHU0kzUEsiOiJHU0kzUEsjZml4ZWQiLCJHU0kzU0siOiJHU0kzU0sjdmFsdWUifQ=="`
|
|
43
|
+
)
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe("encoding with encryption", () => {
|
|
48
|
+
const encryptionKey = crypto.randomBytes(32)
|
|
49
|
+
|
|
50
|
+
it("should encrypt the cursor when encryption key is provided", () => {
|
|
51
|
+
const result = encodeDDBCursor(
|
|
52
|
+
{
|
|
53
|
+
PK: "USER#123",
|
|
54
|
+
SK: "PROFILE#456",
|
|
55
|
+
},
|
|
56
|
+
encryptionKey
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
// The result should be encrypted and different from the unencrypted version
|
|
60
|
+
expect(result).not.toBe(
|
|
61
|
+
"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiJ9"
|
|
62
|
+
)
|
|
63
|
+
expect(result).toMatch(/^[A-Za-z0-9+/=]+$/) // Base64 format
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it("should produce consistent encrypted results for same input", () => {
|
|
67
|
+
const input = {
|
|
68
|
+
PK: "USER#123",
|
|
69
|
+
SK: "PROFILE#456",
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const result1 = encodeDDBCursor(input, encryptionKey)
|
|
73
|
+
const result2 = encodeDDBCursor(input, encryptionKey)
|
|
74
|
+
|
|
75
|
+
expect(result1).toBe(result2)
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it("should encrypt with GSI values", () => {
|
|
79
|
+
const result = encodeDDBCursor(
|
|
80
|
+
{
|
|
81
|
+
PK: "USER#123",
|
|
82
|
+
SK: "PROFILE#456",
|
|
83
|
+
GSI2PK: "GSI2PK#user123",
|
|
84
|
+
GSI2SK: "GSI2SK#profile456",
|
|
85
|
+
},
|
|
86
|
+
encryptionKey
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
expect(result).toMatch(/^[A-Za-z0-9+/=]+$/)
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
describe("decodeDDBCursor", () => {
|
|
95
|
+
describe("basic decoding without encryption", () => {
|
|
96
|
+
it("should decode basic PK and SK", () => {
|
|
97
|
+
const encoded = "eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiJ9"
|
|
98
|
+
const result = decodeDDBCursor(encoded)
|
|
99
|
+
|
|
100
|
+
expect(result).toMatchInlineSnapshot(`
|
|
101
|
+
Object {
|
|
102
|
+
"PK": "USER#123",
|
|
103
|
+
"SK": "PROFILE#456",
|
|
104
|
+
}
|
|
105
|
+
`)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it("should decode with GSI2 values", () => {
|
|
109
|
+
const encoded =
|
|
110
|
+
"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYifQ=="
|
|
111
|
+
const result = decodeDDBCursor(encoded, "GSI2")
|
|
112
|
+
|
|
113
|
+
expect(result).toMatchInlineSnapshot(`
|
|
114
|
+
Object {
|
|
115
|
+
"GSI2PK": "GSI2PK#user123",
|
|
116
|
+
"GSI2SK": "GSI2SK#profile456",
|
|
117
|
+
"PK": "USER#123",
|
|
118
|
+
"SK": "PROFILE#456",
|
|
119
|
+
}
|
|
120
|
+
`)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it("should decode with GSI3 values", () => {
|
|
124
|
+
const encoded =
|
|
125
|
+
"eyJQSyI6IlVTRVIjMTIzIiwiU0siOiJQUk9GSUxFIzQ1NiIsIkdTSTJQSyI6IkdTSTJQSyN1c2VyMTIzIiwiR1NJMlNLIjoiR1NJMlNLI3Byb2ZpbGU0NTYiLCJHU0kzUEsiOiJHU0kzUEsjZml4ZWQiLCJHU0kzU0siOiJHU0kzU0sjdmFsdWUifQ=="
|
|
126
|
+
const result = decodeDDBCursor(encoded, "GSI3")
|
|
127
|
+
|
|
128
|
+
expect(result).toMatchInlineSnapshot(`
|
|
129
|
+
Object {
|
|
130
|
+
"GSI3PK": "GSI3PK#fixed",
|
|
131
|
+
"GSI3SK": "GSI3SK#value",
|
|
132
|
+
"PK": "USER#123",
|
|
133
|
+
"SK": "PROFILE#456",
|
|
134
|
+
}
|
|
135
|
+
`)
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
describe("decoding with encryption", () => {
|
|
140
|
+
const encryptionKey = crypto.randomBytes(32)
|
|
141
|
+
|
|
142
|
+
it("should decode encrypted cursor", () => {
|
|
143
|
+
const input = {
|
|
144
|
+
PK: "USER#123",
|
|
145
|
+
SK: "PROFILE#456",
|
|
146
|
+
}
|
|
147
|
+
const encoded = encodeDDBCursor(input, encryptionKey)
|
|
148
|
+
const result = decodeDDBCursor(encoded, undefined, encryptionKey)
|
|
149
|
+
|
|
150
|
+
expect(result).toMatchInlineSnapshot(`
|
|
151
|
+
Object {
|
|
152
|
+
"PK": "USER#123",
|
|
153
|
+
"SK": "PROFILE#456",
|
|
154
|
+
}
|
|
155
|
+
`)
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it("should decode encrypted cursor with GSI values", () => {
|
|
159
|
+
const input = {
|
|
160
|
+
PK: "USER#123",
|
|
161
|
+
SK: "PROFILE#456",
|
|
162
|
+
GSI2PK: "GSI2PK#user123",
|
|
163
|
+
GSI2SK: "GSI2SK#profile456",
|
|
164
|
+
}
|
|
165
|
+
const encoded = encodeDDBCursor(input, encryptionKey)
|
|
166
|
+
const result = decodeDDBCursor(encoded, "GSI2", encryptionKey)
|
|
167
|
+
|
|
168
|
+
expect(result).toMatchInlineSnapshot(`
|
|
169
|
+
Object {
|
|
170
|
+
"GSI2PK": "GSI2PK#user123",
|
|
171
|
+
"GSI2SK": "GSI2SK#profile456",
|
|
172
|
+
"PK": "USER#123",
|
|
173
|
+
"SK": "PROFILE#456",
|
|
174
|
+
}
|
|
175
|
+
`)
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it("should throw PaginationError when decryption fails", () => {
|
|
179
|
+
const wrongKey = crypto.randomBytes(32)
|
|
180
|
+
const input = {
|
|
181
|
+
PK: "USER#123",
|
|
182
|
+
SK: "PROFILE#456",
|
|
183
|
+
}
|
|
184
|
+
const encoded = encodeDDBCursor(input, encryptionKey)
|
|
185
|
+
|
|
186
|
+
expect(() => {
|
|
187
|
+
decodeDDBCursor(encoded, undefined, wrongKey)
|
|
188
|
+
}).toThrow(PaginationError)
|
|
189
|
+
expect(() => {
|
|
190
|
+
decodeDDBCursor(encoded, undefined, wrongKey)
|
|
191
|
+
}).toThrow("Couldn't decode cursor")
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
describe("error handling", () => {
|
|
196
|
+
it("should throw PaginationError for invalid base64", () => {
|
|
197
|
+
expect(() => {
|
|
198
|
+
decodeDDBCursor("invalid-base64")
|
|
199
|
+
}).toThrow(PaginationError)
|
|
200
|
+
expect(() => {
|
|
201
|
+
decodeDDBCursor("invalid-base64")
|
|
202
|
+
}).toThrow("Couldn't decode cursor")
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
it("should throw PaginationError for invalid JSON", () => {
|
|
206
|
+
const invalidJson = Buffer.from("invalid json").toString("base64")
|
|
207
|
+
expect(() => {
|
|
208
|
+
decodeDDBCursor(invalidJson)
|
|
209
|
+
}).toThrow(PaginationError)
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
it("should throw PaginationError when PK is missing", () => {
|
|
213
|
+
const invalidData = Buffer.from(
|
|
214
|
+
JSON.stringify({ SK: "PROFILE#456" })
|
|
215
|
+
).toString("base64")
|
|
216
|
+
expect(() => {
|
|
217
|
+
decodeDDBCursor(invalidData)
|
|
218
|
+
}).toThrow(PaginationError)
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
it("should throw PaginationError when SK is missing", () => {
|
|
222
|
+
const invalidData = Buffer.from(
|
|
223
|
+
JSON.stringify({ PK: "USER#123" })
|
|
224
|
+
).toString("base64")
|
|
225
|
+
expect(() => {
|
|
226
|
+
decodeDDBCursor(invalidData)
|
|
227
|
+
}).toThrow(PaginationError)
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
it("should throw PaginationError when PK is not a string", () => {
|
|
231
|
+
const invalidData = Buffer.from(
|
|
232
|
+
JSON.stringify({ PK: 123, SK: "PROFILE#456" })
|
|
233
|
+
).toString("base64")
|
|
234
|
+
expect(() => {
|
|
235
|
+
decodeDDBCursor(invalidData)
|
|
236
|
+
}).toThrow(PaginationError)
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
it("should throw PaginationError when SK is not a string", () => {
|
|
240
|
+
const invalidData = Buffer.from(
|
|
241
|
+
JSON.stringify({ PK: "USER#123", SK: 456 })
|
|
242
|
+
).toString("base64")
|
|
243
|
+
expect(() => {
|
|
244
|
+
decodeDDBCursor(invalidData)
|
|
245
|
+
}).toThrow(PaginationError)
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
describe("round-trip encoding and decoding", () => {
|
|
250
|
+
it("should round-trip basic values", () => {
|
|
251
|
+
const input = {
|
|
252
|
+
PK: "USER#123",
|
|
253
|
+
SK: "PROFILE#456",
|
|
254
|
+
}
|
|
255
|
+
const encoded = encodeDDBCursor(input)
|
|
256
|
+
const decoded = decodeDDBCursor(encoded)
|
|
257
|
+
|
|
258
|
+
expect(decoded).toEqual(input)
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
it("should round-trip with GSI values", () => {
|
|
262
|
+
const input = {
|
|
263
|
+
PK: "USER#123",
|
|
264
|
+
SK: "PROFILE#456",
|
|
265
|
+
GSI2PK: "GSI2PK#user123",
|
|
266
|
+
GSI2SK: "GSI2SK#profile456",
|
|
267
|
+
GSI3PK: "GSI3PK#fixed",
|
|
268
|
+
GSI3SK: "GSI3SK#value",
|
|
269
|
+
}
|
|
270
|
+
const encoded = encodeDDBCursor(input)
|
|
271
|
+
const decoded = decodeDDBCursor(encoded, "GSI2")
|
|
272
|
+
|
|
273
|
+
expect(decoded).toEqual({
|
|
274
|
+
PK: input.PK,
|
|
275
|
+
SK: input.SK,
|
|
276
|
+
GSI2PK: input.GSI2PK,
|
|
277
|
+
GSI2SK: input.GSI2SK,
|
|
278
|
+
})
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
it("should round-trip with encryption", () => {
|
|
282
|
+
const encryptionKey = crypto.randomBytes(32)
|
|
283
|
+
const input = {
|
|
284
|
+
PK: "USER#123",
|
|
285
|
+
SK: "PROFILE#456",
|
|
286
|
+
GSI2PK: "GSI2PK#user123",
|
|
287
|
+
GSI2SK: "GSI2SK#profile456",
|
|
288
|
+
}
|
|
289
|
+
const encoded = encodeDDBCursor(input, encryptionKey)
|
|
290
|
+
const decoded = decodeDDBCursor(encoded, "GSI2", encryptionKey)
|
|
291
|
+
|
|
292
|
+
expect(decoded).toEqual({
|
|
293
|
+
PK: input.PK,
|
|
294
|
+
SK: input.SK,
|
|
295
|
+
GSI2PK: input.GSI2PK,
|
|
296
|
+
GSI2SK: input.GSI2SK,
|
|
297
|
+
})
|
|
298
|
+
})
|
|
299
|
+
})
|
|
300
|
+
})
|
package/src/pagination.ts
CHANGED
|
@@ -132,11 +132,7 @@ const decryptCursor = (key: Buffer, encryptedCursor: string) => {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
export const encodeDDBCursor = (
|
|
135
|
-
{
|
|
136
|
-
PK,
|
|
137
|
-
SK,
|
|
138
|
-
...values
|
|
139
|
-
}: {
|
|
135
|
+
item: {
|
|
140
136
|
PK: string
|
|
141
137
|
SK: string
|
|
142
138
|
} & { [key in GSIPK]?: string } &
|
|
@@ -145,11 +141,11 @@ export const encodeDDBCursor = (
|
|
|
145
141
|
) => {
|
|
146
142
|
const cursor = Buffer.from(
|
|
147
143
|
JSON.stringify({
|
|
148
|
-
PK,
|
|
149
|
-
SK,
|
|
144
|
+
PK: item.PK,
|
|
145
|
+
SK: item.SK,
|
|
150
146
|
...GSI_NAMES.map((GSI) => ({
|
|
151
|
-
[`${GSI}PK`]:
|
|
152
|
-
[`${GSI}SK`]:
|
|
147
|
+
[`${GSI}PK`]: item[`${GSI}PK` as const],
|
|
148
|
+
[`${GSI}SK`]: item[`${GSI}SK` as const],
|
|
153
149
|
})).reduce((acc, cur) => Object.assign(acc, cur), {}),
|
|
154
150
|
})
|
|
155
151
|
).toString("base64")
|