betterddb 0.6.0 → 0.6.4

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.
Files changed (49) hide show
  1. package/.eslintrc.cjs +41 -0
  2. package/lib/betterddb.js +29 -17
  3. package/lib/builders/batch-get-builder.js +6 -2
  4. package/lib/builders/create-builder.js +14 -6
  5. package/lib/builders/delete-builder.js +8 -5
  6. package/lib/builders/get-builder.js +11 -6
  7. package/lib/builders/query-builder.js +38 -31
  8. package/lib/builders/scan-builder.js +17 -11
  9. package/lib/builders/update-builder.js +27 -18
  10. package/lib/operator.js +10 -10
  11. package/lib/{betterddb.d.ts → types/betterddb.d.ts} +13 -9
  12. package/lib/types/betterddb.d.ts.map +1 -0
  13. package/lib/{builders → types/builders}/batch-get-builder.d.ts +2 -1
  14. package/lib/types/builders/batch-get-builder.d.ts.map +1 -0
  15. package/lib/{builders → types/builders}/create-builder.d.ts +3 -2
  16. package/lib/types/builders/create-builder.d.ts.map +1 -0
  17. package/lib/{builders → types/builders}/delete-builder.d.ts +3 -2
  18. package/lib/types/builders/delete-builder.d.ts.map +1 -0
  19. package/lib/{builders → types/builders}/get-builder.d.ts +3 -2
  20. package/lib/types/builders/get-builder.d.ts.map +1 -0
  21. package/lib/{builders → types/builders}/query-builder.d.ts +4 -3
  22. package/lib/types/builders/query-builder.d.ts.map +1 -0
  23. package/lib/{builders → types/builders}/scan-builder.d.ts +4 -3
  24. package/lib/types/builders/scan-builder.d.ts.map +1 -0
  25. package/lib/{builders → types/builders}/update-builder.d.ts +3 -2
  26. package/lib/types/builders/update-builder.d.ts.map +1 -0
  27. package/lib/types/index.d.ts +2 -0
  28. package/lib/types/index.d.ts.map +1 -0
  29. package/lib/types/operator.d.ts +3 -0
  30. package/lib/types/operator.d.ts.map +1 -0
  31. package/lib/types/{paginated-result.d.ts → types/paginated-result.d.ts} +1 -0
  32. package/lib/types/types/paginated-result.d.ts.map +1 -0
  33. package/package.json +15 -5
  34. package/prettier.config.js +6 -0
  35. package/src/betterddb.ts +46 -37
  36. package/src/builders/batch-get-builder.ts +11 -6
  37. package/src/builders/create-builder.ts +42 -27
  38. package/src/builders/delete-builder.ts +28 -17
  39. package/src/builders/get-builder.ts +26 -19
  40. package/src/builders/query-builder.ts +64 -44
  41. package/src/builders/scan-builder.ts +18 -14
  42. package/src/builders/update-builder.ts +53 -27
  43. package/src/index.ts +1 -1
  44. package/src/operator.ts +21 -21
  45. package/src/types/paginated-result.ts +1 -1
  46. package/test/update.test.ts +6 -0
  47. package/tsconfig.json +25 -11
  48. package/lib/index.d.ts +0 -1
  49. package/lib/operator.d.ts +0 -2
