@model-ts/dynamodb 3.0.4 → 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.
@@ -8,7 +8,7 @@ import {
8
8
  ItemNotFoundError,
9
9
  ConditionalCheckFailedError,
10
10
  RaceConditionError,
11
- BulkWriteTransactionError
11
+ BulkWriteTransactionError,
12
12
  } from "../errors"
13
13
 
14
14
  const client = new Client({ tableName: "table" })
@@ -16,7 +16,7 @@ const provider = getProvider(client)
16
16
 
17
17
  const SIMPLE_CODEC = t.type({
18
18
  foo: t.string,
19
- bar: t.number
19
+ bar: t.number,
20
20
  })
21
21
 
22
22
  class Simple extends model("Simple", SIMPLE_CODEC, provider) {
@@ -335,7 +335,7 @@ describe("put", () => {
335
335
 
336
336
  await expect(
337
337
  MultiGSI.put(new MultiGSI({ foo: "yes", bar: 42 }), {
338
- IgnoreExistence: true
338
+ IgnoreExistence: true,
339
339
  })
340
340
  ).resolves.toBeInstanceOf(MultiGSI)
341
341
  })
@@ -355,7 +355,7 @@ describe("get", () => {
355
355
 
356
356
  const result = await Simple.get({
357
357
  PK: item.keys().PK,
358
- SK: item.keys().SK
358
+ SK: item.keys().SK,
359
359
  })
360
360
 
361
361
  expect(result.values()).toMatchInlineSnapshot(`
@@ -421,8 +421,8 @@ describe("delete", () => {
421
421
  _model: Simple,
422
422
  key: {
423
423
  PK: item.keys().PK,
424
- SK: item.keys().SK
425
- }
424
+ SK: item.keys().SK,
425
+ },
426
426
  })
427
427
 
428
428
  expect(result).toBeNull()
@@ -455,7 +455,7 @@ describe("delete", () => {
455
455
 
456
456
  const result = await Simple.delete({
457
457
  PK: item.keys().PK,
458
- SK: item.keys().SK
458
+ SK: item.keys().SK,
459
459
  })
460
460
 
461
461
  expect(result).toBeNull()
@@ -825,16 +825,17 @@ describe("applyUpdate", () => {
825
825
  })
826
826
 
827
827
  describe("query", () => {
828
- test("it returns empty results", async () => {
829
- expect(
830
- await client.query(
831
- {
832
- KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
833
- ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT" }
834
- },
835
- { a: A, b: B, union: Union }
836
- )
837
- ).toMatchInlineSnapshot(`
828
+ describe("via client", () => {
829
+ test("it returns empty results", async () => {
830
+ expect(
831
+ await client.query(
832
+ {
833
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
834
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT" },
835
+ },
836
+ { a: A, b: B, union: Union }
837
+ )
838
+ ).toMatchInlineSnapshot(`
838
839
  Object {
839
840
  "_unknown": Array [],
840
841
  "a": Array [],
@@ -845,20 +846,20 @@ describe("query", () => {
845
846
  "union": Array [],
846
847
  }
847
848
  `)
848
- })
849
+ })
849
850
 
850
- test("it returns unknown results", async () => {
851
- await sandbox.seed({ PK: "abc", SK: "SORT#1", doesnt: "match" })
851
+ test("it returns unknown results", async () => {
852
+ await sandbox.seed({ PK: "abc", SK: "SORT#1", doesnt: "match" })
852
853
 
853
- expect(
854
- await client.query(
855
- {
856
- KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
857
- ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" }
858
- },
859
- { a: A, b: B, union: Union }
860
- )
861
- ).toMatchInlineSnapshot(`
854
+ expect(
855
+ await client.query(
856
+ {
857
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
858
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
859
+ },
860
+ { a: A, b: B, union: Union }
861
+ )
862
+ ).toMatchInlineSnapshot(`
862
863
  Object {
863
864
  "_unknown": Array [
864
865
  Object {
@@ -875,33 +876,33 @@ describe("query", () => {
875
876
  "union": Array [],
876
877
  }
877
878
  `)
878
- })
879
+ })
879
880
 
880
- test("it returns results", async () => {
881
- await sandbox.seed(
882
- new A({ pk: "abc", sk: "SORT#1", a: 1 }),
883
- new A({ pk: "abc", sk: "SORT#2", a: 2 }),
884
- new B({ pk: "abc", sk: "SORT#3", b: "hi" }),
885
- { PK: "abc", SK: "SORT#4", probably: "unknown" },
886
- new C({ pk: "abc", sk: "SORT#5", c: "hi" }),
887
- new D({ pk: "abc", sk: "SORT#6", d: "hi" })
888
- )
881
+ test("it returns results", async () => {
882
+ await sandbox.seed(
883
+ new A({ pk: "abc", sk: "SORT#1", a: 1 }),
884
+ new A({ pk: "abc", sk: "SORT#2", a: 2 }),
885
+ new B({ pk: "abc", sk: "SORT#3", b: "hi" }),
886
+ { PK: "abc", SK: "SORT#4", probably: "unknown" },
887
+ new C({ pk: "abc", sk: "SORT#5", c: "hi" }),
888
+ new D({ pk: "abc", sk: "SORT#6", d: "hi" })
889
+ )
889
890
 
890
- const { a, b, union, _unknown, meta } = await client.query(
891
- {
892
- KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
893
- ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" }
894
- },
895
- { a: A, b: B, union: Union }
896
- )
891
+ const { a, b, union, _unknown, meta } = await client.query(
892
+ {
893
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
894
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
895
+ },
896
+ { a: A, b: B, union: Union }
897
+ )
897
898
 
898
- expect({
899
- meta: meta,
900
- _unknown: _unknown,
901
- a: a.map(item => item.values()),
902
- b: b.map(item => item.values()),
903
- union: union.map(item => item.values())
904
- }).toMatchInlineSnapshot(`
899
+ expect({
900
+ meta: meta,
901
+ _unknown: _unknown,
902
+ a: a.map((item) => item.values()),
903
+ b: b.map((item) => item.values()),
904
+ union: union.map((item) => item.values()),
905
+ }).toMatchInlineSnapshot(`
905
906
  Object {
906
907
  "_unknown": Array [
907
908
  Object {
@@ -946,75 +947,278 @@ describe("query", () => {
946
947
  ],
947
948
  }
948
949
  `)
950
+ })
951
+
952
+ test("it paginates", async () => {
953
+ await sandbox.seed(
954
+ ...Array.from({ length: 20 }).map(
955
+ (_, i) =>
956
+ new A({ pk: "abc", sk: `SORT#${String(i).padStart(2, "0")}`, a: i })
957
+ ),
958
+ ...Array.from({ length: 20 }).map(
959
+ (_, i) => new B({ pk: "abc", sk: `SORT#${i + 20}`, b: "bar" })
960
+ )
961
+ )
962
+
963
+ const firstPage = await client.query(
964
+ {
965
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
966
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
967
+ Limit: 30,
968
+ },
969
+ { a: A, b: B }
970
+ )
971
+
972
+ expect(firstPage.a.length).toBe(20)
973
+ expect(firstPage.b.length).toBe(10)
974
+ expect(firstPage._unknown.length).toBe(0)
975
+ expect(firstPage.meta.lastEvaluatedKey).not.toBeUndefined()
976
+
977
+ const secondPage = await client.query(
978
+ {
979
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
980
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
981
+ Limit: 30,
982
+ ExclusiveStartKey: firstPage.meta.lastEvaluatedKey,
983
+ },
984
+ { a: A, b: B }
985
+ )
986
+
987
+ expect(secondPage.a.length).toBe(0)
988
+ expect(secondPage.b.length).toBe(10)
989
+ expect(secondPage._unknown.length).toBe(0)
990
+ expect(secondPage.meta.lastEvaluatedKey).toBeUndefined()
991
+ })
992
+
993
+ test("it fetches all pages automatically", async () => {
994
+ await sandbox.seed(
995
+ ...Array.from({ length: 20 }).map(
996
+ (_, i) =>
997
+ new A({ pk: "abc", sk: `SORT#${String(i).padStart(2, "0")}`, a: i })
998
+ ),
999
+ ...Array.from({ length: 20 }).map(
1000
+ (_, i) => new B({ pk: "abc", sk: `SORT#${i + 20}`, b: "bar" })
1001
+ )
1002
+ )
1003
+
1004
+ const { a, b, meta, _unknown } = await client.query(
1005
+ {
1006
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
1007
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
1008
+ FetchAllPages: true,
1009
+ // You wouldn't set a limit in a real-world use case here to optimize fetching all items.
1010
+ Limit: 10,
1011
+ },
1012
+ { a: A, b: B }
1013
+ )
1014
+
1015
+ expect(a.length).toBe(20)
1016
+ expect(b.length).toBe(20)
1017
+ expect(_unknown.length).toBe(0)
1018
+ expect(meta.lastEvaluatedKey).toBeUndefined()
1019
+ })
949
1020
  })
950
1021
 
951
- test("it paginates", async () => {
952
- await sandbox.seed(
953
- ...Array.from({ length: 20 }).map(
954
- (_, i) =>
955
- new A({ pk: "abc", sk: `SORT#${String(i).padStart(2, "0")}`, a: i })
956
- ),
957
- ...Array.from({ length: 20 }).map(
958
- (_, i) => new B({ pk: "abc", sk: `SORT#${i + 20}`, b: "bar" })
1022
+ describe("via model", () => {
1023
+ test("it returns empty results for specific model", async () => {
1024
+ const result = await A.query({
1025
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
1026
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT" },
1027
+ })
1028
+
1029
+ expect(result.length).toBe(0)
1030
+ expect(result.meta).toEqual({ lastEvaluatedKey: undefined })
1031
+ })
1032
+
1033
+ test("it returns only matching model items", async () => {
1034
+ await sandbox.seed(
1035
+ new A({ pk: "abc", sk: "SORT#1", a: 1 }),
1036
+ new A({ pk: "abc", sk: "SORT#2", a: 2 }),
1037
+ new B({ pk: "abc", sk: "SORT#3", b: "hi" }),
1038
+ { PK: "abc", SK: "SORT#4", probably: "unknown" },
1039
+ new C({ pk: "abc", sk: "SORT#5", c: "hi" })
959
1040
  )
960
- )
961
1041
 
962
- const firstPage = await client.query(
963
- {
1042
+ const result = await A.query({
964
1043
  KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
965
1044
  ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
966
- Limit: 30
967
- },
968
- { a: A, b: B }
969
- )
1045
+ })
970
1046
 
971
- expect(firstPage.a.length).toBe(20)
972
- expect(firstPage.b.length).toBe(10)
973
- expect(firstPage._unknown.length).toBe(0)
974
- expect(firstPage.meta.lastEvaluatedKey).not.toBeUndefined()
1047
+ expect(result.length).toBe(2)
1048
+ expect(result.map((item) => item.values())).toMatchInlineSnapshot(`
1049
+ Array [
1050
+ Object {
1051
+ "a": 1,
1052
+ "pk": "abc",
1053
+ "sk": "SORT#1",
1054
+ },
1055
+ Object {
1056
+ "a": 2,
1057
+ "pk": "abc",
1058
+ "sk": "SORT#2",
1059
+ },
1060
+ ]
1061
+ `)
1062
+ expect(result.meta).toEqual({ lastEvaluatedKey: undefined })
1063
+ })
975
1064
 
976
- const secondPage = await client.query(
977
- {
1065
+ test("it respects query parameters", async () => {
1066
+ await sandbox.seed(
1067
+ new A({ pk: "abc", sk: "SORT#1", a: 1 }),
1068
+ new A({ pk: "abc", sk: "SORT#2", a: 2 }),
1069
+ new A({ pk: "abc", sk: "SORT#3", a: 3 }),
1070
+ new A({ pk: "abc", sk: "SORT#4", a: 4 })
1071
+ )
1072
+
1073
+ const result = await A.query({
978
1074
  KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
979
1075
  ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
980
- Limit: 30,
981
- ExclusiveStartKey: firstPage.meta.lastEvaluatedKey
982
- },
983
- { a: A, b: B }
984
- )
1076
+ Limit: 2,
1077
+ })
985
1078
 
986
- expect(secondPage.a.length).toBe(0)
987
- expect(secondPage.b.length).toBe(10)
988
- expect(secondPage._unknown.length).toBe(0)
989
- expect(secondPage.meta.lastEvaluatedKey).toBeUndefined()
1079
+ expect(result.length).toBe(2)
1080
+ expect(result[0].a).toBe(1)
1081
+ expect(result[1].a).toBe(2)
1082
+ expect(result.meta.lastEvaluatedKey).toBeDefined()
1083
+ })
1084
+
1085
+ test("it fetches all pages when FetchAllPages is true", async () => {
1086
+ await sandbox.seed(
1087
+ ...Array.from({ length: 15 }).map(
1088
+ (_, i) =>
1089
+ new A({ pk: "abc", sk: `SORT#${String(i).padStart(2, "0")}`, a: i })
1090
+ ),
1091
+ // Add some B items that should be ignored
1092
+ new B({ pk: "abc", sk: "SORT#20", b: "ignored" }),
1093
+ new B({ pk: "abc", sk: "SORT#21", b: "ignored" })
1094
+ )
1095
+
1096
+ const result = await A.query({
1097
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
1098
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
1099
+ FetchAllPages: true,
1100
+ Limit: 5, // Force pagination
1101
+ })
1102
+
1103
+ expect(result.length).toBe(15) // Only A items
1104
+ expect(result.map((item) => item.a)).toEqual(
1105
+ Array.from({ length: 15 }, (_, i) => i)
1106
+ )
1107
+ expect(result.meta.lastEvaluatedKey).toBeUndefined()
1108
+ })
1109
+
1110
+ test("it works with different query conditions", async () => {
1111
+ await sandbox.seed(
1112
+ new A({ pk: "user1", sk: "post#1", a: 1 }),
1113
+ new A({ pk: "user1", sk: "post#2", a: 2 }),
1114
+ new A({ pk: "user1", sk: "comment#1", a: 3 }),
1115
+ new A({ pk: "user2", sk: "post#1", a: 4 })
1116
+ )
1117
+
1118
+ // Query for posts only
1119
+ const posts = await A.query({
1120
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
1121
+ ExpressionAttributeValues: { ":pk": "user1", ":sk": "post#" },
1122
+ })
1123
+
1124
+ expect(posts.length).toBe(2)
1125
+ expect(posts.map((item) => item.a).sort()).toEqual([1, 2])
1126
+
1127
+ // Query for all user1 items
1128
+ const allUser1 = await A.query({
1129
+ KeyConditionExpression: `PK = :pk`,
1130
+ ExpressionAttributeValues: { ":pk": "user1" },
1131
+ })
1132
+
1133
+ expect(allUser1.length).toBe(3)
1134
+ expect(allUser1.map((item) => item.a).sort()).toEqual([1, 2, 3])
1135
+ })
1136
+
1137
+ test("it works with FilterExpression", async () => {
1138
+ await sandbox.seed(
1139
+ new A({ pk: "test", sk: "item#1", a: 1 }),
1140
+ new A({ pk: "test", sk: "item#2", a: 2 }),
1141
+ new A({ pk: "test", sk: "item#3", a: 3 }),
1142
+ new A({ pk: "test", sk: "item#4", a: 4 })
1143
+ )
1144
+
1145
+ const result = await A.query({
1146
+ KeyConditionExpression: `PK = :pk`,
1147
+ FilterExpression: `a > :min`,
1148
+ ExpressionAttributeValues: { ":pk": "test", ":min": 2 },
1149
+ })
1150
+
1151
+ expect(result.length).toBe(2)
1152
+ expect(result.map((item) => item.a).sort()).toEqual([3, 4])
1153
+ })
990
1154
  })
991
1155
 
992
- test("it fetches all pages automatically", async () => {
993
- await sandbox.seed(
994
- ...Array.from({ length: 20 }).map(
995
- (_, i) =>
996
- new A({ pk: "abc", sk: `SORT#${String(i).padStart(2, "0")}`, a: i })
997
- ),
998
- ...Array.from({ length: 20 }).map(
999
- (_, i) => new B({ pk: "abc", sk: `SORT#${i + 20}`, b: "bar" })
1156
+ describe("via union", () => {
1157
+ test("it returns empty results for union", async () => {
1158
+ const result = await Union.query({
1159
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
1160
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT" },
1161
+ })
1162
+
1163
+ expect(result.length).toBe(0)
1164
+ expect(result.meta).toEqual({ lastEvaluatedKey: undefined })
1165
+ })
1166
+
1167
+ test("it returns only union model items", async () => {
1168
+ await sandbox.seed(
1169
+ new A({ pk: "abc", sk: "SORT#1", a: 1 }),
1170
+ new B({ pk: "abc", sk: "SORT#2", b: "hi" }),
1171
+ new C({ pk: "abc", sk: "SORT#3", c: "c1" }),
1172
+ new D({ pk: "abc", sk: "SORT#4", d: "d1" }),
1173
+ { PK: "abc", SK: "SORT#5", unknown: "data" }
1000
1174
  )
1001
- )
1002
1175
 
1003
- const { a, b, meta, _unknown } = await client.query(
1004
- {
1176
+ const result = await Union.query({
1177
+ KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
1178
+ ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
1179
+ })
1180
+
1181
+ expect(result.length).toBe(2) // Only C and D items (union members)
1182
+ expect(result[0]).toBeInstanceOf(C)
1183
+ expect(result[1]).toBeInstanceOf(D)
1184
+ expect(result.meta).toEqual({ lastEvaluatedKey: undefined })
1185
+ })
1186
+
1187
+ test("it fetches all pages for union when FetchAllPages is true", async () => {
1188
+ await sandbox.seed(
1189
+ ...Array.from({ length: 10 }).map(
1190
+ (_, i) =>
1191
+ new C({
1192
+ pk: "abc",
1193
+ sk: `SORT#${String(i).padStart(2, "0")}`,
1194
+ c: `c${i}`,
1195
+ })
1196
+ ),
1197
+ ...Array.from({ length: 10 }).map(
1198
+ (_, i) =>
1199
+ new D({
1200
+ pk: "abc",
1201
+ sk: `SORT#${String(i + 10).padStart(2, "0")}`,
1202
+ d: `d${i}`,
1203
+ })
1204
+ ),
1205
+ // Add some non-union items that should be ignored
1206
+ new A({ pk: "abc", sk: "SORT#30", a: 1 }),
1207
+ new B({ pk: "abc", sk: "SORT#31", b: "ignored" })
1208
+ )
1209
+
1210
+ const result = await Union.query({
1005
1211
  KeyConditionExpression: `PK = :pk and begins_with(SK, :sk)`,
1006
1212
  ExpressionAttributeValues: { ":pk": "abc", ":sk": "SORT#" },
1007
1213
  FetchAllPages: true,
1008
- // You wouldn't set a limit in a real-world use case here to optimize fetching all items.
1009
- Limit: 10
1010
- },
1011
- { a: A, b: B }
1012
- )
1214
+ Limit: 5, // Force pagination
1215
+ })
1013
1216
 
1014
- expect(a.length).toBe(20)
1015
- expect(b.length).toBe(20)
1016
- expect(_unknown.length).toBe(0)
1017
- expect(meta.lastEvaluatedKey).toBeUndefined()
1217
+ expect(result.length).toBe(20) // Only union items (C and D)
1218
+ expect(result.filter((item: C | D) => item instanceof C).length).toBe(10)
1219
+ expect(result.filter((item: C | D) => item instanceof D).length).toBe(10)
1220
+ expect(result.meta.lastEvaluatedKey).toBeUndefined()
1221
+ })
1018
1222
  })
1019
1223
  })
1020
1224
 
@@ -1043,16 +1247,16 @@ describe("bulk", () => {
1043
1247
  new B({
1044
1248
  pk: "PK#UPDATE",
1045
1249
  sk: "SK#UPDATE",
1046
- b: "bar"
1250
+ b: "bar",
1047
1251
  }).operation("update", { b: "baz" }),
1048
1252
  new B({
1049
1253
  pk: "PK#COND",
1050
1254
  sk: "SK#COND",
1051
- b: "cond"
1255
+ b: "cond",
1052
1256
  }).operation("condition", {
1053
1257
  ConditionExpression: "b = :cond",
1054
- ExpressionAttributeValues: { ":cond": "cond" }
1055
- })
1258
+ ExpressionAttributeValues: { ":cond": "cond" },
1259
+ }),
1056
1260
  ])
1057
1261
 
1058
1262
  expect(await sandbox.diff(before)).toMatchInlineSnapshot(`
@@ -1172,7 +1376,7 @@ describe("bulk", () => {
1172
1376
  "updateRaw",
1173
1377
  { PK: "PK#nicetry", SK: "SK#nope" },
1174
1378
  { a: 234 }
1175
- )
1379
+ ),
1176
1380
  ])
1177
1381
  ).rejects.toBeInstanceOf(BulkWriteTransactionError)
1178
1382
 
@@ -1200,11 +1404,11 @@ describe("bulk", () => {
1200
1404
  new B({
1201
1405
  pk: "PK#UPDATE",
1202
1406
  sk: "SK#UPDATE",
1203
- b: "bar"
1407
+ b: "bar",
1204
1408
  }).operation("update", { b: "baz" }),
1205
1409
  ...Array.from({ length: 100 }).map((_, i) =>
1206
1410
  new A({ pk: `PK#A${i}`, sk: `SK#A${i}`, a: i }).operation("put")
1207
- )
1411
+ ),
1208
1412
  ])
1209
1413
 
1210
1414
  //#region snapshot
@@ -2191,7 +2395,7 @@ describe("bulk", () => {
2191
2395
  "condition",
2192
2396
  { PK: "nicetry", SK: "nope" },
2193
2397
  { ConditionExpression: "attribute_exists(PK)" }
2194
- )
2398
+ ),
2195
2399
  ])
2196
2400
  ).rejects.toBeInstanceOf(BulkWriteTransactionError)
2197
2401
 
@@ -2225,7 +2429,7 @@ describe("batchGet", () => {
2225
2429
  two: A.operation("get", { PK: "PK#2", SK: "SK#2" }),
2226
2430
  three: A.operation("get", { PK: "PK#3", SK: "SK#3" }),
2227
2431
  four: A.operation("get", { PK: "PK#4", SK: "SK#4" }),
2228
- duplicate: A.operation("get", { PK: "PK#1", SK: "SK#1" })
2432
+ duplicate: A.operation("get", { PK: "PK#1", SK: "SK#1" }),
2229
2433
  })
2230
2434
  ).rejects.toBeInstanceOf(ItemNotFoundError)
2231
2435
  })
@@ -2242,7 +2446,7 @@ describe("batchGet", () => {
2242
2446
  two: A.operation("get", { PK: "PK#2", SK: "SK#2" }),
2243
2447
  duplicate: A.operation("get", { PK: "PK#1", SK: "SK#1" }),
2244
2448
  error: A.operation("get", { PK: "PK#error", SK: "SK#error" }),
2245
- error2: A.operation("get", { PK: "PK#error2", SK: "SK#error2" })
2449
+ error2: A.operation("get", { PK: "PK#error2", SK: "SK#error2" }),
2246
2450
  },
2247
2451
  { individualErrors: true }
2248
2452
  )
@@ -2266,7 +2470,7 @@ describe("batchGet", () => {
2266
2470
  two: A.operation("get", { PK: "PK#2", SK: "SK#2" }),
2267
2471
  three: A.operation("get", { PK: "PK#3", SK: "SK#3" }),
2268
2472
  four: A.operation("get", { PK: "PK#4", SK: "SK#4" }),
2269
- duplicate: A.operation("get", { PK: "PK#1", SK: "SK#1" })
2473
+ duplicate: A.operation("get", { PK: "PK#1", SK: "SK#1" }),
2270
2474
  })
2271
2475
 
2272
2476
  expect(
@@ -2329,7 +2533,7 @@ describe("load", () => {
2329
2533
  const recovered = await client.load(
2330
2534
  A.operation("get", { PK: "PK#1", SK: "SK#1" }),
2331
2535
  {
2332
- recover: true
2536
+ recover: true,
2333
2537
  }
2334
2538
  )
2335
2539
 
@@ -2340,7 +2544,7 @@ describe("load", () => {
2340
2544
  test("it throws if no item or soft deleted item exists", async () => {
2341
2545
  await expect(
2342
2546
  client.load(A.operation("get", { PK: "PK", SK: "SK" }), {
2343
- recover: true
2547
+ recover: true,
2344
2548
  })
2345
2549
  ).rejects.toBeInstanceOf(ItemNotFoundError)
2346
2550
  })
@@ -2349,7 +2553,7 @@ describe("load", () => {
2349
2553
  await expect(
2350
2554
  client.load(A.operation("get", { PK: "PK", SK: "SK" }), {
2351
2555
  recover: true,
2352
- null: true
2556
+ null: true,
2353
2557
  })
2354
2558
  ).resolves.toBeNull()
2355
2559
  })
@@ -2444,8 +2648,8 @@ describe("load", () => {
2444
2648
  )
2445
2649
 
2446
2650
  expect(results.length).toBe(234)
2447
- expect(results.filter(item => item instanceof C).length).toBe(123)
2448
- expect(results.filter(item => item instanceof D).length).toBe(111)
2651
+ expect(results.filter((item) => item instanceof C).length).toBe(123)
2652
+ expect(results.filter((item) => item instanceof D).length).toBe(111)
2449
2653
  expect(spy).toHaveBeenCalledTimes(3)
2450
2654
 
2451
2655
  spy.mockReset()
@@ -2520,8 +2724,8 @@ describe("loadMany", () => {
2520
2724
  )
2521
2725
 
2522
2726
  expect(results.length).toBe(234)
2523
- expect(results.filter(item => item instanceof C).length).toBe(123)
2524
- expect(results.filter(item => item instanceof D).length).toBe(111)
2727
+ expect(results.filter((item) => item instanceof C).length).toBe(123)
2728
+ expect(results.filter((item) => item instanceof D).length).toBe(111)
2525
2729
  expect(spy).toHaveBeenCalledTimes(3)
2526
2730
 
2527
2731
  spy.mockReset()
@@ -2546,7 +2750,7 @@ describe("paginate", () => {
2546
2750
  {},
2547
2751
  {
2548
2752
  KeyConditionExpression: "PK = :pk",
2549
- ExpressionAttributeValues: { ":pk": "PK" }
2753
+ ExpressionAttributeValues: { ":pk": "PK" },
2550
2754
  }
2551
2755
  )
2552
2756
  expect(page1.pageInfo).toMatchInlineSnapshot(`
@@ -2566,7 +2770,7 @@ describe("paginate", () => {
2566
2770
  { after: page1.pageInfo.endCursor },
2567
2771
  {
2568
2772
  KeyConditionExpression: "PK = :pk",
2569
- ExpressionAttributeValues: { ":pk": "PK" }
2773
+ ExpressionAttributeValues: { ":pk": "PK" },
2570
2774
  }
2571
2775
  )
2572
2776
  expect(page2.pageInfo).toMatchInlineSnapshot(`
@@ -2586,7 +2790,7 @@ describe("paginate", () => {
2586
2790
  { after: page2.pageInfo.endCursor },
2587
2791
  {
2588
2792
  KeyConditionExpression: "PK = :pk",
2589
- ExpressionAttributeValues: { ":pk": "PK" }
2793
+ ExpressionAttributeValues: { ":pk": "PK" },
2590
2794
  }
2591
2795
  )
2592
2796
  expect(page3.pageInfo).toMatchInlineSnapshot(`
@@ -2607,7 +2811,7 @@ describe("paginate", () => {
2607
2811
  { before: page3.pageInfo.startCursor },
2608
2812
  {
2609
2813
  KeyConditionExpression: "PK = :pk",
2610
- ExpressionAttributeValues: { ":pk": "PK" }
2814
+ ExpressionAttributeValues: { ":pk": "PK" },
2611
2815
  }
2612
2816
  )
2613
2817
  expect(backwardsPage2.pageInfo).toMatchInlineSnapshot(`
@@ -2627,7 +2831,7 @@ describe("paginate", () => {
2627
2831
  { before: backwardsPage2.pageInfo.startCursor },
2628
2832
  {
2629
2833
  KeyConditionExpression: "PK = :pk",
2630
- ExpressionAttributeValues: { ":pk": "PK" }
2834
+ ExpressionAttributeValues: { ":pk": "PK" },
2631
2835
  }
2632
2836
  )
2633
2837
  expect(backwardsPage1.pageInfo).toMatchInlineSnapshot(`
@@ -2658,7 +2862,7 @@ describe("paginate", () => {
2658
2862
  {},
2659
2863
  {
2660
2864
  KeyConditionExpression: "PK = :pk",
2661
- ExpressionAttributeValues: { ":pk": "PK" }
2865
+ ExpressionAttributeValues: { ":pk": "PK" },
2662
2866
  }
2663
2867
  )
2664
2868
  expect(page1.pageInfo).toMatchInlineSnapshot(`
@@ -2678,7 +2882,7 @@ describe("paginate", () => {
2678
2882
  { after: page1.pageInfo.endCursor },
2679
2883
  {
2680
2884
  KeyConditionExpression: "PK = :pk",
2681
- ExpressionAttributeValues: { ":pk": "PK" }
2885
+ ExpressionAttributeValues: { ":pk": "PK" },
2682
2886
  }
2683
2887
  )
2684
2888
  expect(page2.pageInfo).toMatchInlineSnapshot(`
@@ -2698,7 +2902,7 @@ describe("paginate", () => {
2698
2902
  { after: page2.pageInfo.endCursor },
2699
2903
  {
2700
2904
  KeyConditionExpression: "PK = :pk",
2701
- ExpressionAttributeValues: { ":pk": "PK" }
2905
+ ExpressionAttributeValues: { ":pk": "PK" },
2702
2906
  }
2703
2907
  )
2704
2908
  expect(page3.pageInfo).toMatchInlineSnapshot(`
@@ -2719,7 +2923,7 @@ describe("paginate", () => {
2719
2923
  { before: page3.pageInfo.startCursor },
2720
2924
  {
2721
2925
  KeyConditionExpression: "PK = :pk",
2722
- ExpressionAttributeValues: { ":pk": "PK" }
2926
+ ExpressionAttributeValues: { ":pk": "PK" },
2723
2927
  }
2724
2928
  )
2725
2929
  expect(backwardsPage2.pageInfo).toMatchInlineSnapshot(`
@@ -2739,7 +2943,7 @@ describe("paginate", () => {
2739
2943
  { before: backwardsPage2.pageInfo.startCursor },
2740
2944
  {
2741
2945
  KeyConditionExpression: "PK = :pk",
2742
- ExpressionAttributeValues: { ":pk": "PK" }
2946
+ ExpressionAttributeValues: { ":pk": "PK" },
2743
2947
  }
2744
2948
  )
2745
2949
  expect(backwardsPage1.pageInfo).toMatchInlineSnapshot(`
@@ -2769,7 +2973,7 @@ describe("paginate", () => {
2769
2973
  { first: 10 },
2770
2974
  {
2771
2975
  KeyConditionExpression: "PK = :pk",
2772
- ExpressionAttributeValues: { ":pk": "PK" }
2976
+ ExpressionAttributeValues: { ":pk": "PK" },
2773
2977
  }
2774
2978
  )
2775
2979
  expect(page.pageInfo).toMatchInlineSnapshot(`
@@ -2799,7 +3003,7 @@ describe("paginate", () => {
2799
3003
  { first: 60 },
2800
3004
  {
2801
3005
  KeyConditionExpression: "PK = :pk",
2802
- ExpressionAttributeValues: { ":pk": "PK" }
3006
+ ExpressionAttributeValues: { ":pk": "PK" },
2803
3007
  }
2804
3008
  )
2805
3009
  expect(page1.pageInfo).toMatchInlineSnapshot(`
@@ -2817,7 +3021,7 @@ describe("paginate", () => {
2817
3021
 
2818
3022
  test("it respects custom pagination default", async () => {
2819
3023
  client.paginationOptions = {
2820
- default: 40
3024
+ default: 40,
2821
3025
  }
2822
3026
 
2823
3027
  const items = Array.from({ length: 50 }).map(
@@ -2832,7 +3036,7 @@ describe("paginate", () => {
2832
3036
  {},
2833
3037
  {
2834
3038
  KeyConditionExpression: "PK = :pk",
2835
- ExpressionAttributeValues: { ":pk": "PK" }
3039
+ ExpressionAttributeValues: { ":pk": "PK" },
2836
3040
  }
2837
3041
  )
2838
3042
  expect(page.edges.length).toBe(40)
@@ -2842,7 +3046,7 @@ describe("paginate", () => {
2842
3046
 
2843
3047
  test("it respects custom pagination limit", async () => {
2844
3048
  client.paginationOptions = {
2845
- limit: 100
3049
+ limit: 100,
2846
3050
  }
2847
3051
 
2848
3052
  const items = Array.from({ length: 120 }).map(
@@ -2857,7 +3061,7 @@ describe("paginate", () => {
2857
3061
  { first: 110 },
2858
3062
  {
2859
3063
  KeyConditionExpression: "PK = :pk",
2860
- ExpressionAttributeValues: { ":pk": "PK" }
3064
+ ExpressionAttributeValues: { ":pk": "PK" },
2861
3065
  }
2862
3066
  )
2863
3067
  expect(page.edges.length).toBe(100)
@@ -2880,7 +3084,7 @@ describe("paginate", () => {
2880
3084
  {},
2881
3085
  {
2882
3086
  KeyConditionExpression: "PK = :pk",
2883
- ExpressionAttributeValues: { ":pk": "PK" }
3087
+ ExpressionAttributeValues: { ":pk": "PK" },
2884
3088
  }
2885
3089
  )
2886
3090
  expect(page1.pageInfo).toMatchInlineSnapshot(`
@@ -2899,7 +3103,7 @@ describe("paginate", () => {
2899
3103
  { after: page1.pageInfo.endCursor },
2900
3104
  {
2901
3105
  KeyConditionExpression: "PK = :pk",
2902
- ExpressionAttributeValues: { ":pk": "PK" }
3106
+ ExpressionAttributeValues: { ":pk": "PK" },
2903
3107
  }
2904
3108
  )
2905
3109
  expect(page2.pageInfo).toMatchInlineSnapshot(`
@@ -2918,7 +3122,7 @@ describe("paginate", () => {
2918
3122
  { after: page2.pageInfo.endCursor },
2919
3123
  {
2920
3124
  KeyConditionExpression: "PK = :pk",
2921
- ExpressionAttributeValues: { ":pk": "PK" }
3125
+ ExpressionAttributeValues: { ":pk": "PK" },
2922
3126
  }
2923
3127
  )
2924
3128
  expect(page3.pageInfo).toMatchInlineSnapshot(`
@@ -2938,7 +3142,7 @@ describe("paginate", () => {
2938
3142
  { before: page3.pageInfo.startCursor },
2939
3143
  {
2940
3144
  KeyConditionExpression: "PK = :pk",
2941
- ExpressionAttributeValues: { ":pk": "PK" }
3145
+ ExpressionAttributeValues: { ":pk": "PK" },
2942
3146
  }
2943
3147
  )
2944
3148
  expect(backwardsPage2.pageInfo).toMatchInlineSnapshot(`
@@ -2957,7 +3161,7 @@ describe("paginate", () => {
2957
3161
  { before: backwardsPage2.pageInfo.startCursor },
2958
3162
  {
2959
3163
  KeyConditionExpression: "PK = :pk",
2960
- ExpressionAttributeValues: { ":pk": "PK" }
3164
+ ExpressionAttributeValues: { ":pk": "PK" },
2961
3165
  }
2962
3166
  )
2963
3167
  expect(backwardsPage1.pageInfo).toMatchInlineSnapshot(`
@@ -2986,7 +3190,7 @@ describe("paginate", () => {
2986
3190
  { first: 10 },
2987
3191
  {
2988
3192
  KeyConditionExpression: "PK = :pk",
2989
- ExpressionAttributeValues: { ":pk": "PK" }
3193
+ ExpressionAttributeValues: { ":pk": "PK" },
2990
3194
  }
2991
3195
  )
2992
3196
  expect(page.pageInfo).toMatchInlineSnapshot(`
@@ -3015,7 +3219,7 @@ describe("paginate", () => {
3015
3219
  { first: 60 },
3016
3220
  {
3017
3221
  KeyConditionExpression: "PK = :pk",
3018
- ExpressionAttributeValues: { ":pk": "PK" }
3222
+ ExpressionAttributeValues: { ":pk": "PK" },
3019
3223
  }
3020
3224
  )
3021
3225
  expect(page1.pageInfo).toMatchInlineSnapshot(`
@@ -3033,7 +3237,7 @@ describe("paginate", () => {
3033
3237
 
3034
3238
  test("it respects custom pagination default", async () => {
3035
3239
  client.paginationOptions = {
3036
- default: 40
3240
+ default: 40,
3037
3241
  }
3038
3242
 
3039
3243
  const items = Array.from({ length: 50 }).map(
@@ -3047,7 +3251,7 @@ describe("paginate", () => {
3047
3251
  {},
3048
3252
  {
3049
3253
  KeyConditionExpression: "PK = :pk",
3050
- ExpressionAttributeValues: { ":pk": "PK" }
3254
+ ExpressionAttributeValues: { ":pk": "PK" },
3051
3255
  }
3052
3256
  )
3053
3257
  expect(page.edges.length).toBe(40)
@@ -3057,7 +3261,7 @@ describe("paginate", () => {
3057
3261
 
3058
3262
  test("it respects custom pagination limit", async () => {
3059
3263
  client.paginationOptions = {
3060
- limit: 100
3264
+ limit: 100,
3061
3265
  }
3062
3266
 
3063
3267
  const items = Array.from({ length: 120 }).map(
@@ -3071,7 +3275,7 @@ describe("paginate", () => {
3071
3275
  { first: 110 },
3072
3276
  {
3073
3277
  KeyConditionExpression: "PK = :pk",
3074
- ExpressionAttributeValues: { ":pk": "PK" }
3278
+ ExpressionAttributeValues: { ":pk": "PK" },
3075
3279
  }
3076
3280
  )
3077
3281
  expect(page.edges.length).toBe(100)
@@ -3095,7 +3299,7 @@ describe("paginate", () => {
3095
3299
  {},
3096
3300
  {
3097
3301
  KeyConditionExpression: "PK = :pk",
3098
- ExpressionAttributeValues: { ":pk": "PK" }
3302
+ ExpressionAttributeValues: { ":pk": "PK" },
3099
3303
  }
3100
3304
  )
3101
3305
  expect(page1.pageInfo).toMatchInlineSnapshot(`
@@ -3114,7 +3318,7 @@ describe("paginate", () => {
3114
3318
  { after: page1.pageInfo.endCursor },
3115
3319
  {
3116
3320
  KeyConditionExpression: "PK = :pk",
3117
- ExpressionAttributeValues: { ":pk": "PK" }
3321
+ ExpressionAttributeValues: { ":pk": "PK" },
3118
3322
  }
3119
3323
  )
3120
3324
  expect(page2.pageInfo).toMatchInlineSnapshot(`
@@ -3133,7 +3337,7 @@ describe("paginate", () => {
3133
3337
  { after: page2.pageInfo.endCursor },
3134
3338
  {
3135
3339
  KeyConditionExpression: "PK = :pk",
3136
- ExpressionAttributeValues: { ":pk": "PK" }
3340
+ ExpressionAttributeValues: { ":pk": "PK" },
3137
3341
  }
3138
3342
  )
3139
3343
  expect(page3.pageInfo).toMatchInlineSnapshot(`
@@ -3153,7 +3357,7 @@ describe("paginate", () => {
3153
3357
  { before: page3.pageInfo.startCursor },
3154
3358
  {
3155
3359
  KeyConditionExpression: "PK = :pk",
3156
- ExpressionAttributeValues: { ":pk": "PK" }
3360
+ ExpressionAttributeValues: { ":pk": "PK" },
3157
3361
  }
3158
3362
  )
3159
3363
  expect(backwardsPage2.pageInfo).toMatchInlineSnapshot(`
@@ -3172,7 +3376,7 @@ describe("paginate", () => {
3172
3376
  { before: backwardsPage2.pageInfo.startCursor },
3173
3377
  {
3174
3378
  KeyConditionExpression: "PK = :pk",
3175
- ExpressionAttributeValues: { ":pk": "PK" }
3379
+ ExpressionAttributeValues: { ":pk": "PK" },
3176
3380
  }
3177
3381
  )
3178
3382
  expect(backwardsPage1.pageInfo).toMatchInlineSnapshot(`
@@ -3202,7 +3406,7 @@ describe("paginate", () => {
3202
3406
  { first: 10 },
3203
3407
  {
3204
3408
  KeyConditionExpression: "PK = :pk",
3205
- ExpressionAttributeValues: { ":pk": "PK" }
3409
+ ExpressionAttributeValues: { ":pk": "PK" },
3206
3410
  }
3207
3411
  )
3208
3412
  expect(page.pageInfo).toMatchInlineSnapshot(`
@@ -3232,7 +3436,7 @@ describe("paginate", () => {
3232
3436
  { first: 60 },
3233
3437
  {
3234
3438
  KeyConditionExpression: "PK = :pk",
3235
- ExpressionAttributeValues: { ":pk": "PK" }
3439
+ ExpressionAttributeValues: { ":pk": "PK" },
3236
3440
  }
3237
3441
  )
3238
3442
  expect(page1.pageInfo).toMatchInlineSnapshot(`
@@ -3250,7 +3454,7 @@ describe("paginate", () => {
3250
3454
 
3251
3455
  test("it respects custom pagination default", async () => {
3252
3456
  client.paginationOptions = {
3253
- default: 40
3457
+ default: 40,
3254
3458
  }
3255
3459
 
3256
3460
  const items = Array.from({ length: 50 }).map((_, i) =>
@@ -3258,12 +3462,12 @@ describe("paginate", () => {
3258
3462
  ? new C({
3259
3463
  pk: "PK",
3260
3464
  sk: String(i).padStart(3, "0"),
3261
- c: String(i)
3465
+ c: String(i),
3262
3466
  })
3263
3467
  : new D({
3264
3468
  pk: "PK",
3265
3469
  sk: String(i).padStart(3, "0"),
3266
- d: String(i)
3470
+ d: String(i),
3267
3471
  })
3268
3472
  )
3269
3473
 
@@ -3273,7 +3477,7 @@ describe("paginate", () => {
3273
3477
  {},
3274
3478
  {
3275
3479
  KeyConditionExpression: "PK = :pk",
3276
- ExpressionAttributeValues: { ":pk": "PK" }
3480
+ ExpressionAttributeValues: { ":pk": "PK" },
3277
3481
  }
3278
3482
  )
3279
3483
  expect(page.edges.length).toBe(40)
@@ -3283,7 +3487,7 @@ describe("paginate", () => {
3283
3487
 
3284
3488
  test("it respects custom pagination limit", async () => {
3285
3489
  client.paginationOptions = {
3286
- limit: 100
3490
+ limit: 100,
3287
3491
  }
3288
3492
 
3289
3493
  const items = Array.from({ length: 110 }).map((_, i) =>
@@ -3291,12 +3495,12 @@ describe("paginate", () => {
3291
3495
  ? new C({
3292
3496
  pk: "PK",
3293
3497
  sk: String(i).padStart(3, "0"),
3294
- c: String(i)
3498
+ c: String(i),
3295
3499
  })
3296
3500
  : new D({
3297
3501
  pk: "PK",
3298
3502
  sk: String(i).padStart(3, "0"),
3299
- d: String(i)
3503
+ d: String(i),
3300
3504
  })
3301
3505
  )
3302
3506
 
@@ -3306,7 +3510,7 @@ describe("paginate", () => {
3306
3510
  { first: 110 },
3307
3511
  {
3308
3512
  KeyConditionExpression: "PK = :pk",
3309
- ExpressionAttributeValues: { ":pk": "PK" }
3513
+ ExpressionAttributeValues: { ":pk": "PK" },
3310
3514
  }
3311
3515
  )
3312
3516
  expect(page.edges.length).toBe(100)