@kravc/dos-dynamodb 1.0.0-alpha.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.
Files changed (136) hide show
  1. package/README.md +30 -0
  2. package/bin/table.js +88 -0
  3. package/config/default.yaml +36 -0
  4. package/config/test.yaml +0 -0
  5. package/dist/example/Activity.d.ts +34 -0
  6. package/dist/example/Activity.d.ts.map +1 -0
  7. package/dist/example/Activity.js +66 -0
  8. package/dist/example/Activity.js.map +1 -0
  9. package/dist/example/ActivityAttributes.d.ts +23 -0
  10. package/dist/example/ActivityAttributes.d.ts.map +1 -0
  11. package/dist/example/ActivityAttributes.js +54 -0
  12. package/dist/example/ActivityAttributes.js.map +1 -0
  13. package/dist/example/Asset.d.ts +36 -0
  14. package/dist/example/Asset.d.ts.map +1 -0
  15. package/dist/example/Asset.js +56 -0
  16. package/dist/example/Asset.js.map +1 -0
  17. package/dist/example/AssetAttributes.d.ts +28 -0
  18. package/dist/example/AssetAttributes.d.ts.map +1 -0
  19. package/dist/example/AssetAttributes.js +72 -0
  20. package/dist/example/AssetAttributes.js.map +1 -0
  21. package/dist/example/Organization.d.ts +19 -0
  22. package/dist/example/Organization.d.ts.map +1 -0
  23. package/dist/example/Organization.js +42 -0
  24. package/dist/example/Organization.js.map +1 -0
  25. package/dist/example/OrganizationAttributes.d.ts +13 -0
  26. package/dist/example/OrganizationAttributes.d.ts.map +1 -0
  27. package/dist/example/OrganizationAttributes.js +24 -0
  28. package/dist/example/OrganizationAttributes.js.map +1 -0
  29. package/dist/example/index.d.ts +5 -0
  30. package/dist/example/index.d.ts.map +1 -0
  31. package/dist/example/index.js +13 -0
  32. package/dist/example/index.js.map +1 -0
  33. package/dist/src/Document/Document.d.ts +67 -0
  34. package/dist/src/Document/Document.d.ts.map +1 -0
  35. package/dist/src/Document/Document.js +216 -0
  36. package/dist/src/Document/Document.js.map +1 -0
  37. package/dist/src/Document/DocumentWithHashId.d.ts +22 -0
  38. package/dist/src/Document/DocumentWithHashId.d.ts.map +1 -0
  39. package/dist/src/Document/DocumentWithHashId.js +73 -0
  40. package/dist/src/Document/DocumentWithHashId.js.map +1 -0
  41. package/dist/src/Document/__tests__/__helpers.d.ts +21 -0
  42. package/dist/src/Document/__tests__/__helpers.d.ts.map +1 -0
  43. package/dist/src/Document/__tests__/__helpers.js +92 -0
  44. package/dist/src/Document/__tests__/__helpers.js.map +1 -0
  45. package/dist/src/Document/helpers/composeIndexKeys.d.ts +11 -0
  46. package/dist/src/Document/helpers/composeIndexKeys.d.ts.map +1 -0
  47. package/dist/src/Document/helpers/composeIndexKeys.js +81 -0
  48. package/dist/src/Document/helpers/composeIndexKeys.js.map +1 -0
  49. package/dist/src/Document/helpers/index.d.ts +3 -0
  50. package/dist/src/Document/helpers/index.d.ts.map +1 -0
  51. package/dist/src/Document/helpers/index.js +9 -0
  52. package/dist/src/Document/helpers/index.js.map +1 -0
  53. package/dist/src/Table/Table.d.ts +56 -0
  54. package/dist/src/Table/Table.d.ts.map +1 -0
  55. package/dist/src/Table/Table.js +228 -0
  56. package/dist/src/Table/Table.js.map +1 -0
  57. package/dist/src/Table/helpers/buildConditionExpression.d.ts +22 -0
  58. package/dist/src/Table/helpers/buildConditionExpression.d.ts.map +1 -0
  59. package/dist/src/Table/helpers/buildConditionExpression.js +128 -0
  60. package/dist/src/Table/helpers/buildConditionExpression.js.map +1 -0
  61. package/dist/src/Table/helpers/buildQueryCommandInput.d.ts +12 -0
  62. package/dist/src/Table/helpers/buildQueryCommandInput.d.ts.map +1 -0
  63. package/dist/src/Table/helpers/buildQueryCommandInput.js +60 -0
  64. package/dist/src/Table/helpers/buildQueryCommandInput.js.map +1 -0
  65. package/dist/src/Table/helpers/buildQueryConditionExpression.d.ts +17 -0
  66. package/dist/src/Table/helpers/buildQueryConditionExpression.d.ts.map +1 -0
  67. package/dist/src/Table/helpers/buildQueryConditionExpression.js +77 -0
  68. package/dist/src/Table/helpers/buildQueryConditionExpression.js.map +1 -0
  69. package/dist/src/Table/helpers/buildTableSchema.d.ts +6 -0
  70. package/dist/src/Table/helpers/buildTableSchema.d.ts.map +1 -0
  71. package/dist/src/Table/helpers/buildTableSchema.js +100 -0
  72. package/dist/src/Table/helpers/buildTableSchema.js.map +1 -0
  73. package/dist/src/Table/helpers/buildUpdateExpression.d.ts +10 -0
  74. package/dist/src/Table/helpers/buildUpdateExpression.d.ts.map +1 -0
  75. package/dist/src/Table/helpers/buildUpdateExpression.js +69 -0
  76. package/dist/src/Table/helpers/buildUpdateExpression.js.map +1 -0
  77. package/dist/src/Table/helpers/filterConditionExpression.d.ts +5 -0
  78. package/dist/src/Table/helpers/filterConditionExpression.d.ts.map +1 -0
  79. package/dist/src/Table/helpers/filterConditionExpression.js +68 -0
  80. package/dist/src/Table/helpers/filterConditionExpression.js.map +1 -0
  81. package/dist/src/Table/helpers/getRawClientConfig.d.ts +5 -0
  82. package/dist/src/Table/helpers/getRawClientConfig.d.ts.map +1 -0
  83. package/dist/src/Table/helpers/getRawClientConfig.js +29 -0
  84. package/dist/src/Table/helpers/getRawClientConfig.js.map +1 -0
  85. package/dist/src/Table/helpers/getTableOptions.d.ts +51 -0
  86. package/dist/src/Table/helpers/getTableOptions.d.ts.map +1 -0
  87. package/dist/src/Table/helpers/getTableOptions.js +144 -0
  88. package/dist/src/Table/helpers/getTableOptions.js.map +1 -0
  89. package/dist/src/Table/helpers/index.d.ts +10 -0
  90. package/dist/src/Table/helpers/index.d.ts.map +1 -0
  91. package/dist/src/Table/helpers/index.js +21 -0
  92. package/dist/src/Table/helpers/index.js.map +1 -0
  93. package/dist/src/Table/index.d.ts +8 -0
  94. package/dist/src/Table/index.d.ts.map +1 -0
  95. package/dist/src/Table/index.js +13 -0
  96. package/dist/src/Table/index.js.map +1 -0
  97. package/dist/src/index.d.ts +7 -0
  98. package/dist/src/index.d.ts.map +1 -0
  99. package/dist/src/index.js +14 -0
  100. package/dist/src/index.js.map +1 -0
  101. package/docker-compose.yaml +10 -0
  102. package/eslint.config.mjs +35 -0
  103. package/example/Activity.ts +123 -0
  104. package/example/ActivityAttributes.ts +72 -0
  105. package/example/Asset.ts +78 -0
  106. package/example/AssetAttributes.ts +87 -0
  107. package/example/Organization.ts +61 -0
  108. package/example/OrganizationAttributes.ts +28 -0
  109. package/example/index.ts +9 -0
  110. package/jest.config.mjs +10 -0
  111. package/package.json +50 -0
  112. package/src/Document/DefaultAttributes.d.ts +16 -0
  113. package/src/Document/Document.ts +257 -0
  114. package/src/Document/DocumentWithHashId.ts +85 -0
  115. package/src/Document/__tests__/Document.test.ts +596 -0
  116. package/src/Document/__tests__/DocumentWithHashId.test.ts +81 -0
  117. package/src/Document/__tests__/__helpers.ts +115 -0
  118. package/src/Document/helpers/__tests__/composeIndexKeys.test.ts +40 -0
  119. package/src/Document/helpers/composeIndexKeys.ts +137 -0
  120. package/src/Document/helpers/index.ts +5 -0
  121. package/src/Table/Table.ts +354 -0
  122. package/src/Table/__tests__/Table.test.ts +64 -0
  123. package/src/Table/helpers/__tests__/buildQueryCommandInput.test.ts +14 -0
  124. package/src/Table/helpers/__tests__/buildTableSchema.test.ts +19 -0
  125. package/src/Table/helpers/buildConditionExpression.ts +151 -0
  126. package/src/Table/helpers/buildQueryCommandInput.ts +113 -0
  127. package/src/Table/helpers/buildQueryConditionExpression.ts +109 -0
  128. package/src/Table/helpers/buildTableSchema.ts +151 -0
  129. package/src/Table/helpers/buildUpdateExpression.ts +95 -0
  130. package/src/Table/helpers/filterConditionExpression.ts +87 -0
  131. package/src/Table/helpers/getRawClientConfig.ts +35 -0
  132. package/src/Table/helpers/getTableOptions.ts +228 -0
  133. package/src/Table/helpers/index.ts +21 -0
  134. package/src/Table/index.ts +18 -0
  135. package/src/index.ts +15 -0
  136. package/tsconfig.json +26 -0
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lodash_1 = require("lodash");
4
+ const dos_1 = require("@kravc/dos");
5
+ const PLACEHOLDER_REGEX = /#(\w+)/g;
6
+ /** Replaces each #name in the template with the value from attributes. */
7
+ const composeValue = (attributes, template) => {
8
+ const names = [...template.matchAll(PLACEHOLDER_REGEX)].map(([, name]) => name);
9
+ for (const name of names) {
10
+ const value = (0, lodash_1.get)(attributes, name);
11
+ if (!value) {
12
+ return;
13
+ }
14
+ }
15
+ const composedValue = template.replace(PLACEHOLDER_REGEX, (_, name) => `#${attributes[name]}`);
16
+ return composedValue;
17
+ };
18
+ /** Returns sort key value using ID prefix and template. */
19
+ const composeSortKeyValue = (attributes, template) => {
20
+ return composeValue(attributes, template);
21
+ };
22
+ /** Returns partition key value using template. */
23
+ const composePartitionKeyValue = (idPrefix, attributes, template) => {
24
+ const composedValue = composeValue(attributes, template);
25
+ if (!composedValue) {
26
+ return;
27
+ }
28
+ return `${idPrefix}#${composedValue}`.replace('##', '#');
29
+ };
30
+ /** Returns index keys composed from item attributes. */
31
+ const composeIndexKeys = ({ idPrefix, attributes, documentName, tableOptions, }) => {
32
+ const { indexKeys, isLocalSecondaryIndex, getLocalIndexSortKeyName, getGlobalIndexSortKeyName, getGlobalIndexPartitionKeyName, } = tableOptions;
33
+ const indexNames = Object.keys(indexKeys);
34
+ const localKeyComposers = indexNames
35
+ .filter(indexName => isLocalSecondaryIndex(indexName))
36
+ .filter(indexName => (0, dos_1.got)(indexKeys[indexName], 'documentName') === documentName)
37
+ .map(indexName => ({
38
+ localIndexComposer: indexKeys[indexName],
39
+ indexName,
40
+ }));
41
+ const globalKeyComposers = indexNames
42
+ .filter(indexName => !isLocalSecondaryIndex(indexName))
43
+ .filter(indexName => !!(0, lodash_1.get)(indexKeys[indexName], documentName))
44
+ .map(indexName => ({
45
+ globalIndexComposer: (0, dos_1.got)(indexKeys[indexName], documentName),
46
+ indexName,
47
+ }));
48
+ const composedKeys = {};
49
+ const indexKeysJson = JSON.stringify(indexKeys, null, 2);
50
+ for (const { indexName, localIndexComposer } of localKeyComposers) {
51
+ const sortKey = getLocalIndexSortKeyName(indexName);
52
+ const errorTemplate = `Sort key composer should be defined by "${indexName}.$PATH", index keys: ${indexKeysJson}`;
53
+ const skTemplate = (0, dos_1.got)(localIndexComposer, 'sk', errorTemplate);
54
+ const skValue = composeSortKeyValue(attributes, skTemplate);
55
+ if (!skValue) {
56
+ continue;
57
+ }
58
+ composedKeys[sortKey] = skValue;
59
+ }
60
+ for (const { indexName, globalIndexComposer } of globalKeyComposers) {
61
+ const sortKey = getGlobalIndexSortKeyName(indexName);
62
+ const partitionKey = getGlobalIndexPartitionKeyName(indexName);
63
+ const skErrorTemplate = `Partition key composer should be defined by "${indexName}.${documentName}.$PATH", index keys: ${indexKeysJson}`;
64
+ const pkTemplate = (0, dos_1.got)(globalIndexComposer, 'pk', skErrorTemplate);
65
+ const pkValue = composePartitionKeyValue(idPrefix, attributes, pkTemplate);
66
+ if (!pkValue) {
67
+ continue;
68
+ }
69
+ composedKeys[partitionKey] = pkValue;
70
+ const pkErrorTemplate = `Sort key composer should be defined by "${indexName}.${documentName}.$PATH", index keys: ${indexKeysJson}`;
71
+ const skTemplate = (0, dos_1.got)(globalIndexComposer, 'sk', pkErrorTemplate);
72
+ const skValue = composeSortKeyValue(attributes, skTemplate);
73
+ if (!skValue) {
74
+ continue;
75
+ }
76
+ composedKeys[sortKey] = skValue;
77
+ }
78
+ return composedKeys;
79
+ };
80
+ exports.default = composeIndexKeys;
81
+ //# sourceMappingURL=composeIndexKeys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composeIndexKeys.js","sourceRoot":"","sources":["../../../../src/Document/helpers/composeIndexKeys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import composeIndexKeys from './composeIndexKeys';
2
+ export { composeIndexKeys, };
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Document/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAElD,OAAO,EACL,gBAAgB,GACjB,CAAC"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.composeIndexKeys = void 0;
7
+ const composeIndexKeys_1 = __importDefault(require("./composeIndexKeys"));
8
+ exports.composeIndexKeys = composeIndexKeys_1.default;
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/Document/helpers/index.ts"],"names":[],"mappings":";;;;;;AAAA,0EAAkD;AAGhD,2BAHK,0BAAgB,CAGL"}
@@ -0,0 +1,56 @@
1
+ import type { MutationMap, QueryMap } from '@kravc/dos';
2
+ import { type QueryCommandInput, type QueryCommandOutput } from '@aws-sdk/lib-dynamodb';
3
+ import { type TableOptions } from './helpers';
4
+ type Options = {
5
+ partitionKey: string;
6
+ sortKey: string;
7
+ };
8
+ export type ItemAttributes = Record<string, unknown>;
9
+ /** DynamoDB table class. */
10
+ declare class Table {
11
+ private _client;
12
+ private _rawClient;
13
+ private _tableOptions;
14
+ /** Creates an instance of a table. */
15
+ constructor(options: Options);
16
+ /** Returns table options. */
17
+ get options(): TableOptions;
18
+ /** Creates a DynamoDB table. */
19
+ create(): Promise<void>;
20
+ /** Deletes a DynamoDB table. */
21
+ delete(): Promise<void>;
22
+ /** Resets a DynamoDB table. */
23
+ reset(): Promise<void>;
24
+ /** Returns key and conditionQuery from query. */
25
+ _parseItemQuery(query: QueryMap): {
26
+ Key: {
27
+ [x: string]: unknown;
28
+ };
29
+ conditionQuery: {
30
+ [x: string]: unknown;
31
+ };
32
+ };
33
+ /** Creates a table item; returns false if item already exists. */
34
+ createItem(attributes: ItemAttributes): Promise<boolean>;
35
+ /** Returns a table item, or undefined if not found. */
36
+ getItem(query: QueryMap): Promise<ItemAttributes | undefined>;
37
+ /** Updates a table item with attributes. */
38
+ updateItem(query: QueryMap, mutation: MutationMap): Promise<ItemAttributes | undefined>;
39
+ /** Deletes a table item; returns false if item not found. */
40
+ deleteItem(query: QueryMap): Promise<boolean>;
41
+ /** Returns item from the table using a query. */
42
+ _queryItems(input: QueryCommandInput): Promise<QueryCommandOutput>;
43
+ /** Lists table items. */
44
+ listItems(query: QueryMap, options: {
45
+ sort: string;
46
+ limit: number;
47
+ indexName?: string;
48
+ exclusiveStartKey?: string;
49
+ }): Promise<{
50
+ count: number;
51
+ items: ItemAttributes[];
52
+ lastEvaluatedKey?: string;
53
+ }>;
54
+ }
55
+ export default Table;
56
+ //# sourceMappingURL=Table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../../src/Table/Table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGxD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EAIxB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,KAAK,YAAY,EAQlB,MAAM,WAAW,CAAC;AAEnB,KAAK,OAAO,GAAG;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErD,4BAA4B;AAC5B,cAAM,KAAK;IACT,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,aAAa,CAAe;IAEpC,sCAAsC;gBAC1B,OAAO,EAAE,OAAO;IAc5B,6BAA6B;IAC7B,IAAI,OAAO,iBAEV;IAED,gCAAgC;IAC1B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAO7B,gCAAgC;IAC1B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAO7B,+BAA+B;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB5B,iDAAiD;IACjD,eAAe,CAAC,KAAK,EAAE,QAAQ;;;;;;;;IAkB/B,kEAAkE;IAC5D,UAAU,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IA4C9D,uDAAuD;IACjD,OAAO,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IA+BnE,4CAA4C;IACtC,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAmD7F,6DAA6D;IACvD,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAuCnD,iDAAiD;IAC3C,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAsBxE,yBAAyB;IACnB,SAAS,CACb,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAC3B,GACA,OAAO,CAAC;QACT,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,cAAc,EAAE,CAAC;QACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CAqCH;AAED,eAAe,KAAK,CAAC"}
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
4
+ const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
+ const helpers_1 = require("./helpers");
6
+ /** DynamoDB table class. */
7
+ class Table {
8
+ _client;
9
+ _rawClient;
10
+ _tableOptions;
11
+ /** Creates an instance of a table. */
12
+ constructor(options) {
13
+ const { sortKey, partitionKey } = options;
14
+ const tableOptions = (0, helpers_1.getTableOptions)(partitionKey, sortKey);
15
+ const { region, profile } = tableOptions;
16
+ const config = (0, helpers_1.getRawClientConfig)(region, profile);
17
+ this._rawClient = new client_dynamodb_1.DynamoDBClient(config);
18
+ this._client = lib_dynamodb_1.DynamoDBDocument.from(this._rawClient);
19
+ this._tableOptions = tableOptions;
20
+ }
21
+ /** Returns table options. */
22
+ get options() {
23
+ return this._tableOptions;
24
+ }
25
+ /** Creates a DynamoDB table. */
26
+ async create() {
27
+ const tableSchema = (0, helpers_1.buildTableSchema)(this._tableOptions);
28
+ const command = new client_dynamodb_1.CreateTableCommand(tableSchema);
29
+ await this._rawClient.send(command);
30
+ }
31
+ /** Deletes a DynamoDB table. */
32
+ async delete() {
33
+ const { name: TableName } = this._tableOptions;
34
+ const deleteTableCommand = new client_dynamodb_1.DeleteTableCommand({ TableName });
35
+ await this._client.send(deleteTableCommand);
36
+ }
37
+ /** Resets a DynamoDB table. */
38
+ async reset() {
39
+ try {
40
+ await this.delete();
41
+ }
42
+ catch (dynamoError) {
43
+ const { name: errorName } = dynamoError;
44
+ /* istanbul ignore next */
45
+ if (errorName !== 'ResourceNotFoundException') {
46
+ throw dynamoError;
47
+ }
48
+ }
49
+ await this.create();
50
+ }
51
+ /** Returns key and conditionQuery from query. */
52
+ _parseItemQuery(query) {
53
+ const { primaryKey } = this._tableOptions;
54
+ const { sortKey, partitionKey } = primaryKey;
55
+ const { [sortKey]: sortKeyValue, [partitionKey]: partitionKeyValue, ...conditionQuery } = query;
56
+ const Key = {
57
+ [sortKey]: sortKeyValue,
58
+ [partitionKey]: partitionKeyValue,
59
+ };
60
+ return { Key, conditionQuery };
61
+ }
62
+ /** Creates a table item; returns false if item already exists. */
63
+ async createItem(attributes) {
64
+ const { name: TableName, primaryKey } = this._tableOptions;
65
+ const { sortKey } = primaryKey;
66
+ const ConditionExpression = `#${sortKey} <> :${sortKey}`;
67
+ const ExpressionAttributeNames = {
68
+ [`#${sortKey}`]: sortKey,
69
+ };
70
+ const ExpressionAttributeValues = {
71
+ [`:${sortKey}`]: attributes[sortKey],
72
+ };
73
+ const putCommandInput = {
74
+ TableName,
75
+ ConditionExpression,
76
+ ExpressionAttributeNames,
77
+ ExpressionAttributeValues,
78
+ Item: attributes,
79
+ };
80
+ try {
81
+ await this._client.put(putCommandInput);
82
+ }
83
+ catch (dynamoError) {
84
+ const { name: errorName } = dynamoError;
85
+ if (errorName === 'ConditionalCheckFailedException') {
86
+ return false;
87
+ }
88
+ /* istanbul ignore next */
89
+ if (errorName !== 'ResourceNotFoundException') {
90
+ throw dynamoError;
91
+ }
92
+ throw new Error(`Table "${TableName}" does not exist`);
93
+ }
94
+ return true;
95
+ }
96
+ /** Returns a table item, or undefined if not found. */
97
+ async getItem(query) {
98
+ const { name: TableName } = this._tableOptions;
99
+ const { Key, conditionQuery } = this._parseItemQuery(query);
100
+ const getCommandInput = {
101
+ ConsistentRead: true,
102
+ TableName,
103
+ Key,
104
+ };
105
+ let result;
106
+ try {
107
+ result = await this._client.get(getCommandInput);
108
+ }
109
+ catch (dynamoError) {
110
+ const { name: errorName } = dynamoError;
111
+ /* istanbul ignore next */
112
+ if (errorName !== 'ResourceNotFoundException') {
113
+ throw dynamoError;
114
+ }
115
+ throw new Error(`Table "${TableName}" does not exist`);
116
+ }
117
+ const { Item: itemAttributes } = result;
118
+ return (0, helpers_1.filterConditionExpression)(itemAttributes, conditionQuery);
119
+ }
120
+ /** Updates a table item with attributes. */
121
+ async updateItem(query, mutation) {
122
+ const { name: TableName, primaryKey } = this._tableOptions;
123
+ const { Key } = this._parseItemQuery(query);
124
+ const { partitionKey, sortKey } = primaryKey;
125
+ delete mutation[sortKey];
126
+ delete mutation[partitionKey];
127
+ const { UpdateExpression, ConditionExpression, ExpressionAttributeNames, ExpressionAttributeValues, } = (0, helpers_1.buildUpdateExpression)(query, mutation);
128
+ const updateCommandInput = {
129
+ ReturnValues: 'ALL_NEW',
130
+ Key,
131
+ TableName,
132
+ UpdateExpression,
133
+ ConditionExpression,
134
+ ExpressionAttributeNames,
135
+ ExpressionAttributeValues,
136
+ };
137
+ let result;
138
+ try {
139
+ result = await this._client.update(updateCommandInput);
140
+ }
141
+ catch (dynamoError) {
142
+ const { name: errorName } = dynamoError;
143
+ if (errorName === 'ConditionalCheckFailedException') {
144
+ return;
145
+ }
146
+ /* istanbul ignore next */
147
+ if (errorName !== 'ResourceNotFoundException') {
148
+ throw dynamoError;
149
+ }
150
+ throw new Error(`Table "${TableName}" does not exist`);
151
+ }
152
+ const { Attributes: attributes } = result;
153
+ return attributes;
154
+ }
155
+ /** Deletes a table item; returns false if item not found. */
156
+ async deleteItem(query) {
157
+ const { name: TableName } = this._tableOptions;
158
+ const { Key } = this._parseItemQuery(query);
159
+ const { ConditionExpression, ExpressionAttributeNames, ExpressionAttributeValues, } = (0, helpers_1.buildConditionExpression)(query);
160
+ const deleteCommandInput = {
161
+ TableName,
162
+ Key,
163
+ ConditionExpression,
164
+ ExpressionAttributeNames,
165
+ ExpressionAttributeValues
166
+ };
167
+ try {
168
+ await this._client.delete(deleteCommandInput);
169
+ }
170
+ catch (dynamoError) {
171
+ const { name: errorName } = dynamoError;
172
+ if (errorName === 'ConditionalCheckFailedException') {
173
+ return false;
174
+ }
175
+ /* istanbul ignore next */
176
+ if (errorName !== 'ResourceNotFoundException') {
177
+ throw dynamoError;
178
+ }
179
+ throw new Error(`Table "${TableName}" does not exist`);
180
+ }
181
+ return true;
182
+ }
183
+ /** Returns item from the table using a query. */
184
+ async _queryItems(input) {
185
+ let result;
186
+ try {
187
+ result = await this._client.query(input);
188
+ }
189
+ catch (dynamoError) {
190
+ const { name: errorName } = dynamoError;
191
+ /* istanbul ignore next */
192
+ if (errorName !== 'ResourceNotFoundException') {
193
+ throw dynamoError;
194
+ }
195
+ const { TableName } = input;
196
+ throw new Error(`Table "${TableName}" does not exist`);
197
+ }
198
+ return result;
199
+ }
200
+ /** Lists table items. */
201
+ async listItems(query, options) {
202
+ const queryCommandInput = (0, helpers_1.buildQueryCommandInput)(this._tableOptions, query, options);
203
+ const { limit } = options;
204
+ let count = 0;
205
+ let items = [];
206
+ let lastEvaluatedKey;
207
+ let isNextChunkRequired = true;
208
+ do {
209
+ const { Items: chunk, LastEvaluatedKey } = await this._queryItems(queryCommandInput);
210
+ const hasMoreItems = !!LastEvaluatedKey;
211
+ items = [...items, ...chunk];
212
+ count = items.length;
213
+ lastEvaluatedKey = LastEvaluatedKey;
214
+ isNextChunkRequired = hasMoreItems && count < limit;
215
+ queryCommandInput.ExclusiveStartKey = LastEvaluatedKey;
216
+ } while (isNextChunkRequired);
217
+ if (lastEvaluatedKey) {
218
+ lastEvaluatedKey = encodeURIComponent(JSON.stringify(lastEvaluatedKey));
219
+ }
220
+ return {
221
+ count,
222
+ items,
223
+ lastEvaluatedKey
224
+ };
225
+ }
226
+ }
227
+ exports.default = Table;
228
+ //# sourceMappingURL=Table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Table.js","sourceRoot":"","sources":["../../../src/Table/Table.ts"],"names":[],"mappings":";;AACA,8DAAkG;AAElG,wDAQ+B;AAE/B,uCASmB;AASnB,4BAA4B;AAC5B,MAAM,KAAK;IACD,OAAO,CAAmB;IAC1B,UAAU,CAAiB;IAC3B,aAAa,CAAe;IAEpC,sCAAsC;IACtC,YAAY,OAAgB;QAC1B,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;QAE1C,MAAM,YAAY,GAAG,IAAA,yBAAe,EAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAE5D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC;QACzC,MAAM,MAAM,GAAG,IAAA,4BAAkB,EAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEnD,IAAI,CAAC,UAAU,GAAG,IAAI,gCAAc,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,+BAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEtD,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;IACpC,CAAC;IAED,6BAA6B;IAC7B,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,gCAAgC;IAChC,KAAK,CAAC,MAAM;QACV,MAAM,WAAW,GAAG,IAAA,0BAAgB,EAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,IAAI,oCAAkB,CAAC,WAAW,CAAC,CAAC;QAEpD,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,gCAAgC;IAChC,KAAK,CAAC,MAAM;QACV,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC/C,MAAM,kBAAkB,GAAG,IAAI,oCAAkB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QAEjE,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC9C,CAAC;IAED,+BAA+B;IAC/B,KAAK,CAAC,KAAK;QACT,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAEtB,CAAC;QAAC,OAAO,WAAoB,EAAE,CAAC;YAC9B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,WAA+B,CAAC;YAE5D,0BAA0B;YAC1B,IAAI,SAAS,KAAK,2BAA2B,EAAE,CAAC;gBAC9C,MAAM,WAAW,CAAC;YACpB,CAAC;QACH,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;IACtB,CAAC;IAED,iDAAiD;IACjD,eAAe,CAAC,KAAe;QAC7B,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC1C,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC;QAE7C,MAAM,EACJ,CAAC,OAAO,CAAC,EAAE,YAAY,EACvB,CAAC,YAAY,CAAC,EAAE,iBAAiB,EACjC,GAAG,cAAc,EAClB,GAAG,KAAK,CAAC;QAEV,MAAM,GAAG,GAAG;YACV,CAAC,OAAO,CAAC,EAAE,YAAY;YACvB,CAAC,YAAY,CAAC,EAAE,iBAAiB;SAClC,CAAC;QAEF,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC;IACjC,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,UAAU,CAAC,UAA0B;QACzC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAE3D,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;QAE/B,MAAM,mBAAmB,GAAG,IAAI,OAAO,QAAQ,OAAO,EAAE,CAAC;QAEzD,MAAM,wBAAwB,GAAG;YAC/B,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,OAAO;SACzB,CAAC;QAEF,MAAM,yBAAyB,GAAG;YAChC,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC;SACrC,CAAC;QAEF,MAAM,eAAe,GAAG;YACtB,SAAS;YACT,mBAAmB;YACnB,wBAAwB;YACxB,yBAAyB;YACzB,IAAI,EAAE,UAAU;SACE,CAAC;QAErB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAE1C,CAAC;QAAC,OAAO,WAAoB,EAAE,CAAC;YAC9B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,WAA+B,CAAC;YAE5D,IAAI,SAAS,KAAK,iCAAiC,EAAE,CAAC;gBACpD,OAAO,KAAK,CAAC;YACf,CAAC;YAED,0BAA0B;YAC1B,IAAI,SAAS,KAAK,2BAA2B,EAAE,CAAC;gBAC9C,MAAM,WAAW,CAAC;YACpB,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,UAAU,SAAS,kBAAkB,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uDAAuD;IACvD,KAAK,CAAC,OAAO,CAAC,KAAe;QAC3B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC/C,MAAM,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAE5D,MAAM,eAAe,GAAG;YACtB,cAAc,EAAE,IAAI;YACpB,SAAS;YACT,GAAG;SACe,CAAC;QAErB,IAAI,MAAM,CAAC;QAEX,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAEnD,CAAC;QAAC,OAAO,WAAoB,EAAE,CAAC;YAC9B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,WAA+B,CAAC;YAE5D,0BAA0B;YAC1B,IAAI,SAAS,KAAK,2BAA2B,EAAE,CAAC;gBAC9C,MAAM,WAAW,CAAC;YACpB,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,UAAU,SAAS,kBAAkB,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,MAAM,CAAC;QAExC,OAAO,IAAA,mCAAyB,EAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IACnE,CAAC;IAED,4CAA4C;IAC5C,KAAK,CAAC,UAAU,CAAC,KAAe,EAAE,QAAqB;QACrD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC3D,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAE5C,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;QAE7C,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzB,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;QAE9B,MAAM,EACJ,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,GAC1B,GAAG,IAAA,+BAAqB,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAE3C,MAAM,kBAAkB,GAAG;YACzB,YAAY,EAAE,SAAS;YACvB,GAAG;YACH,SAAS;YACT,gBAAgB;YAChB,mBAAmB;YACnB,wBAAwB;YACxB,yBAAyB;SACJ,CAAC;QAExB,IAAI,MAAM,CAAC;QAEX,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAEzD,CAAC;QAAC,OAAO,WAAoB,EAAE,CAAC;YAC9B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,WAA+B,CAAC;YAE5D,IAAI,SAAS,KAAK,iCAAiC,EAAE,CAAC;gBACpD,OAAO;YACT,CAAC;YAED,0BAA0B;YAC1B,IAAI,SAAS,KAAK,2BAA2B,EAAE,CAAC;gBAC9C,MAAM,WAAW,CAAC;YACpB,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,UAAU,SAAS,kBAAkB,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;QAE1C,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,UAAU,CAAC,KAAe;QAC9B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAE5C,MAAM,EACJ,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,GAC1B,GAAG,IAAA,kCAAwB,EAAC,KAAK,CAAC,CAAC;QAEpC,MAAM,kBAAkB,GAAG;YACzB,SAAS;YACT,GAAG;YACH,mBAAmB;YACnB,wBAAwB;YACxB,yBAAyB;SACJ,CAAC;QAExB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAEhD,CAAC;QAAC,OAAO,WAAoB,EAAE,CAAC;YAC9B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,WAA+B,CAAC;YAE5D,IAAI,SAAS,KAAK,iCAAiC,EAAE,CAAC;gBACpD,OAAO,KAAK,CAAC;YACf,CAAC;YAED,0BAA0B;YAC1B,IAAI,SAAS,KAAK,2BAA2B,EAAE,CAAC;gBAC9C,MAAM,WAAW,CAAC;YACpB,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,UAAU,SAAS,kBAAkB,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iDAAiD;IACjD,KAAK,CAAC,WAAW,CAAC,KAAwB;QACxC,IAAI,MAA0B,CAAC;QAE/B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAE3C,CAAC;QAAC,OAAO,WAAoB,EAAE,CAAC;YAC9B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,WAA+B,CAAC;YAE5D,0BAA0B;YAC1B,IAAI,SAAS,KAAK,2BAA2B,EAAE,CAAC;gBAC9C,MAAM,WAAW,CAAC;YACpB,CAAC;YAED,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;YAE5B,MAAM,IAAI,KAAK,CAAC,UAAU,SAAS,kBAAkB,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,yBAAyB;IACzB,KAAK,CAAC,SAAS,CACb,KAAe,EACf,OAKC;QAMD,MAAM,iBAAiB,GAAG,IAAA,gCAAsB,EAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAErF,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;QAE1B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,KAAK,GAAG,EAA+B,CAAC;QAC5C,IAAI,gBAAgB,CAAC;QACrB,IAAI,mBAAmB,GAAG,IAAI,CAAC;QAE/B,GAAG,CAAC;YACF,MAAM,EACJ,KAAK,EAAE,KAAK,EACZ,gBAAgB,EACjB,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;YAE9C,MAAM,YAAY,GAAG,CAAC,CAAC,gBAAgB,CAAC;YAExC,KAAK,GAAG,CAAE,GAAG,KAAK,EAAE,GAAI,KAA0B,CAAE,CAAC;YACrD,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;YACrB,gBAAgB,GAAG,gBAAgB,CAAC;YACpC,mBAAmB,GAAG,YAAY,IAAI,KAAK,GAAG,KAAK,CAAC;YAEpD,iBAAiB,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QAEzD,CAAC,QAAQ,mBAAmB,EAAE;QAE9B,IAAI,gBAAgB,EAAE,CAAC;YACrB,gBAAgB,GAAG,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC1E,CAAC;QAED,OAAO;YACL,KAAK;YACL,KAAK;YACL,gBAAgB;SACjB,CAAC;IACJ,CAAC;CACF;AAED,kBAAe,KAAK,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { QueryMap } from '@kravc/dos';
2
+ export declare enum ExpressionKey {
3
+ LT = "lt",
4
+ LE = "le",
5
+ GT = "gt",
6
+ GE = "ge",
7
+ NOT = "not",
8
+ CONTAIN = "contains",
9
+ EXCLUDE = "not_contains"
10
+ }
11
+ /** Builds condition expression from a query for a table query, update and delete methods. */
12
+ declare const buildConditionExpression: (query: QueryMap) => {
13
+ ExpressionAttributeNames: Record<string, string>;
14
+ ExpressionAttributeValues: Record<string, unknown>;
15
+ ConditionExpression?: undefined;
16
+ } | {
17
+ ConditionExpression: string;
18
+ ExpressionAttributeNames: Record<string, string>;
19
+ ExpressionAttributeValues: Record<string, unknown>;
20
+ };
21
+ export default buildConditionExpression;
22
+ //# sourceMappingURL=buildConditionExpression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildConditionExpression.d.ts","sourceRoot":"","sources":["../../../../src/Table/helpers/buildConditionExpression.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,oBAAY,aAAa;IACvB,EAAE,OAAO;IACT,EAAE,OAAO;IACT,EAAE,OAAO;IACT,EAAE,OAAO;IACT,GAAG,QAAQ;IACX,OAAO,aAAa;IACpB,OAAO,iBAAiB;CAIzB;AAED,6FAA6F;AAC7F,QAAA,MAAM,wBAAwB,GAAI,OAAO,QAAQ;;;;;;;;CAoIhD,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExpressionKey = void 0;
4
+ var ExpressionKey;
5
+ (function (ExpressionKey) {
6
+ ExpressionKey["LT"] = "lt";
7
+ ExpressionKey["LE"] = "le";
8
+ ExpressionKey["GT"] = "gt";
9
+ ExpressionKey["GE"] = "ge";
10
+ ExpressionKey["NOT"] = "not";
11
+ ExpressionKey["CONTAIN"] = "contains";
12
+ ExpressionKey["EXCLUDE"] = "not_contains";
13
+ // TODO: Add support for:
14
+ // - between: lt and gt
15
+ // - begins with
16
+ })(ExpressionKey || (exports.ExpressionKey = ExpressionKey = {}));
17
+ /** Builds condition expression from a query for a table query, update and delete methods. */
18
+ const buildConditionExpression = (query) => {
19
+ // NOTE: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html
20
+ const ConditionExpressions = [];
21
+ const ExpressionAttributeNames = {};
22
+ const ExpressionAttributeValues = {};
23
+ for (let key in query) {
24
+ let path = '#Q_' + key.replace(/\./g, '.#Q_');
25
+ const valueKey = key.replace(/\.|:/g, '_');
26
+ const filterValue = query[key];
27
+ const isNot = key.endsWith(`:${ExpressionKey.NOT}`);
28
+ const isLessThan = key.endsWith(`:${ExpressionKey.LT}`);
29
+ const isLessThanOrEqual = key.endsWith(`:${ExpressionKey.LE}`);
30
+ const isGreaterThan = key.endsWith(`:${ExpressionKey.GT}`);
31
+ const isGreaterThanOrEqual = key.endsWith(`:${ExpressionKey.GE}`);
32
+ const isContains = key.endsWith(`:${ExpressionKey.CONTAIN}`);
33
+ const isNotContains = key.endsWith(`:${ExpressionKey.EXCLUDE}`);
34
+ const isFilterValueNull = filterValue === null;
35
+ if (isNot) {
36
+ key = key.replace(/:not/g, '');
37
+ }
38
+ if (isContains) {
39
+ key = key.replace(/:contains/g, '');
40
+ }
41
+ if (isNotContains) {
42
+ key = key.replace(/:not_contains/g, '');
43
+ }
44
+ if (isLessThan) {
45
+ key = key.replace(/:lt/g, '');
46
+ }
47
+ if (isLessThanOrEqual) {
48
+ key = key.replace(/:le/g, '');
49
+ }
50
+ if (isGreaterThan) {
51
+ key = key.replace(/:gt/g, '');
52
+ }
53
+ if (isGreaterThanOrEqual) {
54
+ key = key.replace(/:ge/g, '');
55
+ }
56
+ const pathKeys = key.split('.');
57
+ for (const pathKey of pathKeys) {
58
+ ExpressionAttributeNames[`#Q_${pathKey}`] = pathKey;
59
+ }
60
+ const isFilterValueArray = Array.isArray(filterValue);
61
+ if (isFilterValueArray) {
62
+ const filterValues = filterValue.entries();
63
+ const valueKeys = [];
64
+ for (const [index, value] of filterValues) {
65
+ ExpressionAttributeValues[`:Q_${valueKey}${index + 1}`] = value;
66
+ valueKeys.push(`:Q_${valueKey}${index + 1}`);
67
+ }
68
+ ConditionExpressions.push(`${path} in (${valueKeys})`);
69
+ }
70
+ else {
71
+ ExpressionAttributeValues[`:Q_${valueKey}`] = filterValue;
72
+ if (isNot) {
73
+ path = path.replace(/:not/, '');
74
+ ConditionExpressions.push(`${path} <> :Q_${valueKey}`);
75
+ if (isFilterValueNull) {
76
+ ConditionExpressions.push(`attribute_exists(${path})`);
77
+ }
78
+ }
79
+ else if (isContains) {
80
+ path = path.replace(/:contains/, '');
81
+ ConditionExpressions.push(`contains(${path}, :Q_${valueKey})`);
82
+ }
83
+ else if (isNotContains) {
84
+ path = path.replace(/:not_contains/, '');
85
+ ConditionExpressions.push(`not contains(${path}, :Q_${valueKey})`);
86
+ }
87
+ else if (isLessThan) {
88
+ path = path.replace(/:lt/, '');
89
+ ConditionExpressions.push(`${path} < :Q_${valueKey}`);
90
+ }
91
+ else if (isLessThanOrEqual) {
92
+ path = path.replace(/:le/, '');
93
+ ConditionExpressions.push(`${path} <= :Q_${valueKey}`);
94
+ }
95
+ else if (isGreaterThan) {
96
+ path = path.replace(/:gt/, '');
97
+ ConditionExpressions.push(`${path} > :Q_${valueKey}`);
98
+ }
99
+ else if (isGreaterThanOrEqual) {
100
+ path = path.replace(/:ge/, '');
101
+ ConditionExpressions.push(`${path} >= :Q_${valueKey}`);
102
+ }
103
+ else {
104
+ if (isFilterValueNull) {
105
+ ConditionExpressions.push(`(${path} = :Q_${valueKey} OR attribute_not_exists(${path}))`);
106
+ }
107
+ else {
108
+ ConditionExpressions.push(`${path} = :Q_${valueKey}`);
109
+ }
110
+ }
111
+ }
112
+ }
113
+ const ConditionExpression = ConditionExpressions.join(' AND ');
114
+ const hasConditionExpression = ConditionExpression !== '';
115
+ if (!hasConditionExpression) {
116
+ return {
117
+ ExpressionAttributeNames,
118
+ ExpressionAttributeValues
119
+ };
120
+ }
121
+ return {
122
+ ConditionExpression,
123
+ ExpressionAttributeNames,
124
+ ExpressionAttributeValues,
125
+ };
126
+ };
127
+ exports.default = buildConditionExpression;
128
+ //# sourceMappingURL=buildConditionExpression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildConditionExpression.js","sourceRoot":"","sources":["../../../../src/Table/helpers/buildConditionExpression.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { TableOptions } from './getTableOptions';
2
+ import { type QueryMap } from '@kravc/dos';
3
+ import { type QueryCommandInput } from '@aws-sdk/lib-dynamodb';
4
+ /** Builds query command input. */
5
+ declare const buildQueryCommandInput: (tableOptions: TableOptions, query: QueryMap, options: {
6
+ sort: string;
7
+ limit: number;
8
+ indexName?: string;
9
+ exclusiveStartKey?: string;
10
+ }) => QueryCommandInput;
11
+ export default buildQueryCommandInput;
12
+ //# sourceMappingURL=buildQueryCommandInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildQueryCommandInput.d.ts","sourceRoot":"","sources":["../../../../src/Table/helpers/buildQueryCommandInput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AA8C/D,kCAAkC;AAClC,QAAA,MAAM,sBAAsB,GAC1B,cAAc,YAAY,EAC1B,OAAO,QAAQ,EACf,SAAS;IACP,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,sBAqDF,CAAC;AAEF,eAAe,sBAAsB,CAAC"}