package/.eslintrc.cjs ADDED
@@ -0,0 +1,41 @@
1
+ /** @type {import("eslint").Linter.Config} */
2
+ const config = {
3
+ "parser": "@typescript-eslint/parser",
4
+ "parserOptions": {
5
+ "project": true
6
+ },
7
+ "plugins": [
8
+ "@typescript-eslint"
9
+ ],
10
+ "extends": [
11
+ "plugin:@typescript-eslint/recommended-type-checked",
12
+ "plugin:@typescript-eslint/stylistic-type-checked"
13
+ ],
14
+ "rules": {
15
+ "@typescript-eslint/array-type": "off",
16
+ "@typescript-eslint/consistent-type-definitions": "off",
17
+ "@typescript-eslint/consistent-type-imports": [
18
+ "warn",
19
+ {
20
+ "prefer": "type-imports",
21
+ "fixStyle": "inline-type-imports"
22
+ }
23
+ ],
24
+ "@typescript-eslint/no-unused-vars": [
25
+ "warn",
26
+ {
27
+ "argsIgnorePattern": "^_"
28
+ }
29
+ ],
30
+ "@typescript-eslint/require-await": "off",
31
+ "@typescript-eslint/no-misused-promises": [
32
+ "error",
33
+ {
34
+ "checksVoidReturn": {
35
+ "attributes": false
36
+ }
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ module.exports = config;
package/lib/betterddb.js CHANGED
@@ -12,14 +12,24 @@ const batch_get_builder_1 = require("./builders/batch-get-builder");
12
12
  * BetterDDB is a definition-based DynamoDB wrapper library.
13
13
  */
14
14
  class BetterDDB {
15
+ schema;
16
+ tableName;
17
+ entityType;
18
+ client;
19
+ keys;
20
+ timestamps;
21
+ counter;
15
22
  constructor(options) {
16
- var _a, _b;
17
23
  this.schema = options.schema;
18
24
  this.tableName = options.tableName;
19
- this.entityType = (_a = options.entityType) === null || _a === void 0 ? void 0 : _a.toUpperCase();
25
+ this.entityType = options.entityType?.toUpperCase();
20
26
  this.keys = options.keys;
21
27
  this.client = options.client;
22
- this.timestamps = (_b = options.timestamps) !== null && _b !== void 0 ? _b : false;
28
+ this.timestamps = options.timestamps ?? false;
29
+ this.counter = options.counter ?? false;
30
+ }
31
+ getCounter() {
32
+ return this.counter;
23
33
  }
24
34
  getKeys() {
25
35
  return this.keys;
@@ -41,7 +51,9 @@ class BetterDDB {
41
51
  }
42
52
  // Helper: Retrieve the key value from a KeyDefinition.
43
53
  getKeyValue(def, rawKey) {
44
- if (typeof def === 'string' || typeof def === 'number' || typeof def === 'symbol') {
54
+ if (typeof def === "string" ||
55
+ typeof def === "number" ||
56
+ typeof def === "symbol") {
45
57
  return String(rawKey[def]);
46
58
  }
47
59
  else {
@@ -56,18 +68,18 @@ class BetterDDB {
56
68
  // For primary (partition) key:
57
69
  const pkConfig = this.keys.primary;
58
70
  keyObj[pkConfig.name] =
59
- (typeof pkConfig.definition === 'string' ||
60
- typeof pkConfig.definition === 'number' ||
61
- typeof pkConfig.definition === 'symbol')
71
+ typeof pkConfig.definition === "string" ||
72
+ typeof pkConfig.definition === "number" ||
73
+ typeof pkConfig.definition === "symbol"
62
74
  ? String(rawKey[pkConfig.definition])
63
75
  : pkConfig.definition.build(rawKey);
64
76
  // For sort key, if defined:
65
77
  if (this.keys.sort) {
66
78
  const skConfig = this.keys.sort;
67
79
  keyObj[skConfig.name] =
68
- (typeof skConfig.definition === 'string' ||
69
- typeof skConfig.definition === 'number' ||
70
- typeof skConfig.definition === 'symbol')
80
+ typeof skConfig.definition === "string" ||
81
+ typeof skConfig.definition === "number" ||
82
+ typeof skConfig.definition === "symbol"
71
83
  ? String(rawKey[skConfig.definition])
72
84
  : skConfig.definition.build(rawKey);
73
85
  }
@@ -84,18 +96,18 @@ class BetterDDB {
84
96
  // Compute primary index attribute.
85
97
  const primaryConfig = gsiConfig.primary;
86
98
  indexAttributes[primaryConfig.name] =
87
- (typeof primaryConfig.definition === 'string' ||
88
- typeof primaryConfig.definition === 'number' ||
89
- typeof primaryConfig.definition === 'symbol')
99
+ typeof primaryConfig.definition === "string" ||
100
+ typeof primaryConfig.definition === "number" ||
101
+ typeof primaryConfig.definition === "symbol"
90
102
  ? String(rawItem[primaryConfig.definition])
91
103
  : primaryConfig.definition.build(rawItem);
92
104
  // Compute sort index attribute if provided.
93
- if (gsiConfig.sort) {
105
+ if (gsiConfig?.sort) {
94
106
  const sortConfig = gsiConfig.sort;
95
107
  indexAttributes[sortConfig.name] =
96
- (typeof sortConfig.definition === 'string' ||
97
- typeof sortConfig.definition === 'number' ||
98
- typeof sortConfig.definition === 'symbol')
108
+ typeof sortConfig.definition === "string" ||
109
+ typeof sortConfig.definition === "number" ||
110
+ typeof sortConfig.definition === "symbol"
99
111
  ? String(rawItem[sortConfig.definition])
100
112
  : sortConfig.definition.build(rawItem);
101
113
  }
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BatchGetBuilder = void 0;
4
4
  const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
5
  class BatchGetBuilder {
6
+ parent;
7
+ keys;
6
8
  /**
7
9
  * @param parent - The BetterDDB instance for the table.
8
10
  * @param keys - An array of partial keys for the items you wish to retrieve.
@@ -30,7 +32,7 @@ class BatchGetBuilder {
30
32
  });
31
33
  const tableName = this.parent.getTableName();
32
34
  // Build an array of keys using the parent's key builder.
33
- const keysArray = deduplicatedKeys.map(key => this.parent.buildKey(key));
35
+ const keysArray = deduplicatedKeys.map((key) => this.parent.buildKey(key));
34
36
  // Construct the BatchGet parameters.
35
37
  const params = {
36
38
  RequestItems: {
@@ -39,7 +41,9 @@ class BatchGetBuilder {
39
41
  },
40
42
  },
41
43
  };
42
- const result = await this.parent.getClient().send(new lib_dynamodb_1.BatchGetCommand(params));
44
+ const result = await this.parent
45
+ .getClient()
46
+ .send(new lib_dynamodb_1.BatchGetCommand(params));
43
47
  const responses = result.Responses ? result.Responses[tableName] : [];
44
48
  if (!responses) {
45
49
  return [];
@@ -3,10 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CreateBuilder = void 0;
4
4
  const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
5
  class CreateBuilder {
6
+ parent;
7
+ item;
8
+ extraTransactItems = [];
6
9
  constructor(parent, item) {
7
10
  this.parent = parent;
8
11
  this.item = item;
9
- this.extraTransactItems = [];
10
12
  }
11
13
  async execute() {
12
14
  const validated = this.parent.getSchema().parse(this.item);
@@ -16,17 +18,20 @@ class CreateBuilder {
16
18
  // Combine with extra transaction items.
17
19
  const allItems = [...this.extraTransactItems, myTransactItem];
18
20
  await this.parent.getClient().send(new lib_dynamodb_1.TransactWriteCommand({
19
- TransactItems: allItems
21
+ TransactItems: allItems,
20
22
  }));
21
23
  // After transaction, retrieve the updated item.
22
24
  const result = await this.parent.get(this.item).execute();
23
25
  if (result === null) {
24
- throw new Error('Item not found after transaction create');
26
+ throw new Error("Item not found after transaction create");
25
27
  }
26
28
  return result;
27
29
  }
28
30
  else {
29
- let finalItem = { ...this.item, entityType: this.parent.getEntityType() };
31
+ let finalItem = {
32
+ ...this.item,
33
+ entityType: this.parent.getEntityType(),
34
+ };
30
35
  if (this.parent.getTimestamps()) {
31
36
  const now = new Date().toISOString();
32
37
  finalItem = { ...finalItem, createdAt: now, updatedAt: now };
@@ -39,7 +44,7 @@ class CreateBuilder {
39
44
  finalItem = { ...finalItem, ...indexAttributes };
40
45
  await this.parent.getClient().send(new lib_dynamodb_1.PutCommand({
41
46
  TableName: this.parent.getTableName(),
42
- Item: finalItem
47
+ Item: finalItem,
43
48
  }));
44
49
  return validated;
45
50
  }
@@ -55,7 +60,10 @@ class CreateBuilder {
55
60
  }
56
61
  toTransactPut() {
57
62
  const validated = this.parent.getSchema().parse(this.item);
58
- let finalItem = { ...this.item, entityType: this.parent.getEntityType() };
63
+ let finalItem = {
64
+ ...this.item,
65
+ entityType: this.parent.getEntityType(),
66
+ };
59
67
  if (this.parent.getTimestamps()) {
60
68
  const now = new Date().toISOString();
61
69
  finalItem = { ...finalItem, createdAt: now, updatedAt: now };
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DeleteBuilder = void 0;
4
4
  const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
5
  class DeleteBuilder {
6
+ parent;
7
+ key;
8
+ condition;
9
+ extraTransactItems = [];
6
10
  constructor(parent, key) {
7
11
  this.parent = parent;
8
12
  this.key = key;
9
- this.extraTransactItems = [];
10
13
  }
11
14
  /**
12
15
  * Specify a condition expression for the delete operation.
@@ -28,18 +31,18 @@ class DeleteBuilder {
28
31
  // Combine with extra transaction items.
29
32
  const allItems = [...this.extraTransactItems, myTransactItem];
30
33
  await this.parent.getClient().send(new lib_dynamodb_1.TransactWriteCommand({
31
- TransactItems: allItems
34
+ TransactItems: allItems,
32
35
  }));
33
36
  // After transaction, retrieve the updated item.
34
37
  const result = await this.parent.get(this.key).execute();
35
38
  if (result === null) {
36
- throw new Error('Item not found after transaction delete');
39
+ throw new Error("Item not found after transaction delete");
37
40
  }
38
41
  }
39
42
  else {
40
43
  const params = {
41
44
  TableName: this.parent.getTableName(),
42
- Key: this.parent.buildKey(this.key)
45
+ Key: this.parent.buildKey(this.key),
43
46
  };
44
47
  if (this.condition) {
45
48
  params.ConditionExpression = this.condition.expression;
@@ -60,7 +63,7 @@ class DeleteBuilder {
60
63
  toTransactDelete() {
61
64
  const deleteItem = {
62
65
  TableName: this.parent.getTableName(),
63
- Key: this.parent.buildKey(this.key)
66
+ Key: this.parent.buildKey(this.key),
64
67
  };
65
68
  if (this.condition) {
66
69
  deleteItem.ConditionExpression = this.condition.expression;
@@ -3,17 +3,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GetBuilder = void 0;
4
4
  const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
5
  class GetBuilder {
6
+ parent;
7
+ key;
8
+ projectionExpression;
9
+ expressionAttributeNames = {};
10
+ extraTransactItems = [];
6
11
  constructor(parent, key) {
7
12
  this.parent = parent;
8
13
  this.key = key;
9
- this.expressionAttributeNames = {};
10
- this.extraTransactItems = [];
11
14
  }
12
15
  /**
13
16
  * Specify a projection by providing an array of attribute names.
14
17
  */
15
18
  withProjection(attributes) {
16
- this.projectionExpression = attributes.map(attr => `#${String(attr)}`).join(', ');
19
+ this.projectionExpression = attributes
20
+ .map((attr) => `#${String(attr)}`)
21
+ .join(", ");
17
22
  for (const attr of attributes) {
18
23
  this.expressionAttributeNames[`#${String(attr)}`] = String(attr);
19
24
  }
@@ -26,7 +31,7 @@ class GetBuilder {
26
31
  // Combine with extra transaction items.
27
32
  const allItems = [...this.extraTransactItems, myTransactItem];
28
33
  await this.parent.getClient().send(new lib_dynamodb_1.TransactGetCommand({
29
- TransactItems: allItems
34
+ TransactItems: allItems,
30
35
  }));
31
36
  // After transaction, retrieve the updated item.
32
37
  const result = await this.parent.get(this.key).execute();
@@ -35,7 +40,7 @@ class GetBuilder {
35
40
  else {
36
41
  const params = {
37
42
  TableName: this.parent.getTableName(),
38
- Key: this.parent.buildKey(this.key)
43
+ Key: this.parent.buildKey(this.key),
39
44
  };
40
45
  if (this.projectionExpression) {
41
46
  params.ProjectionExpression = this.projectionExpression;
@@ -59,7 +64,7 @@ class GetBuilder {
59
64
  toTransactGet() {
60
65
  const getItem = {
61
66
  TableName: this.parent.getTableName(),
62
- Key: this.parent.buildKey(this.key)
67
+ Key: this.parent.buildKey(this.key),
63
68
  };
64
69
  if (this.projectionExpression) {
65
70
  getItem.ProjectionExpression = this.projectionExpression;
@@ -4,32 +4,37 @@ exports.QueryBuilder = void 0;
4
4
  const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
5
  const operator_1 = require("../operator");
6
6
  class QueryBuilder {
7
+ parent;
8
+ key;
9
+ keyConditions = [];
10
+ filterConditions = [];
11
+ expressionAttributeNames = {};
12
+ expressionAttributeValues = {};
13
+ index;
14
+ limit;
15
+ lastKey;
16
+ ascending = true;
7
17
  constructor(parent, key) {
8
18
  this.parent = parent;
9
19
  this.key = key;
10
- this.keyConditions = [];
11
- this.filterConditions = [];
12
- this.expressionAttributeNames = {};
13
- this.expressionAttributeValues = {};
14
- this.ascending = true;
15
20
  const keys = this.parent.getKeys();
16
21
  let pkName = keys.primary.name;
17
22
  let builtKey = this.parent.buildKey(this.key);
18
- this.expressionAttributeNames['#pk'] = pkName;
19
- this.expressionAttributeValues[':pk_value'] = builtKey[pkName];
23
+ this.expressionAttributeNames["#pk"] = pkName;
24
+ this.expressionAttributeValues[":pk_value"] = builtKey[pkName];
20
25
  }
21
26
  usingIndex(indexName) {
22
27
  if (!this.parent.getKeys().gsis) {
23
- throw new Error('No global secondary indexes defined for this table');
28
+ throw new Error("No global secondary indexes defined for this table");
24
29
  }
25
30
  if (!(indexName in this.parent.getKeys().gsis)) {
26
- throw new Error('index does not exist');
31
+ throw new Error("index does not exist");
27
32
  }
28
33
  this.index = this.parent.getKeys().gsis[indexName];
29
34
  const pkName = this.index.primary.name;
30
35
  const builtKey = this.parent.buildIndexes(this.key);
31
- this.expressionAttributeNames['#pk'] = pkName;
32
- this.expressionAttributeValues[':pk_value'] = builtKey[pkName];
36
+ this.expressionAttributeNames["#pk"] = pkName;
37
+ this.expressionAttributeValues[":pk_value"] = builtKey[pkName];
33
38
  return this;
34
39
  }
35
40
  sortAscending() {
@@ -41,25 +46,24 @@ class QueryBuilder {
41
46
  return this;
42
47
  }
43
48
  where(operator, values) {
44
- var _a, _b;
45
49
  const keys = this.parent.getKeys();
46
50
  // Determine the sort key name from either the index or the primary keys.
47
- const sortKeyName = this.index ? (_a = this.index.sort) === null || _a === void 0 ? void 0 : _a.name : (_b = keys.sort) === null || _b === void 0 ? void 0 : _b.name;
51
+ const sortKeyName = this.index ? this.index.sort?.name : keys.sort?.name;
48
52
  if (!sortKeyName) {
49
- throw new Error('Sort key is not defined for this table/index.');
53
+ throw new Error("Sort key is not defined for this table/index.");
50
54
  }
51
- const nameKey = '#sk';
55
+ const nameKey = "#sk";
52
56
  this.expressionAttributeNames[nameKey] = sortKeyName;
53
57
  // Enforce that a complex sort key requires an object input.
54
- if (typeof values !== 'object' || values === null) {
58
+ if (typeof values !== "object" || values === null) {
55
59
  throw new Error(`For complex sort keys, please provide an object with all necessary properties.`);
56
60
  }
57
- if (operator === 'between') {
61
+ if (operator === "between") {
58
62
  if (!Array.isArray(values) || values.length !== 2) {
59
63
  throw new Error(`For 'between' operator, values must be a tuple of two objects`);
60
64
  }
61
- const valueKeyStart = ':sk_start';
62
- const valueKeyEnd = ':sk_end';
65
+ const valueKeyStart = ":sk_start";
66
+ const valueKeyEnd = ":sk_end";
63
67
  // Use the key definition's build function to build the key from the full object.
64
68
  this.expressionAttributeValues[valueKeyStart] = this.index
65
69
  ? this.parent.buildIndexes(values[0])[sortKeyName]
@@ -69,8 +73,8 @@ class QueryBuilder {
69
73
  : this.parent.buildKey(values[1])[sortKeyName];
70
74
  this.keyConditions.push(`${nameKey} BETWEEN ${valueKeyStart} AND ${valueKeyEnd}`);
71
75
  }
72
- else if (operator === 'begins_with') {
73
- const valueKey = ':sk_value';
76
+ else if (operator === "begins_with") {
77
+ const valueKey = ":sk_value";
74
78
  this.expressionAttributeValues[valueKey] = this.index
75
79
  ? this.parent.buildIndexes(values)[sortKeyName]
76
80
  : this.parent.buildKey(values)[sortKeyName];
@@ -78,7 +82,7 @@ class QueryBuilder {
78
82
  }
79
83
  else {
80
84
  // For eq, lt, lte, gt, gte:
81
- const valueKey = ':sk_value';
85
+ const valueKey = ":sk_value";
82
86
  this.expressionAttributeValues[valueKey] = this.index
83
87
  ? this.parent.buildIndexes(values)[sortKeyName]
84
88
  : this.parent.buildKey(values)[sortKeyName];
@@ -92,7 +96,7 @@ class QueryBuilder {
92
96
  const randomString = Math.random().toString(36).substring(2, 15);
93
97
  const placeholderName = `#attr_${attrStr}_${randomString}`;
94
98
  this.expressionAttributeNames[placeholderName] = attrStr;
95
- if (operator === 'between') {
99
+ if (operator === "between") {
96
100
  if (!Array.isArray(values) || values.length !== 2) {
97
101
  throw new Error("For 'between' operator, values must be a tuple of two items");
98
102
  }
@@ -102,7 +106,7 @@ class QueryBuilder {
102
106
  this.expressionAttributeValues[placeholderValueEnd] = values[1];
103
107
  this.filterConditions.push(`${placeholderName} BETWEEN ${placeholderValueStart} AND ${placeholderValueEnd}`);
104
108
  }
105
- else if (operator === 'begins_with' || operator === 'contains') {
109
+ else if (operator === "begins_with" || operator === "contains") {
106
110
  const placeholderValue = `:val_${attrStr}_${randomString}`;
107
111
  this.expressionAttributeValues[placeholderValue] = values;
108
112
  this.filterConditions.push(`${operator}(${placeholderName}, ${placeholderValue})`);
@@ -127,9 +131,8 @@ class QueryBuilder {
127
131
  * Executes the query and returns a Promise that resolves with an array of items.
128
132
  */
129
133
  async execute() {
130
- var _a, _b, _c;
131
134
  this.keyConditions.unshift(`#pk = :pk_value`);
132
- const keyConditionExpression = this.keyConditions.join(' AND ');
135
+ const keyConditionExpression = this.keyConditions.join(" AND ");
133
136
  const params = {
134
137
  TableName: this.parent.getTableName(),
135
138
  KeyConditionExpression: keyConditionExpression,
@@ -138,16 +141,20 @@ class QueryBuilder {
138
141
  ScanIndexForward: this.ascending,
139
142
  Limit: this.limit,
140
143
  ExclusiveStartKey: this.lastKey,
141
- IndexName: (_b = (_a = this.index) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : undefined,
144
+ IndexName: this.index?.name ?? undefined,
142
145
  };
143
146
  if (this.parent.getEntityType()) {
144
147
  this.filterConditions.push(`#entity = :entity_value`);
145
- this.expressionAttributeNames['#entity'] = 'entityType';
146
- this.expressionAttributeValues[':entity_value'] = this.parent.getEntityType();
148
+ this.expressionAttributeNames["#entity"] = "entityType";
149
+ this.expressionAttributeValues[":entity_value"] =
150
+ this.parent.getEntityType();
147
151
  }
148
- params.FilterExpression = this.filterConditions.join(' AND ');
152
+ params.FilterExpression = this.filterConditions.join(" AND ");
149
153
  const result = await this.parent.getClient().send(new lib_dynamodb_1.QueryCommand(params));
150
- return { items: this.parent.getSchema().array().parse(result.Items), lastKey: (_c = result.LastEvaluatedKey) !== null && _c !== void 0 ? _c : undefined };
154
+ return {
155
+ items: this.parent.getSchema().array().parse(result.Items),
156
+ lastKey: result.LastEvaluatedKey ?? undefined,
157
+ };
151
158
  }
152
159
  }
153
160
  exports.QueryBuilder = QueryBuilder;
@@ -4,17 +4,20 @@ exports.ScanBuilder = void 0;
4
4
  const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
5
  const operator_1 = require("../operator");
6
6
  class ScanBuilder {
7
+ parent;
8
+ filters = [];
9
+ expressionAttributeNames = {};
10
+ expressionAttributeValues = {};
11
+ limit;
12
+ lastKey;
7
13
  constructor(parent) {
8
14
  this.parent = parent;
9
- this.filters = [];
10
- this.expressionAttributeNames = {};
11
- this.expressionAttributeValues = {};
12
15
  }
13
16
  where(attribute, operator, values) {
14
17
  const attrStr = String(attribute);
15
18
  const nameKey = `#attr_${attrStr}`;
16
19
  this.expressionAttributeNames[nameKey] = attrStr;
17
- if (operator === 'between') {
20
+ if (operator === "between") {
18
21
  if (!Array.isArray(values) || values.length !== 2) {
19
22
  throw new Error(`For 'between' operator, values must be a tuple of two items`);
20
23
  }
@@ -24,7 +27,7 @@ class ScanBuilder {
24
27
  this.expressionAttributeValues[valueKeyEnd] = values[1];
25
28
  this.filters.push(`${nameKey} BETWEEN ${valueKeyStart} AND ${valueKeyEnd}`);
26
29
  }
27
- else if (operator === 'begins_with' || operator === 'contains') {
30
+ else if (operator === "begins_with" || operator === "contains") {
28
31
  const valueKey = `:val_${attrStr}`;
29
32
  this.expressionAttributeValues[valueKey] = values;
30
33
  this.filters.push(`${operator}(${nameKey}, ${valueKey})`);
@@ -49,22 +52,25 @@ class ScanBuilder {
49
52
  * Executes the scan and returns a Promise that resolves with an array of items.
50
53
  */
51
54
  async execute() {
52
- var _a;
53
55
  const params = {
54
56
  TableName: this.parent.getTableName(),
55
57
  ExpressionAttributeNames: this.expressionAttributeNames,
56
58
  ExpressionAttributeValues: this.expressionAttributeValues,
57
59
  Limit: this.limit,
58
- ExclusiveStartKey: this.lastKey
60
+ ExclusiveStartKey: this.lastKey,
59
61
  };
60
62
  if (this.parent.getEntityType()) {
61
63
  this.filters.push(`#entity = :entity_value`);
62
- this.expressionAttributeNames['#entity'] = 'entityType';
63
- this.expressionAttributeValues[':entity_value'] = this.parent.getEntityType();
64
+ this.expressionAttributeNames["#entity"] = "entityType";
65
+ this.expressionAttributeValues[":entity_value"] =
66
+ this.parent.getEntityType();
64
67
  }
65
- params.FilterExpression = this.filters.join(' AND ');
68
+ params.FilterExpression = this.filters.join(" AND ");
66
69
  const result = await this.parent.getClient().send(new lib_dynamodb_1.ScanCommand(params));
67
- return { items: this.parent.getSchema().array().parse(result.Items), lastKey: (_a = result.LastEvaluatedKey) !== null && _a !== void 0 ? _a : undefined };
70
+ return {
71
+ items: this.parent.getSchema().array().parse(result.Items),
72
+ lastKey: result.LastEvaluatedKey ?? undefined,
73
+ };
68
74
  }
69
75
  }
70
76
  exports.ScanBuilder = ScanBuilder;