@twin.org/entity-storage-connector-dynamodb 0.0.3-next.16 → 0.0.3-next.20

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.
@@ -6,7 +6,7 @@ import { unmarshall } from "@aws-sdk/util-dynamodb";
6
6
  import { ContextIdHelper, ContextIdStore } from "@twin.org/context";
7
7
  import { BaseError, Coerce, ComponentFactory, Converter, GeneralError, Guards, HealthStatus, Is, ObjectHelper } from "@twin.org/core";
8
8
  import { ComparisonOperator, EntitySchemaFactory, EntitySchemaHelper, LogicalOperator, SortDirection } from "@twin.org/entity";
9
- import { EntityHelper } from "@twin.org/entity-storage-models";
9
+ import { EntityStorageHelper } from "@twin.org/entity-storage-models";
10
10
  /**
11
11
  * Class for performing entity storage operations using Dynamo DB.
12
12
  */
@@ -287,7 +287,7 @@ export class DynamoDbEntityStorageConnector {
287
287
  });
288
288
  const response = await docClient.send(getCommand);
289
289
  if (response.Item) {
290
- return EntityHelper.unPrepareEntity(response.Item, [
290
+ return EntityStorageHelper.unPrepareEntity(response.Item, [
291
291
  DynamoDbEntityStorageConnector._PARTITION_KEY
292
292
  ]);
293
293
  }
@@ -336,14 +336,14 @@ export class DynamoDbEntityStorageConnector {
336
336
  Guards.object(DynamoDbEntityStorageConnector.CLASS_NAME, "entity", entity);
337
337
  const contextIds = await ContextIdStore.getContextIds();
338
338
  const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
339
- const prepared = EntityHelper.prepareEntity(entity, this._entitySchema, partitionKey
339
+ const prepared = EntityStorageHelper.prepareEntity(entity, this._entitySchema, partitionKey
340
340
  ? [{ property: DynamoDbEntityStorageConnector._PARTITION_KEY, value: partitionKey }]
341
341
  : [
342
342
  {
343
343
  property: DynamoDbEntityStorageConnector._PARTITION_KEY,
344
344
  value: DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE
345
345
  }
346
- ]);
346
+ ], { nullBehavior: "omit" });
347
347
  const id = prepared[this._primaryKey.property];
348
348
  try {
349
349
  const docClient = this.createDocClient();
@@ -384,14 +384,14 @@ export class DynamoDbEntityStorageConnector {
384
384
  Guards.arrayValue(DynamoDbEntityStorageConnector.CLASS_NAME, "entities", entities);
385
385
  const contextIds = await ContextIdStore.getContextIds();
386
386
  const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
387
- const preparedEntities = entities.map(entity => EntityHelper.prepareEntity(entity, this._entitySchema, partitionKey
387
+ const preparedEntities = entities.map(entity => EntityStorageHelper.prepareEntity(entity, this._entitySchema, partitionKey
388
388
  ? [{ property: DynamoDbEntityStorageConnector._PARTITION_KEY, value: partitionKey }]
389
389
  : [
390
390
  {
391
391
  property: DynamoDbEntityStorageConnector._PARTITION_KEY,
392
392
  value: DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE
393
393
  }
394
- ]));
394
+ ], { nullBehavior: "omit" }));
395
395
  try {
396
396
  const docClient = this.createDocClient();
397
397
  const chunkSize = 25;
@@ -869,15 +869,13 @@ export class DynamoDbEntityStorageConnector {
869
869
  prop += comparator.property;
870
870
  let attributeName = this.populateAttributeNames(prop, attributeNames);
871
871
  if (Is.empty(comparator.value)) {
872
- // prepareEntity converts undefined null before storing, so DynamoDB holds the
873
- // attribute with type NULL rather than omitting it. Use attribute_type to match.
874
- const nullTypePropName = `:${attributeName.replace(/\./g, "").replace(/#/g, "")}Null`;
875
- attributeValues[nullTypePropName] = { S: "NULL" };
872
+ // With "omit" storage, optional null/undefined fields are absent from the item entirely.
873
+ // attribute_not_exists matches absent attributes; attribute_exists matches present ones.
876
874
  if (comparator.comparison === ComparisonOperator.Equals) {
877
- return `attribute_type(${attributeName}, ${nullTypePropName})`;
875
+ return `attribute_not_exists(${attributeName})`;
878
876
  }
879
877
  else if (comparator.comparison === ComparisonOperator.NotEquals) {
880
- return `NOT attribute_type(${attributeName}, ${nullTypePropName})`;
878
+ return `attribute_exists(${attributeName})`;
881
879
  }
882
880
  }
883
881
  const basePropName = `:${attributeName.replace(/\./g, "").replace(/#/g, "")}`;
@@ -1150,7 +1148,7 @@ export class DynamoDbEntityStorageConnector {
1150
1148
  }
1151
1149
  const scanEntities = returnedRawItems.map(item => {
1152
1150
  const unmarshalled = unmarshall(item);
1153
- return EntityHelper.unPrepareEntity(unmarshalled, [
1151
+ return EntityStorageHelper.unPrepareEntity(unmarshalled, [
1154
1152
  DynamoDbEntityStorageConnector._PARTITION_KEY
1155
1153
  ]);
1156
1154
  });
@@ -1195,7 +1193,7 @@ export class DynamoDbEntityStorageConnector {
1195
1193
  }
1196
1194
  const entities = returnedRawItems.map(item => {
1197
1195
  const unmarshalled = unmarshall(item);
1198
- return EntityHelper.unPrepareEntity(unmarshalled, [
1196
+ return EntityStorageHelper.unPrepareEntity(unmarshalled, [
1199
1197
  DynamoDbEntityStorageConnector._PARTITION_KEY
1200
1198
  ]);
1201
1199
  });
@@ -1 +1 @@
1
- {"version":3,"file":"dynamoDbEntityStorageConnector.js","sourceRoot":"","sources":["../../src/dynamoDbEntityStorageConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\ttype AttributeValue,\n\tBatchWriteItemCommand,\n\ttype CreateTableCommandInput,\n\tDynamoDB,\n\ttype DynamoDBClientConfig,\n\ttype GlobalSecondaryIndex,\n\tQueryCommand,\n\tScanCommand as RawScanCommand,\n\twaitUntilTableExists,\n\twaitUntilTableNotExists\n} from \"@aws-sdk/client-dynamodb\";\nimport {\n\tBatchWriteCommand,\n\tDeleteCommand,\n\tDynamoDBDocumentClient,\n\tGetCommand,\n\tPutCommand,\n\tScanCommand\n} from \"@aws-sdk/lib-dynamodb\";\nimport { type NativeAttributeValue, unmarshall } from \"@aws-sdk/util-dynamodb\";\nimport { ContextIdHelper, ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tCoerce,\n\tComponentFactory,\n\tConverter,\n\tGeneralError,\n\tGuards,\n\tHealthStatus,\n\ttype IHealth,\n\tIs,\n\tObjectHelper\n} from \"@twin.org/core\";\nimport {\n\tComparisonOperator,\n\ttype EntityCondition,\n\tEntitySchemaFactory,\n\tEntitySchemaHelper,\n\ttype EntitySchemaPropertyType,\n\ttype IComparator,\n\ttype IEntitySchema,\n\ttype IEntitySchemaProperty,\n\tLogicalOperator,\n\tSortDirection\n} from \"@twin.org/entity\";\nimport {\n\tEntityHelper,\n\ttype IEntityStorageConnector,\n\ttype IEntityStorageMigrationConnector,\n\ttype IMigrationOptions\n} from \"@twin.org/entity-storage-models\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { IDynamoDbEntityStorageConnectorConfig } from \"./models/IDynamoDbEntityStorageConnectorConfig.js\";\nimport type { IDynamoDbEntityStorageConnectorConstructorOptions } from \"./models/IDynamoDbEntityStorageConnectorConstructorOptions.js\";\n\n/**\n * Class for performing entity storage operations using Dynamo DB.\n */\nexport class DynamoDbEntityStorageConnector<\n\tT = unknown\n> implements IEntityStorageMigrationConnector<T> {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<DynamoDbEntityStorageConnector>();\n\n\t/**\n\t * Limit the number of entities when finding.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_LIMIT: number = 40;\n\n\t/**\n\t * Partition id field name.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY: string = \"partitionId\";\n\n\t/**\n\t * Partition id field value.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY_VALUE: string = \"root\";\n\n\t/**\n\t * The name for the schema.\n\t * @internal\n\t */\n\tprivate readonly _entitySchemaName: string;\n\n\t/**\n\t * The schema for the entity.\n\t * @internal\n\t */\n\tprivate readonly _entitySchema: IEntitySchema<T>;\n\n\t/**\n\t * The keys to use from the context ids to create partitions.\n\t * @internal\n\t */\n\tprivate readonly _partitionContextIds?: string[];\n\n\t/**\n\t * The primary key.\n\t * @internal\n\t */\n\tprivate readonly _primaryKey: IEntitySchemaProperty<T>;\n\n\t/**\n\t * The configuration for the connector.\n\t * @internal\n\t */\n\tprivate readonly _config: IDynamoDbEntityStorageConnectorConfig;\n\n\t/**\n\t * Create a new instance of DynamoDbEntityStorageConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: IDynamoDbEntityStorageConnectorConstructorOptions) {\n\t\tGuards.object(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(options), options);\n\t\tGuards.stringValue(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.entitySchema),\n\t\t\toptions.entitySchema\n\t\t);\n\t\tGuards.object<IDynamoDbEntityStorageConnectorConfig>(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\n\t\toptions.config.authMode ??= \"credentials\";\n\n\t\tif (options.config.authMode === \"credentials\") {\n\t\t\tGuards.stringValue(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.accessKeyId),\n\t\t\t\toptions.config.accessKeyId\n\t\t\t);\n\t\t\tGuards.stringValue(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.secretAccessKey),\n\t\t\t\toptions.config.secretAccessKey\n\t\t\t);\n\t\t}\n\t\tGuards.stringValue(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.region),\n\t\t\toptions.config.region\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.tableName),\n\t\t\toptions.config.tableName\n\t\t);\n\n\t\tthis._partitionContextIds = options.partitionContextIds;\n\n\t\tthis._entitySchemaName = options.entitySchema;\n\t\tthis._entitySchema = EntitySchemaFactory.get(options.entitySchema);\n\t\tthis._primaryKey = EntitySchemaHelper.getPrimaryKey<T>(this._entitySchema);\n\n\t\tthis._config = options.config;\n\t\tthis._config.endpoint = Is.stringValue(this._config.endpoint)\n\t\t\t? this._config.endpoint\n\t\t\t: undefined;\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn DynamoDbEntityStorageConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Returns the health status of the component.\n\t * @returns The health status of the component.\n\t */\n\tpublic async health(): Promise<IHealth[]> {\n\t\ttry {\n\t\t\tconst dbConnection = this.createConnection();\n\t\t\tawait dbConnection.describeTable({ TableName: this._config.tableName });\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tdata: { tableName: this._config.tableName }\n\t\t\t\t}\n\t\t\t];\n\t\t} catch {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tmessage: \"connectionFailed\",\n\t\t\t\t\tdata: { tableName: this._config.tableName }\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\t}\n\n\t/**\n\t * Get the schema for the entities.\n\t * @returns The schema for the entities.\n\t */\n\tpublic getSchema(): IEntitySchema {\n\t\treturn this._entitySchema as IEntitySchema;\n\t}\n\n\t/**\n\t * Bootstrap the component by creating and initializing any resources it needs.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the bootstrapping process was successful.\n\t */\n\tpublic async bootstrap(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tif (!(await this.tableExists(this._config.tableName))) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableCreating\",\n\t\t\t\tdata: {\n\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t}\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tconst dbConnection = this.createConnection();\n\n\t\t\t\tconst tableParams: CreateTableCommandInput = {\n\t\t\t\t\tAttributeDefinitions: [],\n\t\t\t\t\tKeySchema: [],\n\t\t\t\t\tProvisionedThroughput: {\n\t\t\t\t\t\tReadCapacityUnits: 1,\n\t\t\t\t\t\tWriteCapacityUnits: 1\n\t\t\t\t\t},\n\t\t\t\t\tTableName: this._config.tableName\n\t\t\t\t};\n\n\t\t\t\t// We always add a partition key to the table as a non optional hash key\n\t\t\t\t// is always required when querying using sort parameters\n\t\t\t\ttableParams.AttributeDefinitions?.push({\n\t\t\t\t\tAttributeName: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\tAttributeType: \"S\"\n\t\t\t\t});\n\t\t\t\ttableParams.KeySchema?.push({\n\t\t\t\t\tAttributeName: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\tKeyType: \"HASH\"\n\t\t\t\t});\n\n\t\t\t\tconst gsi: GlobalSecondaryIndex[] = [];\n\n\t\t\t\tif (Is.arrayValue(this._entitySchema.properties)) {\n\t\t\t\t\tfor (const prop of this._entitySchema.properties) {\n\t\t\t\t\t\tif (prop.isPrimary) {\n\t\t\t\t\t\t\ttableParams.AttributeDefinitions?.push({\n\t\t\t\t\t\t\t\tAttributeName: prop.property as string,\n\t\t\t\t\t\t\t\tAttributeType: prop.type === \"integer\" || prop.type === \"number\" ? \"N\" : \"S\"\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ttableParams.KeySchema?.push({\n\t\t\t\t\t\t\t\tAttributeName: prop.property as string,\n\t\t\t\t\t\t\t\tKeyType: \"RANGE\"\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (Is.stringValue(prop.sortDirection) || prop.isSecondary) {\n\t\t\t\t\t\t\t// You can only query and sort items if you have a secondary index\n\t\t\t\t\t\t\t// defined for the property\n\t\t\t\t\t\t\ttableParams.AttributeDefinitions?.push({\n\t\t\t\t\t\t\t\tAttributeName: prop.property as string,\n\t\t\t\t\t\t\t\tAttributeType: prop.type === \"integer\" || prop.type === \"number\" ? \"N\" : \"S\"\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tgsi.push({\n\t\t\t\t\t\t\t\tIndexName: `${prop.property as string}Index`,\n\t\t\t\t\t\t\t\tKeySchema: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tAttributeName: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\t\t\t\t\t\tKeyType: \"HASH\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tAttributeName: prop.property as string,\n\t\t\t\t\t\t\t\t\t\tKeyType: \"RANGE\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tProjection: {\n\t\t\t\t\t\t\t\t\tProjectionType: \"ALL\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tProvisionedThroughput: {\n\t\t\t\t\t\t\t\t\tReadCapacityUnits: 1,\n\t\t\t\t\t\t\t\t\tWriteCapacityUnits: 1\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (gsi.length > 0) {\n\t\t\t\t\ttableParams.GlobalSecondaryIndexes = gsi;\n\t\t\t\t}\n\n\t\t\t\tawait dbConnection.createTable(tableParams);\n\n\t\t\t\t// Wait for table to exist\n\t\t\t\tawait waitUntilTableExists(\n\t\t\t\t\t{\n\t\t\t\t\t\tclient: dbConnection,\n\t\t\t\t\t\tmaxWaitTime: 60\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tTableName: this._config.tableName\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableCreated\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (BaseError.isErrorCode(err, \"ResourceInUseException\")) {\n\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\tmessage: \"tableExists\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\tmessage: \"tableCreateFailed\",\n\t\t\t\t\t\terror: BaseError.fromError(err),\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableExists\",\n\t\t\t\tdata: {\n\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get an entity.\n\t * @param id The id of the entity to get, or the index value if secondaryIndex is set.\n\t * @param secondaryIndex Get the item using a secondary index.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The object if it can be found or undefined.\n\t */\n\tpublic async get(\n\t\tid: string,\n\t\tsecondaryIndex?: keyof T,\n\t\tconditions?: { property: keyof T; value: unknown }[]\n\t): Promise<T | undefined> {\n\t\tGuards.stringValue(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\n\t\t\tif (Is.empty(secondaryIndex) && Is.empty(conditions)) {\n\t\t\t\tconst getCommand = new GetCommand({\n\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\tKey: {\n\t\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\t\tpartitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\t\t\t[this._primaryKey.property]: id\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst response = await docClient.send(getCommand);\n\n\t\t\t\tif (response.Item) {\n\t\t\t\t\treturn EntityHelper.unPrepareEntity<T>(response.Item as T, [\n\t\t\t\t\t\tDynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst finalConditions: EntityCondition<T> = {\n\t\t\t\tconditions: []\n\t\t\t};\n\n\t\t\tif (Is.stringValue(secondaryIndex)) {\n\t\t\t\tfinalConditions.conditions.push({\n\t\t\t\t\tproperty: secondaryIndex,\n\t\t\t\t\tcomparison: ComparisonOperator.Equals,\n\t\t\t\t\tvalue: id\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\tfor (const c of conditions) {\n\t\t\t\t\tfinalConditions.conditions.push({\n\t\t\t\t\t\tproperty: c.property as string,\n\t\t\t\t\t\tcomparison: ComparisonOperator.Equals,\n\t\t\t\t\t\tvalue: c.value\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst queryResult = await this.internalQuery(\n\t\t\t\tfinalConditions,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\t1,\n\t\t\t\tsecondaryIndex as string,\n\t\t\t\tpartitionKey\n\t\t\t);\n\n\t\t\treturn queryResult.entities[0] as T;\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t},\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"getFailed\",\n\t\t\t\t{\n\t\t\t\t\tid\n\t\t\t\t},\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Set an entity.\n\t * @param entity The entity to set.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The id of the entity.\n\t */\n\tpublic async set(entity: T, conditions?: { property: keyof T; value: unknown }[]): Promise<void> {\n\t\tGuards.object<T>(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(entity), entity);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst prepared = EntityHelper.prepareEntity(\n\t\t\tentity,\n\t\t\tthis._entitySchema,\n\t\t\tpartitionKey\n\t\t\t\t? [{ property: DynamoDbEntityStorageConnector._PARTITION_KEY, value: partitionKey }]\n\t\t\t\t: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tproperty: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\t\t\tvalue: DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t);\n\n\t\tconst id = (prepared as { [id: string]: unknown })[this._primaryKey.property as string];\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\n\t\t\tconst { conditionExpression, attributeNames, attributeValues } =\n\t\t\t\tthis.buildConditionExpression(conditions);\n\n\t\t\tconst putCommand = new PutCommand({\n\t\t\t\tTableName: this._config.tableName,\n\t\t\t\tItem: prepared as { [id: string]: unknown },\n\t\t\t\t// Only set the condition expression if we have conditions to match\n\t\t\t\t// and the primary key exists, otherwise we are creating a new object\n\t\t\t\tConditionExpression: Is.stringValue(conditionExpression)\n\t\t\t\t\t? `(attribute_exists(${this._primaryKey.property as string}) AND ${conditionExpression}) OR attribute_not_exists(${this._primaryKey.property as string})`\n\t\t\t\t\t: undefined,\n\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\tExpressionAttributeValues: attributeValues\n\t\t\t});\n\n\t\t\tawait docClient.send(putCommand);\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, \"ConditionalCheckFailedException\")) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t},\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"setFailed\",\n\t\t\t\t{\n\t\t\t\t\tid\n\t\t\t\t},\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Set multiple entities in a batch.\n\t * @param entities The entities to set.\n\t * @returns Nothing.\n\t */\n\tpublic async setBatch(entities: T[]): Promise<void> {\n\t\tGuards.arrayValue(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(entities), entities);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst preparedEntities = entities.map(entity =>\n\t\t\tEntityHelper.prepareEntity(\n\t\t\t\tentity,\n\t\t\t\tthis._entitySchema,\n\t\t\t\tpartitionKey\n\t\t\t\t\t? [{ property: DynamoDbEntityStorageConnector._PARTITION_KEY, value: partitionKey }]\n\t\t\t\t\t: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproperty: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\t\t\t\tvalue: DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t)\n\t\t);\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\t\t\tconst chunkSize = 25;\n\n\t\t\tfor (let i = 0; i < preparedEntities.length; i += chunkSize) {\n\t\t\t\tconst chunk = preparedEntities.slice(i, i + chunkSize);\n\t\t\t\tawait docClient.send(\n\t\t\t\t\tnew BatchWriteCommand({\n\t\t\t\t\t\tRequestItems: {\n\t\t\t\t\t\t\t[this._config.tableName]: chunk.map(entity => ({\n\t\t\t\t\t\t\t\tPutRequest: {\n\t\t\t\t\t\t\t\t\tItem: entity as { [id: string]: unknown }\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{ tableName: this._config.tableName },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"setBatchFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Empty the entity storage.\n\t * @returns Nothing.\n\t */\n\tpublic async empty(): Promise<void> {\n\t\ttry {\n\t\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\t\tconst partitionKey = ContextIdHelper.combinedContextKey(\n\t\t\t\tcontextIds,\n\t\t\t\tthis._partitionContextIds\n\t\t\t);\n\n\t\t\tconst pKey = partitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\t\tconst docClient = this.createDocClient();\n\t\t\tconst chunkSize = 25;\n\n\t\t\tlet exclusiveStartKey: { [key: string]: NativeAttributeValue } | undefined;\n\n\t\t\tdo {\n\t\t\t\tconst scanResult = await docClient.send(\n\t\t\t\t\tnew ScanCommand({\n\t\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\t\tFilterExpression: \"#partitionId = :partitionId\",\n\t\t\t\t\t\tExpressionAttributeNames: {\n\t\t\t\t\t\t\t\"#partitionId\": DynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpressionAttributeValues: {\n\t\t\t\t\t\t\t\":partitionId\": pKey\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExclusiveStartKey: exclusiveStartKey\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tconst items = scanResult.Items ?? [];\n\n\t\t\t\tfor (let i = 0; i < items.length; i += chunkSize) {\n\t\t\t\t\tconst chunk = items.slice(i, i + chunkSize);\n\t\t\t\t\tawait docClient.send(\n\t\t\t\t\t\tnew BatchWriteCommand({\n\t\t\t\t\t\t\tRequestItems: {\n\t\t\t\t\t\t\t\t[this._config.tableName]: chunk.map(\n\t\t\t\t\t\t\t\t\t(item: { [key: string]: NativeAttributeValue }) => ({\n\t\t\t\t\t\t\t\t\t\tDeleteRequest: {\n\t\t\t\t\t\t\t\t\t\t\tKey: {\n\t\t\t\t\t\t\t\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\t\t\t\t\t\t\t\titem[DynamoDbEntityStorageConnector._PARTITION_KEY],\n\t\t\t\t\t\t\t\t\t\t\t\t[this._primaryKey.property as string]:\n\t\t\t\t\t\t\t\t\t\t\t\t\titem[this._primaryKey.property as string]\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\texclusiveStartKey = scanResult.LastEvaluatedKey;\n\t\t\t} while (exclusiveStartKey);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"emptyFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Remove the entity.\n\t * @param id The id of the entity to remove.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns Nothing.\n\t */\n\tpublic async remove(\n\t\tid: string,\n\t\tconditions?: { property: keyof T; value: unknown }[]\n\t): Promise<void> {\n\t\tGuards.stringValue(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\n\t\t\tconst { conditionExpression, attributeNames, attributeValues } =\n\t\t\t\tthis.buildConditionExpression(conditions);\n\n\t\t\tconst deleteCommand = new DeleteCommand({\n\t\t\t\tTableName: this._config.tableName,\n\t\t\t\tKey: {\n\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\tpartitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\t\t[this._primaryKey.property as string]: id\n\t\t\t\t},\n\t\t\t\tConditionExpression: conditionExpression,\n\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\tExpressionAttributeValues: attributeValues\n\t\t\t});\n\n\t\t\tawait docClient.send(deleteCommand);\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, \"ConditionalCheckFailedException\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t},\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"removeFailed\",\n\t\t\t\t{\n\t\t\t\t\tid\n\t\t\t\t},\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Remove multiple entities by their IDs in a batch.\n\t * @param ids The ids of the entities to remove.\n\t * @returns Nothing.\n\t */\n\tpublic async removeBatch(ids: string[]): Promise<void> {\n\t\tGuards.arrayValue(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(ids), ids);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\t\t\tconst chunkSize = 25;\n\t\t\tconst primaryKeyProperty = this._primaryKey.property as string;\n\n\t\t\tfor (let i = 0; i < ids.length; i += chunkSize) {\n\t\t\t\tconst chunk = ids.slice(i, i + chunkSize);\n\t\t\t\tawait docClient.send(\n\t\t\t\t\tnew BatchWriteCommand({\n\t\t\t\t\t\tRequestItems: {\n\t\t\t\t\t\t\t[this._config.tableName]: chunk.map(id => ({\n\t\t\t\t\t\t\t\tDeleteRequest: {\n\t\t\t\t\t\t\t\t\tKey: {\n\t\t\t\t\t\t\t\t\t\t[primaryKeyProperty]: id,\n\t\t\t\t\t\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\t\t\t\t\t\tpartitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"removeBatchFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Teardown the entity storage by deleting the underlying table.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the teardown process was successful.\n\t */\n\tpublic async teardown(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tawait nodeLogging?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"tableDeleting\",\n\t\t\tdata: { tableName: this._config.tableName }\n\t\t});\n\n\t\ttry {\n\t\t\tconst dbConnection = this.createConnection();\n\n\t\t\tawait dbConnection.deleteTable({ TableName: this._config.tableName });\n\n\t\t\tawait waitUntilTableNotExists(\n\t\t\t\t{ client: dbConnection, maxWaitTime: 60 },\n\t\t\t\t{ TableName: this._config.tableName }\n\t\t\t);\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableDeleted\",\n\t\t\t\tdata: { tableName: this._config.tableName }\n\t\t\t});\n\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"teardownFailed\",\n\t\t\t\terror: BaseError.fromError(err)\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Find all the entities which match the conditions.\n\t * @param conditions The conditions to match for the entities.\n\t * @param sortProperties The optional sort order.\n\t * @param properties The optional properties to return, defaults to all.\n\t * @param cursor The cursor to request the next chunk of entities.\n\t * @param limit The suggested number of entities to return in each chunk, in some scenarios can return a different amount.\n\t * @returns All the entities for the storage matching the conditions,\n\t * and a cursor which can be used to request more entities.\n\t */\n\tpublic async query(\n\t\tconditions?: EntityCondition<T>,\n\t\tsortProperties?: {\n\t\t\tproperty: keyof T;\n\t\t\tsortDirection: SortDirection;\n\t\t}[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{\n\t\t/**\n\t\t * The entities, which can be partial if a limited keys list was provided.\n\t\t */\n\t\tentities: Partial<T>[];\n\t\t/**\n\t\t * An optional cursor, when defined can be used to call find to get more entities.\n\t\t */\n\t\tcursor?: string;\n\t}> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\treturn this.internalQuery(\n\t\t\tconditions,\n\t\t\tsortProperties,\n\t\t\tproperties,\n\t\t\tcursor,\n\t\t\tlimit,\n\t\t\tundefined,\n\t\t\tpartitionKey\n\t\t);\n\t}\n\n\t/**\n\t * Count all the entities which match the conditions.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The total count of entities in the storage.\n\t */\n\tpublic async count(conditions?: EntityCondition<T>): Promise<number> {\n\t\ttry {\n\t\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\t\tconst partitionKey = ContextIdHelper.combinedContextKey(\n\t\t\t\tcontextIds,\n\t\t\t\tthis._partitionContextIds\n\t\t\t);\n\n\t\t\tconst attributeNames: { [id: string]: string } = {\n\t\t\t\t\"#partitionId\": DynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t};\n\t\t\tconst attributeValues: { [id: string]: AttributeValue } = {\n\t\t\t\t\":partitionId\": {\n\t\t\t\t\tS: partitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst expressions = this.buildQueryParameters(\n\t\t\t\t\"\",\n\t\t\t\tconditions,\n\t\t\t\tattributeNames,\n\t\t\t\tattributeValues\n\t\t\t);\n\n\t\t\tconst dbConnection = this.createConnection();\n\t\t\tlet total = 0;\n\t\t\tlet exclusiveStartKey: { [key: string]: AttributeValue } | undefined;\n\n\t\t\tdo {\n\t\t\t\tconst result = await dbConnection.send(\n\t\t\t\t\tnew QueryCommand({\n\t\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\t\tSelect: \"COUNT\",\n\t\t\t\t\t\tKeyConditionExpression: \"#partitionId = :partitionId\",\n\t\t\t\t\t\tFilterExpression: Is.stringValue(expressions.filterCondition)\n\t\t\t\t\t\t\t? expressions.filterCondition\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\t\t\tExpressionAttributeValues: attributeValues,\n\t\t\t\t\t\tExclusiveStartKey: exclusiveStartKey\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\ttotal += result.Count ?? 0;\n\t\t\t\texclusiveStartKey = result.LastEvaluatedKey;\n\t\t\t} while (exclusiveStartKey);\n\n\t\t\treturn total;\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"countFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get a unique list of all the context ids from the storage.\n\t * @returns The list of unique context ids.\n\t */\n\tpublic async getPartitionContextIds(): Promise<IContextIds[]> {\n\t\tif (!Is.arrayValue(this._partitionContextIds)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contextIdsMap: { [id: string]: IContextIds } = {};\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\t\t\tlet exclusiveStartKey: { [key: string]: NativeAttributeValue } | undefined;\n\n\t\t\tdo {\n\t\t\t\tconst scanResult = await docClient.send(\n\t\t\t\t\tnew ScanCommand({\n\t\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\t\tProjectionExpression: \"#partitionId\",\n\t\t\t\t\t\tExpressionAttributeNames: {\n\t\t\t\t\t\t\t\"#partitionId\": DynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExclusiveStartKey: exclusiveStartKey\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tfor (const item of scanResult.Items ?? []) {\n\t\t\t\t\tconst partitionId = item[DynamoDbEntityStorageConnector._PARTITION_KEY] as string;\n\t\t\t\t\tif (Is.stringValue(partitionId) && !(partitionId in contextIdsMap)) {\n\t\t\t\t\t\tcontextIdsMap[partitionId] = ContextIdHelper.shortSplit(\n\t\t\t\t\t\t\tthis._partitionContextIds ?? [],\n\t\t\t\t\t\t\tpartitionId\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\texclusiveStartKey = scanResult.LastEvaluatedKey;\n\t\t\t} while (exclusiveStartKey);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"getPartitionContextIdsFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\n\t\treturn Object.values(contextIdsMap);\n\t}\n\n\t/**\n\t * Create the target connector for performing the migration it will use a temporary storage location.\n\t * @param newEntitySchema The name of the new entity schema to create the connector for.\n\t * @returns Connector for performing the migration.\n\t */\n\tpublic async createTargetConnector<U>(\n\t\tnewEntitySchema: string\n\t): Promise<IEntityStorageConnector<U>> {\n\t\t// We create a new table for the migration with a unique name to avoid conflicts with the existing table\n\t\t// This table will be swapped with the existing table once the migration is finalized.\n\t\tconst migrationTableName = `${this._config.tableName}Migration${Date.now()}`;\n\t\treturn new DynamoDbEntityStorageConnector<U>({\n\t\t\tentitySchema: newEntitySchema,\n\t\t\tconfig: {\n\t\t\t\t...this._config,\n\t\t\t\ttableName: migrationTableName\n\t\t\t},\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t}\n\n\t/**\n\t * Finalize the migration by tearing down the old connector and replacing it with the new one.\n\t * @param targetConnector The target connector to finalize the migration with.\n\t * @param options The options to control how the migration is finalized.\n\t * @param loggingComponentType The logging component type to use for logging during the migration finalization.\n\t * @returns A promise that resolves when the migration is finalized.\n\t */\n\tpublic async finalizeMigration<U>(\n\t\ttargetConnector: DynamoDbEntityStorageConnector<U>,\n\t\toptions?: IMigrationOptions<T, U>,\n\t\tloggingComponentType?: string\n\t): Promise<DynamoDbEntityStorageConnector<U>> {\n\t\t// There is no rename operation in DynamoDB so we have to create a new table with the original name and copy the data over\n\n\t\t// Teardown the existing table with the original name to free up the name for the new table\n\t\tawait this.teardown(loggingComponentType);\n\n\t\t// Create a new connector with the original table name but with the new schema\n\t\t// and copy the data from the migration table to the new table using batch operations\n\t\tconst finalConnector = new DynamoDbEntityStorageConnector<U>({\n\t\t\tentitySchema: targetConnector._entitySchemaName,\n\t\t\tconfig: this._config,\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\n\t\tif (await finalConnector.bootstrap(loggingComponentType)) {\n\t\t\t// Since there is no rename, we need to copy the data from the migration table to the new table\n\t\t\tconst partitions = await targetConnector.getPartitionContextIds();\n\t\t\tconst batchSize = options?.batchSize ?? DynamoDbEntityStorageConnector._DEFAULT_LIMIT;\n\t\t\tawait this.bulkCopy(targetConnector, finalConnector, partitions, batchSize);\n\n\t\t\tawait targetConnector.teardown(loggingComponentType);\n\n\t\t\treturn finalConnector;\n\t\t}\n\n\t\tthrow new GeneralError(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\"finalizeMigrationFailedBootstrap\",\n\t\t\tundefined\n\t\t);\n\t}\n\n\t/**\n\t * Cleanup the migration if a migration fails or needs to be aborted.\n\t * @param targetConnector The target connector to cleanup the migration with.\n\t * @param options The options to control how the migration is cleaned up.\n\t * @param loggingComponentType The optional component type to use for logging the migration progress.\n\t * @returns A promise that resolves when the migration is cleaned up.\n\t */\n\tpublic async cleanupMigration<U>(\n\t\ttargetConnector: IEntityStorageConnector<U> | undefined,\n\t\toptions?: IMigrationOptions<T, U>,\n\t\tloggingComponentType?: string\n\t): Promise<void> {\n\t\t// If something failed the only thing to cleanup is the migration table\n\t\tawait targetConnector?.teardown?.(loggingComponentType);\n\t}\n\n\t/**\n\t * Copy all entities from sourceConnector to destConnector, paging through each partition.\n\t * @param sourceConnector The connector to read entities from.\n\t * @param destConnector The connector to write entities to.\n\t * @param partitions The partition list returned by getPartitionContextIds.\n\t * @param batchSize The number of entities to read per page.\n\t * @internal\n\t */\n\tprivate async bulkCopy<U>(\n\t\tsourceConnector: DynamoDbEntityStorageConnector<U>,\n\t\tdestConnector: DynamoDbEntityStorageConnector<U>,\n\t\tpartitions: IContextIds[],\n\t\tbatchSize: number\n\t): Promise<void> {\n\t\tlet partitionList: IContextIds[];\n\t\tif (Is.arrayValue(partitions)) {\n\t\t\tpartitionList = partitions;\n\t\t} else if (Is.arrayValue(sourceConnector._partitionContextIds)) {\n\t\t\tpartitionList = [];\n\t\t} else {\n\t\t\tpartitionList = [{}];\n\t\t}\n\n\t\tconst dbConnection = sourceConnector.createConnection();\n\t\tconst chunkSize = 25;\n\n\t\tfor (let i = 0; i < partitionList.length; i++) {\n\t\t\tconst partitionKey =\n\t\t\t\tContextIdHelper.combinedContextKey(\n\t\t\t\t\tpartitionList[i],\n\t\t\t\t\tsourceConnector._partitionContextIds\n\t\t\t\t) ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\t\tlet exclusiveStartKey: { [key: string]: AttributeValue } | undefined;\n\t\t\tdo {\n\t\t\t\tconst { Items: items, LastEvaluatedKey: lastKey } = await dbConnection.send(\n\t\t\t\t\tnew QueryCommand({\n\t\t\t\t\t\tTableName: sourceConnector._config.tableName,\n\t\t\t\t\t\tKeyConditionExpression: `#${DynamoDbEntityStorageConnector._PARTITION_KEY} = :${DynamoDbEntityStorageConnector._PARTITION_KEY}`,\n\t\t\t\t\t\tExpressionAttributeNames: {\n\t\t\t\t\t\t\t[`#${DynamoDbEntityStorageConnector._PARTITION_KEY}`]:\n\t\t\t\t\t\t\t\tDynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpressionAttributeValues: {\n\t\t\t\t\t\t\t[`:${DynamoDbEntityStorageConnector._PARTITION_KEY}`]: { S: partitionKey }\n\t\t\t\t\t\t},\n\t\t\t\t\t\tLimit: batchSize,\n\t\t\t\t\t\tExclusiveStartKey: exclusiveStartKey\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\texclusiveStartKey = lastKey;\n\n\t\t\t\tif (Is.arrayValue(items)) {\n\t\t\t\t\tfor (let j = 0; j < items.length; j += chunkSize) {\n\t\t\t\t\t\tconst chunk = items.slice(j, j + chunkSize) as { [key: string]: AttributeValue }[];\n\t\t\t\t\t\tawait dbConnection.send(\n\t\t\t\t\t\t\tnew BatchWriteItemCommand({\n\t\t\t\t\t\t\t\tRequestItems: {\n\t\t\t\t\t\t\t\t\t[destConnector._config.tableName]: chunk.map(item => ({\n\t\t\t\t\t\t\t\t\t\tPutRequest: { Item: item }\n\t\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} while (exclusiveStartKey);\n\t\t}\n\t}\n\n\t/**\n\t * Create the parameters for a query.\n\t * @param objectPath The path for the nested object.\n\t * @param condition The conditions to create the query from.\n\t * @param attributeNames The attribute names to use in the query.\n\t * @param attributeValues The attribute values to use in the query.\n\t * @returns The condition clause.\n\t * @internal\n\t */\n\tprivate buildQueryParameters(\n\t\tobjectPath: string,\n\t\tcondition: EntityCondition<T> | undefined,\n\t\tattributeNames: { [id: string]: string },\n\t\tattributeValues: { [id: string]: AttributeValue },\n\t\tsecondaryIndex?: string\n\t): {\n\t\tkeyCondition: string;\n\t\tfilterCondition: string;\n\t\trequiresScan: boolean;\n\t} {\n\t\t// If no conditions are defined then return empty string\n\t\tif (Is.undefined(condition)) {\n\t\t\treturn {\n\t\t\t\tkeyCondition: \"\",\n\t\t\t\tfilterCondition: \"\",\n\t\t\t\trequiresScan: false\n\t\t\t};\n\t\t}\n\n\t\tif (\"conditions\" in condition) {\n\t\t\tif (condition.conditions.length === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tkeyCondition: \"\",\n\t\t\t\t\tfilterCondition: \"\",\n\t\t\t\t\trequiresScan: false\n\t\t\t\t};\n\t\t\t}\n\t\t\t// It's a group of comparisons, so check the individual items and combine with the logical operator\n\t\t\tconst joinConditions: {\n\t\t\t\tkeyCondition: string;\n\t\t\t\tfilterCondition: string;\n\t\t\t\trequiresScan: boolean;\n\t\t\t}[] = condition.conditions.map(c =>\n\t\t\t\tthis.buildQueryParameters(objectPath, c, attributeNames, attributeValues, secondaryIndex)\n\t\t\t);\n\n\t\t\tconst logicalOperator = this.mapConditionalOperator(condition.logicalOperator);\n\n\t\t\t// DynamoDB does not support OR in KeyConditionExpression, so when the operator\n\t\t\t// is OR we must move all conditions (including key conditions) into FilterExpression.\n\t\t\tif (condition.logicalOperator === LogicalOperator.Or) {\n\t\t\t\tconst parts = joinConditions\n\t\t\t\t\t.map(j => {\n\t\t\t\t\t\tconst subParts = [j.keyCondition.trim(), j.filterCondition.trim()].filter(\n\t\t\t\t\t\t\ts => s.length > 0\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (subParts.length === 0) {\n\t\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subParts.length === 1) {\n\t\t\t\t\t\t\treturn subParts[0];\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn `(${subParts.join(\" AND \")})`;\n\t\t\t\t\t})\n\t\t\t\t\t.filter(s => s.length > 0);\n\t\t\t\tconst hasKeyConditions = joinConditions.some(j => j.keyCondition.length > 0);\n\t\t\t\tconst filterCondition = parts.join(\" OR \");\n\t\t\t\treturn {\n\t\t\t\t\tkeyCondition: \"\",\n\t\t\t\t\tfilterCondition: Is.stringValue(filterCondition) ? ` (${filterCondition}) ` : \"\",\n\t\t\t\t\trequiresScan: hasKeyConditions\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst keyCondition = joinConditions\n\t\t\t\t.filter(j => j.keyCondition.length > 0)\n\t\t\t\t.map(j => j.keyCondition)\n\t\t\t\t.join(` ${logicalOperator} `);\n\t\t\tconst filterCondition = joinConditions\n\t\t\t\t.filter(j => j.filterCondition.length > 0)\n\t\t\t\t.map(j => j.filterCondition)\n\t\t\t\t.join(` ${logicalOperator} `);\n\n\t\t\treturn {\n\t\t\t\tkeyCondition: Is.stringValue(keyCondition) ? ` (${keyCondition}) ` : \"\",\n\t\t\t\tfilterCondition: Is.stringValue(filterCondition) ? ` (${filterCondition}) ` : \"\",\n\t\t\t\trequiresScan: joinConditions.some(j => j.requiresScan)\n\t\t\t};\n\t\t}\n\n\t\tconst schemaProp = this._entitySchema.properties?.find(p => p.property === condition.property);\n\n\t\t// It's a single value so just create the property comparison for the condition\n\t\tconst comparison = this.mapComparisonOperator(\n\t\t\tobjectPath,\n\t\t\tcondition,\n\t\t\tschemaProp?.type,\n\t\t\tattributeNames,\n\t\t\tattributeValues\n\t\t);\n\n\t\tconst isKey =\n\t\t\tschemaProp?.isPrimary ?? (schemaProp?.isSecondary && schemaProp?.property === secondaryIndex);\n\t\treturn {\n\t\t\tkeyCondition: isKey ? comparison : \"\",\n\t\t\tfilterCondition: !isKey ? comparison : \"\",\n\t\t\trequiresScan: false\n\t\t};\n\t}\n\n\t/**\n\t * Map the framework comparison operators to those in DynamoDB.\n\t * @param objectPath The prefix to use for the condition.\n\t * @param comparator The operator to map.\n\t * @param type The type of the property.\n\t * @param attributeNames The attribute names to use in the query.\n\t * @param attributeValues The attribute values to use in the query.\n\t * @returns The comparison expression.\n\t * @throws GeneralError if the comparison operator is not supported.\n\t * @internal\n\t */\n\tprivate mapComparisonOperator(\n\t\tobjectPath: string,\n\t\tcomparator: IComparator,\n\t\ttype: EntitySchemaPropertyType | undefined,\n\t\tattributeNames: { [id: string]: string },\n\t\tattributeValues: { [id: string]: AttributeValue }\n\t): string {\n\t\tlet prop = objectPath;\n\t\tif (prop.length > 0) {\n\t\t\tprop += \".\";\n\t\t}\n\t\tprop += comparator.property;\n\n\t\tlet attributeName = this.populateAttributeNames(prop, attributeNames);\n\n\t\tif (Is.empty(comparator.value)) {\n\t\t\t// prepareEntity converts undefined → null before storing, so DynamoDB holds the\n\t\t\t// attribute with type NULL rather than omitting it. Use attribute_type to match.\n\t\t\tconst nullTypePropName = `:${attributeName.replace(/\\./g, \"\").replace(/#/g, \"\")}Null`;\n\t\t\tattributeValues[nullTypePropName] = { S: \"NULL\" };\n\t\t\tif (comparator.comparison === ComparisonOperator.Equals) {\n\t\t\t\treturn `attribute_type(${attributeName}, ${nullTypePropName})`;\n\t\t\t} else if (comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\treturn `NOT attribute_type(${attributeName}, ${nullTypePropName})`;\n\t\t\t}\n\t\t}\n\n\t\tconst basePropName = `:${attributeName.replace(/\\./g, \"\").replace(/#/g, \"\")}`;\n\t\tlet propName = basePropName;\n\t\tlet propSuffix = 0;\n\t\twhile (!Is.undefined(attributeValues[propName])) {\n\t\t\tpropSuffix++;\n\t\t\tpropName = `${basePropName}${propSuffix}`;\n\t\t}\n\n\t\tif (Is.array(comparator.value)) {\n\t\t\tconst dbValues = comparator.value.map(v => this.propertyToDbValue(v, type));\n\t\t\tconst arrAttributeNames = [];\n\t\t\tfor (let i = 0; i < dbValues.length; i++) {\n\t\t\t\tconst arrAttributeName = `${propName}${i}`;\n\t\t\t\tattributeValues[arrAttributeName] = dbValues[i];\n\t\t\t\tarrAttributeNames.push(arrAttributeName);\n\t\t\t}\n\t\t\tpropName = attributeName;\n\t\t\tattributeName = `(${arrAttributeNames.join(\", \")})`;\n\t\t} else {\n\t\t\tattributeValues[propName] = this.propertyToDbValue(comparator.value, type);\n\t\t}\n\n\t\tif (comparator.comparison === ComparisonOperator.Equals) {\n\t\t\treturn `${attributeName} = ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\treturn `${attributeName} <> ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.GreaterThan) {\n\t\t\treturn `${attributeName} > ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.LessThan) {\n\t\t\treturn `${attributeName} < ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.GreaterThanOrEqual) {\n\t\t\treturn `${attributeName} >= ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.LessThanOrEqual) {\n\t\t\treturn `${attributeName} <= ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.Includes) {\n\t\t\treturn `contains(${attributeName}, ${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.NotIncludes) {\n\t\t\treturn `NOT contains(${attributeName}, ${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.In) {\n\t\t\treturn `${propName} IN ${attributeName}`;\n\t\t}\n\n\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"comparisonNotSupported\", {\n\t\t\tcomparison: comparator.comparison\n\t\t});\n\t}\n\n\t/**\n\t * Create a unique name for the attribute.\n\t * @param name The name to create a unique name for.\n\t * @param attributeNames The attribute names to use in the query.\n\t * @returns The unique name.\n\t * @internal\n\t */\n\tprivate populateAttributeNames(name: string, attributeNames: { [id: string]: string }): string {\n\t\tconst parts = name.split(\".\");\n\t\tconst attributeNameParts: string[] = [];\n\n\t\tfor (const part of parts) {\n\t\t\tconst hashPart = `#${part}`;\n\t\t\tif (Is.empty(attributeNames[hashPart])) {\n\t\t\t\tattributeNames[hashPart] = part;\n\t\t\t}\n\t\t\tattributeNameParts.push(hashPart);\n\t\t}\n\n\t\treturn attributeNameParts.join(\".\");\n\t}\n\n\t/**\n\t * Map the framework conditional operators to those in DynamoDB.\n\t * @param operator The operator to map.\n\t * @returns The conditional operator.\n\t * @throws GeneralError if the conditional operator is not supported.\n\t * @internal\n\t */\n\tprivate mapConditionalOperator(operator?: LogicalOperator): string {\n\t\tif ((operator ?? LogicalOperator.And) === LogicalOperator.And) {\n\t\t\treturn \"AND\";\n\t\t} else if (operator === LogicalOperator.Or) {\n\t\t\treturn \"OR\";\n\t\t}\n\n\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"conditionalNotSupported\", {\n\t\t\toperator\n\t\t});\n\t}\n\n\t/**\n\t * Format a value to insert into DB.\n\t * @param value The value to format.\n\t * @param type The type for the property.\n\t * @returns The value after conversion.\n\t * @internal\n\t */\n\tprivate propertyToDbValue(value: unknown, type?: EntitySchemaPropertyType): AttributeValue {\n\t\tif (Is.object(value)) {\n\t\t\tconst map: { [id: string]: AttributeValue } = {};\n\t\t\tfor (const key in value) {\n\t\t\t\tmap[key] = this.propertyToDbValue(value[key]);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tM: map\n\t\t\t};\n\t\t}\n\n\t\tif (type === \"integer\" || type === \"number\") {\n\t\t\treturn { N: Coerce.string(value) ?? \"\" };\n\t\t} else if (type === \"boolean\") {\n\t\t\treturn { BOOL: Coerce.boolean(value) ?? false };\n\t\t}\n\n\t\treturn { S: Coerce.string(value) ?? \"\" };\n\t}\n\n\t/**\n\t * Create a doc client connection.\n\t * @returns The dynamo db document client.\n\t * @internal\n\t */\n\tprivate createDocClient(): DynamoDBDocumentClient {\n\t\treturn DynamoDBDocumentClient.from(\n\t\t\tnew DynamoDB({\n\t\t\t\tapiVersion: \"2012-10-08\",\n\t\t\t\t...this.createConnectionConfig()\n\t\t\t}),\n\t\t\t{\n\t\t\t\tmarshallOptions: {\n\t\t\t\t\tremoveUndefinedValues: true\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n\t/**\n\t * Create a new DB connection.\n\t * @returns The Dynamo DB connection.\n\t * @internal\n\t */\n\tprivate createConnection(): DynamoDB {\n\t\treturn new DynamoDB(this.createConnectionConfig());\n\t}\n\n\t/**\n\t * Create a new DB connection configuration.\n\t * @returns The Dynamo DB connection configuration.\n\t * @internal\n\t */\n\tprivate createConnectionConfig(): DynamoDBClientConfig {\n\t\tconst requestHandler = Is.number(this._config.connectionTimeoutMs)\n\t\t\t? { requestTimeout: this._config.connectionTimeoutMs }\n\t\t\t: undefined;\n\n\t\tif (\n\t\t\tIs.stringValue(this._config.secretAccessKey) &&\n\t\t\tIs.stringValue(this._config.accessKeyId) &&\n\t\t\tthis._config.authMode === \"credentials\"\n\t\t) {\n\t\t\treturn {\n\t\t\t\tcredentials: {\n\t\t\t\t\taccessKeyId: this._config.accessKeyId,\n\t\t\t\t\tsecretAccessKey: this._config.secretAccessKey\n\t\t\t\t},\n\t\t\t\tendpoint: this._config.endpoint,\n\t\t\t\tregion: this._config.region,\n\t\t\t\trequestHandler,\n\t\t\t\tmaxAttempts: this._config.maxAttempts\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tendpoint: this._config.endpoint,\n\t\t\tregion: this._config.region,\n\t\t\trequestHandler,\n\t\t\tmaxAttempts: this._config.maxAttempts\n\t\t};\n\t}\n\n\t/**\n\t * Check if the table exists.\n\t * @param tableName The table to check.\n\t * @returns True if the table exists.\n\t * @internal\n\t */\n\tprivate async tableExists(tableName: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst dbConnection = this.createConnection();\n\n\t\t\tconst result = await dbConnection.describeTable({ TableName: tableName });\n\n\t\t\t// A table in DELETING state should not be treated as existing\n\t\t\treturn result.Table?.TableStatus !== \"DELETING\";\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Find all the entities which match the conditions.\n\t * @param conditions The conditions to match for the entities.\n\t * @param sortProperties The optional sort order.\n\t * @param properties The optional properties to return, defaults to all.\n\t * @param cursor The cursor to request the next chunk of entities.\n\t * @param limit The suggested number of entities to return in each chunk, in some scenarios can return a different amount.\n\t * @param secondaryIndex The secondary index to use for the query.\n\t * @param partitionKey The partition key to use for the query.\n\t * @returns All the entities for the storage matching the conditions,\n\t * and a cursor which can be used to request more entities.\n\t * @internal\n\t */\n\tprivate async internalQuery(\n\t\tconditions?: EntityCondition<T>,\n\t\tsortProperties?: {\n\t\t\tproperty: keyof T;\n\t\t\tsortDirection: SortDirection;\n\t\t}[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number,\n\t\tsecondaryIndex?: string,\n\t\tpartitionKey?: string\n\t): Promise<{\n\t\t/**\n\t\t * The entities, which can be partial if a limited keys list was provided.\n\t\t */\n\t\tentities: Partial<T>[];\n\t\t/**\n\t\t * An optional cursor, when defined can be used to call find to get more entities.\n\t\t */\n\t\tcursor?: string;\n\t}> {\n\t\ttry {\n\t\t\tconst returnSize = limit ?? DynamoDbEntityStorageConnector._DEFAULT_LIMIT;\n\n\t\t\tlet indexName: string | undefined = Is.stringValue(secondaryIndex)\n\t\t\t\t? `${secondaryIndex}Index`\n\t\t\t\t: undefined;\n\n\t\t\t// If we have a sortable property defined in the descriptor then we must use\n\t\t\t// the secondary index for the query\n\t\t\tlet scanAscending = true;\n\t\t\tif (Is.arrayValue(sortProperties)) {\n\t\t\t\tif (sortProperties.length > 1) {\n\t\t\t\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"sortSingle\");\n\t\t\t\t}\n\n\t\t\t\tfor (const sortProperty of sortProperties) {\n\t\t\t\t\tconst propertySchema = this._entitySchema.properties?.find(\n\t\t\t\t\t\te => e.property === sortProperty.property\n\t\t\t\t\t);\n\t\t\t\t\tif (\n\t\t\t\t\t\tIs.undefined(propertySchema) ||\n\t\t\t\t\t\t(!propertySchema.isPrimary &&\n\t\t\t\t\t\t\t!propertySchema.isSecondary &&\n\t\t\t\t\t\t\tIs.empty(propertySchema.sortDirection))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"sortNotIndexed\", {\n\t\t\t\t\t\t\tproperty: sortProperty.property\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tindexName = propertySchema.isPrimary\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: `${sortProperty.property as string}Index`;\n\t\t\t\t\tscanAscending = sortProperty.sortDirection === SortDirection.Ascending;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst attributeNames: { [id: string]: string } = { \"#partitionId\": \"partitionId\" };\n\t\t\tconst attributeValues: { [id: string]: AttributeValue } = {\n\t\t\t\t[`:${DynamoDbEntityStorageConnector._PARTITION_KEY}`]: {\n\t\t\t\t\tS: partitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst expressions = this.buildQueryParameters(\n\t\t\t\t\"\",\n\t\t\t\tconditions,\n\t\t\t\tattributeNames,\n\t\t\t\tattributeValues,\n\t\t\t\tsecondaryIndex\n\t\t\t);\n\n\t\t\t// OR conditions on primary key attributes can't use KeyConditionExpression or\n\t\t\t// FilterExpression in a QueryCommand — fall back to a full table ScanCommand.\n\t\t\tif (expressions.requiresScan) {\n\t\t\t\tlet scanFilter = \"#partitionId = :partitionId\";\n\t\t\t\tif (Is.stringValue(expressions.filterCondition)) {\n\t\t\t\t\tscanFilter += ` AND ${expressions.filterCondition.trim()}`;\n\t\t\t\t}\n\n\t\t\t\tconst dbConnection = this.createConnection();\n\t\t\t\tconst matchingItems: { [id: string]: AttributeValue }[] = [];\n\t\t\t\tlet scanStartKey: { [id: string]: AttributeValue } | undefined = Is.empty(cursor)\n\t\t\t\t\t? undefined\n\t\t\t\t\t: ObjectHelper.fromBytes(Converter.base64ToBytes(cursor));\n\n\t\t\t\tdo {\n\t\t\t\t\tconst scanResult = await dbConnection.send(\n\t\t\t\t\t\tnew RawScanCommand({\n\t\t\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\t\t\tFilterExpression: scanFilter,\n\t\t\t\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\t\t\t\tExpressionAttributeValues: attributeValues,\n\t\t\t\t\t\t\tProjectionExpression: properties?.map(p => p as string).join(\", \"),\n\t\t\t\t\t\t\tExclusiveStartKey: scanStartKey\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tmatchingItems.push(...(scanResult.Items ?? []));\n\t\t\t\t\tscanStartKey = scanResult.LastEvaluatedKey;\n\t\t\t\t} while (!Is.empty(scanStartKey));\n\n\t\t\t\tconst hasMore = matchingItems.length > returnSize;\n\t\t\t\tconst returnedRawItems = hasMore ? matchingItems.slice(0, returnSize) : matchingItems;\n\n\t\t\t\tlet resultCursor: string | undefined;\n\t\t\t\tif (hasMore) {\n\t\t\t\t\tconst lastRawItem = returnedRawItems[returnedRawItems.length - 1];\n\t\t\t\t\tconst syntheticKey: { [id: string]: AttributeValue } = {\n\t\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\t\tlastRawItem[DynamoDbEntityStorageConnector._PARTITION_KEY],\n\t\t\t\t\t\t[this._primaryKey.property as string]: lastRawItem[this._primaryKey.property as string]\n\t\t\t\t\t};\n\t\t\t\t\tresultCursor = Converter.bytesToBase64(ObjectHelper.toBytes(syntheticKey));\n\t\t\t\t}\n\n\t\t\t\tconst scanEntities: T[] = returnedRawItems.map(item => {\n\t\t\t\t\tconst unmarshalled = unmarshall(item);\n\t\t\t\t\treturn EntityHelper.unPrepareEntity(unmarshalled as T, [\n\t\t\t\t\t\tDynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t]);\n\t\t\t\t});\n\n\t\t\t\treturn { entities: scanEntities, cursor: resultCursor };\n\t\t\t}\n\n\t\t\tlet keyExpression = \"#partitionId = :partitionId\";\n\t\t\tif (expressions.keyCondition.length > 0) {\n\t\t\t\tkeyExpression += ` AND ${expressions.keyCondition}`;\n\t\t\t}\n\n\t\t\tconst query = new QueryCommand({\n\t\t\t\tTableName: this._config.tableName,\n\t\t\t\tIndexName: indexName,\n\t\t\t\tKeyConditionExpression: keyExpression,\n\t\t\t\tFilterExpression: Is.stringValue(expressions.filterCondition)\n\t\t\t\t\t? expressions.filterCondition\n\t\t\t\t\t: undefined,\n\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\tExpressionAttributeValues: attributeValues,\n\t\t\t\tProjectionExpression: properties?.map(p => p as string).join(\", \"),\n\t\t\t\tLimit: returnSize + 1,\n\t\t\t\tScanIndexForward: scanAscending,\n\t\t\t\tExclusiveStartKey: Is.empty(cursor)\n\t\t\t\t\t? undefined\n\t\t\t\t\t: ObjectHelper.fromBytes(Converter.base64ToBytes(cursor))\n\t\t\t});\n\n\t\t\tconst connection = this.createDocClient();\n\n\t\t\tconst results = await connection.send(query);\n\n\t\t\tconst rawItems = results.Items ?? [];\n\t\t\tconst hasMore = rawItems.length > returnSize;\n\t\t\tconst returnedRawItems = hasMore ? rawItems.slice(0, returnSize) : rawItems;\n\n\t\t\tlet resultCursor: string | undefined;\n\t\t\tif (hasMore) {\n\t\t\t\tconst lastRawItem = returnedRawItems[returnedRawItems.length - 1] as {\n\t\t\t\t\t[id: string]: AttributeValue;\n\t\t\t\t};\n\t\t\t\tconst syntheticKey: { [id: string]: AttributeValue } = {\n\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\tlastRawItem[DynamoDbEntityStorageConnector._PARTITION_KEY],\n\t\t\t\t\t[this._primaryKey.property as string]: lastRawItem[this._primaryKey.property as string]\n\t\t\t\t};\n\t\t\t\tif (Is.stringValue(secondaryIndex)) {\n\t\t\t\t\tsyntheticKey[secondaryIndex] = lastRawItem[secondaryIndex];\n\t\t\t\t}\n\t\t\t\tresultCursor = Converter.bytesToBase64(ObjectHelper.toBytes(syntheticKey));\n\t\t\t}\n\n\t\t\tconst entities: T[] = returnedRawItems.map(item => {\n\t\t\t\tconst unmarshalled = unmarshall(item);\n\t\t\t\treturn EntityHelper.unPrepareEntity(unmarshalled as T, [\n\t\t\t\t\tDynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t]);\n\t\t\t});\n\n\t\t\treturn { entities, cursor: resultCursor };\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t},\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"queryFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Build the condition expression for the query.\n\t * @param conditions The conditions to build the expression from.\n\t * @returns The condition expression.\n\t * @throws GeneralError if the property is not found in the schema.\n\t * @internal\n\t */\n\tprivate buildConditionExpression(conditions?: { property: keyof T; value: unknown }[]): {\n\t\tconditionExpression: string | undefined;\n\t\tattributeNames: { [id: string]: string } | undefined;\n\t\tattributeValues: { [key: string]: NativeAttributeValue } | undefined;\n\t} {\n\t\tlet conditionExpression: string | undefined;\n\t\tlet attributeNames: { [id: string]: string } | undefined;\n\t\tlet attributeValues: { [key: string]: NativeAttributeValue } | undefined;\n\n\t\tif (Is.arrayValue(conditions)) {\n\t\t\tconst expressions: string[] = [];\n\n\t\t\tfor (const c of conditions) {\n\t\t\t\tconst schemaProp = this._entitySchema.properties?.find(p => p.property === c.property);\n\n\t\t\t\tif (Is.undefined(schemaProp)) {\n\t\t\t\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"propertyNotFound\", {\n\t\t\t\t\t\tproperty: c.property\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst attributeName = `#${c.property as string}`;\n\t\t\t\tconst attributeValueName = `:${c.property as string}`;\n\t\t\t\tattributeNames ??= {};\n\t\t\t\tattributeValues ??= {};\n\t\t\t\tattributeNames[attributeName] = c.property as string;\n\t\t\t\tattributeValues[attributeValueName] = c.value;\n\t\t\t\texpressions.push(`${attributeName} = ${attributeValueName}`);\n\t\t\t}\n\n\t\t\tconditionExpression = expressions.join(\" AND \");\n\t\t}\n\t\treturn { conditionExpression, attributeNames, attributeValues };\n\t}\n}\n"]}
1
+ {"version":3,"file":"dynamoDbEntityStorageConnector.js","sourceRoot":"","sources":["../../src/dynamoDbEntityStorageConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\ttype AttributeValue,\n\tBatchWriteItemCommand,\n\ttype CreateTableCommandInput,\n\tDynamoDB,\n\ttype DynamoDBClientConfig,\n\ttype GlobalSecondaryIndex,\n\tQueryCommand,\n\tScanCommand as RawScanCommand,\n\twaitUntilTableExists,\n\twaitUntilTableNotExists\n} from \"@aws-sdk/client-dynamodb\";\nimport {\n\tBatchWriteCommand,\n\tDeleteCommand,\n\tDynamoDBDocumentClient,\n\tGetCommand,\n\tPutCommand,\n\tScanCommand\n} from \"@aws-sdk/lib-dynamodb\";\nimport { type NativeAttributeValue, unmarshall } from \"@aws-sdk/util-dynamodb\";\nimport { ContextIdHelper, ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tCoerce,\n\tComponentFactory,\n\tConverter,\n\tGeneralError,\n\tGuards,\n\tHealthStatus,\n\ttype IHealth,\n\tIs,\n\tObjectHelper\n} from \"@twin.org/core\";\nimport {\n\tComparisonOperator,\n\ttype EntityCondition,\n\tEntitySchemaFactory,\n\tEntitySchemaHelper,\n\ttype EntitySchemaPropertyType,\n\ttype IComparator,\n\ttype IEntitySchema,\n\ttype IEntitySchemaProperty,\n\tLogicalOperator,\n\tSortDirection\n} from \"@twin.org/entity\";\nimport {\n\tEntityStorageHelper,\n\ttype IEntityStorageConnector,\n\ttype IEntityStorageMigrationConnector,\n\ttype IMigrationOptions\n} from \"@twin.org/entity-storage-models\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { IDynamoDbEntityStorageConnectorConfig } from \"./models/IDynamoDbEntityStorageConnectorConfig.js\";\nimport type { IDynamoDbEntityStorageConnectorConstructorOptions } from \"./models/IDynamoDbEntityStorageConnectorConstructorOptions.js\";\n\n/**\n * Class for performing entity storage operations using Dynamo DB.\n */\nexport class DynamoDbEntityStorageConnector<\n\tT = unknown\n> implements IEntityStorageMigrationConnector<T> {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<DynamoDbEntityStorageConnector>();\n\n\t/**\n\t * Limit the number of entities when finding.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_LIMIT: number = 40;\n\n\t/**\n\t * Partition id field name.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY: string = \"partitionId\";\n\n\t/**\n\t * Partition id field value.\n\t * @internal\n\t */\n\tprivate static readonly _PARTITION_KEY_VALUE: string = \"root\";\n\n\t/**\n\t * The name for the schema.\n\t * @internal\n\t */\n\tprivate readonly _entitySchemaName: string;\n\n\t/**\n\t * The schema for the entity.\n\t * @internal\n\t */\n\tprivate readonly _entitySchema: IEntitySchema<T>;\n\n\t/**\n\t * The keys to use from the context ids to create partitions.\n\t * @internal\n\t */\n\tprivate readonly _partitionContextIds?: string[];\n\n\t/**\n\t * The primary key.\n\t * @internal\n\t */\n\tprivate readonly _primaryKey: IEntitySchemaProperty<T>;\n\n\t/**\n\t * The configuration for the connector.\n\t * @internal\n\t */\n\tprivate readonly _config: IDynamoDbEntityStorageConnectorConfig;\n\n\t/**\n\t * Create a new instance of DynamoDbEntityStorageConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: IDynamoDbEntityStorageConnectorConstructorOptions) {\n\t\tGuards.object(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(options), options);\n\t\tGuards.stringValue(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.entitySchema),\n\t\t\toptions.entitySchema\n\t\t);\n\t\tGuards.object<IDynamoDbEntityStorageConnectorConfig>(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\n\t\toptions.config.authMode ??= \"credentials\";\n\n\t\tif (options.config.authMode === \"credentials\") {\n\t\t\tGuards.stringValue(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.accessKeyId),\n\t\t\t\toptions.config.accessKeyId\n\t\t\t);\n\t\t\tGuards.stringValue(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tnameof(options.config.secretAccessKey),\n\t\t\t\toptions.config.secretAccessKey\n\t\t\t);\n\t\t}\n\t\tGuards.stringValue(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.region),\n\t\t\toptions.config.region\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.tableName),\n\t\t\toptions.config.tableName\n\t\t);\n\n\t\tthis._partitionContextIds = options.partitionContextIds;\n\n\t\tthis._entitySchemaName = options.entitySchema;\n\t\tthis._entitySchema = EntitySchemaFactory.get(options.entitySchema);\n\t\tthis._primaryKey = EntitySchemaHelper.getPrimaryKey<T>(this._entitySchema);\n\n\t\tthis._config = options.config;\n\t\tthis._config.endpoint = Is.stringValue(this._config.endpoint)\n\t\t\t? this._config.endpoint\n\t\t\t: undefined;\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn DynamoDbEntityStorageConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Returns the health status of the component.\n\t * @returns The health status of the component.\n\t */\n\tpublic async health(): Promise<IHealth[]> {\n\t\ttry {\n\t\t\tconst dbConnection = this.createConnection();\n\t\t\tawait dbConnection.describeTable({ TableName: this._config.tableName });\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tdata: { tableName: this._config.tableName }\n\t\t\t\t}\n\t\t\t];\n\t\t} catch {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tmessage: \"connectionFailed\",\n\t\t\t\t\tdata: { tableName: this._config.tableName }\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\t}\n\n\t/**\n\t * Get the schema for the entities.\n\t * @returns The schema for the entities.\n\t */\n\tpublic getSchema(): IEntitySchema {\n\t\treturn this._entitySchema as IEntitySchema;\n\t}\n\n\t/**\n\t * Bootstrap the component by creating and initializing any resources it needs.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the bootstrapping process was successful.\n\t */\n\tpublic async bootstrap(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tif (!(await this.tableExists(this._config.tableName))) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableCreating\",\n\t\t\t\tdata: {\n\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t}\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tconst dbConnection = this.createConnection();\n\n\t\t\t\tconst tableParams: CreateTableCommandInput = {\n\t\t\t\t\tAttributeDefinitions: [],\n\t\t\t\t\tKeySchema: [],\n\t\t\t\t\tProvisionedThroughput: {\n\t\t\t\t\t\tReadCapacityUnits: 1,\n\t\t\t\t\t\tWriteCapacityUnits: 1\n\t\t\t\t\t},\n\t\t\t\t\tTableName: this._config.tableName\n\t\t\t\t};\n\n\t\t\t\t// We always add a partition key to the table as a non optional hash key\n\t\t\t\t// is always required when querying using sort parameters\n\t\t\t\ttableParams.AttributeDefinitions?.push({\n\t\t\t\t\tAttributeName: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\tAttributeType: \"S\"\n\t\t\t\t});\n\t\t\t\ttableParams.KeySchema?.push({\n\t\t\t\t\tAttributeName: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\tKeyType: \"HASH\"\n\t\t\t\t});\n\n\t\t\t\tconst gsi: GlobalSecondaryIndex[] = [];\n\n\t\t\t\tif (Is.arrayValue(this._entitySchema.properties)) {\n\t\t\t\t\tfor (const prop of this._entitySchema.properties) {\n\t\t\t\t\t\tif (prop.isPrimary) {\n\t\t\t\t\t\t\ttableParams.AttributeDefinitions?.push({\n\t\t\t\t\t\t\t\tAttributeName: prop.property as string,\n\t\t\t\t\t\t\t\tAttributeType: prop.type === \"integer\" || prop.type === \"number\" ? \"N\" : \"S\"\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ttableParams.KeySchema?.push({\n\t\t\t\t\t\t\t\tAttributeName: prop.property as string,\n\t\t\t\t\t\t\t\tKeyType: \"RANGE\"\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (Is.stringValue(prop.sortDirection) || prop.isSecondary) {\n\t\t\t\t\t\t\t// You can only query and sort items if you have a secondary index\n\t\t\t\t\t\t\t// defined for the property\n\t\t\t\t\t\t\ttableParams.AttributeDefinitions?.push({\n\t\t\t\t\t\t\t\tAttributeName: prop.property as string,\n\t\t\t\t\t\t\t\tAttributeType: prop.type === \"integer\" || prop.type === \"number\" ? \"N\" : \"S\"\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tgsi.push({\n\t\t\t\t\t\t\t\tIndexName: `${prop.property as string}Index`,\n\t\t\t\t\t\t\t\tKeySchema: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tAttributeName: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\t\t\t\t\t\tKeyType: \"HASH\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tAttributeName: prop.property as string,\n\t\t\t\t\t\t\t\t\t\tKeyType: \"RANGE\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tProjection: {\n\t\t\t\t\t\t\t\t\tProjectionType: \"ALL\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tProvisionedThroughput: {\n\t\t\t\t\t\t\t\t\tReadCapacityUnits: 1,\n\t\t\t\t\t\t\t\t\tWriteCapacityUnits: 1\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (gsi.length > 0) {\n\t\t\t\t\ttableParams.GlobalSecondaryIndexes = gsi;\n\t\t\t\t}\n\n\t\t\t\tawait dbConnection.createTable(tableParams);\n\n\t\t\t\t// Wait for table to exist\n\t\t\t\tawait waitUntilTableExists(\n\t\t\t\t\t{\n\t\t\t\t\t\tclient: dbConnection,\n\t\t\t\t\t\tmaxWaitTime: 60\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tTableName: this._config.tableName\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"tableCreated\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (BaseError.isErrorCode(err, \"ResourceInUseException\")) {\n\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\tmessage: \"tableExists\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tts: Date.now(),\n\t\t\t\t\t\tmessage: \"tableCreateFailed\",\n\t\t\t\t\t\terror: BaseError.fromError(err),\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableExists\",\n\t\t\t\tdata: {\n\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get an entity.\n\t * @param id The id of the entity to get, or the index value if secondaryIndex is set.\n\t * @param secondaryIndex Get the item using a secondary index.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The object if it can be found or undefined.\n\t */\n\tpublic async get(\n\t\tid: string,\n\t\tsecondaryIndex?: keyof T,\n\t\tconditions?: { property: keyof T; value: unknown }[]\n\t): Promise<T | undefined> {\n\t\tGuards.stringValue(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\n\t\t\tif (Is.empty(secondaryIndex) && Is.empty(conditions)) {\n\t\t\t\tconst getCommand = new GetCommand({\n\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\tKey: {\n\t\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\t\tpartitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\t\t\t[this._primaryKey.property]: id\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst response = await docClient.send(getCommand);\n\n\t\t\t\tif (response.Item) {\n\t\t\t\t\treturn EntityStorageHelper.unPrepareEntity<T>(response.Item as T, [\n\t\t\t\t\t\tDynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst finalConditions: EntityCondition<T> = {\n\t\t\t\tconditions: []\n\t\t\t};\n\n\t\t\tif (Is.stringValue(secondaryIndex)) {\n\t\t\t\tfinalConditions.conditions.push({\n\t\t\t\t\tproperty: secondaryIndex,\n\t\t\t\t\tcomparison: ComparisonOperator.Equals,\n\t\t\t\t\tvalue: id\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\tfor (const c of conditions) {\n\t\t\t\t\tfinalConditions.conditions.push({\n\t\t\t\t\t\tproperty: c.property as string,\n\t\t\t\t\t\tcomparison: ComparisonOperator.Equals,\n\t\t\t\t\t\tvalue: c.value\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst queryResult = await this.internalQuery(\n\t\t\t\tfinalConditions,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\t1,\n\t\t\t\tsecondaryIndex as string,\n\t\t\t\tpartitionKey\n\t\t\t);\n\n\t\t\treturn queryResult.entities[0] as T;\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t},\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"getFailed\",\n\t\t\t\t{\n\t\t\t\t\tid\n\t\t\t\t},\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Set an entity.\n\t * @param entity The entity to set.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The id of the entity.\n\t */\n\tpublic async set(entity: T, conditions?: { property: keyof T; value: unknown }[]): Promise<void> {\n\t\tGuards.object<T>(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(entity), entity);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst prepared = EntityStorageHelper.prepareEntity(\n\t\t\tentity,\n\t\t\tthis._entitySchema,\n\t\t\tpartitionKey\n\t\t\t\t? [{ property: DynamoDbEntityStorageConnector._PARTITION_KEY, value: partitionKey }]\n\t\t\t\t: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tproperty: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\t\t\tvalue: DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t{ nullBehavior: \"omit\" }\n\t\t);\n\n\t\tconst id = (prepared as { [id: string]: unknown })[this._primaryKey.property as string];\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\n\t\t\tconst { conditionExpression, attributeNames, attributeValues } =\n\t\t\t\tthis.buildConditionExpression(conditions);\n\n\t\t\tconst putCommand = new PutCommand({\n\t\t\t\tTableName: this._config.tableName,\n\t\t\t\tItem: prepared as { [id: string]: unknown },\n\t\t\t\t// Only set the condition expression if we have conditions to match\n\t\t\t\t// and the primary key exists, otherwise we are creating a new object\n\t\t\t\tConditionExpression: Is.stringValue(conditionExpression)\n\t\t\t\t\t? `(attribute_exists(${this._primaryKey.property as string}) AND ${conditionExpression}) OR attribute_not_exists(${this._primaryKey.property as string})`\n\t\t\t\t\t: undefined,\n\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\tExpressionAttributeValues: attributeValues\n\t\t\t});\n\n\t\t\tawait docClient.send(putCommand);\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, \"ConditionalCheckFailedException\")) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t},\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"setFailed\",\n\t\t\t\t{\n\t\t\t\t\tid\n\t\t\t\t},\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Set multiple entities in a batch.\n\t * @param entities The entities to set.\n\t * @returns Nothing.\n\t */\n\tpublic async setBatch(entities: T[]): Promise<void> {\n\t\tGuards.arrayValue(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(entities), entities);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst preparedEntities = entities.map(entity =>\n\t\t\tEntityStorageHelper.prepareEntity(\n\t\t\t\tentity,\n\t\t\t\tthis._entitySchema,\n\t\t\t\tpartitionKey\n\t\t\t\t\t? [{ property: DynamoDbEntityStorageConnector._PARTITION_KEY, value: partitionKey }]\n\t\t\t\t\t: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproperty: DynamoDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\t\t\t\t\tvalue: DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t{ nullBehavior: \"omit\" }\n\t\t\t)\n\t\t);\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\t\t\tconst chunkSize = 25;\n\n\t\t\tfor (let i = 0; i < preparedEntities.length; i += chunkSize) {\n\t\t\t\tconst chunk = preparedEntities.slice(i, i + chunkSize);\n\t\t\t\tawait docClient.send(\n\t\t\t\t\tnew BatchWriteCommand({\n\t\t\t\t\t\tRequestItems: {\n\t\t\t\t\t\t\t[this._config.tableName]: chunk.map(entity => ({\n\t\t\t\t\t\t\t\tPutRequest: {\n\t\t\t\t\t\t\t\t\tItem: entity as { [id: string]: unknown }\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{ tableName: this._config.tableName },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"setBatchFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Empty the entity storage.\n\t * @returns Nothing.\n\t */\n\tpublic async empty(): Promise<void> {\n\t\ttry {\n\t\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\t\tconst partitionKey = ContextIdHelper.combinedContextKey(\n\t\t\t\tcontextIds,\n\t\t\t\tthis._partitionContextIds\n\t\t\t);\n\n\t\t\tconst pKey = partitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\t\tconst docClient = this.createDocClient();\n\t\t\tconst chunkSize = 25;\n\n\t\t\tlet exclusiveStartKey: { [key: string]: NativeAttributeValue } | undefined;\n\n\t\t\tdo {\n\t\t\t\tconst scanResult = await docClient.send(\n\t\t\t\t\tnew ScanCommand({\n\t\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\t\tFilterExpression: \"#partitionId = :partitionId\",\n\t\t\t\t\t\tExpressionAttributeNames: {\n\t\t\t\t\t\t\t\"#partitionId\": DynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpressionAttributeValues: {\n\t\t\t\t\t\t\t\":partitionId\": pKey\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExclusiveStartKey: exclusiveStartKey\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tconst items = scanResult.Items ?? [];\n\n\t\t\t\tfor (let i = 0; i < items.length; i += chunkSize) {\n\t\t\t\t\tconst chunk = items.slice(i, i + chunkSize);\n\t\t\t\t\tawait docClient.send(\n\t\t\t\t\t\tnew BatchWriteCommand({\n\t\t\t\t\t\t\tRequestItems: {\n\t\t\t\t\t\t\t\t[this._config.tableName]: chunk.map(\n\t\t\t\t\t\t\t\t\t(item: { [key: string]: NativeAttributeValue }) => ({\n\t\t\t\t\t\t\t\t\t\tDeleteRequest: {\n\t\t\t\t\t\t\t\t\t\t\tKey: {\n\t\t\t\t\t\t\t\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\t\t\t\t\t\t\t\titem[DynamoDbEntityStorageConnector._PARTITION_KEY],\n\t\t\t\t\t\t\t\t\t\t\t\t[this._primaryKey.property as string]:\n\t\t\t\t\t\t\t\t\t\t\t\t\titem[this._primaryKey.property as string]\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\texclusiveStartKey = scanResult.LastEvaluatedKey;\n\t\t\t} while (exclusiveStartKey);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"emptyFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Remove the entity.\n\t * @param id The id of the entity to remove.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns Nothing.\n\t */\n\tpublic async remove(\n\t\tid: string,\n\t\tconditions?: { property: keyof T; value: unknown }[]\n\t): Promise<void> {\n\t\tGuards.stringValue(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\n\t\t\tconst { conditionExpression, attributeNames, attributeValues } =\n\t\t\t\tthis.buildConditionExpression(conditions);\n\n\t\t\tconst deleteCommand = new DeleteCommand({\n\t\t\t\tTableName: this._config.tableName,\n\t\t\t\tKey: {\n\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\tpartitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\t\t[this._primaryKey.property as string]: id\n\t\t\t\t},\n\t\t\t\tConditionExpression: conditionExpression,\n\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\tExpressionAttributeValues: attributeValues\n\t\t\t});\n\n\t\t\tawait docClient.send(deleteCommand);\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, \"ConditionalCheckFailedException\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t},\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"removeFailed\",\n\t\t\t\t{\n\t\t\t\t\tid\n\t\t\t\t},\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Remove multiple entities by their IDs in a batch.\n\t * @param ids The ids of the entities to remove.\n\t * @returns Nothing.\n\t */\n\tpublic async removeBatch(ids: string[]): Promise<void> {\n\t\tGuards.arrayValue(DynamoDbEntityStorageConnector.CLASS_NAME, nameof(ids), ids);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\t\t\tconst chunkSize = 25;\n\t\t\tconst primaryKeyProperty = this._primaryKey.property as string;\n\n\t\t\tfor (let i = 0; i < ids.length; i += chunkSize) {\n\t\t\t\tconst chunk = ids.slice(i, i + chunkSize);\n\t\t\t\tawait docClient.send(\n\t\t\t\t\tnew BatchWriteCommand({\n\t\t\t\t\t\tRequestItems: {\n\t\t\t\t\t\t\t[this._config.tableName]: chunk.map(id => ({\n\t\t\t\t\t\t\t\tDeleteRequest: {\n\t\t\t\t\t\t\t\t\tKey: {\n\t\t\t\t\t\t\t\t\t\t[primaryKeyProperty]: id,\n\t\t\t\t\t\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\t\t\t\t\t\tpartitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"removeBatchFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Teardown the entity storage by deleting the underlying table.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the teardown process was successful.\n\t */\n\tpublic async teardown(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tawait nodeLogging?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"tableDeleting\",\n\t\t\tdata: { tableName: this._config.tableName }\n\t\t});\n\n\t\ttry {\n\t\t\tconst dbConnection = this.createConnection();\n\n\t\t\tawait dbConnection.deleteTable({ TableName: this._config.tableName });\n\n\t\t\tawait waitUntilTableNotExists(\n\t\t\t\t{ client: dbConnection, maxWaitTime: 60 },\n\t\t\t\t{ TableName: this._config.tableName }\n\t\t\t);\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"tableDeleted\",\n\t\t\t\tdata: { tableName: this._config.tableName }\n\t\t\t});\n\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: DynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"teardownFailed\",\n\t\t\t\terror: BaseError.fromError(err)\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Find all the entities which match the conditions.\n\t * @param conditions The conditions to match for the entities.\n\t * @param sortProperties The optional sort order.\n\t * @param properties The optional properties to return, defaults to all.\n\t * @param cursor The cursor to request the next chunk of entities.\n\t * @param limit The suggested number of entities to return in each chunk, in some scenarios can return a different amount.\n\t * @returns All the entities for the storage matching the conditions,\n\t * and a cursor which can be used to request more entities.\n\t */\n\tpublic async query(\n\t\tconditions?: EntityCondition<T>,\n\t\tsortProperties?: {\n\t\t\tproperty: keyof T;\n\t\t\tsortDirection: SortDirection;\n\t\t}[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{\n\t\t/**\n\t\t * The entities, which can be partial if a limited keys list was provided.\n\t\t */\n\t\tentities: Partial<T>[];\n\t\t/**\n\t\t * An optional cursor, when defined can be used to call find to get more entities.\n\t\t */\n\t\tcursor?: string;\n\t}> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\treturn this.internalQuery(\n\t\t\tconditions,\n\t\t\tsortProperties,\n\t\t\tproperties,\n\t\t\tcursor,\n\t\t\tlimit,\n\t\t\tundefined,\n\t\t\tpartitionKey\n\t\t);\n\t}\n\n\t/**\n\t * Count all the entities which match the conditions.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The total count of entities in the storage.\n\t */\n\tpublic async count(conditions?: EntityCondition<T>): Promise<number> {\n\t\ttry {\n\t\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\t\tconst partitionKey = ContextIdHelper.combinedContextKey(\n\t\t\t\tcontextIds,\n\t\t\t\tthis._partitionContextIds\n\t\t\t);\n\n\t\t\tconst attributeNames: { [id: string]: string } = {\n\t\t\t\t\"#partitionId\": DynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t};\n\t\t\tconst attributeValues: { [id: string]: AttributeValue } = {\n\t\t\t\t\":partitionId\": {\n\t\t\t\t\tS: partitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst expressions = this.buildQueryParameters(\n\t\t\t\t\"\",\n\t\t\t\tconditions,\n\t\t\t\tattributeNames,\n\t\t\t\tattributeValues\n\t\t\t);\n\n\t\t\tconst dbConnection = this.createConnection();\n\t\t\tlet total = 0;\n\t\t\tlet exclusiveStartKey: { [key: string]: AttributeValue } | undefined;\n\n\t\t\tdo {\n\t\t\t\tconst result = await dbConnection.send(\n\t\t\t\t\tnew QueryCommand({\n\t\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\t\tSelect: \"COUNT\",\n\t\t\t\t\t\tKeyConditionExpression: \"#partitionId = :partitionId\",\n\t\t\t\t\t\tFilterExpression: Is.stringValue(expressions.filterCondition)\n\t\t\t\t\t\t\t? expressions.filterCondition\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\t\t\tExpressionAttributeValues: attributeValues,\n\t\t\t\t\t\tExclusiveStartKey: exclusiveStartKey\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\ttotal += result.Count ?? 0;\n\t\t\t\texclusiveStartKey = result.LastEvaluatedKey;\n\t\t\t} while (exclusiveStartKey);\n\n\t\t\treturn total;\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"countFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get a unique list of all the context ids from the storage.\n\t * @returns The list of unique context ids.\n\t */\n\tpublic async getPartitionContextIds(): Promise<IContextIds[]> {\n\t\tif (!Is.arrayValue(this._partitionContextIds)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contextIdsMap: { [id: string]: IContextIds } = {};\n\n\t\ttry {\n\t\t\tconst docClient = this.createDocClient();\n\t\t\tlet exclusiveStartKey: { [key: string]: NativeAttributeValue } | undefined;\n\n\t\t\tdo {\n\t\t\t\tconst scanResult = await docClient.send(\n\t\t\t\t\tnew ScanCommand({\n\t\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\t\tProjectionExpression: \"#partitionId\",\n\t\t\t\t\t\tExpressionAttributeNames: {\n\t\t\t\t\t\t\t\"#partitionId\": DynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExclusiveStartKey: exclusiveStartKey\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tfor (const item of scanResult.Items ?? []) {\n\t\t\t\t\tconst partitionId = item[DynamoDbEntityStorageConnector._PARTITION_KEY] as string;\n\t\t\t\t\tif (Is.stringValue(partitionId) && !(partitionId in contextIdsMap)) {\n\t\t\t\t\t\tcontextIdsMap[partitionId] = ContextIdHelper.shortSplit(\n\t\t\t\t\t\t\tthis._partitionContextIds ?? [],\n\t\t\t\t\t\t\tpartitionId\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\texclusiveStartKey = scanResult.LastEvaluatedKey;\n\t\t\t} while (exclusiveStartKey);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"getPartitionContextIdsFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\n\t\treturn Object.values(contextIdsMap);\n\t}\n\n\t/**\n\t * Create the target connector for performing the migration it will use a temporary storage location.\n\t * @param newEntitySchema The name of the new entity schema to create the connector for.\n\t * @returns Connector for performing the migration.\n\t */\n\tpublic async createTargetConnector<U>(\n\t\tnewEntitySchema: string\n\t): Promise<IEntityStorageConnector<U>> {\n\t\t// We create a new table for the migration with a unique name to avoid conflicts with the existing table\n\t\t// This table will be swapped with the existing table once the migration is finalized.\n\t\tconst migrationTableName = `${this._config.tableName}Migration${Date.now()}`;\n\t\treturn new DynamoDbEntityStorageConnector<U>({\n\t\t\tentitySchema: newEntitySchema,\n\t\t\tconfig: {\n\t\t\t\t...this._config,\n\t\t\t\ttableName: migrationTableName\n\t\t\t},\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t}\n\n\t/**\n\t * Finalize the migration by tearing down the old connector and replacing it with the new one.\n\t * @param targetConnector The target connector to finalize the migration with.\n\t * @param options The options to control how the migration is finalized.\n\t * @param loggingComponentType The logging component type to use for logging during the migration finalization.\n\t * @returns A promise that resolves when the migration is finalized.\n\t */\n\tpublic async finalizeMigration<U>(\n\t\ttargetConnector: DynamoDbEntityStorageConnector<U>,\n\t\toptions?: IMigrationOptions<T, U>,\n\t\tloggingComponentType?: string\n\t): Promise<DynamoDbEntityStorageConnector<U>> {\n\t\t// There is no rename operation in DynamoDB so we have to create a new table with the original name and copy the data over\n\n\t\t// Teardown the existing table with the original name to free up the name for the new table\n\t\tawait this.teardown(loggingComponentType);\n\n\t\t// Create a new connector with the original table name but with the new schema\n\t\t// and copy the data from the migration table to the new table using batch operations\n\t\tconst finalConnector = new DynamoDbEntityStorageConnector<U>({\n\t\t\tentitySchema: targetConnector._entitySchemaName,\n\t\t\tconfig: this._config,\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\n\t\tif (await finalConnector.bootstrap(loggingComponentType)) {\n\t\t\t// Since there is no rename, we need to copy the data from the migration table to the new table\n\t\t\tconst partitions = await targetConnector.getPartitionContextIds();\n\t\t\tconst batchSize = options?.batchSize ?? DynamoDbEntityStorageConnector._DEFAULT_LIMIT;\n\t\t\tawait this.bulkCopy(targetConnector, finalConnector, partitions, batchSize);\n\n\t\t\tawait targetConnector.teardown(loggingComponentType);\n\n\t\t\treturn finalConnector;\n\t\t}\n\n\t\tthrow new GeneralError(\n\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\"finalizeMigrationFailedBootstrap\",\n\t\t\tundefined\n\t\t);\n\t}\n\n\t/**\n\t * Cleanup the migration if a migration fails or needs to be aborted.\n\t * @param targetConnector The target connector to cleanup the migration with.\n\t * @param options The options to control how the migration is cleaned up.\n\t * @param loggingComponentType The optional component type to use for logging the migration progress.\n\t * @returns A promise that resolves when the migration is cleaned up.\n\t */\n\tpublic async cleanupMigration<U>(\n\t\ttargetConnector: IEntityStorageConnector<U> | undefined,\n\t\toptions?: IMigrationOptions<T, U>,\n\t\tloggingComponentType?: string\n\t): Promise<void> {\n\t\t// If something failed the only thing to cleanup is the migration table\n\t\tawait targetConnector?.teardown?.(loggingComponentType);\n\t}\n\n\t/**\n\t * Copy all entities from sourceConnector to destConnector, paging through each partition.\n\t * @param sourceConnector The connector to read entities from.\n\t * @param destConnector The connector to write entities to.\n\t * @param partitions The partition list returned by getPartitionContextIds.\n\t * @param batchSize The number of entities to read per page.\n\t * @internal\n\t */\n\tprivate async bulkCopy<U>(\n\t\tsourceConnector: DynamoDbEntityStorageConnector<U>,\n\t\tdestConnector: DynamoDbEntityStorageConnector<U>,\n\t\tpartitions: IContextIds[],\n\t\tbatchSize: number\n\t): Promise<void> {\n\t\tlet partitionList: IContextIds[];\n\t\tif (Is.arrayValue(partitions)) {\n\t\t\tpartitionList = partitions;\n\t\t} else if (Is.arrayValue(sourceConnector._partitionContextIds)) {\n\t\t\tpartitionList = [];\n\t\t} else {\n\t\t\tpartitionList = [{}];\n\t\t}\n\n\t\tconst dbConnection = sourceConnector.createConnection();\n\t\tconst chunkSize = 25;\n\n\t\tfor (let i = 0; i < partitionList.length; i++) {\n\t\t\tconst partitionKey =\n\t\t\t\tContextIdHelper.combinedContextKey(\n\t\t\t\t\tpartitionList[i],\n\t\t\t\t\tsourceConnector._partitionContextIds\n\t\t\t\t) ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\t\tlet exclusiveStartKey: { [key: string]: AttributeValue } | undefined;\n\t\t\tdo {\n\t\t\t\tconst { Items: items, LastEvaluatedKey: lastKey } = await dbConnection.send(\n\t\t\t\t\tnew QueryCommand({\n\t\t\t\t\t\tTableName: sourceConnector._config.tableName,\n\t\t\t\t\t\tKeyConditionExpression: `#${DynamoDbEntityStorageConnector._PARTITION_KEY} = :${DynamoDbEntityStorageConnector._PARTITION_KEY}`,\n\t\t\t\t\t\tExpressionAttributeNames: {\n\t\t\t\t\t\t\t[`#${DynamoDbEntityStorageConnector._PARTITION_KEY}`]:\n\t\t\t\t\t\t\t\tDynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpressionAttributeValues: {\n\t\t\t\t\t\t\t[`:${DynamoDbEntityStorageConnector._PARTITION_KEY}`]: { S: partitionKey }\n\t\t\t\t\t\t},\n\t\t\t\t\t\tLimit: batchSize,\n\t\t\t\t\t\tExclusiveStartKey: exclusiveStartKey\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\texclusiveStartKey = lastKey;\n\n\t\t\t\tif (Is.arrayValue(items)) {\n\t\t\t\t\tfor (let j = 0; j < items.length; j += chunkSize) {\n\t\t\t\t\t\tconst chunk = items.slice(j, j + chunkSize) as { [key: string]: AttributeValue }[];\n\t\t\t\t\t\tawait dbConnection.send(\n\t\t\t\t\t\t\tnew BatchWriteItemCommand({\n\t\t\t\t\t\t\t\tRequestItems: {\n\t\t\t\t\t\t\t\t\t[destConnector._config.tableName]: chunk.map(item => ({\n\t\t\t\t\t\t\t\t\t\tPutRequest: { Item: item }\n\t\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} while (exclusiveStartKey);\n\t\t}\n\t}\n\n\t/**\n\t * Create the parameters for a query.\n\t * @param objectPath The path for the nested object.\n\t * @param condition The conditions to create the query from.\n\t * @param attributeNames The attribute names to use in the query.\n\t * @param attributeValues The attribute values to use in the query.\n\t * @returns The condition clause.\n\t * @internal\n\t */\n\tprivate buildQueryParameters(\n\t\tobjectPath: string,\n\t\tcondition: EntityCondition<T> | undefined,\n\t\tattributeNames: { [id: string]: string },\n\t\tattributeValues: { [id: string]: AttributeValue },\n\t\tsecondaryIndex?: string\n\t): {\n\t\tkeyCondition: string;\n\t\tfilterCondition: string;\n\t\trequiresScan: boolean;\n\t} {\n\t\t// If no conditions are defined then return empty string\n\t\tif (Is.undefined(condition)) {\n\t\t\treturn {\n\t\t\t\tkeyCondition: \"\",\n\t\t\t\tfilterCondition: \"\",\n\t\t\t\trequiresScan: false\n\t\t\t};\n\t\t}\n\n\t\tif (\"conditions\" in condition) {\n\t\t\tif (condition.conditions.length === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tkeyCondition: \"\",\n\t\t\t\t\tfilterCondition: \"\",\n\t\t\t\t\trequiresScan: false\n\t\t\t\t};\n\t\t\t}\n\t\t\t// It's a group of comparisons, so check the individual items and combine with the logical operator\n\t\t\tconst joinConditions: {\n\t\t\t\tkeyCondition: string;\n\t\t\t\tfilterCondition: string;\n\t\t\t\trequiresScan: boolean;\n\t\t\t}[] = condition.conditions.map(c =>\n\t\t\t\tthis.buildQueryParameters(objectPath, c, attributeNames, attributeValues, secondaryIndex)\n\t\t\t);\n\n\t\t\tconst logicalOperator = this.mapConditionalOperator(condition.logicalOperator);\n\n\t\t\t// DynamoDB does not support OR in KeyConditionExpression, so when the operator\n\t\t\t// is OR we must move all conditions (including key conditions) into FilterExpression.\n\t\t\tif (condition.logicalOperator === LogicalOperator.Or) {\n\t\t\t\tconst parts = joinConditions\n\t\t\t\t\t.map(j => {\n\t\t\t\t\t\tconst subParts = [j.keyCondition.trim(), j.filterCondition.trim()].filter(\n\t\t\t\t\t\t\ts => s.length > 0\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (subParts.length === 0) {\n\t\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subParts.length === 1) {\n\t\t\t\t\t\t\treturn subParts[0];\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn `(${subParts.join(\" AND \")})`;\n\t\t\t\t\t})\n\t\t\t\t\t.filter(s => s.length > 0);\n\t\t\t\tconst hasKeyConditions = joinConditions.some(j => j.keyCondition.length > 0);\n\t\t\t\tconst filterCondition = parts.join(\" OR \");\n\t\t\t\treturn {\n\t\t\t\t\tkeyCondition: \"\",\n\t\t\t\t\tfilterCondition: Is.stringValue(filterCondition) ? ` (${filterCondition}) ` : \"\",\n\t\t\t\t\trequiresScan: hasKeyConditions\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst keyCondition = joinConditions\n\t\t\t\t.filter(j => j.keyCondition.length > 0)\n\t\t\t\t.map(j => j.keyCondition)\n\t\t\t\t.join(` ${logicalOperator} `);\n\t\t\tconst filterCondition = joinConditions\n\t\t\t\t.filter(j => j.filterCondition.length > 0)\n\t\t\t\t.map(j => j.filterCondition)\n\t\t\t\t.join(` ${logicalOperator} `);\n\n\t\t\treturn {\n\t\t\t\tkeyCondition: Is.stringValue(keyCondition) ? ` (${keyCondition}) ` : \"\",\n\t\t\t\tfilterCondition: Is.stringValue(filterCondition) ? ` (${filterCondition}) ` : \"\",\n\t\t\t\trequiresScan: joinConditions.some(j => j.requiresScan)\n\t\t\t};\n\t\t}\n\n\t\tconst schemaProp = this._entitySchema.properties?.find(p => p.property === condition.property);\n\n\t\t// It's a single value so just create the property comparison for the condition\n\t\tconst comparison = this.mapComparisonOperator(\n\t\t\tobjectPath,\n\t\t\tcondition,\n\t\t\tschemaProp?.type,\n\t\t\tattributeNames,\n\t\t\tattributeValues\n\t\t);\n\n\t\tconst isKey =\n\t\t\tschemaProp?.isPrimary ?? (schemaProp?.isSecondary && schemaProp?.property === secondaryIndex);\n\t\treturn {\n\t\t\tkeyCondition: isKey ? comparison : \"\",\n\t\t\tfilterCondition: !isKey ? comparison : \"\",\n\t\t\trequiresScan: false\n\t\t};\n\t}\n\n\t/**\n\t * Map the framework comparison operators to those in DynamoDB.\n\t * @param objectPath The prefix to use for the condition.\n\t * @param comparator The operator to map.\n\t * @param type The type of the property.\n\t * @param attributeNames The attribute names to use in the query.\n\t * @param attributeValues The attribute values to use in the query.\n\t * @returns The comparison expression.\n\t * @throws GeneralError if the comparison operator is not supported.\n\t * @internal\n\t */\n\tprivate mapComparisonOperator(\n\t\tobjectPath: string,\n\t\tcomparator: IComparator,\n\t\ttype: EntitySchemaPropertyType | undefined,\n\t\tattributeNames: { [id: string]: string },\n\t\tattributeValues: { [id: string]: AttributeValue }\n\t): string {\n\t\tlet prop = objectPath;\n\t\tif (prop.length > 0) {\n\t\t\tprop += \".\";\n\t\t}\n\t\tprop += comparator.property;\n\n\t\tlet attributeName = this.populateAttributeNames(prop, attributeNames);\n\n\t\tif (Is.empty(comparator.value)) {\n\t\t\t// With \"omit\" storage, optional null/undefined fields are absent from the item entirely.\n\t\t\t// attribute_not_exists matches absent attributes; attribute_exists matches present ones.\n\t\t\tif (comparator.comparison === ComparisonOperator.Equals) {\n\t\t\t\treturn `attribute_not_exists(${attributeName})`;\n\t\t\t} else if (comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\treturn `attribute_exists(${attributeName})`;\n\t\t\t}\n\t\t}\n\n\t\tconst basePropName = `:${attributeName.replace(/\\./g, \"\").replace(/#/g, \"\")}`;\n\t\tlet propName = basePropName;\n\t\tlet propSuffix = 0;\n\t\twhile (!Is.undefined(attributeValues[propName])) {\n\t\t\tpropSuffix++;\n\t\t\tpropName = `${basePropName}${propSuffix}`;\n\t\t}\n\n\t\tif (Is.array(comparator.value)) {\n\t\t\tconst dbValues = comparator.value.map(v => this.propertyToDbValue(v, type));\n\t\t\tconst arrAttributeNames = [];\n\t\t\tfor (let i = 0; i < dbValues.length; i++) {\n\t\t\t\tconst arrAttributeName = `${propName}${i}`;\n\t\t\t\tattributeValues[arrAttributeName] = dbValues[i];\n\t\t\t\tarrAttributeNames.push(arrAttributeName);\n\t\t\t}\n\t\t\tpropName = attributeName;\n\t\t\tattributeName = `(${arrAttributeNames.join(\", \")})`;\n\t\t} else {\n\t\t\tattributeValues[propName] = this.propertyToDbValue(comparator.value, type);\n\t\t}\n\n\t\tif (comparator.comparison === ComparisonOperator.Equals) {\n\t\t\treturn `${attributeName} = ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\treturn `${attributeName} <> ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.GreaterThan) {\n\t\t\treturn `${attributeName} > ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.LessThan) {\n\t\t\treturn `${attributeName} < ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.GreaterThanOrEqual) {\n\t\t\treturn `${attributeName} >= ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.LessThanOrEqual) {\n\t\t\treturn `${attributeName} <= ${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.Includes) {\n\t\t\treturn `contains(${attributeName}, ${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.NotIncludes) {\n\t\t\treturn `NOT contains(${attributeName}, ${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.In) {\n\t\t\treturn `${propName} IN ${attributeName}`;\n\t\t}\n\n\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"comparisonNotSupported\", {\n\t\t\tcomparison: comparator.comparison\n\t\t});\n\t}\n\n\t/**\n\t * Create a unique name for the attribute.\n\t * @param name The name to create a unique name for.\n\t * @param attributeNames The attribute names to use in the query.\n\t * @returns The unique name.\n\t * @internal\n\t */\n\tprivate populateAttributeNames(name: string, attributeNames: { [id: string]: string }): string {\n\t\tconst parts = name.split(\".\");\n\t\tconst attributeNameParts: string[] = [];\n\n\t\tfor (const part of parts) {\n\t\t\tconst hashPart = `#${part}`;\n\t\t\tif (Is.empty(attributeNames[hashPart])) {\n\t\t\t\tattributeNames[hashPart] = part;\n\t\t\t}\n\t\t\tattributeNameParts.push(hashPart);\n\t\t}\n\n\t\treturn attributeNameParts.join(\".\");\n\t}\n\n\t/**\n\t * Map the framework conditional operators to those in DynamoDB.\n\t * @param operator The operator to map.\n\t * @returns The conditional operator.\n\t * @throws GeneralError if the conditional operator is not supported.\n\t * @internal\n\t */\n\tprivate mapConditionalOperator(operator?: LogicalOperator): string {\n\t\tif ((operator ?? LogicalOperator.And) === LogicalOperator.And) {\n\t\t\treturn \"AND\";\n\t\t} else if (operator === LogicalOperator.Or) {\n\t\t\treturn \"OR\";\n\t\t}\n\n\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"conditionalNotSupported\", {\n\t\t\toperator\n\t\t});\n\t}\n\n\t/**\n\t * Format a value to insert into DB.\n\t * @param value The value to format.\n\t * @param type The type for the property.\n\t * @returns The value after conversion.\n\t * @internal\n\t */\n\tprivate propertyToDbValue(value: unknown, type?: EntitySchemaPropertyType): AttributeValue {\n\t\tif (Is.object(value)) {\n\t\t\tconst map: { [id: string]: AttributeValue } = {};\n\t\t\tfor (const key in value) {\n\t\t\t\tmap[key] = this.propertyToDbValue(value[key]);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tM: map\n\t\t\t};\n\t\t}\n\n\t\tif (type === \"integer\" || type === \"number\") {\n\t\t\treturn { N: Coerce.string(value) ?? \"\" };\n\t\t} else if (type === \"boolean\") {\n\t\t\treturn { BOOL: Coerce.boolean(value) ?? false };\n\t\t}\n\n\t\treturn { S: Coerce.string(value) ?? \"\" };\n\t}\n\n\t/**\n\t * Create a doc client connection.\n\t * @returns The dynamo db document client.\n\t * @internal\n\t */\n\tprivate createDocClient(): DynamoDBDocumentClient {\n\t\treturn DynamoDBDocumentClient.from(\n\t\t\tnew DynamoDB({\n\t\t\t\tapiVersion: \"2012-10-08\",\n\t\t\t\t...this.createConnectionConfig()\n\t\t\t}),\n\t\t\t{\n\t\t\t\tmarshallOptions: {\n\t\t\t\t\tremoveUndefinedValues: true\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n\t/**\n\t * Create a new DB connection.\n\t * @returns The Dynamo DB connection.\n\t * @internal\n\t */\n\tprivate createConnection(): DynamoDB {\n\t\treturn new DynamoDB(this.createConnectionConfig());\n\t}\n\n\t/**\n\t * Create a new DB connection configuration.\n\t * @returns The Dynamo DB connection configuration.\n\t * @internal\n\t */\n\tprivate createConnectionConfig(): DynamoDBClientConfig {\n\t\tconst requestHandler = Is.number(this._config.connectionTimeoutMs)\n\t\t\t? { requestTimeout: this._config.connectionTimeoutMs }\n\t\t\t: undefined;\n\n\t\tif (\n\t\t\tIs.stringValue(this._config.secretAccessKey) &&\n\t\t\tIs.stringValue(this._config.accessKeyId) &&\n\t\t\tthis._config.authMode === \"credentials\"\n\t\t) {\n\t\t\treturn {\n\t\t\t\tcredentials: {\n\t\t\t\t\taccessKeyId: this._config.accessKeyId,\n\t\t\t\t\tsecretAccessKey: this._config.secretAccessKey\n\t\t\t\t},\n\t\t\t\tendpoint: this._config.endpoint,\n\t\t\t\tregion: this._config.region,\n\t\t\t\trequestHandler,\n\t\t\t\tmaxAttempts: this._config.maxAttempts\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tendpoint: this._config.endpoint,\n\t\t\tregion: this._config.region,\n\t\t\trequestHandler,\n\t\t\tmaxAttempts: this._config.maxAttempts\n\t\t};\n\t}\n\n\t/**\n\t * Check if the table exists.\n\t * @param tableName The table to check.\n\t * @returns True if the table exists.\n\t * @internal\n\t */\n\tprivate async tableExists(tableName: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst dbConnection = this.createConnection();\n\n\t\t\tconst result = await dbConnection.describeTable({ TableName: tableName });\n\n\t\t\t// A table in DELETING state should not be treated as existing\n\t\t\treturn result.Table?.TableStatus !== \"DELETING\";\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Find all the entities which match the conditions.\n\t * @param conditions The conditions to match for the entities.\n\t * @param sortProperties The optional sort order.\n\t * @param properties The optional properties to return, defaults to all.\n\t * @param cursor The cursor to request the next chunk of entities.\n\t * @param limit The suggested number of entities to return in each chunk, in some scenarios can return a different amount.\n\t * @param secondaryIndex The secondary index to use for the query.\n\t * @param partitionKey The partition key to use for the query.\n\t * @returns All the entities for the storage matching the conditions,\n\t * and a cursor which can be used to request more entities.\n\t * @internal\n\t */\n\tprivate async internalQuery(\n\t\tconditions?: EntityCondition<T>,\n\t\tsortProperties?: {\n\t\t\tproperty: keyof T;\n\t\t\tsortDirection: SortDirection;\n\t\t}[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number,\n\t\tsecondaryIndex?: string,\n\t\tpartitionKey?: string\n\t): Promise<{\n\t\t/**\n\t\t * The entities, which can be partial if a limited keys list was provided.\n\t\t */\n\t\tentities: Partial<T>[];\n\t\t/**\n\t\t * An optional cursor, when defined can be used to call find to get more entities.\n\t\t */\n\t\tcursor?: string;\n\t}> {\n\t\ttry {\n\t\t\tconst returnSize = limit ?? DynamoDbEntityStorageConnector._DEFAULT_LIMIT;\n\n\t\t\tlet indexName: string | undefined = Is.stringValue(secondaryIndex)\n\t\t\t\t? `${secondaryIndex}Index`\n\t\t\t\t: undefined;\n\n\t\t\t// If we have a sortable property defined in the descriptor then we must use\n\t\t\t// the secondary index for the query\n\t\t\tlet scanAscending = true;\n\t\t\tif (Is.arrayValue(sortProperties)) {\n\t\t\t\tif (sortProperties.length > 1) {\n\t\t\t\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"sortSingle\");\n\t\t\t\t}\n\n\t\t\t\tfor (const sortProperty of sortProperties) {\n\t\t\t\t\tconst propertySchema = this._entitySchema.properties?.find(\n\t\t\t\t\t\te => e.property === sortProperty.property\n\t\t\t\t\t);\n\t\t\t\t\tif (\n\t\t\t\t\t\tIs.undefined(propertySchema) ||\n\t\t\t\t\t\t(!propertySchema.isPrimary &&\n\t\t\t\t\t\t\t!propertySchema.isSecondary &&\n\t\t\t\t\t\t\tIs.empty(propertySchema.sortDirection))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"sortNotIndexed\", {\n\t\t\t\t\t\t\tproperty: sortProperty.property\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tindexName = propertySchema.isPrimary\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: `${sortProperty.property as string}Index`;\n\t\t\t\t\tscanAscending = sortProperty.sortDirection === SortDirection.Ascending;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst attributeNames: { [id: string]: string } = { \"#partitionId\": \"partitionId\" };\n\t\t\tconst attributeValues: { [id: string]: AttributeValue } = {\n\t\t\t\t[`:${DynamoDbEntityStorageConnector._PARTITION_KEY}`]: {\n\t\t\t\t\tS: partitionKey ?? DynamoDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst expressions = this.buildQueryParameters(\n\t\t\t\t\"\",\n\t\t\t\tconditions,\n\t\t\t\tattributeNames,\n\t\t\t\tattributeValues,\n\t\t\t\tsecondaryIndex\n\t\t\t);\n\n\t\t\t// OR conditions on primary key attributes can't use KeyConditionExpression or\n\t\t\t// FilterExpression in a QueryCommand — fall back to a full table ScanCommand.\n\t\t\tif (expressions.requiresScan) {\n\t\t\t\tlet scanFilter = \"#partitionId = :partitionId\";\n\t\t\t\tif (Is.stringValue(expressions.filterCondition)) {\n\t\t\t\t\tscanFilter += ` AND ${expressions.filterCondition.trim()}`;\n\t\t\t\t}\n\n\t\t\t\tconst dbConnection = this.createConnection();\n\t\t\t\tconst matchingItems: { [id: string]: AttributeValue }[] = [];\n\t\t\t\tlet scanStartKey: { [id: string]: AttributeValue } | undefined = Is.empty(cursor)\n\t\t\t\t\t? undefined\n\t\t\t\t\t: ObjectHelper.fromBytes(Converter.base64ToBytes(cursor));\n\n\t\t\t\tdo {\n\t\t\t\t\tconst scanResult = await dbConnection.send(\n\t\t\t\t\t\tnew RawScanCommand({\n\t\t\t\t\t\t\tTableName: this._config.tableName,\n\t\t\t\t\t\t\tFilterExpression: scanFilter,\n\t\t\t\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\t\t\t\tExpressionAttributeValues: attributeValues,\n\t\t\t\t\t\t\tProjectionExpression: properties?.map(p => p as string).join(\", \"),\n\t\t\t\t\t\t\tExclusiveStartKey: scanStartKey\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tmatchingItems.push(...(scanResult.Items ?? []));\n\t\t\t\t\tscanStartKey = scanResult.LastEvaluatedKey;\n\t\t\t\t} while (!Is.empty(scanStartKey));\n\n\t\t\t\tconst hasMore = matchingItems.length > returnSize;\n\t\t\t\tconst returnedRawItems = hasMore ? matchingItems.slice(0, returnSize) : matchingItems;\n\n\t\t\t\tlet resultCursor: string | undefined;\n\t\t\t\tif (hasMore) {\n\t\t\t\t\tconst lastRawItem = returnedRawItems[returnedRawItems.length - 1];\n\t\t\t\t\tconst syntheticKey: { [id: string]: AttributeValue } = {\n\t\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\t\tlastRawItem[DynamoDbEntityStorageConnector._PARTITION_KEY],\n\t\t\t\t\t\t[this._primaryKey.property as string]: lastRawItem[this._primaryKey.property as string]\n\t\t\t\t\t};\n\t\t\t\t\tresultCursor = Converter.bytesToBase64(ObjectHelper.toBytes(syntheticKey));\n\t\t\t\t}\n\n\t\t\t\tconst scanEntities: T[] = returnedRawItems.map(item => {\n\t\t\t\t\tconst unmarshalled = unmarshall(item);\n\t\t\t\t\treturn EntityStorageHelper.unPrepareEntity(unmarshalled as T, [\n\t\t\t\t\t\tDynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t\t]);\n\t\t\t\t});\n\n\t\t\t\treturn { entities: scanEntities, cursor: resultCursor };\n\t\t\t}\n\n\t\t\tlet keyExpression = \"#partitionId = :partitionId\";\n\t\t\tif (expressions.keyCondition.length > 0) {\n\t\t\t\tkeyExpression += ` AND ${expressions.keyCondition}`;\n\t\t\t}\n\n\t\t\tconst query = new QueryCommand({\n\t\t\t\tTableName: this._config.tableName,\n\t\t\t\tIndexName: indexName,\n\t\t\t\tKeyConditionExpression: keyExpression,\n\t\t\t\tFilterExpression: Is.stringValue(expressions.filterCondition)\n\t\t\t\t\t? expressions.filterCondition\n\t\t\t\t\t: undefined,\n\t\t\t\tExpressionAttributeNames: attributeNames,\n\t\t\t\tExpressionAttributeValues: attributeValues,\n\t\t\t\tProjectionExpression: properties?.map(p => p as string).join(\", \"),\n\t\t\t\tLimit: returnSize + 1,\n\t\t\t\tScanIndexForward: scanAscending,\n\t\t\t\tExclusiveStartKey: Is.empty(cursor)\n\t\t\t\t\t? undefined\n\t\t\t\t\t: ObjectHelper.fromBytes(Converter.base64ToBytes(cursor))\n\t\t\t});\n\n\t\t\tconst connection = this.createDocClient();\n\n\t\t\tconst results = await connection.send(query);\n\n\t\t\tconst rawItems = results.Items ?? [];\n\t\t\tconst hasMore = rawItems.length > returnSize;\n\t\t\tconst returnedRawItems = hasMore ? rawItems.slice(0, returnSize) : rawItems;\n\n\t\t\tlet resultCursor: string | undefined;\n\t\t\tif (hasMore) {\n\t\t\t\tconst lastRawItem = returnedRawItems[returnedRawItems.length - 1] as {\n\t\t\t\t\t[id: string]: AttributeValue;\n\t\t\t\t};\n\t\t\t\tconst syntheticKey: { [id: string]: AttributeValue } = {\n\t\t\t\t\t[DynamoDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\tlastRawItem[DynamoDbEntityStorageConnector._PARTITION_KEY],\n\t\t\t\t\t[this._primaryKey.property as string]: lastRawItem[this._primaryKey.property as string]\n\t\t\t\t};\n\t\t\t\tif (Is.stringValue(secondaryIndex)) {\n\t\t\t\t\tsyntheticKey[secondaryIndex] = lastRawItem[secondaryIndex];\n\t\t\t\t}\n\t\t\t\tresultCursor = Converter.bytesToBase64(ObjectHelper.toBytes(syntheticKey));\n\t\t\t}\n\n\t\t\tconst entities: T[] = returnedRawItems.map(item => {\n\t\t\t\tconst unmarshalled = unmarshall(item);\n\t\t\t\treturn EntityStorageHelper.unPrepareEntity(unmarshalled as T, [\n\t\t\t\t\tDynamoDbEntityStorageConnector._PARTITION_KEY\n\t\t\t\t]);\n\t\t\t});\n\n\t\t\treturn { entities, cursor: resultCursor };\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"ResourceNotFoundException\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"tableDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\ttableName: this._config.tableName\n\t\t\t\t\t},\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tDynamoDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"queryFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Build the condition expression for the query.\n\t * @param conditions The conditions to build the expression from.\n\t * @returns The condition expression.\n\t * @throws GeneralError if the property is not found in the schema.\n\t * @internal\n\t */\n\tprivate buildConditionExpression(conditions?: { property: keyof T; value: unknown }[]): {\n\t\tconditionExpression: string | undefined;\n\t\tattributeNames: { [id: string]: string } | undefined;\n\t\tattributeValues: { [key: string]: NativeAttributeValue } | undefined;\n\t} {\n\t\tlet conditionExpression: string | undefined;\n\t\tlet attributeNames: { [id: string]: string } | undefined;\n\t\tlet attributeValues: { [key: string]: NativeAttributeValue } | undefined;\n\n\t\tif (Is.arrayValue(conditions)) {\n\t\t\tconst expressions: string[] = [];\n\n\t\t\tfor (const c of conditions) {\n\t\t\t\tconst schemaProp = this._entitySchema.properties?.find(p => p.property === c.property);\n\n\t\t\t\tif (Is.undefined(schemaProp)) {\n\t\t\t\t\tthrow new GeneralError(DynamoDbEntityStorageConnector.CLASS_NAME, \"propertyNotFound\", {\n\t\t\t\t\t\tproperty: c.property\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst attributeName = `#${c.property as string}`;\n\t\t\t\tconst attributeValueName = `:${c.property as string}`;\n\t\t\t\tattributeNames ??= {};\n\t\t\t\tattributeValues ??= {};\n\t\t\t\tattributeNames[attributeName] = c.property as string;\n\t\t\t\tattributeValues[attributeValueName] = c.value;\n\t\t\t\texpressions.push(`${attributeName} = ${attributeValueName}`);\n\t\t\t}\n\n\t\t\tconditionExpression = expressions.join(\" AND \");\n\t\t}\n\t\treturn { conditionExpression, attributeNames, attributeValues };\n\t}\n}\n"]}
package/docs/changelog.md CHANGED
@@ -1,5 +1,165 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.3-next.20](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-dynamodb-v0.0.3-next.19...entity-storage-connector-dynamodb-v0.0.3-next.20) (2026-06-01)
4
+
5
+
6
+ ### Features
7
+
8
+ * add AWS pod authentication mode ([caaae36](https://github.com/iotaledger/twin-entity-storage/commit/caaae368ca104cd9994e1af7b6c4c20e603c2021))
9
+ * add context id features ([#55](https://github.com/iotaledger/twin-entity-storage/issues/55)) ([99c15a2](https://github.com/iotaledger/twin-entity-storage/commit/99c15a257539b61d9da63649ce573ebf47699fc9))
10
+ * add production release automation ([1eb4c8e](https://github.com/iotaledger/twin-entity-storage/commit/1eb4c8ee3eb099defdfc2d063ae44935276dcae8))
11
+ * add support for connection timeout config ([96d0025](https://github.com/iotaledger/twin-entity-storage/commit/96d0025bc11d27138bfd845e0248ba19382c3fd9))
12
+ * add support for connection timeout config ([64f987e](https://github.com/iotaledger/twin-entity-storage/commit/64f987e1ddfd0f09cb24eb0bd5fc3739e9b58a00))
13
+ * add support for object comparison conditions ([eb505a1](https://github.com/iotaledger/twin-entity-storage/commit/eb505a17a3642e95c4e3cf137a77a0a8fb388c97))
14
+ * add synchronised to release configs ([e1e749c](https://github.com/iotaledger/twin-entity-storage/commit/e1e749cf261b58c8c36729686861e29c7d5e068e))
15
+ * add validate-locales ([e66ef0d](https://github.com/iotaledger/twin-entity-storage/commit/e66ef0de26ca2f82b3fe89bb5c7a15a0978a9644))
16
+ * adding schema migration functionality to all the connectors ([#85](https://github.com/iotaledger/twin-entity-storage/issues/85)) ([fd1555a](https://github.com/iotaledger/twin-entity-storage/commit/fd1555a34380158214a577586dafae821e72a578))
17
+ * additional information in health ([1e658b7](https://github.com/iotaledger/twin-entity-storage/commit/1e658b74288e9411538286d25b81823df80703e9))
18
+ * disable endpoint discovery for cosmos ([49df2a2](https://github.com/iotaledger/twin-entity-storage/commit/49df2a254f385dc42e2e1f7e26e71f89b5bf5bcf))
19
+ * entity storage enhancements ([#86](https://github.com/iotaledger/twin-entity-storage/issues/86)) ([1279af4](https://github.com/iotaledger/twin-entity-storage/commit/1279af42615c6497bb06539842cee44842dd1f75))
20
+ * eslint migration to flat config ([f033b64](https://github.com/iotaledger/twin-entity-storage/commit/f033b64984c0e6a8129d929c9dd816dcc1b8dab0))
21
+ * logging naming consistency ([f99d12d](https://github.com/iotaledger/twin-entity-storage/commit/f99d12dea04b6d4f2b5632ff5473e9ec7d5f9055))
22
+ * synchronised storage ([#44](https://github.com/iotaledger/twin-entity-storage/issues/44)) ([94e10e2](https://github.com/iotaledger/twin-entity-storage/commit/94e10e26d1feec801449dc04af7a9757ac7495ff))
23
+ * typescript 6 update ([995a0c6](https://github.com/iotaledger/twin-entity-storage/commit/995a0c6fa9a6813bfdc7200779ce3664236e59e9))
24
+ * update dependencies ([7ccc0c4](https://github.com/iotaledger/twin-entity-storage/commit/7ccc0c429125d073dc60b3de6cf101abc8cc6cba))
25
+ * update docs ([5203e62](https://github.com/iotaledger/twin-entity-storage/commit/5203e621c3ae368f6fefb29ea5146f024f4a1b0d))
26
+ * update framework core ([b59a380](https://github.com/iotaledger/twin-entity-storage/commit/b59a380bb7fba2b43610f69074dcdee24a4737da))
27
+ * use shared store mechanism ([#34](https://github.com/iotaledger/twin-entity-storage/issues/34)) ([68b6b71](https://github.com/iotaledger/twin-entity-storage/commit/68b6b71e7a96d7d016cd57bfff36775b56bf3f93))
28
+
29
+
30
+ ### Bug Fixes
31
+
32
+ * add missing dependency ([3282535](https://github.com/iotaledger/twin-entity-storage/commit/328253516e0d13b276406fb4de97dab8ee5e8ba7))
33
+ * add missing dependency ([2b848f3](https://github.com/iotaledger/twin-entity-storage/commit/2b848f3a345522c869b798d7a1cb64112dd8e3e3))
34
+ * adding tests and fixes for dot notation ([#76](https://github.com/iotaledger/twin-entity-storage/issues/76)) ([3879337](https://github.com/iotaledger/twin-entity-storage/commit/387933797e33543e4d8b2d49b8beeb792512a4ff))
35
+ * adding tests and support when neccesary for string include operator when needed ([#72](https://github.com/iotaledger/twin-entity-storage/issues/72)) ([3c723dd](https://github.com/iotaledger/twin-entity-storage/commit/3c723dd5694814398099d9d4594089dc6c66ba97))
36
+ * document AWS SDK pins for minimum release age consumers ([#96](https://github.com/iotaledger/twin-entity-storage/issues/96)) ([c4bcc26](https://github.com/iotaledger/twin-entity-storage/commit/c4bcc26f962da6f6bd090630f48d26ab58946c4e))
37
+ * dynamodb or conditions ([7a28b07](https://github.com/iotaledger/twin-entity-storage/commit/7a28b0702e03ec1fed04424136aca8a8c40cb28a))
38
+ * null secondary indexes ([#103](https://github.com/iotaledger/twin-entity-storage/issues/103)) ([5e44f11](https://github.com/iotaledger/twin-entity-storage/commit/5e44f11bb5af5bf2c27d6f1d56aba5851116ff89))
39
+ * query params force coercion ([dd6aa87](https://github.com/iotaledger/twin-entity-storage/commit/dd6aa87efdfb60bab7d6756a86888863c45c51a7))
40
+ * tests and fixes for the comparisons for null and undefined ([#79](https://github.com/iotaledger/twin-entity-storage/issues/79)) ([e7ffd62](https://github.com/iotaledger/twin-entity-storage/commit/e7ffd62e9ec40ef31498e6e2350bb25d9c84638a))
41
+
42
+
43
+ ### Dependencies
44
+
45
+ * The following workspace dependencies were updated
46
+ * dependencies
47
+ * @twin.org/entity-storage-models bumped from 0.0.3-next.19 to 0.0.3-next.20
48
+ * devDependencies
49
+ * @twin.org/entity-storage-connector-memory bumped from 0.0.3-next.19 to 0.0.3-next.20
50
+
51
+ ## [0.0.3-next.19](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-dynamodb-v0.0.3-next.18...entity-storage-connector-dynamodb-v0.0.3-next.19) (2026-06-01)
52
+
53
+
54
+ ### Features
55
+
56
+ * add AWS pod authentication mode ([caaae36](https://github.com/iotaledger/twin-entity-storage/commit/caaae368ca104cd9994e1af7b6c4c20e603c2021))
57
+ * add context id features ([#55](https://github.com/iotaledger/twin-entity-storage/issues/55)) ([99c15a2](https://github.com/iotaledger/twin-entity-storage/commit/99c15a257539b61d9da63649ce573ebf47699fc9))
58
+ * add production release automation ([1eb4c8e](https://github.com/iotaledger/twin-entity-storage/commit/1eb4c8ee3eb099defdfc2d063ae44935276dcae8))
59
+ * add support for connection timeout config ([96d0025](https://github.com/iotaledger/twin-entity-storage/commit/96d0025bc11d27138bfd845e0248ba19382c3fd9))
60
+ * add support for connection timeout config ([64f987e](https://github.com/iotaledger/twin-entity-storage/commit/64f987e1ddfd0f09cb24eb0bd5fc3739e9b58a00))
61
+ * add support for object comparison conditions ([eb505a1](https://github.com/iotaledger/twin-entity-storage/commit/eb505a17a3642e95c4e3cf137a77a0a8fb388c97))
62
+ * add synchronised to release configs ([e1e749c](https://github.com/iotaledger/twin-entity-storage/commit/e1e749cf261b58c8c36729686861e29c7d5e068e))
63
+ * add validate-locales ([e66ef0d](https://github.com/iotaledger/twin-entity-storage/commit/e66ef0de26ca2f82b3fe89bb5c7a15a0978a9644))
64
+ * adding schema migration functionality to all the connectors ([#85](https://github.com/iotaledger/twin-entity-storage/issues/85)) ([fd1555a](https://github.com/iotaledger/twin-entity-storage/commit/fd1555a34380158214a577586dafae821e72a578))
65
+ * additional information in health ([1e658b7](https://github.com/iotaledger/twin-entity-storage/commit/1e658b74288e9411538286d25b81823df80703e9))
66
+ * disable endpoint discovery for cosmos ([49df2a2](https://github.com/iotaledger/twin-entity-storage/commit/49df2a254f385dc42e2e1f7e26e71f89b5bf5bcf))
67
+ * entity storage enhancements ([#86](https://github.com/iotaledger/twin-entity-storage/issues/86)) ([1279af4](https://github.com/iotaledger/twin-entity-storage/commit/1279af42615c6497bb06539842cee44842dd1f75))
68
+ * eslint migration to flat config ([f033b64](https://github.com/iotaledger/twin-entity-storage/commit/f033b64984c0e6a8129d929c9dd816dcc1b8dab0))
69
+ * logging naming consistency ([f99d12d](https://github.com/iotaledger/twin-entity-storage/commit/f99d12dea04b6d4f2b5632ff5473e9ec7d5f9055))
70
+ * synchronised storage ([#44](https://github.com/iotaledger/twin-entity-storage/issues/44)) ([94e10e2](https://github.com/iotaledger/twin-entity-storage/commit/94e10e26d1feec801449dc04af7a9757ac7495ff))
71
+ * typescript 6 update ([995a0c6](https://github.com/iotaledger/twin-entity-storage/commit/995a0c6fa9a6813bfdc7200779ce3664236e59e9))
72
+ * update dependencies ([7ccc0c4](https://github.com/iotaledger/twin-entity-storage/commit/7ccc0c429125d073dc60b3de6cf101abc8cc6cba))
73
+ * update docs ([5203e62](https://github.com/iotaledger/twin-entity-storage/commit/5203e621c3ae368f6fefb29ea5146f024f4a1b0d))
74
+ * update framework core ([b59a380](https://github.com/iotaledger/twin-entity-storage/commit/b59a380bb7fba2b43610f69074dcdee24a4737da))
75
+ * use shared store mechanism ([#34](https://github.com/iotaledger/twin-entity-storage/issues/34)) ([68b6b71](https://github.com/iotaledger/twin-entity-storage/commit/68b6b71e7a96d7d016cd57bfff36775b56bf3f93))
76
+
77
+
78
+ ### Bug Fixes
79
+
80
+ * add missing dependency ([3282535](https://github.com/iotaledger/twin-entity-storage/commit/328253516e0d13b276406fb4de97dab8ee5e8ba7))
81
+ * add missing dependency ([2b848f3](https://github.com/iotaledger/twin-entity-storage/commit/2b848f3a345522c869b798d7a1cb64112dd8e3e3))
82
+ * adding tests and fixes for dot notation ([#76](https://github.com/iotaledger/twin-entity-storage/issues/76)) ([3879337](https://github.com/iotaledger/twin-entity-storage/commit/387933797e33543e4d8b2d49b8beeb792512a4ff))
83
+ * adding tests and support when neccesary for string include operator when needed ([#72](https://github.com/iotaledger/twin-entity-storage/issues/72)) ([3c723dd](https://github.com/iotaledger/twin-entity-storage/commit/3c723dd5694814398099d9d4594089dc6c66ba97))
84
+ * document AWS SDK pins for minimum release age consumers ([#96](https://github.com/iotaledger/twin-entity-storage/issues/96)) ([c4bcc26](https://github.com/iotaledger/twin-entity-storage/commit/c4bcc26f962da6f6bd090630f48d26ab58946c4e))
85
+ * dynamodb or conditions ([7a28b07](https://github.com/iotaledger/twin-entity-storage/commit/7a28b0702e03ec1fed04424136aca8a8c40cb28a))
86
+ * null secondary indexes ([#103](https://github.com/iotaledger/twin-entity-storage/issues/103)) ([5e44f11](https://github.com/iotaledger/twin-entity-storage/commit/5e44f11bb5af5bf2c27d6f1d56aba5851116ff89))
87
+ * query params force coercion ([dd6aa87](https://github.com/iotaledger/twin-entity-storage/commit/dd6aa87efdfb60bab7d6756a86888863c45c51a7))
88
+ * tests and fixes for the comparisons for null and undefined ([#79](https://github.com/iotaledger/twin-entity-storage/issues/79)) ([e7ffd62](https://github.com/iotaledger/twin-entity-storage/commit/e7ffd62e9ec40ef31498e6e2350bb25d9c84638a))
89
+
90
+
91
+ ### Dependencies
92
+
93
+ * The following workspace dependencies were updated
94
+ * dependencies
95
+ * @twin.org/entity-storage-models bumped from 0.0.3-next.18 to 0.0.3-next.19
96
+ * devDependencies
97
+ * @twin.org/entity-storage-connector-memory bumped from 0.0.3-next.18 to 0.0.3-next.19
98
+
99
+ ## [0.0.3-next.18](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-dynamodb-v0.0.3-next.17...entity-storage-connector-dynamodb-v0.0.3-next.18) (2026-06-01)
100
+
101
+
102
+ ### Features
103
+
104
+ * add AWS pod authentication mode ([caaae36](https://github.com/iotaledger/twin-entity-storage/commit/caaae368ca104cd9994e1af7b6c4c20e603c2021))
105
+ * add context id features ([#55](https://github.com/iotaledger/twin-entity-storage/issues/55)) ([99c15a2](https://github.com/iotaledger/twin-entity-storage/commit/99c15a257539b61d9da63649ce573ebf47699fc9))
106
+ * add production release automation ([1eb4c8e](https://github.com/iotaledger/twin-entity-storage/commit/1eb4c8ee3eb099defdfc2d063ae44935276dcae8))
107
+ * add support for connection timeout config ([96d0025](https://github.com/iotaledger/twin-entity-storage/commit/96d0025bc11d27138bfd845e0248ba19382c3fd9))
108
+ * add support for connection timeout config ([64f987e](https://github.com/iotaledger/twin-entity-storage/commit/64f987e1ddfd0f09cb24eb0bd5fc3739e9b58a00))
109
+ * add support for object comparison conditions ([eb505a1](https://github.com/iotaledger/twin-entity-storage/commit/eb505a17a3642e95c4e3cf137a77a0a8fb388c97))
110
+ * add synchronised to release configs ([e1e749c](https://github.com/iotaledger/twin-entity-storage/commit/e1e749cf261b58c8c36729686861e29c7d5e068e))
111
+ * add validate-locales ([e66ef0d](https://github.com/iotaledger/twin-entity-storage/commit/e66ef0de26ca2f82b3fe89bb5c7a15a0978a9644))
112
+ * adding schema migration functionality to all the connectors ([#85](https://github.com/iotaledger/twin-entity-storage/issues/85)) ([fd1555a](https://github.com/iotaledger/twin-entity-storage/commit/fd1555a34380158214a577586dafae821e72a578))
113
+ * additional information in health ([1e658b7](https://github.com/iotaledger/twin-entity-storage/commit/1e658b74288e9411538286d25b81823df80703e9))
114
+ * disable endpoint discovery for cosmos ([49df2a2](https://github.com/iotaledger/twin-entity-storage/commit/49df2a254f385dc42e2e1f7e26e71f89b5bf5bcf))
115
+ * entity storage enhancements ([#86](https://github.com/iotaledger/twin-entity-storage/issues/86)) ([1279af4](https://github.com/iotaledger/twin-entity-storage/commit/1279af42615c6497bb06539842cee44842dd1f75))
116
+ * eslint migration to flat config ([f033b64](https://github.com/iotaledger/twin-entity-storage/commit/f033b64984c0e6a8129d929c9dd816dcc1b8dab0))
117
+ * logging naming consistency ([f99d12d](https://github.com/iotaledger/twin-entity-storage/commit/f99d12dea04b6d4f2b5632ff5473e9ec7d5f9055))
118
+ * synchronised storage ([#44](https://github.com/iotaledger/twin-entity-storage/issues/44)) ([94e10e2](https://github.com/iotaledger/twin-entity-storage/commit/94e10e26d1feec801449dc04af7a9757ac7495ff))
119
+ * typescript 6 update ([995a0c6](https://github.com/iotaledger/twin-entity-storage/commit/995a0c6fa9a6813bfdc7200779ce3664236e59e9))
120
+ * update dependencies ([7ccc0c4](https://github.com/iotaledger/twin-entity-storage/commit/7ccc0c429125d073dc60b3de6cf101abc8cc6cba))
121
+ * update docs ([5203e62](https://github.com/iotaledger/twin-entity-storage/commit/5203e621c3ae368f6fefb29ea5146f024f4a1b0d))
122
+ * update framework core ([b59a380](https://github.com/iotaledger/twin-entity-storage/commit/b59a380bb7fba2b43610f69074dcdee24a4737da))
123
+ * use shared store mechanism ([#34](https://github.com/iotaledger/twin-entity-storage/issues/34)) ([68b6b71](https://github.com/iotaledger/twin-entity-storage/commit/68b6b71e7a96d7d016cd57bfff36775b56bf3f93))
124
+
125
+
126
+ ### Bug Fixes
127
+
128
+ * add missing dependency ([3282535](https://github.com/iotaledger/twin-entity-storage/commit/328253516e0d13b276406fb4de97dab8ee5e8ba7))
129
+ * add missing dependency ([2b848f3](https://github.com/iotaledger/twin-entity-storage/commit/2b848f3a345522c869b798d7a1cb64112dd8e3e3))
130
+ * adding tests and fixes for dot notation ([#76](https://github.com/iotaledger/twin-entity-storage/issues/76)) ([3879337](https://github.com/iotaledger/twin-entity-storage/commit/387933797e33543e4d8b2d49b8beeb792512a4ff))
131
+ * adding tests and support when neccesary for string include operator when needed ([#72](https://github.com/iotaledger/twin-entity-storage/issues/72)) ([3c723dd](https://github.com/iotaledger/twin-entity-storage/commit/3c723dd5694814398099d9d4594089dc6c66ba97))
132
+ * document AWS SDK pins for minimum release age consumers ([#96](https://github.com/iotaledger/twin-entity-storage/issues/96)) ([c4bcc26](https://github.com/iotaledger/twin-entity-storage/commit/c4bcc26f962da6f6bd090630f48d26ab58946c4e))
133
+ * dynamodb or conditions ([7a28b07](https://github.com/iotaledger/twin-entity-storage/commit/7a28b0702e03ec1fed04424136aca8a8c40cb28a))
134
+ * null secondary indexes ([#103](https://github.com/iotaledger/twin-entity-storage/issues/103)) ([5e44f11](https://github.com/iotaledger/twin-entity-storage/commit/5e44f11bb5af5bf2c27d6f1d56aba5851116ff89))
135
+ * query params force coercion ([dd6aa87](https://github.com/iotaledger/twin-entity-storage/commit/dd6aa87efdfb60bab7d6756a86888863c45c51a7))
136
+ * tests and fixes for the comparisons for null and undefined ([#79](https://github.com/iotaledger/twin-entity-storage/issues/79)) ([e7ffd62](https://github.com/iotaledger/twin-entity-storage/commit/e7ffd62e9ec40ef31498e6e2350bb25d9c84638a))
137
+
138
+
139
+ ### Dependencies
140
+
141
+ * The following workspace dependencies were updated
142
+ * dependencies
143
+ * @twin.org/entity-storage-models bumped from 0.0.3-next.17 to 0.0.3-next.18
144
+ * devDependencies
145
+ * @twin.org/entity-storage-connector-memory bumped from 0.0.3-next.17 to 0.0.3-next.18
146
+
147
+ ## [0.0.3-next.17](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-dynamodb-v0.0.3-next.16...entity-storage-connector-dynamodb-v0.0.3-next.17) (2026-06-01)
148
+
149
+
150
+ ### Bug Fixes
151
+
152
+ * null secondary indexes ([#103](https://github.com/iotaledger/twin-entity-storage/issues/103)) ([5e44f11](https://github.com/iotaledger/twin-entity-storage/commit/5e44f11bb5af5bf2c27d6f1d56aba5851116ff89))
153
+
154
+
155
+ ### Dependencies
156
+
157
+ * The following workspace dependencies were updated
158
+ * dependencies
159
+ * @twin.org/entity-storage-models bumped from 0.0.3-next.16 to 0.0.3-next.17
160
+ * devDependencies
161
+ * @twin.org/entity-storage-connector-memory bumped from 0.0.3-next.16 to 0.0.3-next.17
162
+
3
163
  ## [0.0.3-next.16](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-dynamodb-v0.0.3-next.15...entity-storage-connector-dynamodb-v0.0.3-next.16) (2026-05-20)
4
164
 
5
165
 
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@twin.org/entity-storage-connector-dynamodb",
3
- "version": "0.0.3-next.16",
3
+ "version": "0.0.3-next.20",
4
4
  "description": "Amazon DynamoDB connector for managed NoSQL persistence.",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "git+https://github.com/iotaledger/entity-storage.git",
7
+ "url": "git+https://github.com/iotaledger/twin-entity-storage.git",
8
8
  "directory": "packages/entity-storage-connector-dynamodb"
9
9
  },
10
10
  "author": "martyn.janes@iota.org",
@@ -20,7 +20,7 @@
20
20
  "@twin.org/context": "next",
21
21
  "@twin.org/core": "next",
22
22
  "@twin.org/entity": "next",
23
- "@twin.org/entity-storage-models": "0.0.3-next.16",
23
+ "@twin.org/entity-storage-models": "0.0.3-next.20",
24
24
  "@twin.org/logging-models": "next",
25
25
  "@twin.org/nameof": "next"
26
26
  },
@@ -56,7 +56,7 @@
56
56
  "integration"
57
57
  ],
58
58
  "bugs": {
59
- "url": "git+https://github.com/iotaledger/entity-storage/issues"
59
+ "url": "git+https://github.com/iotaledger/twin-entity-storage/issues"
60
60
  },
61
61
  "homepage": "https://twindev.org"
62
62
  }