@twin.org/entity-storage-connector-cosmosdb 0.9.2-next.7 → 0.9.2-next.8

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.
@@ -3,9 +3,9 @@
3
3
  import { BulkOperationType, CosmosClient, PartitionKeyKind } from "@azure/cosmos";
4
4
  import { HealthCategory, HealthStatus } from "@twin.org/api-models";
5
5
  import { ContextIdHelper, ContextIdStore } from "@twin.org/context";
6
- import { BaseError, Coerce, ComponentFactory, ConflictError, GeneralError, Guards, Is, Mutex, ObjectHelper, Validation } from "@twin.org/core";
6
+ import { BaseError, Coerce, ComponentFactory, ConflictError, GeneralError, Guards, Is, Mutex, ObjectHelper, RandomHelper, Validation } from "@twin.org/core";
7
7
  import { ComparisonOperator, EntitySchemaFactory, EntitySchemaHelper, LogicalOperator, SortDirection } from "@twin.org/entity";
8
- import { EntityStorageHelper } from "@twin.org/entity-storage-models";
8
+ import { ConnectionHelper, EntityStorageHelper } from "@twin.org/entity-storage-models";
9
9
  /**
10
10
  * Class for performing entity storage operations using Cosmos DB.
11
11
  */
@@ -29,6 +29,16 @@ export class CosmosDbEntityStorageConnector {
29
29
  * @internal
30
30
  */
31
31
  static _PARTITION_KEY_VALUE = "root";
32
+ /**
33
+ * Batch chunk size for bulk write operations.
34
+ * @internal
35
+ */
36
+ static _BATCH_CHUNK_SIZE = 1000;
37
+ /**
38
+ * Number of bulk operation chunks to dispatch concurrently in setBatch.
39
+ * @internal
40
+ */
41
+ static _WRITE_CONCURRENCY = 10;
32
42
  /**
33
43
  * The name for the schema.
34
44
  * @internal
@@ -65,15 +75,10 @@ export class CosmosDbEntityStorageConnector {
65
75
  */
66
76
  _mutexTimeoutMs;
67
77
  /**
68
- * The Cosmos DB client.
78
+ * Unique identifier for this connector instance, used to track references in SharedStore.
69
79
  * @internal
70
80
  */
71
- _client;
72
- /**
73
- * Container user for the data storage.
74
- * @internal
75
- */
76
- _container;
81
+ _instanceId;
77
82
  /**
78
83
  * Create a new instance of CosmosDbEntityStorageConnector.
79
84
  * @param options The options for the connector.
@@ -93,16 +98,15 @@ export class CosmosDbEntityStorageConnector {
93
98
  this._versionKey = EntitySchemaHelper.findVersionProperty(this._entitySchema);
94
99
  this._config = options.config;
95
100
  this._mutexTimeoutMs = Coerce.integer(options.config.mutexTimeoutMs);
96
- this._client = new CosmosClient({
97
- endpoint: this._config.endpoint,
98
- key: this._config.key,
99
- connectionPolicy: {
100
- enableEndpointDiscovery: !this._config.disableEndpointDiscovery
101
- }
102
- });
103
- this._container = this._client
104
- .database(this._config.databaseId)
105
- .container(this._config.containerId);
101
+ this._instanceId = RandomHelper.generateUuidV7("compact");
102
+ }
103
+ /**
104
+ * The component needs to be stopped when the node is closed.
105
+ * @param nodeLoggingComponentType The node logging component type.
106
+ * @returns Nothing.
107
+ */
108
+ async stop(nodeLoggingComponentType) {
109
+ await ConnectionHelper.closeClient("cosmosDbClients", this.createClientId(), this._instanceId, this._mutexTimeoutMs, async (client) => client.dispose());
106
110
  }
107
111
  /**
108
112
  * Initialize the Cosmos DB environment.
@@ -111,6 +115,7 @@ export class CosmosDbEntityStorageConnector {
111
115
  */
112
116
  async bootstrap(nodeLoggingComponentType) {
113
117
  const nodeLogging = ComponentFactory.getIfExists(nodeLoggingComponentType);
118
+ const client = await this.getClient();
114
119
  // Create the database if it does not exist
115
120
  try {
116
121
  const databaseExists = await this.databaseExists();
@@ -135,7 +140,7 @@ export class CosmosDbEntityStorageConnector {
135
140
  databaseId: this._config.databaseId
136
141
  }
137
142
  });
138
- await this._client.databases.create({
143
+ await client.databases.create({
139
144
  id: this._config.databaseId
140
145
  });
141
146
  await this.waitForDatabaseExists();
@@ -178,7 +183,7 @@ export class CosmosDbEntityStorageConnector {
178
183
  containerId: this._config.containerId
179
184
  }
180
185
  });
181
- await this._client.database(this._config.databaseId).containers.create({
186
+ await client.database(this._config.databaseId).containers.create({
182
187
  id: this._config.containerId,
183
188
  partitionKey: {
184
189
  kind: PartitionKeyKind.Hash,
@@ -217,10 +222,8 @@ export class CosmosDbEntityStorageConnector {
217
222
  */
218
223
  async health() {
219
224
  try {
220
- await this._client
221
- .database(this._config.databaseId)
222
- .container(this._config.containerId)
223
- .read();
225
+ const container = await this.getContainer();
226
+ await container.read();
224
227
  return [
225
228
  {
226
229
  source: CosmosDbEntityStorageConnector.CLASS_NAME,
@@ -264,9 +267,10 @@ export class CosmosDbEntityStorageConnector {
264
267
  const contextIds = await ContextIdStore.getContextIds();
265
268
  const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
266
269
  try {
270
+ const container = await this.getContainer();
267
271
  // No secondary index or conditions
268
272
  if (Is.empty(secondaryIndex) && !Is.arrayValue(conditions)) {
269
- const { resource: item } = await this._container
273
+ const { resource: item } = await container
270
274
  .item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE)
271
275
  .read();
272
276
  if (Is.empty(item)) {
@@ -305,7 +309,7 @@ export class CosmosDbEntityStorageConnector {
305
309
  query: `SELECT * FROM c WHERE ${whereQuery.join(" AND ")}`,
306
310
  parameters: conditionValues
307
311
  };
308
- const { resources: items } = await this._container.items.query(query).fetchAll();
312
+ const { resources: items } = await container.items.query(query).fetchAll();
309
313
  if (items.length === 1) {
310
314
  return this.itemToEntity(items[0]);
311
315
  }
@@ -351,9 +355,10 @@ export class CosmosDbEntityStorageConnector {
351
355
  });
352
356
  }
353
357
  try {
358
+ const container = await this.getContainer();
354
359
  let itemEtag;
355
360
  if (Is.stringValue(this._versionKey) || Is.arrayValue(conditions)) {
356
- const item = this._container.item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE);
361
+ const item = container.item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE);
357
362
  const { resource: itemData } = await item.read();
358
363
  if (!Is.empty(itemData)) {
359
364
  if (hasVersionCheck) {
@@ -377,7 +382,7 @@ export class CosmosDbEntityStorageConnector {
377
382
  ObjectHelper.propertySet(prepared, this._versionKey, storedVersion + 1);
378
383
  }
379
384
  }
380
- await this._container.items.upsert({
385
+ await container.items.upsert({
381
386
  id,
382
387
  [CosmosDbEntityStorageConnector._PARTITION_KEY]: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE,
383
388
  ...prepared
@@ -423,15 +428,30 @@ export class CosmosDbEntityStorageConnector {
423
428
  nullBehavior: "omit"
424
429
  }));
425
430
  try {
426
- await this._container.items.executeBulkOperations(preparedEntities.map(prepared => ({
427
- operationType: BulkOperationType.Upsert,
428
- partitionKey: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE,
429
- resourceBody: {
430
- id: prepared[this._primaryKey.property],
431
- [CosmosDbEntityStorageConnector._PARTITION_KEY]: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE,
432
- ...prepared
431
+ const container = await this.getContainer();
432
+ const pk = partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;
433
+ const chunkSize = CosmosDbEntityStorageConnector._BATCH_CHUNK_SIZE;
434
+ const concurrency = CosmosDbEntityStorageConnector._WRITE_CONCURRENCY;
435
+ const windowSize = chunkSize * concurrency;
436
+ for (let offset = 0; offset < preparedEntities.length; offset += windowSize) {
437
+ const window = preparedEntities.slice(offset, offset + windowSize);
438
+ const sends = [];
439
+ for (let j = 0; j < window.length; j += chunkSize) {
440
+ const chunk = window.slice(j, j + chunkSize);
441
+ sends.push((async () => {
442
+ await container.items.executeBulkOperations(chunk.map(prepared => ({
443
+ operationType: BulkOperationType.Upsert,
444
+ partitionKey: pk,
445
+ resourceBody: {
446
+ id: prepared[this._primaryKey.property],
447
+ [CosmosDbEntityStorageConnector._PARTITION_KEY]: pk,
448
+ ...prepared
449
+ }
450
+ })));
451
+ })());
433
452
  }
434
- })));
453
+ await Promise.all(sends);
454
+ }
435
455
  }
436
456
  catch (err) {
437
457
  throw new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, "setBatchFailed", undefined, err);
@@ -446,10 +466,11 @@ export class CosmosDbEntityStorageConnector {
446
466
  const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
447
467
  const pk = partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;
448
468
  try {
469
+ const container = await this.getContainer();
449
470
  let continuationToken;
450
471
  do {
451
472
  const feedOptions = { maxItemCount: 100, continuationToken };
452
- const { resources, continuationToken: nextToken } = await this._container.items
473
+ const { resources, continuationToken: nextToken } = await container.items
453
474
  .query({
454
475
  query: `SELECT c.id FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @pk`,
455
476
  parameters: [{ name: "@pk", value: pk }]
@@ -462,7 +483,7 @@ export class CosmosDbEntityStorageConnector {
462
483
  id: r.id,
463
484
  partitionKey: pk
464
485
  }));
465
- await this._container.items.executeBulkOperations(operations);
486
+ await container.items.executeBulkOperations(operations);
466
487
  }
467
488
  } while (Is.stringValue(continuationToken));
468
489
  }
@@ -491,7 +512,8 @@ export class CosmosDbEntityStorageConnector {
491
512
  });
492
513
  }
493
514
  try {
494
- const item = this._container.item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE);
515
+ const container = await this.getContainer();
516
+ const item = container.item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE);
495
517
  const { resource: itemData } = await item.read();
496
518
  if (Is.notEmpty(itemData)) {
497
519
  if (Is.arrayValue(conditions) && !this.verifyConditions(conditions, itemData)) {
@@ -532,12 +554,13 @@ export class CosmosDbEntityStorageConnector {
532
554
  const contextIds = await ContextIdStore.getContextIds();
533
555
  const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
534
556
  try {
557
+ const container = await this.getContainer();
535
558
  const operations = ids.map(id => ({
536
559
  operationType: BulkOperationType.Delete,
537
560
  id,
538
561
  partitionKey: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE
539
562
  }));
540
- await this._container.items.executeBulkOperations(operations);
563
+ await container.items.executeBulkOperations(operations);
541
564
  }
542
565
  catch (err) {
543
566
  throw new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, "removeBatchFailed", undefined, err);
@@ -558,8 +581,9 @@ export class CosmosDbEntityStorageConnector {
558
581
  data: { containerId: this._config.containerId }
559
582
  });
560
583
  try {
584
+ const container = await this.getContainer();
561
585
  if (await this.containerExists()) {
562
- await this._container.delete();
586
+ await container.delete();
563
587
  await this.waitForContainerNotExists();
564
588
  }
565
589
  await nodeLogging?.log({
@@ -615,6 +639,7 @@ export class CosmosDbEntityStorageConnector {
615
639
  Validation.asValidationError(CosmosDbEntityStorageConnector.CLASS_NAME, "query", validationFailures);
616
640
  }
617
641
  try {
642
+ const container = await this.getContainer();
618
643
  const returnSize = limit ?? CosmosDbEntityStorageConnector._DEFAULT_LIMIT;
619
644
  let orderByClause = "";
620
645
  if (Is.arrayValue(sortProperties)) {
@@ -650,7 +675,7 @@ export class CosmosDbEntityStorageConnector {
650
675
  const startIndex = Coerce.number(cursor) ?? 0;
651
676
  sql = `${baseQuery} ${orderByClause} OFFSET ${startIndex} LIMIT ${returnSize + 1}`;
652
677
  const sortedQuerySpecs = { query: sql, parameters: queryParameters };
653
- const sortedResponse = await this._container.items
678
+ const sortedResponse = await container.items
654
679
  .query(sortedQuerySpecs, {
655
680
  partitionKey: queryPartitionKey,
656
681
  maxItemCount: returnSize + 1
@@ -675,6 +700,7 @@ export class CosmosDbEntityStorageConnector {
675
700
  async count(conditions) {
676
701
  EntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);
677
702
  try {
703
+ const container = await this.getContainer();
678
704
  const contextIds = await ContextIdStore.getContextIds();
679
705
  const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
680
706
  const attributeNames = {};
@@ -695,7 +721,7 @@ export class CosmosDbEntityStorageConnector {
695
721
  ...Object.keys(attributeValues).map(key => ({ name: `@${key}`, value: attributeValues[key] }))
696
722
  ]
697
723
  };
698
- const { resources } = await this._container.items.query(querySpec).fetchAll();
724
+ const { resources } = await container.items.query(querySpec).fetchAll();
699
725
  return resources[0] ?? 0;
700
726
  }
701
727
  catch (err) {
@@ -712,7 +738,8 @@ export class CosmosDbEntityStorageConnector {
712
738
  return undefined;
713
739
  }
714
740
  try {
715
- const { resources: partitionIds } = await this._container.items
741
+ const container = await this.getContainer();
742
+ const { resources: partitionIds } = await container.items
716
743
  .query({
717
744
  query: `SELECT DISTINCT VALUE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} FROM c`
718
745
  })
@@ -725,6 +752,13 @@ export class CosmosDbEntityStorageConnector {
725
752
  throw new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, "getPartitionContextIdsFailed", undefined, err);
726
753
  }
727
754
  }
755
+ /**
756
+ * Get the connector implementation version.
757
+ * @returns The connector implementation version.
758
+ */
759
+ connectorVersion() {
760
+ return 0;
761
+ }
728
762
  /**
729
763
  * Create the target connector for performing the migration using a temporary container.
730
764
  * @param newEntitySchema The name of the new entity schema to create the connector for.
@@ -802,7 +836,7 @@ export class CosmosDbEntityStorageConnector {
802
836
  let continuationToken;
803
837
  do {
804
838
  const feedOptions = { maxItemCount: batchSize, continuationToken };
805
- const { resources, continuationToken: nextToken } = await sourceConnector._container.items
839
+ const { resources, continuationToken: nextToken } = await (await sourceConnector.getContainer()).items
806
840
  .query({
807
841
  query: `SELECT * FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionId`,
808
842
  parameters: [{ name: "@partitionId", value: partitionKey }]
@@ -815,7 +849,7 @@ export class CosmosDbEntityStorageConnector {
815
849
  partitionKey,
816
850
  resourceBody: rest
817
851
  }));
818
- await destConnector._container.items.executeBulkOperations(operations);
852
+ await (await destConnector.getContainer()).items.executeBulkOperations(operations);
819
853
  }
820
854
  } while (Is.stringValue(continuationToken));
821
855
  }
@@ -1069,6 +1103,38 @@ export class CosmosDbEntityStorageConnector {
1069
1103
  "_ts"
1070
1104
  ]);
1071
1105
  }
1106
+ /**
1107
+ * Retrieve (or lazily create) the shared Cosmos DB client for this endpoint.
1108
+ * @returns The shared client.
1109
+ * @internal
1110
+ */
1111
+ async getClient() {
1112
+ return ConnectionHelper.openClient("cosmosDbClients", this.createClientId(), this._instanceId, this._mutexTimeoutMs, async () => new CosmosClient({
1113
+ endpoint: this._config.endpoint,
1114
+ key: this._config.key,
1115
+ connectionPolicy: {
1116
+ enableEndpointDiscovery: !this._config.disableEndpointDiscovery
1117
+ }
1118
+ }));
1119
+ }
1120
+ /**
1121
+ * Get the container for this connector's configured database and container.
1122
+ * @returns The container reference.
1123
+ * @internal
1124
+ */
1125
+ async getContainer() {
1126
+ return (await this.getClient())
1127
+ .database(this._config.databaseId)
1128
+ .container(this._config.containerId);
1129
+ }
1130
+ /**
1131
+ * Build a stable cache key for the shared client based on connection parameters.
1132
+ * @returns The client cache key.
1133
+ * @internal
1134
+ */
1135
+ createClientId() {
1136
+ return `${this._config.endpoint}|${this._config.databaseId}|${this._config.containerId}`;
1137
+ }
1072
1138
  /**
1073
1139
  * Check if the database exists.
1074
1140
  * @returns True if the database exists, false otherwise.
@@ -1076,7 +1142,8 @@ export class CosmosDbEntityStorageConnector {
1076
1142
  */
1077
1143
  async databaseExists() {
1078
1144
  try {
1079
- const { resources: databaseList } = await this._client.databases.readAll().fetchAll();
1145
+ const client = await this.getClient();
1146
+ const { resources: databaseList } = await client.databases.readAll().fetchAll();
1080
1147
  return databaseList.some((db) => db.id === this._config.databaseId);
1081
1148
  }
1082
1149
  catch {
@@ -1139,7 +1206,8 @@ export class CosmosDbEntityStorageConnector {
1139
1206
  */
1140
1207
  async containerExists() {
1141
1208
  try {
1142
- const { resources: containers } = await this._client
1209
+ const client = await this.getClient();
1210
+ const { resources: containers } = await client
1143
1211
  .database(this._config.databaseId)
1144
1212
  .containers.readAll()
1145
1213
  .fetchAll();
@@ -1 +1 @@
1
- {"version":3,"file":"cosmosDbEntityStorageConnector.js","sourceRoot":"","sources":["../../src/cosmosDbEntityStorageConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tBulkOperationType,\n\ttype CompositePath,\n\ttype Container,\n\tCosmosClient,\n\ttype FeedOptions,\n\ttype IndexingPolicy,\n\ttype ItemDefinition,\n\ttype JSONValue,\n\ttype OperationInput,\n\tPartitionKeyKind,\n\ttype Resource,\n\ttype SqlParameter,\n\ttype SqlQuerySpec\n} from \"@azure/cosmos\";\nimport {\n\tHealthCategory,\n\tHealthStatus,\n\ttype IHealth,\n\ttype IHealthProviderComponent\n} from \"@twin.org/api-models\";\nimport { ContextIdHelper, ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tCoerce,\n\tComponentFactory,\n\tConflictError,\n\tGeneralError,\n\tGuards,\n\tIs,\n\tMutex,\n\ttype IValidationFailure,\n\tObjectHelper,\n\tValidation\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 { ICosmosDbEntityStorageConnectorConfig } from \"./models/ICosmosDbEntityStorageConnectorConfig.js\";\nimport type { ICosmosDbEntityStorageConnectorConstructorOptions } from \"./models/ICosmosDbEntityStorageConnectorConstructorOptions.js\";\n\n/**\n * Class for performing entity storage operations using Cosmos DB.\n */\nexport class CosmosDbEntityStorageConnector<T = unknown>\n\timplements IEntityStorageMigrationConnector<T>, IHealthProviderComponent\n{\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<CosmosDbEntityStorageConnector>();\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 name of the version property, if any.\n\t * @internal\n\t */\n\tprivate readonly _versionKey?: string;\n\n\t/**\n\t * The configuration for the connector.\n\t * @internal\n\t */\n\tprivate readonly _config: ICosmosDbEntityStorageConnectorConfig;\n\n\t/**\n\t * Milliseconds to wait for optimistic-lock mutexes before throwing.\n\t * @internal\n\t */\n\tprivate readonly _mutexTimeoutMs?: number;\n\n\t/**\n\t * The Cosmos DB client.\n\t * @internal\n\t */\n\tprivate readonly _client: CosmosClient;\n\n\t/**\n\t * Container user for the data storage.\n\t * @internal\n\t */\n\tprivate readonly _container: Container;\n\n\t/**\n\t * Create a new instance of CosmosDbEntityStorageConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: ICosmosDbEntityStorageConnectorConstructorOptions) {\n\t\tGuards.object(CosmosDbEntityStorageConnector.CLASS_NAME, nameof(options), options);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.entitySchema),\n\t\t\toptions.entitySchema\n\t\t);\n\t\tGuards.object<ICosmosDbEntityStorageConnectorConfig>(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.endpoint),\n\t\t\toptions.config.endpoint\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.key),\n\t\t\toptions.config.key\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.databaseId),\n\t\t\toptions.config.databaseId\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.containerId),\n\t\t\toptions.config.containerId\n\t\t);\n\n\t\tthis._entitySchema = EntitySchemaFactory.get(options.entitySchema);\n\t\tthis._entitySchemaName = options.entitySchema;\n\t\tthis._partitionContextIds = options.partitionContextIds;\n\n\t\tthis._primaryKey = EntitySchemaHelper.getPrimaryKey<T>(this._entitySchema);\n\t\tthis._versionKey = EntitySchemaHelper.findVersionProperty(this._entitySchema);\n\n\t\tthis._config = options.config;\n\t\tthis._mutexTimeoutMs = Coerce.integer(options.config.mutexTimeoutMs);\n\n\t\tthis._client = new CosmosClient({\n\t\t\tendpoint: this._config.endpoint,\n\t\t\tkey: this._config.key,\n\t\t\tconnectionPolicy: {\n\t\t\t\tenableEndpointDiscovery: !this._config.disableEndpointDiscovery\n\t\t\t}\n\t\t});\n\n\t\tthis._container = this._client\n\t\t\t.database(this._config.databaseId)\n\t\t\t.container(this._config.containerId);\n\t}\n\n\t/**\n\t * Initialize the Cosmos DB environment.\n\t * @param nodeLoggingComponentType Optional type of the logging component.\n\t * @returns A promise that resolves to a boolean indicating success.\n\t */\n\tpublic async bootstrap(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\t// Create the database if it does not exist\n\t\ttry {\n\t\t\tconst databaseExists = await this.databaseExists();\n\n\t\t\tif (databaseExists) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"databaseExists\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdatabaseId: this._config.databaseId\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"databaseCreating\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdatabaseId: this._config.databaseId\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tawait this._client.databases.create({\n\t\t\t\t\tid: this._config.databaseId\n\t\t\t\t});\n\n\t\t\t\tawait this.waitForDatabaseExists();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"databaseCreateFailed\",\n\t\t\t\terror: BaseError.fromError(error),\n\t\t\t\tdata: {\n\t\t\t\t\tdatabaseId: this._config.databaseId\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\t// Create the container if it does not exist\n\t\ttry {\n\t\t\tconst containerExists = await this.containerExists();\n\n\t\t\tif (containerExists) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"containerExists\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tcontainerId: this._config.containerId\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"containerCreating\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tcontainerId: this._config.containerId\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tawait this._client.database(this._config.databaseId).containers.create(\n\t\t\t\t\t{\n\t\t\t\t\t\tid: this._config.containerId,\n\t\t\t\t\t\tpartitionKey: {\n\t\t\t\t\t\t\tkind: PartitionKeyKind.Hash,\n\t\t\t\t\t\t\tpaths: [`/${CosmosDbEntityStorageConnector._PARTITION_KEY}`]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tindexingPolicy: this.buildIndexingPolicy()\n\t\t\t\t\t},\n\t\t\t\t\t{ offerThroughput: this._config.offerThroughput }\n\t\t\t\t);\n\n\t\t\t\tawait this.waitForContainerExists();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"containerCreateFailed\",\n\t\t\t\terror: BaseError.fromError(error),\n\t\t\t\tdata: {\n\t\t\t\t\tcontainerId: this._config.containerId\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\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 CosmosDbEntityStorageConnector.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\tawait this._client\n\t\t\t\t.database(this._config.databaseId)\n\t\t\t\t.container(this._config.containerId)\n\t\t\t\t.read();\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tcategory: HealthCategory.Connectivity,\n\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tdata: { databaseId: this._config.databaseId, containerId: this._config.containerId }\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: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tcategory: HealthCategory.Connectivity,\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: { databaseId: this._config.databaseId, containerId: this._config.containerId }\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 * Get an entity from Cosmos DB.\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(CosmosDbEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\ttry {\n\t\t\t// No secondary index or conditions\n\t\t\tif (Is.empty(secondaryIndex) && !Is.arrayValue(conditions)) {\n\t\t\t\tconst { resource: item } = await this._container\n\t\t\t\t\t.item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE)\n\t\t\t\t\t.read<ItemDefinition>();\n\t\t\t\tif (Is.empty(item)) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\treturn this.itemToEntity(item);\n\t\t\t}\n\n\t\t\tconst conditionValues: SqlParameter[] = [];\n\n\t\t\tconst whereQuery: string[] = [\n\t\t\t\t`c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionKey`\n\t\t\t];\n\t\t\tconditionValues.push({\n\t\t\t\tname: \"@partitionKey\",\n\t\t\t\tvalue: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t});\n\n\t\t\t// With a secondary index\n\t\t\tif (Is.stringValue(secondaryIndex)) {\n\t\t\t\tconst secIndex = secondaryIndex.toString();\n\t\t\t\twhereQuery.push(`c.${secIndex} = @id`);\n\t\t\t} else {\n\t\t\t\twhereQuery.push(`c.${this._primaryKey.property as string} = @id`);\n\t\t\t}\n\t\t\tconditionValues.push({ name: \"@id\", value: id });\n\n\t\t\t// With conditions\n\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\tfor (const c of conditions) {\n\t\t\t\t\twhereQuery.push(`c.${c.property as string} = @${c.property as string}`);\n\t\t\t\t\tconditionValues.push({\n\t\t\t\t\t\tname: `@${c.property as string}`,\n\t\t\t\t\t\tvalue: c.value as JSONValue\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst query: SqlQuerySpec = {\n\t\t\t\tquery: `SELECT * FROM c WHERE ${whereQuery.join(\" AND \")}`,\n\t\t\t\tparameters: conditionValues\n\t\t\t};\n\n\t\t\tconst { resources: items } = await this._container.items.query(query).fetchAll();\n\n\t\t\tif (items.length === 1) {\n\t\t\t\treturn this.itemToEntity(items[0]);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"NotFound\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"containerDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcontainerId: this._config.containerId\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\tCosmosDbEntityStorageConnector.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\treturn undefined;\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>(CosmosDbEntityStorageConnector.CLASS_NAME, nameof(entity), entity);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst submittedVersion = Is.stringValue(this._versionKey)\n\t\t\t? ObjectHelper.propertyGet<number>(entity, this._versionKey)\n\t\t\t: undefined;\n\t\tconst hasVersionCheck =\n\t\t\t!Is.empty(this._versionKey) && !Is.empty(submittedVersion) && submittedVersion > 0;\n\n\t\tconst prepared = EntityStorageHelper.prepareEntity(entity, this._entitySchema, undefined, {\n\t\t\tnullBehavior: \"omit\"\n\t\t});\n\n\t\tconst id = prepared[this._primaryKey.property] as string;\n\t\tconst optimisticMutexKey = Is.stringValue(this._versionKey)\n\t\t\t? this.buildOptimisticMutexKey(partitionKey, id)\n\t\t\t: undefined;\n\n\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\tawait Mutex.lock(optimisticMutexKey, {\n\t\t\t\tthrowOnTimeout: true,\n\t\t\t\ttimeoutMs: this._mutexTimeoutMs\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tlet itemEtag: string | undefined;\n\n\t\t\tif (Is.stringValue(this._versionKey) || Is.arrayValue(conditions)) {\n\t\t\t\tconst item = this._container.item(\n\t\t\t\t\tid,\n\t\t\t\t\tpartitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t);\n\t\t\t\tconst { resource: itemData } = await item.read<ItemDefinition>();\n\t\t\t\tif (!Is.empty(itemData)) {\n\t\t\t\t\tif (hasVersionCheck) {\n\t\t\t\t\t\tconst storedVersion = ObjectHelper.propertyGet<number>(itemData, this._versionKey) ?? 0;\n\t\t\t\t\t\tif (storedVersion !== submittedVersion) {\n\t\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\t\"optimisticLockFailed\",\n\t\t\t\t\t\t\t\tid\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\tif (Is.arrayValue(conditions) && !this.verifyConditions(conditions, itemData as T)) {\n\t\t\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\t\tid\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\titemEtag = ObjectHelper.propertyGet(itemData, \"_etag\");\n\t\t\t\t}\n\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\tconst storedVersion = !Is.empty(itemData)\n\t\t\t\t\t\t? (ObjectHelper.propertyGet<number>(itemData, this._versionKey) ?? 0)\n\t\t\t\t\t\t: 0;\n\t\t\t\t\tObjectHelper.propertySet(prepared, this._versionKey, storedVersion + 1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait this._container.items.upsert(\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\t[CosmosDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\tpartitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\t\t...prepared\n\t\t\t\t},\n\t\t\t\tIs.stringValue(itemEtag)\n\t\t\t\t\t? { accessCondition: { type: \"IfMatch\", condition: itemEtag } }\n\t\t\t\t\t: undefined\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tif (Is.object<{ code?: number }>(err) && err.code === 412) {\n\t\t\t\tthrow new ConflictError(\n\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"optimisticLockFailed\",\n\t\t\t\t\tid\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (BaseError.isAggregateError(err)) {\n\t\t\t\tconst errors = BaseError.fromAggregate(err);\n\t\t\t\tif (BaseError.someErrorCode(errors, \"ResourceNotFoundException\")) {\n\t\t\t\t\tthrow new GeneralError(\n\t\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\"containerDoesNotExist\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontainerId: this._config.containerId\n\t\t\t\t\t\t},\n\t\t\t\t\t\terr\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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} finally {\n\t\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\t\tMutex.unlock(optimisticMutexKey);\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(CosmosDbEntityStorageConnector.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(entity, this._entitySchema, undefined, {\n\t\t\t\tnullBehavior: \"omit\"\n\t\t\t})\n\t\t);\n\n\t\ttry {\n\t\t\tawait this._container.items.executeBulkOperations(\n\t\t\t\tpreparedEntities.map(\n\t\t\t\t\tprepared =>\n\t\t\t\t\t\t({\n\t\t\t\t\t\t\toperationType: BulkOperationType.Upsert,\n\t\t\t\t\t\t\tpartitionKey: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\t\t\t\tresourceBody: {\n\t\t\t\t\t\t\t\tid: prepared[this._primaryKey.property] as string,\n\t\t\t\t\t\t\t\t[CosmosDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\t\t\t\tpartitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\t\t\t\t\t...(prepared as { [key: string]: unknown })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}) as OperationInput\n\t\t\t\t)\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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 all entities from the storage.\n\t * @returns Nothing.\n\t */\n\tpublic async empty(): Promise<void> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\t\tconst pk = partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\ttry {\n\t\t\tlet continuationToken: string | undefined;\n\t\t\tdo {\n\t\t\t\tconst feedOptions: FeedOptions = { maxItemCount: 100, continuationToken };\n\t\t\t\tconst { resources, continuationToken: nextToken } = await this._container.items\n\t\t\t\t\t.query<{ id: string }>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tquery: `SELECT c.id FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @pk`,\n\t\t\t\t\t\t\tparameters: [{ name: \"@pk\", value: pk }]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfeedOptions\n\t\t\t\t\t)\n\t\t\t\t\t.fetchNext();\n\n\t\t\t\tcontinuationToken = nextToken;\n\n\t\t\t\tif (Is.arrayValue(resources)) {\n\t\t\t\t\tconst operations: OperationInput[] = resources.map(r => ({\n\t\t\t\t\t\toperationType: BulkOperationType.Delete,\n\t\t\t\t\t\tid: r.id,\n\t\t\t\t\t\tpartitionKey: pk\n\t\t\t\t\t}));\n\t\t\t\t\tawait this._container.items.executeBulkOperations(operations);\n\t\t\t\t}\n\t\t\t} while (Is.stringValue(continuationToken));\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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(CosmosDbEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\t\tconst optimisticMutexKey = Is.stringValue(this._versionKey)\n\t\t\t? this.buildOptimisticMutexKey(partitionKey, id)\n\t\t\t: undefined;\n\n\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\tawait Mutex.lock(optimisticMutexKey, {\n\t\t\t\tthrowOnTimeout: true,\n\t\t\t\ttimeoutMs: this._mutexTimeoutMs\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tconst item = this._container.item(\n\t\t\t\tid,\n\t\t\t\tpartitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t);\n\t\t\tconst { resource: itemData } = await item.read<ItemDefinition>();\n\t\t\tif (Is.notEmpty(itemData)) {\n\t\t\t\tif (Is.arrayValue(conditions) && !this.verifyConditions(conditions, itemData as T)) {\n\t\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\tid\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tawait item.delete();\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tBaseError.fromError(err) &&\n\t\t\t\tIs.object<{ body?: { code?: string } }>(err) &&\n\t\t\t\terr.body?.code === \"NotFound\"\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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} finally {\n\t\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\t\tMutex.unlock(optimisticMutexKey);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Remove multiple entities by id.\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(CosmosDbEntityStorageConnector.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 operations: OperationInput[] = ids.map(id => ({\n\t\t\t\toperationType: BulkOperationType.Delete,\n\t\t\t\tid,\n\t\t\t\tpartitionKey: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t}));\n\n\t\t\tawait this._container.items.executeBulkOperations(operations);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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 storage by deleting the underlying container.\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: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"containerDeleting\",\n\t\t\tdata: { containerId: this._config.containerId }\n\t\t});\n\n\t\ttry {\n\t\t\tif (await this.containerExists()) {\n\t\t\t\tawait this._container.delete();\n\t\t\t\tawait this.waitForContainerNotExists();\n\t\t\t}\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"containerDeleted\",\n\t\t\t\tdata: { containerId: this._config.containerId }\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: CosmosDbEntityStorageConnector.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?: { property: keyof T; sortDirection: SortDirection }[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{ entities: Partial<T>[]; cursor?: string }> {\n\t\tlet sql = \"\";\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tEntityStorageHelper.validateSortProperties(this._entitySchema, sortProperties);\n\t\tEntityStorageHelper.validateProperties(this._entitySchema, properties);\n\t\tEntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);\n\n\t\t// Only the sort shapes covered by the composite indexes from buildIndexingPolicy are accepted.\n\t\tif (Is.arrayValue(sortProperties)) {\n\t\t\tconst nonPrimarySorts = sortProperties.filter(\n\t\t\t\tsortProperty => sortProperty.property !== this._primaryKey.property\n\t\t\t);\n\t\t\tif (nonPrimarySorts.length > 1) {\n\t\t\t\tthrow new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, \"sortUnsupported\", {\n\t\t\t\t\tproperties: sortProperties.map(sortProperty => sortProperty.property),\n\t\t\t\t\tprimaryKey: this._primaryKey.property\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (!Is.empty(limit)) {\n\t\t\tconst validationFailures: IValidationFailure[] = [];\n\t\t\tValidation.integer(nameof(limit), limit, validationFailures, undefined, { minValue: 1 });\n\t\t\tValidation.asValidationError(\n\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"query\",\n\t\t\t\tvalidationFailures\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst returnSize = limit ?? CosmosDbEntityStorageConnector._DEFAULT_LIMIT;\n\n\t\t\tlet orderByClause: string = \"\";\n\t\t\tif (Is.arrayValue(sortProperties)) {\n\t\t\t\t// The primary key is unique so no property after its first occurrence can affect\n\t\t\t\t// the order, truncating keeps the ORDER BY within the provisioned composite indexes.\n\t\t\t\tconst primaryKeyIndex = sortProperties.findIndex(\n\t\t\t\t\tsortProperty => sortProperty.property === this._primaryKey.property\n\t\t\t\t);\n\t\t\t\tconst effectiveSorts =\n\t\t\t\t\tprimaryKeyIndex === -1 ? sortProperties : sortProperties.slice(0, primaryKeyIndex + 1);\n\t\t\t\tconst orderClauses = effectiveSorts.map(sortProperty => {\n\t\t\t\t\tconst direction = sortProperty.sortDirection === SortDirection.Ascending ? \"asc\" : \"desc\";\n\t\t\t\t\treturn `c.${String(sortProperty.property)} ${direction}`;\n\t\t\t\t});\n\t\t\t\torderByClause = `ORDER BY ${orderClauses.join(\", \")}`;\n\t\t\t}\n\n\t\t\tconst attributeNames: { [id: string]: string } = {};\n\t\t\tconst attributeValues: { [id: string]: unknown } = {};\n\t\t\tlet queryClause = this.buildQueryParameters(\"\", conditions, attributeNames, attributeValues);\n\n\t\t\tif (queryClause.length > 0) {\n\t\t\t\tqueryClause = ` AND ${queryClause}`;\n\t\t\t}\n\n\t\t\tconst selectClause = properties ? properties.map(p => `c.${p as string}`).join(\", \") : \"*\";\n\t\t\tconst baseQuery = `SELECT ${selectClause} FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionId${queryClause}`;\n\t\t\tconst queryParameters: SqlParameter[] = [\n\t\t\t\t{\n\t\t\t\t\tname: \"@partitionId\",\n\t\t\t\t\tvalue: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t},\n\t\t\t\t...Object.keys(attributeValues).map(\n\t\t\t\t\tkey => ({ name: `@${key}`, value: attributeValues[key] }) as SqlParameter\n\t\t\t\t)\n\t\t\t];\n\t\t\tconst queryPartitionKey = partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\t\t// For sorted queries use OFFSET LIMIT - CosmosDB continuation tokens are\n\t\t\t// not reliably returned for ORDER BY queries across all service versions.\n\t\t\t// The cursor is a numeric offset encoded as a string (same as SQL connectors).\n\t\t\tconst startIndex = Coerce.number(cursor) ?? 0;\n\t\t\tsql = `${baseQuery} ${orderByClause} OFFSET ${startIndex} LIMIT ${returnSize + 1}`;\n\t\t\tconst sortedQuerySpecs: SqlQuerySpec = { query: sql, parameters: queryParameters };\n\t\t\tconst sortedResponse = await this._container.items\n\t\t\t\t.query(sortedQuerySpecs, {\n\t\t\t\t\tpartitionKey: queryPartitionKey,\n\t\t\t\t\tmaxItemCount: returnSize + 1\n\t\t\t\t})\n\t\t\t\t.fetchNext();\n\t\t\tconst allItems = sortedResponse.resources;\n\t\t\tconst hasMore = allItems.length > returnSize;\n\t\t\treturn {\n\t\t\t\tentities: (hasMore ? allItems.slice(0, returnSize) : allItems).map(i =>\n\t\t\t\t\tthis.itemToEntity(i)\n\t\t\t\t),\n\t\t\t\tcursor: hasMore ? Coerce.string(startIndex + returnSize) : undefined\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"queryFailed\",\n\t\t\t\t{ sql },\n\t\t\t\terr\n\t\t\t);\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\tEntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);\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\tconst attributeValues: { [id: string]: unknown } = {};\n\t\t\tlet queryClause = Is.empty(conditions)\n\t\t\t\t? \"\"\n\t\t\t\t: this.buildQueryParameters(\"\", conditions, attributeNames, attributeValues);\n\n\t\t\tif (queryClause.length > 0) {\n\t\t\t\tqueryClause = ` AND ${queryClause}`;\n\t\t\t}\n\n\t\t\tconst querySpec: SqlQuerySpec = {\n\t\t\t\tquery: `SELECT VALUE COUNT(1) FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionId${queryClause}`,\n\t\t\t\tparameters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"@partitionId\",\n\t\t\t\t\t\tvalue: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t},\n\t\t\t\t\t...Object.keys(attributeValues).map(\n\t\t\t\t\t\tkey => ({ name: `@${key}`, value: attributeValues[key] }) as SqlParameter\n\t\t\t\t\t)\n\t\t\t\t]\n\t\t\t};\n\t\t\tconst { resources } = await this._container.items.query(querySpec).fetchAll();\n\t\t\treturn resources[0] ?? 0;\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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[] | undefined> {\n\t\tconst partitionContextIds = this._partitionContextIds;\n\t\tif (!Is.arrayValue(partitionContextIds)) {\n\t\t\treturn undefined;\n\t\t}\n\t\ttry {\n\t\t\tconst { resources: partitionIds } = await this._container.items\n\t\t\t\t.query<string>({\n\t\t\t\t\tquery: `SELECT DISTINCT VALUE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} FROM c`\n\t\t\t\t})\n\t\t\t\t.fetchAll();\n\t\t\treturn partitionIds\n\t\t\t\t.filter(id => Is.stringValue(id))\n\t\t\t\t.map(id => ContextIdHelper.shortSplit(partitionContextIds, id));\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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\t}\n\n\t/**\n\t * Create the target connector for performing the migration using a temporary container.\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\tconst migrationContainerId = `${this._config.containerId}Migration${Date.now()}`;\n\t\treturn new CosmosDbEntityStorageConnector<U>({\n\t\t\tentitySchema: newEntitySchema,\n\t\t\tconfig: { ...this._config, containerId: migrationContainerId },\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t}\n\n\t/**\n\t * Finalize the migration by tearing down the old container and replacing it with the target container.\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 optional component type to use for logging.\n\t * @returns The final connector pointing at the original container id.\n\t */\n\tpublic async finalizeMigration<U>(\n\t\ttargetConnector: CosmosDbEntityStorageConnector<U>,\n\t\toptions?: IMigrationOptions,\n\t\tloggingComponentType?: string\n\t): Promise<CosmosDbEntityStorageConnector<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 CosmosDbEntityStorageConnector<U>({\n\t\t\tentitySchema: targetConnector._entitySchemaName,\n\t\t\tconfig: this._config,\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\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 ?? CosmosDbEntityStorageConnector._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\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\"finalizeMigrationFailedBootstrap\"\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.\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.\n\t */\n\tpublic async cleanupMigration<U>(\n\t\ttargetConnector: IEntityStorageConnector<U> | undefined,\n\t\toptions?: IMigrationOptions,\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: CosmosDbEntityStorageConnector<U>,\n\t\tdestConnector: CosmosDbEntityStorageConnector<U>,\n\t\tpartitions: IContextIds[] | undefined,\n\t\tbatchSize: number\n\t): Promise<void> {\n\t\t// undefined → not partitioned: one pass with no partition key.\n\t\t// [] → partitioned but empty: nothing to copy, return early.\n\t\t// [{…}, …] → partitioned with data: iterate over each partition.\n\t\tif (partitions?.length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst partitionList = partitions ?? [{}];\n\n\t\tfor (let i = 0; i < partitionList.length; i++) {\n\t\t\t// Values from getPartitionContextIds are already short-form, so we join them\n\t\t\t// directly rather than using combinedContextKey, which expects long-form input\n\t\t\t// and calls guardAll (throwing if a registered handler rejects short-form values).\n\t\t\tconst partitionKey = Is.arrayValue(sourceConnector._partitionContextIds)\n\t\t\t\t? sourceConnector._partitionContextIds.map(k => partitionList[i][k]).join(\"/\")\n\t\t\t\t: CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\t\tlet continuationToken: string | undefined;\n\t\t\tdo {\n\t\t\t\tconst feedOptions: FeedOptions = { maxItemCount: batchSize, continuationToken };\n\t\t\t\tconst { resources, continuationToken: nextToken } = await sourceConnector._container.items\n\t\t\t\t\t.query<ItemDefinition & Resource>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tquery: `SELECT * FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionId`,\n\t\t\t\t\t\t\tparameters: [{ name: \"@partitionId\", value: partitionKey }]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfeedOptions\n\t\t\t\t\t)\n\t\t\t\t\t.fetchNext();\n\n\t\t\t\tcontinuationToken = nextToken;\n\n\t\t\t\tif (Is.arrayValue(resources)) {\n\t\t\t\t\tconst operations: OperationInput[] = resources.map(\n\t\t\t\t\t\t({\n\t\t\t\t\t\t\t_rid: rid,\n\t\t\t\t\t\t\t_self: self,\n\t\t\t\t\t\t\t_ts: ts,\n\t\t\t\t\t\t\t_etag: etag,\n\t\t\t\t\t\t\t_attachments: attachments,\n\t\t\t\t\t\t\t...rest\n\t\t\t\t\t\t}) => ({\n\t\t\t\t\t\t\toperationType: BulkOperationType.Upsert,\n\t\t\t\t\t\t\tpartitionKey,\n\t\t\t\t\t\t\tresourceBody: rest\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tawait destConnector._container.items.executeBulkOperations(operations);\n\t\t\t\t}\n\t\t\t} while (Is.stringValue(continuationToken));\n\t\t}\n\t}\n\n\t/**\n\t * Create an SQL condition clause.\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]: unknown }\n\t): string {\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}\n\n\t\tif (\"conditions\" in condition) {\n\t\t\tif (condition.conditions.length === 0) {\n\t\t\t\treturn \"\";\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: string[] = condition.conditions.map(c =>\n\t\t\t\tthis.buildQueryParameters(objectPath, c, attributeNames, attributeValues)\n\t\t\t);\n\n\t\t\tconst logicalOperator = this.mapConditionalOperator(condition.logicalOperator);\n\t\t\tconst queryClause = joinConditions\n\t\t\t\t.filter(j => j.length > 0)\n\t\t\t\t.map(j => j)\n\t\t\t\t.join(` ${logicalOperator} `);\n\n\t\t\treturn Is.stringValue(queryClause) ? ` (${queryClause}) ` : \"\";\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\treturn comparison;\n\t}\n\n\t/**\n\t * Map the framework comparison operators to those in CosmosDB.\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 * @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]: unknown }\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\t\tlet propName = `${attributeName.replace(/\\./g, \"\").replace(/@/g, \"\")}`;\n\n\t\tif (\n\t\t\t(comparator.comparison === ComparisonOperator.Equals ||\n\t\t\t\tcomparator.comparison === ComparisonOperator.NotEquals) &&\n\t\t\t(comparator.value === null || comparator.value === undefined)\n\t\t) {\n\t\t\t// Cosmos DB SQL null semantics mirror standard SQL: any comparison using = or <>\n\t\t\t// against null evaluates to UNKNOWN, not TRUE, so no rows are returned.\n\t\t\t// IS_NULL() and IS_DEFINED() must be used instead (no bound parameter needed).\n\t\t\tif (comparator.comparison === ComparisonOperator.Equals) {\n\t\t\t\treturn `(IS_NULL(c.${attributeName}) OR NOT IS_DEFINED(c.${attributeName}))`;\n\t\t\t}\n\t\t\treturn `(IS_DEFINED(c.${attributeName}) AND NOT IS_NULL(c.${attributeName}))`;\n\t\t} else if (Is.array(comparator.value)) {\n\t\t\tconst dbValues = comparator.value.map(v => this.propertyToDbValue(v, type));\n\t\t\tif (dbValues.length === 0 && comparator.comparison === ComparisonOperator.In) {\n\t\t\t\t// CosmosDB rejects `IN ()` - return always-false sentinel (#141).\n\t\t\t\treturn \"1=0\";\n\t\t\t}\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.map(name => `@${name}`).join(\", \")})`;\n\t\t} else if (\n\t\t\tIs.object(comparator.value) &&\n\t\t\t(comparator.comparison === ComparisonOperator.Equals ||\n\t\t\t\tcomparator.comparison === ComparisonOperator.NotEquals)\n\t\t) {\n\t\t\t// CosmosDB SQL does not support object equality with =; expand to per-property comparisons.\n\t\t\tconst op = comparator.comparison === ComparisonOperator.Equals ? \"=\" : \"<>\";\n\t\t\tconst join = comparator.comparison === ComparisonOperator.Equals ? \" AND \" : \" OR \";\n\t\t\tconst clauses: string[] = [];\n\t\t\tfor (const [key, val] of Object.entries(comparator.value)) {\n\t\t\t\tconst paramName = `${propName}${key}`;\n\t\t\t\tattributeValues[paramName] = val;\n\t\t\t\tclauses.push(`c.${attributeName}.${key} ${op} @${paramName}`);\n\t\t\t}\n\t\t\treturn clauses.length === 1 ? clauses[0] : `(${clauses.join(join)})`;\n\t\t} else {\n\t\t\t// Avoid parameter name conflicts by ensuring unique parameter names in the query\n\t\t\tlet counter = 1;\n\t\t\twhile (propName in attributeValues) {\n\t\t\t\tpropName = `${attributeName.replace(/\\./g, \"\").replace(/@/g, \"\")}${counter}`;\n\t\t\t\tcounter++;\n\t\t\t}\n\t\t\tattributeValues[propName] = comparator.value;\n\t\t}\n\n\t\tconst matches = attributeName.split(\".\").length;\n\t\tif (matches && comparator.comparison === ComparisonOperator.Equals) {\n\t\t\tattributeName = attributeName\n\t\t\t\t.split(\".\")\n\t\t\t\t.map(part => `[\"${part}\"]`)\n\t\t\t\t.join(\"\");\n\t\t\treturn `c${attributeName} = @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.Equals) {\n\t\t\treturn `c.${attributeName} = @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\treturn `c.${attributeName} <> @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.GreaterThan) {\n\t\t\treturn `c.${attributeName} > @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.LessThan) {\n\t\t\treturn `c.${attributeName} < @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.GreaterThanOrEqual) {\n\t\t\treturn `c.${attributeName} >= @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.LessThanOrEqual) {\n\t\t\treturn `c.${attributeName} <= @${propName}`;\n\t\t} else if (\n\t\t\tIs.object(attributeValues[propName]) &&\n\t\t\tcomparator.comparison === ComparisonOperator.Includes\n\t\t) {\n\t\t\treturn `ARRAY_CONTAINS(c.${attributeName}, @${propName}, true)`;\n\t\t} else if (\n\t\t\t(type === \"array\" || type === \"object\") &&\n\t\t\tcomparator.comparison === ComparisonOperator.Includes\n\t\t) {\n\t\t\treturn `ARRAY_CONTAINS(c.${attributeName}, @${propName})`;\n\t\t} else if (\n\t\t\t(type === \"array\" || type === \"object\") &&\n\t\t\tcomparator.comparison === ComparisonOperator.NotIncludes\n\t\t) {\n\t\t\treturn `NOT ARRAY_CONTAINS(c.${attributeName}, @${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.Includes) {\n\t\t\treturn `CONTAINS(c.${attributeName}, @${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.NotIncludes) {\n\t\t\treturn `NOT CONTAINS(c.${attributeName}, @${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.In) {\n\t\t\treturn `c.${propName} IN ${attributeName}`;\n\t\t}\n\n\t\tthrow new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, \"comparisonNotSupported\", {\n\t\t\tcomparison: comparator.comparison\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): unknown {\n\t\tif (Is.object(value)) {\n\t\t\tconst map: { [id: string]: unknown } = {};\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 map;\n\t\t}\n\n\t\tif (type === \"string\") {\n\t\t\treturn `${Coerce.string(value)}`;\n\t\t} else if (type === \"integer\" || type === \"number\") {\n\t\t\treturn Coerce.number(value) ?? 0;\n\t\t} else if (type === \"boolean\") {\n\t\t\treturn Coerce.boolean(value) ?? false;\n\t\t}\n\n\t\treturn Coerce.string(value) ?? \"\";\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 CosmosDB.\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(CosmosDbEntityStorageConnector.CLASS_NAME, \"conditionalNotSupported\", {\n\t\t\toperator\n\t\t});\n\t}\n\n\t/**\n\t * Verify the conditions for the entity.\n\t * @param conditions The conditions to verify.\n\t * @param obj The object to verify the conditions against.\n\t * @returns True if all conditions are met, false otherwise.\n\t * @internal\n\t */\n\tprivate verifyConditions(\n\t\tconditions: { property: keyof T; value: unknown }[],\n\t\tobj: { [key in keyof T]: unknown }\n\t): boolean {\n\t\treturn conditions.every(\n\t\t\tcondition => ObjectHelper.propertyGet(obj, condition.property as string) === condition.value\n\t\t);\n\t}\n\n\t/**\n\t * Build a mutex key for optimistic-locking critical sections.\n\t * @param partitionKey The resolved partition key.\n\t * @param id The entity id.\n\t * @returns The mutex key.\n\t * @internal\n\t */\n\tprivate buildOptimisticMutexKey(partitionKey: string | undefined, id: string): string {\n\t\treturn `${CosmosDbEntityStorageConnector.CLASS_NAME}:optimistic:${this._config.databaseId}:${this._config.containerId}:${partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE}:${id}`;\n\t}\n\n\t/**\n\t * Convert an entity to an item.\n\t * @param item The item to convert.\n\t * @returns The entity.\n\t * @internal\n\t */\n\tprivate itemToEntity(item: (ItemDefinition & Resource) | undefined): T {\n\t\treturn EntityStorageHelper.unPrepareEntity<T>(item as T, [\n\t\t\tCosmosDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\"_attachments\",\n\t\t\t\"_etag\",\n\t\t\t\"_rid\",\n\t\t\t\"_self\",\n\t\t\t\"_ts\"\n\t\t]);\n\t}\n\n\t/**\n\t * Check if the database exists.\n\t * @returns True if the database exists, false otherwise.\n\t * @internal\n\t */\n\tprivate async databaseExists(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst { resources: databaseList } = await this._client.databases.readAll().fetchAll();\n\n\t\t\treturn databaseList.some((db: Resource) => db.id === this._config.databaseId);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a database to exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForDatabaseExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst databaseExists = await this.databaseExists();\n\t\t\tif (databaseExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Build the composite indexes needed to serve multi-property ORDER BY queries.\n\t * Pairing each sortable property with the primary key in both directions covers all\n\t * four direction combinations, as Cosmos DB also serves each index reversed.\n\t * @returns The indexing policy for the container, or undefined if the schema has no\n\t * sortable properties.\n\t * @internal\n\t */\n\tprivate buildIndexingPolicy(): IndexingPolicy | undefined {\n\t\tconst primaryKeyPath = `/${this._primaryKey.property as string}`;\n\t\tconst compositeIndexes: CompositePath[][] = [];\n\n\t\tif (Is.arrayValue(this._entitySchema.properties)) {\n\t\t\tfor (const prop of this._entitySchema.properties) {\n\t\t\t\tif (!prop.isPrimary && (Is.stringValue(prop.sortDirection) || prop.isSecondary)) {\n\t\t\t\t\tconst propertyPath = `/${prop.property as string}`;\n\t\t\t\t\tcompositeIndexes.push([\n\t\t\t\t\t\t{ path: propertyPath, order: \"ascending\" },\n\t\t\t\t\t\t{ path: primaryKeyPath, order: \"ascending\" }\n\t\t\t\t\t]);\n\t\t\t\t\tcompositeIndexes.push([\n\t\t\t\t\t\t{ path: propertyPath, order: \"ascending\" },\n\t\t\t\t\t\t{ path: primaryKeyPath, order: \"descending\" }\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn compositeIndexes.length > 0\n\t\t\t? {\n\t\t\t\t\tindexingMode: \"consistent\",\n\t\t\t\t\tautomatic: true,\n\t\t\t\t\tincludedPaths: [{ path: \"/*\" }],\n\t\t\t\t\tcompositeIndexes\n\t\t\t\t}\n\t\t\t: undefined;\n\t}\n\n\t/**\n\t * Check if the container exists.\n\t * @returns True if the container exists, false otherwise.\n\t * @internal\n\t */\n\tprivate async containerExists(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst { resources: containers } = await this._client\n\t\t\t\t.database(this._config.databaseId)\n\t\t\t\t.containers.readAll()\n\t\t\t\t.fetchAll();\n\n\t\t\treturn containers.some((c: Resource) => c.id === this._config.containerId);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a container to exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForContainerExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst containerExists = await this.containerExists();\n\t\t\tif (containerExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a container to not exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForContainerNotExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst containerExists = await this.containerExists();\n\t\t\tif (!containerExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"cosmosDbEntityStorageConnector.js","sourceRoot":"","sources":["../../src/cosmosDbEntityStorageConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tBulkOperationType,\n\ttype CompositePath,\n\ttype Container,\n\tCosmosClient,\n\ttype FeedOptions,\n\ttype IndexingPolicy,\n\ttype ItemDefinition,\n\ttype JSONValue,\n\ttype OperationInput,\n\tPartitionKeyKind,\n\ttype Resource,\n\ttype SqlParameter,\n\ttype SqlQuerySpec\n} from \"@azure/cosmos\";\nimport {\n\tHealthCategory,\n\tHealthStatus,\n\ttype IHealth,\n\ttype IHealthProviderComponent\n} from \"@twin.org/api-models\";\nimport { ContextIdHelper, ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tCoerce,\n\tComponentFactory,\n\tConflictError,\n\tGeneralError,\n\tGuards,\n\tIs,\n\tMutex,\n\ttype IValidationFailure,\n\tObjectHelper,\n\tRandomHelper,\n\tValidation\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\tConnectionHelper,\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 { ICosmosDbEntityStorageConnectorConfig } from \"./models/ICosmosDbEntityStorageConnectorConfig.js\";\nimport type { ICosmosDbEntityStorageConnectorConstructorOptions } from \"./models/ICosmosDbEntityStorageConnectorConstructorOptions.js\";\n\n/**\n * Class for performing entity storage operations using Cosmos DB.\n */\nexport class CosmosDbEntityStorageConnector<T = unknown>\n\timplements IEntityStorageMigrationConnector<T>, IHealthProviderComponent\n{\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<CosmosDbEntityStorageConnector>();\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 * Batch chunk size for bulk write operations.\n\t * @internal\n\t */\n\tprivate static readonly _BATCH_CHUNK_SIZE: number = 1000;\n\n\t/**\n\t * Number of bulk operation chunks to dispatch concurrently in setBatch.\n\t * @internal\n\t */\n\tprivate static readonly _WRITE_CONCURRENCY: number = 10;\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 name of the version property, if any.\n\t * @internal\n\t */\n\tprivate readonly _versionKey?: string;\n\n\t/**\n\t * The configuration for the connector.\n\t * @internal\n\t */\n\tprivate readonly _config: ICosmosDbEntityStorageConnectorConfig;\n\n\t/**\n\t * Milliseconds to wait for optimistic-lock mutexes before throwing.\n\t * @internal\n\t */\n\tprivate readonly _mutexTimeoutMs?: number;\n\n\t/**\n\t * Unique identifier for this connector instance, used to track references in SharedStore.\n\t * @internal\n\t */\n\tprivate readonly _instanceId: string;\n\n\t/**\n\t * Create a new instance of CosmosDbEntityStorageConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: ICosmosDbEntityStorageConnectorConstructorOptions) {\n\t\tGuards.object(CosmosDbEntityStorageConnector.CLASS_NAME, nameof(options), options);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.entitySchema),\n\t\t\toptions.entitySchema\n\t\t);\n\t\tGuards.object<ICosmosDbEntityStorageConnectorConfig>(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.endpoint),\n\t\t\toptions.config.endpoint\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.key),\n\t\t\toptions.config.key\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.databaseId),\n\t\t\toptions.config.databaseId\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.containerId),\n\t\t\toptions.config.containerId\n\t\t);\n\n\t\tthis._entitySchema = EntitySchemaFactory.get(options.entitySchema);\n\t\tthis._entitySchemaName = options.entitySchema;\n\t\tthis._partitionContextIds = options.partitionContextIds;\n\n\t\tthis._primaryKey = EntitySchemaHelper.getPrimaryKey<T>(this._entitySchema);\n\t\tthis._versionKey = EntitySchemaHelper.findVersionProperty(this._entitySchema);\n\n\t\tthis._config = options.config;\n\t\tthis._mutexTimeoutMs = Coerce.integer(options.config.mutexTimeoutMs);\n\t\tthis._instanceId = RandomHelper.generateUuidV7(\"compact\");\n\t}\n\n\t/**\n\t * The component needs to be stopped when the node is closed.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns Nothing.\n\t */\n\tpublic async stop(nodeLoggingComponentType?: string): Promise<void> {\n\t\tawait ConnectionHelper.closeClient<CosmosClient>(\n\t\t\t\"cosmosDbClients\",\n\t\t\tthis.createClientId(),\n\t\t\tthis._instanceId,\n\t\t\tthis._mutexTimeoutMs,\n\t\t\tasync client => client.dispose()\n\t\t);\n\t}\n\n\t/**\n\t * Initialize the Cosmos DB environment.\n\t * @param nodeLoggingComponentType Optional type of the logging component.\n\t * @returns A promise that resolves to a boolean indicating success.\n\t */\n\tpublic async bootstrap(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\t\tconst client = await this.getClient();\n\n\t\t// Create the database if it does not exist\n\t\ttry {\n\t\t\tconst databaseExists = await this.databaseExists();\n\n\t\t\tif (databaseExists) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"databaseExists\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdatabaseId: this._config.databaseId\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"databaseCreating\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdatabaseId: this._config.databaseId\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tawait client.databases.create({\n\t\t\t\t\tid: this._config.databaseId\n\t\t\t\t});\n\n\t\t\t\tawait this.waitForDatabaseExists();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"databaseCreateFailed\",\n\t\t\t\terror: BaseError.fromError(error),\n\t\t\t\tdata: {\n\t\t\t\t\tdatabaseId: this._config.databaseId\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\t// Create the container if it does not exist\n\t\ttry {\n\t\t\tconst containerExists = await this.containerExists();\n\n\t\t\tif (containerExists) {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"containerExists\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tcontainerId: this._config.containerId\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait nodeLogging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tmessage: \"containerCreating\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tcontainerId: this._config.containerId\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tawait client.database(this._config.databaseId).containers.create(\n\t\t\t\t\t{\n\t\t\t\t\t\tid: this._config.containerId,\n\t\t\t\t\t\tpartitionKey: {\n\t\t\t\t\t\t\tkind: PartitionKeyKind.Hash,\n\t\t\t\t\t\t\tpaths: [`/${CosmosDbEntityStorageConnector._PARTITION_KEY}`]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tindexingPolicy: this.buildIndexingPolicy()\n\t\t\t\t\t},\n\t\t\t\t\t{ offerThroughput: this._config.offerThroughput }\n\t\t\t\t);\n\n\t\t\t\tawait this.waitForContainerExists();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"containerCreateFailed\",\n\t\t\t\terror: BaseError.fromError(error),\n\t\t\t\tdata: {\n\t\t\t\t\tcontainerId: this._config.containerId\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\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 CosmosDbEntityStorageConnector.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 container = await this.getContainer();\n\t\t\tawait container.read();\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tcategory: HealthCategory.Connectivity,\n\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\tdata: { databaseId: this._config.databaseId, containerId: this._config.containerId }\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: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\tcategory: HealthCategory.Connectivity,\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: { databaseId: this._config.databaseId, containerId: this._config.containerId }\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 * Get an entity from Cosmos DB.\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(CosmosDbEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\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 container = await this.getContainer();\n\t\t\t// No secondary index or conditions\n\t\t\tif (Is.empty(secondaryIndex) && !Is.arrayValue(conditions)) {\n\t\t\t\tconst { resource: item } = await container\n\t\t\t\t\t.item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE)\n\t\t\t\t\t.read<ItemDefinition>();\n\t\t\t\tif (Is.empty(item)) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\treturn this.itemToEntity(item);\n\t\t\t}\n\n\t\t\tconst conditionValues: SqlParameter[] = [];\n\n\t\t\tconst whereQuery: string[] = [\n\t\t\t\t`c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionKey`\n\t\t\t];\n\t\t\tconditionValues.push({\n\t\t\t\tname: \"@partitionKey\",\n\t\t\t\tvalue: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t});\n\n\t\t\t// With a secondary index\n\t\t\tif (Is.stringValue(secondaryIndex)) {\n\t\t\t\tconst secIndex = secondaryIndex.toString();\n\t\t\t\twhereQuery.push(`c.${secIndex} = @id`);\n\t\t\t} else {\n\t\t\t\twhereQuery.push(`c.${this._primaryKey.property as string} = @id`);\n\t\t\t}\n\t\t\tconditionValues.push({ name: \"@id\", value: id });\n\n\t\t\t// With conditions\n\t\t\tif (Is.arrayValue(conditions)) {\n\t\t\t\tfor (const c of conditions) {\n\t\t\t\t\twhereQuery.push(`c.${c.property as string} = @${c.property as string}`);\n\t\t\t\t\tconditionValues.push({\n\t\t\t\t\t\tname: `@${c.property as string}`,\n\t\t\t\t\t\tvalue: c.value as JSONValue\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst query: SqlQuerySpec = {\n\t\t\t\tquery: `SELECT * FROM c WHERE ${whereQuery.join(\" AND \")}`,\n\t\t\t\tparameters: conditionValues\n\t\t\t};\n\n\t\t\tconst { resources: items } = await container.items.query(query).fetchAll();\n\n\t\t\tif (items.length === 1) {\n\t\t\t\treturn this.itemToEntity(items[0]);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorCode(err, \"NotFound\")) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"containerDoesNotExist\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcontainerId: this._config.containerId\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\tCosmosDbEntityStorageConnector.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\treturn undefined;\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>(CosmosDbEntityStorageConnector.CLASS_NAME, nameof(entity), entity);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tconst submittedVersion = Is.stringValue(this._versionKey)\n\t\t\t? ObjectHelper.propertyGet<number>(entity, this._versionKey)\n\t\t\t: undefined;\n\t\tconst hasVersionCheck =\n\t\t\t!Is.empty(this._versionKey) && !Is.empty(submittedVersion) && submittedVersion > 0;\n\n\t\tconst prepared = EntityStorageHelper.prepareEntity(entity, this._entitySchema, undefined, {\n\t\t\tnullBehavior: \"omit\"\n\t\t});\n\n\t\tconst id = prepared[this._primaryKey.property] as string;\n\t\tconst optimisticMutexKey = Is.stringValue(this._versionKey)\n\t\t\t? this.buildOptimisticMutexKey(partitionKey, id)\n\t\t\t: undefined;\n\n\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\tawait Mutex.lock(optimisticMutexKey, {\n\t\t\t\tthrowOnTimeout: true,\n\t\t\t\ttimeoutMs: this._mutexTimeoutMs\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tconst container = await this.getContainer();\n\t\t\tlet itemEtag: string | undefined;\n\n\t\t\tif (Is.stringValue(this._versionKey) || Is.arrayValue(conditions)) {\n\t\t\t\tconst item = container.item(\n\t\t\t\t\tid,\n\t\t\t\t\tpartitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t);\n\t\t\t\tconst { resource: itemData } = await item.read<ItemDefinition>();\n\t\t\t\tif (!Is.empty(itemData)) {\n\t\t\t\t\tif (hasVersionCheck) {\n\t\t\t\t\t\tconst storedVersion = ObjectHelper.propertyGet<number>(itemData, this._versionKey) ?? 0;\n\t\t\t\t\t\tif (storedVersion !== submittedVersion) {\n\t\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\t\"optimisticLockFailed\",\n\t\t\t\t\t\t\t\tid\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\tif (Is.arrayValue(conditions) && !this.verifyConditions(conditions, itemData as T)) {\n\t\t\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\t\tid\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\titemEtag = ObjectHelper.propertyGet(itemData, \"_etag\");\n\t\t\t\t}\n\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\tconst storedVersion = !Is.empty(itemData)\n\t\t\t\t\t\t? (ObjectHelper.propertyGet<number>(itemData, this._versionKey) ?? 0)\n\t\t\t\t\t\t: 0;\n\t\t\t\t\tObjectHelper.propertySet(prepared, this._versionKey, storedVersion + 1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait container.items.upsert(\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\t[CosmosDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\t\tpartitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\t\t...prepared\n\t\t\t\t},\n\t\t\t\tIs.stringValue(itemEtag)\n\t\t\t\t\t? { accessCondition: { type: \"IfMatch\", condition: itemEtag } }\n\t\t\t\t\t: undefined\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tif (Is.object<{ code?: number }>(err) && err.code === 412) {\n\t\t\t\tthrow new ConflictError(\n\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"optimisticLockFailed\",\n\t\t\t\t\tid\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (BaseError.isAggregateError(err)) {\n\t\t\t\tconst errors = BaseError.fromAggregate(err);\n\t\t\t\tif (BaseError.someErrorCode(errors, \"ResourceNotFoundException\")) {\n\t\t\t\t\tthrow new GeneralError(\n\t\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\"containerDoesNotExist\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontainerId: this._config.containerId\n\t\t\t\t\t\t},\n\t\t\t\t\t\terr\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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} finally {\n\t\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\t\tMutex.unlock(optimisticMutexKey);\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(CosmosDbEntityStorageConnector.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(entity, this._entitySchema, undefined, {\n\t\t\t\tnullBehavior: \"omit\"\n\t\t\t})\n\t\t);\n\n\t\ttry {\n\t\t\tconst container = await this.getContainer();\n\t\t\tconst pk = partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\t\t\tconst chunkSize = CosmosDbEntityStorageConnector._BATCH_CHUNK_SIZE;\n\t\t\tconst concurrency = CosmosDbEntityStorageConnector._WRITE_CONCURRENCY;\n\t\t\tconst windowSize = chunkSize * concurrency;\n\t\t\tfor (let offset = 0; offset < preparedEntities.length; offset += windowSize) {\n\t\t\t\tconst window = preparedEntities.slice(offset, offset + windowSize);\n\t\t\t\tconst sends: Promise<void>[] = [];\n\t\t\t\tfor (let j = 0; j < window.length; j += chunkSize) {\n\t\t\t\t\tconst chunk = window.slice(j, j + chunkSize);\n\t\t\t\t\tsends.push(\n\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\tawait container.items.executeBulkOperations(\n\t\t\t\t\t\t\t\tchunk.map(\n\t\t\t\t\t\t\t\t\tprepared =>\n\t\t\t\t\t\t\t\t\t\t({\n\t\t\t\t\t\t\t\t\t\t\toperationType: BulkOperationType.Upsert,\n\t\t\t\t\t\t\t\t\t\t\tpartitionKey: pk,\n\t\t\t\t\t\t\t\t\t\t\tresourceBody: {\n\t\t\t\t\t\t\t\t\t\t\t\tid: prepared[this._primaryKey.property] as string,\n\t\t\t\t\t\t\t\t\t\t\t\t[CosmosDbEntityStorageConnector._PARTITION_KEY]: pk,\n\t\t\t\t\t\t\t\t\t\t\t\t...(prepared as { [key: string]: unknown })\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}) as OperationInput\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\tawait Promise.all(sends);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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 all entities from the storage.\n\t * @returns Nothing.\n\t */\n\tpublic async empty(): Promise<void> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\t\tconst pk = partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\ttry {\n\t\t\tconst container = await this.getContainer();\n\t\t\tlet continuationToken: string | undefined;\n\t\t\tdo {\n\t\t\t\tconst feedOptions: FeedOptions = { maxItemCount: 100, continuationToken };\n\t\t\t\tconst { resources, continuationToken: nextToken } = await container.items\n\t\t\t\t\t.query<{ id: string }>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tquery: `SELECT c.id FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @pk`,\n\t\t\t\t\t\t\tparameters: [{ name: \"@pk\", value: pk }]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfeedOptions\n\t\t\t\t\t)\n\t\t\t\t\t.fetchNext();\n\n\t\t\t\tcontinuationToken = nextToken;\n\n\t\t\t\tif (Is.arrayValue(resources)) {\n\t\t\t\t\tconst operations: OperationInput[] = resources.map(r => ({\n\t\t\t\t\t\toperationType: BulkOperationType.Delete,\n\t\t\t\t\t\tid: r.id,\n\t\t\t\t\t\tpartitionKey: pk\n\t\t\t\t\t}));\n\t\t\t\t\tawait container.items.executeBulkOperations(operations);\n\t\t\t\t}\n\t\t\t} while (Is.stringValue(continuationToken));\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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(CosmosDbEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tEntityStorageHelper.validateConditions(this._entitySchema, conditions);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\t\tconst optimisticMutexKey = Is.stringValue(this._versionKey)\n\t\t\t? this.buildOptimisticMutexKey(partitionKey, id)\n\t\t\t: undefined;\n\n\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\tawait Mutex.lock(optimisticMutexKey, {\n\t\t\t\tthrowOnTimeout: true,\n\t\t\t\ttimeoutMs: this._mutexTimeoutMs\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tconst container = await this.getContainer();\n\t\t\tconst item = container.item(\n\t\t\t\tid,\n\t\t\t\tpartitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t);\n\t\t\tconst { resource: itemData } = await item.read<ItemDefinition>();\n\t\t\tif (Is.notEmpty(itemData)) {\n\t\t\t\tif (Is.arrayValue(conditions) && !this.verifyConditions(conditions, itemData as T)) {\n\t\t\t\t\tif (Is.stringValue(this._versionKey)) {\n\t\t\t\t\t\tthrow new ConflictError(\n\t\t\t\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\t\t\"conditionFailed\",\n\t\t\t\t\t\t\tid\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tawait item.delete();\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tif (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tBaseError.fromError(err) &&\n\t\t\t\tIs.object<{ body?: { code?: string } }>(err) &&\n\t\t\t\terr.body?.code === \"NotFound\"\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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} finally {\n\t\t\tif (Is.stringValue(optimisticMutexKey)) {\n\t\t\t\tMutex.unlock(optimisticMutexKey);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Remove multiple entities by id.\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(CosmosDbEntityStorageConnector.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 container = await this.getContainer();\n\t\t\tconst operations: OperationInput[] = ids.map(id => ({\n\t\t\t\toperationType: BulkOperationType.Delete,\n\t\t\t\tid,\n\t\t\t\tpartitionKey: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t}));\n\n\t\t\tawait container.items.executeBulkOperations(operations);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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 storage by deleting the underlying container.\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: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\tts: Date.now(),\n\t\t\tmessage: \"containerDeleting\",\n\t\t\tdata: { containerId: this._config.containerId }\n\t\t});\n\n\t\ttry {\n\t\t\tconst container = await this.getContainer();\n\t\t\tif (await this.containerExists()) {\n\t\t\t\tawait container.delete();\n\t\t\t\tawait this.waitForContainerNotExists();\n\t\t\t}\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: CosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"containerDeleted\",\n\t\t\t\tdata: { containerId: this._config.containerId }\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: CosmosDbEntityStorageConnector.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?: { property: keyof T; sortDirection: SortDirection }[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{ entities: Partial<T>[]; cursor?: string }> {\n\t\tlet sql = \"\";\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\n\t\tEntityStorageHelper.validateSortProperties(this._entitySchema, sortProperties);\n\t\tEntityStorageHelper.validateProperties(this._entitySchema, properties);\n\t\tEntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);\n\n\t\t// Only the sort shapes covered by the composite indexes from buildIndexingPolicy are accepted.\n\t\tif (Is.arrayValue(sortProperties)) {\n\t\t\tconst nonPrimarySorts = sortProperties.filter(\n\t\t\t\tsortProperty => sortProperty.property !== this._primaryKey.property\n\t\t\t);\n\t\t\tif (nonPrimarySorts.length > 1) {\n\t\t\t\tthrow new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, \"sortUnsupported\", {\n\t\t\t\t\tproperties: sortProperties.map(sortProperty => sortProperty.property),\n\t\t\t\t\tprimaryKey: this._primaryKey.property\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (!Is.empty(limit)) {\n\t\t\tconst validationFailures: IValidationFailure[] = [];\n\t\t\tValidation.integer(nameof(limit), limit, validationFailures, undefined, { minValue: 1 });\n\t\t\tValidation.asValidationError(\n\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"query\",\n\t\t\t\tvalidationFailures\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst container = await this.getContainer();\n\t\t\tconst returnSize = limit ?? CosmosDbEntityStorageConnector._DEFAULT_LIMIT;\n\n\t\t\tlet orderByClause: string = \"\";\n\t\t\tif (Is.arrayValue(sortProperties)) {\n\t\t\t\t// The primary key is unique so no property after its first occurrence can affect\n\t\t\t\t// the order, truncating keeps the ORDER BY within the provisioned composite indexes.\n\t\t\t\tconst primaryKeyIndex = sortProperties.findIndex(\n\t\t\t\t\tsortProperty => sortProperty.property === this._primaryKey.property\n\t\t\t\t);\n\t\t\t\tconst effectiveSorts =\n\t\t\t\t\tprimaryKeyIndex === -1 ? sortProperties : sortProperties.slice(0, primaryKeyIndex + 1);\n\t\t\t\tconst orderClauses = effectiveSorts.map(sortProperty => {\n\t\t\t\t\tconst direction = sortProperty.sortDirection === SortDirection.Ascending ? \"asc\" : \"desc\";\n\t\t\t\t\treturn `c.${String(sortProperty.property)} ${direction}`;\n\t\t\t\t});\n\t\t\t\torderByClause = `ORDER BY ${orderClauses.join(\", \")}`;\n\t\t\t}\n\n\t\t\tconst attributeNames: { [id: string]: string } = {};\n\t\t\tconst attributeValues: { [id: string]: unknown } = {};\n\t\t\tlet queryClause = this.buildQueryParameters(\"\", conditions, attributeNames, attributeValues);\n\n\t\t\tif (queryClause.length > 0) {\n\t\t\t\tqueryClause = ` AND ${queryClause}`;\n\t\t\t}\n\n\t\t\tconst selectClause = properties ? properties.map(p => `c.${p as string}`).join(\", \") : \"*\";\n\t\t\tconst baseQuery = `SELECT ${selectClause} FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionId${queryClause}`;\n\t\t\tconst queryParameters: SqlParameter[] = [\n\t\t\t\t{\n\t\t\t\t\tname: \"@partitionId\",\n\t\t\t\t\tvalue: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t},\n\t\t\t\t...Object.keys(attributeValues).map(\n\t\t\t\t\tkey => ({ name: `@${key}`, value: attributeValues[key] }) as SqlParameter\n\t\t\t\t)\n\t\t\t];\n\t\t\tconst queryPartitionKey = partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\t\t// For sorted queries use OFFSET LIMIT - CosmosDB continuation tokens are\n\t\t\t// not reliably returned for ORDER BY queries across all service versions.\n\t\t\t// The cursor is a numeric offset encoded as a string (same as SQL connectors).\n\t\t\tconst startIndex = Coerce.number(cursor) ?? 0;\n\t\t\tsql = `${baseQuery} ${orderByClause} OFFSET ${startIndex} LIMIT ${returnSize + 1}`;\n\t\t\tconst sortedQuerySpecs: SqlQuerySpec = { query: sql, parameters: queryParameters };\n\t\t\tconst sortedResponse = await container.items\n\t\t\t\t.query(sortedQuerySpecs, {\n\t\t\t\t\tpartitionKey: queryPartitionKey,\n\t\t\t\t\tmaxItemCount: returnSize + 1\n\t\t\t\t})\n\t\t\t\t.fetchNext();\n\t\t\tconst allItems = sortedResponse.resources;\n\t\t\tconst hasMore = allItems.length > returnSize;\n\t\t\treturn {\n\t\t\t\tentities: (hasMore ? allItems.slice(0, returnSize) : allItems).map(i =>\n\t\t\t\t\tthis.itemToEntity(i)\n\t\t\t\t),\n\t\t\t\tcursor: hasMore ? Coerce.string(startIndex + returnSize) : undefined\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\"queryFailed\",\n\t\t\t\t{ sql },\n\t\t\t\terr\n\t\t\t);\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\tEntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);\n\t\ttry {\n\t\t\tconst container = await this.getContainer();\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\tconst attributeValues: { [id: string]: unknown } = {};\n\t\t\tlet queryClause = Is.empty(conditions)\n\t\t\t\t? \"\"\n\t\t\t\t: this.buildQueryParameters(\"\", conditions, attributeNames, attributeValues);\n\n\t\t\tif (queryClause.length > 0) {\n\t\t\t\tqueryClause = ` AND ${queryClause}`;\n\t\t\t}\n\n\t\t\tconst querySpec: SqlQuerySpec = {\n\t\t\t\tquery: `SELECT VALUE COUNT(1) FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionId${queryClause}`,\n\t\t\t\tparameters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"@partitionId\",\n\t\t\t\t\t\tvalue: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE\n\t\t\t\t\t},\n\t\t\t\t\t...Object.keys(attributeValues).map(\n\t\t\t\t\t\tkey => ({ name: `@${key}`, value: attributeValues[key] }) as SqlParameter\n\t\t\t\t\t)\n\t\t\t\t]\n\t\t\t};\n\t\t\tconst { resources } = await container.items.query(querySpec).fetchAll();\n\t\t\treturn resources[0] ?? 0;\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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[] | undefined> {\n\t\tconst partitionContextIds = this._partitionContextIds;\n\t\tif (!Is.arrayValue(partitionContextIds)) {\n\t\t\treturn undefined;\n\t\t}\n\t\ttry {\n\t\t\tconst container = await this.getContainer();\n\t\t\tconst { resources: partitionIds } = await container.items\n\t\t\t\t.query<string>({\n\t\t\t\t\tquery: `SELECT DISTINCT VALUE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} FROM c`\n\t\t\t\t})\n\t\t\t\t.fetchAll();\n\t\t\treturn partitionIds\n\t\t\t\t.filter(id => Is.stringValue(id))\n\t\t\t\t.map(id => ContextIdHelper.shortSplit(partitionContextIds, id));\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tCosmosDbEntityStorageConnector.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\t}\n\n\t/**\n\t * Get the connector implementation version.\n\t * @returns The connector implementation version.\n\t */\n\tpublic connectorVersion(): number {\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Create the target connector for performing the migration using a temporary container.\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\tconst migrationContainerId = `${this._config.containerId}Migration${Date.now()}`;\n\t\treturn new CosmosDbEntityStorageConnector<U>({\n\t\t\tentitySchema: newEntitySchema,\n\t\t\tconfig: { ...this._config, containerId: migrationContainerId },\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\n\t}\n\n\t/**\n\t * Finalize the migration by tearing down the old container and replacing it with the target container.\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 optional component type to use for logging.\n\t * @returns The final connector pointing at the original container id.\n\t */\n\tpublic async finalizeMigration<U>(\n\t\ttargetConnector: CosmosDbEntityStorageConnector<U>,\n\t\toptions?: IMigrationOptions,\n\t\tloggingComponentType?: string\n\t): Promise<CosmosDbEntityStorageConnector<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 CosmosDbEntityStorageConnector<U>({\n\t\t\tentitySchema: targetConnector._entitySchemaName,\n\t\t\tconfig: this._config,\n\t\t\tpartitionContextIds: this._partitionContextIds\n\t\t});\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 ?? CosmosDbEntityStorageConnector._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\tCosmosDbEntityStorageConnector.CLASS_NAME,\n\t\t\t\"finalizeMigrationFailedBootstrap\"\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.\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.\n\t */\n\tpublic async cleanupMigration<U>(\n\t\ttargetConnector: IEntityStorageConnector<U> | undefined,\n\t\toptions?: IMigrationOptions,\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: CosmosDbEntityStorageConnector<U>,\n\t\tdestConnector: CosmosDbEntityStorageConnector<U>,\n\t\tpartitions: IContextIds[] | undefined,\n\t\tbatchSize: number\n\t): Promise<void> {\n\t\t// undefined → not partitioned: one pass with no partition key.\n\t\t// [] → partitioned but empty: nothing to copy, return early.\n\t\t// [{…}, …] → partitioned with data: iterate over each partition.\n\t\tif (partitions?.length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst partitionList = partitions ?? [{}];\n\n\t\tfor (let i = 0; i < partitionList.length; i++) {\n\t\t\t// Values from getPartitionContextIds are already short-form, so we join them\n\t\t\t// directly rather than using combinedContextKey, which expects long-form input\n\t\t\t// and calls guardAll (throwing if a registered handler rejects short-form values).\n\t\t\tconst partitionKey = Is.arrayValue(sourceConnector._partitionContextIds)\n\t\t\t\t? sourceConnector._partitionContextIds.map(k => partitionList[i][k]).join(\"/\")\n\t\t\t\t: CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;\n\n\t\t\tlet continuationToken: string | undefined;\n\t\t\tdo {\n\t\t\t\tconst feedOptions: FeedOptions = { maxItemCount: batchSize, continuationToken };\n\t\t\t\tconst { resources, continuationToken: nextToken } = await (\n\t\t\t\t\tawait sourceConnector.getContainer()\n\t\t\t\t).items\n\t\t\t\t\t.query<ItemDefinition & Resource>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tquery: `SELECT * FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionId`,\n\t\t\t\t\t\t\tparameters: [{ name: \"@partitionId\", value: partitionKey }]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfeedOptions\n\t\t\t\t\t)\n\t\t\t\t\t.fetchNext();\n\n\t\t\t\tcontinuationToken = nextToken;\n\n\t\t\t\tif (Is.arrayValue(resources)) {\n\t\t\t\t\tconst operations: OperationInput[] = resources.map(\n\t\t\t\t\t\t({\n\t\t\t\t\t\t\t_rid: rid,\n\t\t\t\t\t\t\t_self: self,\n\t\t\t\t\t\t\t_ts: ts,\n\t\t\t\t\t\t\t_etag: etag,\n\t\t\t\t\t\t\t_attachments: attachments,\n\t\t\t\t\t\t\t...rest\n\t\t\t\t\t\t}) => ({\n\t\t\t\t\t\t\toperationType: BulkOperationType.Upsert,\n\t\t\t\t\t\t\tpartitionKey,\n\t\t\t\t\t\t\tresourceBody: rest\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tawait (await destConnector.getContainer()).items.executeBulkOperations(operations);\n\t\t\t\t}\n\t\t\t} while (Is.stringValue(continuationToken));\n\t\t}\n\t}\n\n\t/**\n\t * Create an SQL condition clause.\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]: unknown }\n\t): string {\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}\n\n\t\tif (\"conditions\" in condition) {\n\t\t\tif (condition.conditions.length === 0) {\n\t\t\t\treturn \"\";\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: string[] = condition.conditions.map(c =>\n\t\t\t\tthis.buildQueryParameters(objectPath, c, attributeNames, attributeValues)\n\t\t\t);\n\n\t\t\tconst logicalOperator = this.mapConditionalOperator(condition.logicalOperator);\n\t\t\tconst queryClause = joinConditions\n\t\t\t\t.filter(j => j.length > 0)\n\t\t\t\t.map(j => j)\n\t\t\t\t.join(` ${logicalOperator} `);\n\n\t\t\treturn Is.stringValue(queryClause) ? ` (${queryClause}) ` : \"\";\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\treturn comparison;\n\t}\n\n\t/**\n\t * Map the framework comparison operators to those in CosmosDB.\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 * @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]: unknown }\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\t\tlet propName = `${attributeName.replace(/\\./g, \"\").replace(/@/g, \"\")}`;\n\n\t\tif (\n\t\t\t(comparator.comparison === ComparisonOperator.Equals ||\n\t\t\t\tcomparator.comparison === ComparisonOperator.NotEquals) &&\n\t\t\t(comparator.value === null || comparator.value === undefined)\n\t\t) {\n\t\t\t// Cosmos DB SQL null semantics mirror standard SQL: any comparison using = or <>\n\t\t\t// against null evaluates to UNKNOWN, not TRUE, so no rows are returned.\n\t\t\t// IS_NULL() and IS_DEFINED() must be used instead (no bound parameter needed).\n\t\t\tif (comparator.comparison === ComparisonOperator.Equals) {\n\t\t\t\treturn `(IS_NULL(c.${attributeName}) OR NOT IS_DEFINED(c.${attributeName}))`;\n\t\t\t}\n\t\t\treturn `(IS_DEFINED(c.${attributeName}) AND NOT IS_NULL(c.${attributeName}))`;\n\t\t} else if (Is.array(comparator.value)) {\n\t\t\tconst dbValues = comparator.value.map(v => this.propertyToDbValue(v, type));\n\t\t\tif (dbValues.length === 0 && comparator.comparison === ComparisonOperator.In) {\n\t\t\t\t// CosmosDB rejects `IN ()` - return always-false sentinel (#141).\n\t\t\t\treturn \"1=0\";\n\t\t\t}\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.map(name => `@${name}`).join(\", \")})`;\n\t\t} else if (\n\t\t\tIs.object(comparator.value) &&\n\t\t\t(comparator.comparison === ComparisonOperator.Equals ||\n\t\t\t\tcomparator.comparison === ComparisonOperator.NotEquals)\n\t\t) {\n\t\t\t// CosmosDB SQL does not support object equality with =; expand to per-property comparisons.\n\t\t\tconst op = comparator.comparison === ComparisonOperator.Equals ? \"=\" : \"<>\";\n\t\t\tconst join = comparator.comparison === ComparisonOperator.Equals ? \" AND \" : \" OR \";\n\t\t\tconst clauses: string[] = [];\n\t\t\tfor (const [key, val] of Object.entries(comparator.value)) {\n\t\t\t\tconst paramName = `${propName}${key}`;\n\t\t\t\tattributeValues[paramName] = val;\n\t\t\t\tclauses.push(`c.${attributeName}.${key} ${op} @${paramName}`);\n\t\t\t}\n\t\t\treturn clauses.length === 1 ? clauses[0] : `(${clauses.join(join)})`;\n\t\t} else {\n\t\t\t// Avoid parameter name conflicts by ensuring unique parameter names in the query\n\t\t\tlet counter = 1;\n\t\t\twhile (propName in attributeValues) {\n\t\t\t\tpropName = `${attributeName.replace(/\\./g, \"\").replace(/@/g, \"\")}${counter}`;\n\t\t\t\tcounter++;\n\t\t\t}\n\t\t\tattributeValues[propName] = comparator.value;\n\t\t}\n\n\t\tconst matches = attributeName.split(\".\").length;\n\t\tif (matches && comparator.comparison === ComparisonOperator.Equals) {\n\t\t\tattributeName = attributeName\n\t\t\t\t.split(\".\")\n\t\t\t\t.map(part => `[\"${part}\"]`)\n\t\t\t\t.join(\"\");\n\t\t\treturn `c${attributeName} = @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.Equals) {\n\t\t\treturn `c.${attributeName} = @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\treturn `c.${attributeName} <> @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.GreaterThan) {\n\t\t\treturn `c.${attributeName} > @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.LessThan) {\n\t\t\treturn `c.${attributeName} < @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.GreaterThanOrEqual) {\n\t\t\treturn `c.${attributeName} >= @${propName}`;\n\t\t} else if (comparator.comparison === ComparisonOperator.LessThanOrEqual) {\n\t\t\treturn `c.${attributeName} <= @${propName}`;\n\t\t} else if (\n\t\t\tIs.object(attributeValues[propName]) &&\n\t\t\tcomparator.comparison === ComparisonOperator.Includes\n\t\t) {\n\t\t\treturn `ARRAY_CONTAINS(c.${attributeName}, @${propName}, true)`;\n\t\t} else if (\n\t\t\t(type === \"array\" || type === \"object\") &&\n\t\t\tcomparator.comparison === ComparisonOperator.Includes\n\t\t) {\n\t\t\treturn `ARRAY_CONTAINS(c.${attributeName}, @${propName})`;\n\t\t} else if (\n\t\t\t(type === \"array\" || type === \"object\") &&\n\t\t\tcomparator.comparison === ComparisonOperator.NotIncludes\n\t\t) {\n\t\t\treturn `NOT ARRAY_CONTAINS(c.${attributeName}, @${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.Includes) {\n\t\t\treturn `CONTAINS(c.${attributeName}, @${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.NotIncludes) {\n\t\t\treturn `NOT CONTAINS(c.${attributeName}, @${propName})`;\n\t\t} else if (comparator.comparison === ComparisonOperator.In) {\n\t\t\treturn `c.${propName} IN ${attributeName}`;\n\t\t}\n\n\t\tthrow new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, \"comparisonNotSupported\", {\n\t\t\tcomparison: comparator.comparison\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): unknown {\n\t\tif (Is.object(value)) {\n\t\t\tconst map: { [id: string]: unknown } = {};\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 map;\n\t\t}\n\n\t\tif (type === \"string\") {\n\t\t\treturn `${Coerce.string(value)}`;\n\t\t} else if (type === \"integer\" || type === \"number\") {\n\t\t\treturn Coerce.number(value) ?? 0;\n\t\t} else if (type === \"boolean\") {\n\t\t\treturn Coerce.boolean(value) ?? false;\n\t\t}\n\n\t\treturn Coerce.string(value) ?? \"\";\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 CosmosDB.\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(CosmosDbEntityStorageConnector.CLASS_NAME, \"conditionalNotSupported\", {\n\t\t\toperator\n\t\t});\n\t}\n\n\t/**\n\t * Verify the conditions for the entity.\n\t * @param conditions The conditions to verify.\n\t * @param obj The object to verify the conditions against.\n\t * @returns True if all conditions are met, false otherwise.\n\t * @internal\n\t */\n\tprivate verifyConditions(\n\t\tconditions: { property: keyof T; value: unknown }[],\n\t\tobj: { [key in keyof T]: unknown }\n\t): boolean {\n\t\treturn conditions.every(\n\t\t\tcondition => ObjectHelper.propertyGet(obj, condition.property as string) === condition.value\n\t\t);\n\t}\n\n\t/**\n\t * Build a mutex key for optimistic-locking critical sections.\n\t * @param partitionKey The resolved partition key.\n\t * @param id The entity id.\n\t * @returns The mutex key.\n\t * @internal\n\t */\n\tprivate buildOptimisticMutexKey(partitionKey: string | undefined, id: string): string {\n\t\treturn `${CosmosDbEntityStorageConnector.CLASS_NAME}:optimistic:${this._config.databaseId}:${this._config.containerId}:${partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE}:${id}`;\n\t}\n\n\t/**\n\t * Convert an entity to an item.\n\t * @param item The item to convert.\n\t * @returns The entity.\n\t * @internal\n\t */\n\tprivate itemToEntity(item: (ItemDefinition & Resource) | undefined): T {\n\t\treturn EntityStorageHelper.unPrepareEntity<T>(item as T, [\n\t\t\tCosmosDbEntityStorageConnector._PARTITION_KEY,\n\t\t\t\"_attachments\",\n\t\t\t\"_etag\",\n\t\t\t\"_rid\",\n\t\t\t\"_self\",\n\t\t\t\"_ts\"\n\t\t]);\n\t}\n\n\t/**\n\t * Retrieve (or lazily create) the shared Cosmos DB client for this endpoint.\n\t * @returns The shared client.\n\t * @internal\n\t */\n\tprivate async getClient(): Promise<CosmosClient> {\n\t\treturn ConnectionHelper.openClient<CosmosClient>(\n\t\t\t\"cosmosDbClients\",\n\t\t\tthis.createClientId(),\n\t\t\tthis._instanceId,\n\t\t\tthis._mutexTimeoutMs,\n\t\t\tasync () =>\n\t\t\t\tnew CosmosClient({\n\t\t\t\t\tendpoint: this._config.endpoint,\n\t\t\t\t\tkey: this._config.key,\n\t\t\t\t\tconnectionPolicy: {\n\t\t\t\t\t\tenableEndpointDiscovery: !this._config.disableEndpointDiscovery\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Get the container for this connector's configured database and container.\n\t * @returns The container reference.\n\t * @internal\n\t */\n\tprivate async getContainer(): Promise<Container> {\n\t\treturn (await this.getClient())\n\t\t\t.database(this._config.databaseId)\n\t\t\t.container(this._config.containerId);\n\t}\n\n\t/**\n\t * Build a stable cache key for the shared client based on connection parameters.\n\t * @returns The client cache key.\n\t * @internal\n\t */\n\tprivate createClientId(): string {\n\t\treturn `${this._config.endpoint}|${this._config.databaseId}|${this._config.containerId}`;\n\t}\n\n\t/**\n\t * Check if the database exists.\n\t * @returns True if the database exists, false otherwise.\n\t * @internal\n\t */\n\tprivate async databaseExists(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst client = await this.getClient();\n\t\t\tconst { resources: databaseList } = await client.databases.readAll().fetchAll();\n\n\t\t\treturn databaseList.some((db: Resource) => db.id === this._config.databaseId);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a database to exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForDatabaseExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst databaseExists = await this.databaseExists();\n\t\t\tif (databaseExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Build the composite indexes needed to serve multi-property ORDER BY queries.\n\t * Pairing each sortable property with the primary key in both directions covers all\n\t * four direction combinations, as Cosmos DB also serves each index reversed.\n\t * @returns The indexing policy for the container, or undefined if the schema has no\n\t * sortable properties.\n\t * @internal\n\t */\n\tprivate buildIndexingPolicy(): IndexingPolicy | undefined {\n\t\tconst primaryKeyPath = `/${this._primaryKey.property as string}`;\n\t\tconst compositeIndexes: CompositePath[][] = [];\n\n\t\tif (Is.arrayValue(this._entitySchema.properties)) {\n\t\t\tfor (const prop of this._entitySchema.properties) {\n\t\t\t\tif (!prop.isPrimary && (Is.stringValue(prop.sortDirection) || prop.isSecondary)) {\n\t\t\t\t\tconst propertyPath = `/${prop.property as string}`;\n\t\t\t\t\tcompositeIndexes.push([\n\t\t\t\t\t\t{ path: propertyPath, order: \"ascending\" },\n\t\t\t\t\t\t{ path: primaryKeyPath, order: \"ascending\" }\n\t\t\t\t\t]);\n\t\t\t\t\tcompositeIndexes.push([\n\t\t\t\t\t\t{ path: propertyPath, order: \"ascending\" },\n\t\t\t\t\t\t{ path: primaryKeyPath, order: \"descending\" }\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn compositeIndexes.length > 0\n\t\t\t? {\n\t\t\t\t\tindexingMode: \"consistent\",\n\t\t\t\t\tautomatic: true,\n\t\t\t\t\tincludedPaths: [{ path: \"/*\" }],\n\t\t\t\t\tcompositeIndexes\n\t\t\t\t}\n\t\t\t: undefined;\n\t}\n\n\t/**\n\t * Check if the container exists.\n\t * @returns True if the container exists, false otherwise.\n\t * @internal\n\t */\n\tprivate async containerExists(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst client = await this.getClient();\n\t\t\tconst { resources: containers } = await client\n\t\t\t\t.database(this._config.databaseId)\n\t\t\t\t.containers.readAll()\n\t\t\t\t.fetchAll();\n\n\t\t\treturn containers.some((c: Resource) => c.id === this._config.containerId);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a container to exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForContainerExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst containerExists = await this.containerExists();\n\t\t\tif (containerExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a container to not exist.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async waitForContainerNotExists(): Promise<void> {\n\t\tfor (let attempt = 0; attempt < 20; attempt++) {\n\t\t\tconst containerExists = await this.containerExists();\n\t\t\tif (!containerExists) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise(resolve => setTimeout(resolve, 250));\n\t\t}\n\t}\n}\n"]}
@@ -16,6 +16,12 @@ export declare class CosmosDbEntityStorageConnector<T = unknown> implements IEnt
16
16
  * @param options The options for the connector.
17
17
  */
18
18
  constructor(options: ICosmosDbEntityStorageConnectorConstructorOptions);
19
+ /**
20
+ * The component needs to be stopped when the node is closed.
21
+ * @param nodeLoggingComponentType The node logging component type.
22
+ * @returns Nothing.
23
+ */
24
+ stop(nodeLoggingComponentType?: string): Promise<void>;
19
25
  /**
20
26
  * Initialize the Cosmos DB environment.
21
27
  * @param nodeLoggingComponentType Optional type of the logging component.
@@ -119,6 +125,11 @@ export declare class CosmosDbEntityStorageConnector<T = unknown> implements IEnt
119
125
  * @returns The list of unique context ids.
120
126
  */
121
127
  getPartitionContextIds(): Promise<IContextIds[] | undefined>;
128
+ /**
129
+ * Get the connector implementation version.
130
+ * @returns The connector implementation version.
131
+ */
132
+ connectorVersion(): number;
122
133
  /**
123
134
  * Create the target connector for performing the migration using a temporary container.
124
135
  * @param newEntitySchema The name of the new entity schema to create the connector for.
package/docs/changelog.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.2-next.8](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-cosmosdb-v0.9.2-next.7...entity-storage-connector-cosmosdb-v0.9.2-next.8) (2026-08-12)
4
+
5
+
6
+ ### Features
7
+
8
+ * indexing ([#207](https://github.com/iotaledger/twin-entity-storage/issues/207)) ([2fd1f0d](https://github.com/iotaledger/twin-entity-storage/commit/2fd1f0d992344905c9dd1a44addfc4f9d5b5c168))
9
+ * pooled connections ([#208](https://github.com/iotaledger/twin-entity-storage/issues/208)) ([5d832d1](https://github.com/iotaledger/twin-entity-storage/commit/5d832d15b0639f13ad3f5d2c68c946a72264310a))
10
+
11
+
12
+ ### Dependencies
13
+
14
+ * The following workspace dependencies were updated
15
+ * dependencies
16
+ * @twin.org/entity-storage-models bumped from 0.9.2-next.7 to 0.9.2-next.8
17
+ * devDependencies
18
+ * @twin.org/entity-storage-connector-memory bumped from 0.9.2-next.7 to 0.9.2-next.8
19
+
3
20
  ## [0.9.2-next.7](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-cosmosdb-v0.9.2-next.6...entity-storage-connector-cosmosdb-v0.9.2-next.7) (2026-08-11)
4
21
 
5
22
 
@@ -43,6 +43,32 @@ Runtime name for the class.
43
43
 
44
44
  ## Methods
45
45
 
46
+ ### stop() {#stop}
47
+
48
+ > **stop**(`nodeLoggingComponentType?`): `Promise`\<`void`\>
49
+
50
+ The component needs to be stopped when the node is closed.
51
+
52
+ #### Parameters
53
+
54
+ ##### nodeLoggingComponentType?
55
+
56
+ `string`
57
+
58
+ The node logging component type.
59
+
60
+ #### Returns
61
+
62
+ `Promise`\<`void`\>
63
+
64
+ Nothing.
65
+
66
+ #### Implementation of
67
+
68
+ `IEntityStorageMigrationConnector.stop`
69
+
70
+ ***
71
+
46
72
  ### bootstrap() {#bootstrap}
47
73
 
48
74
  > **bootstrap**(`nodeLoggingComponentType?`): `Promise`\<`boolean`\>
@@ -416,6 +442,24 @@ The list of unique context ids.
416
442
 
417
443
  ***
418
444
 
445
+ ### connectorVersion() {#connectorversion}
446
+
447
+ > **connectorVersion**(): `number`
448
+
449
+ Get the connector implementation version.
450
+
451
+ #### Returns
452
+
453
+ `number`
454
+
455
+ The connector implementation version.
456
+
457
+ #### Implementation of
458
+
459
+ `IEntityStorageMigrationConnector.connectorVersion`
460
+
461
+ ***
462
+
419
463
  ### createTargetConnector() {#createtargetconnector}
420
464
 
421
465
  > **createTargetConnector**\<`U`\>(`newEntitySchema`): `Promise`\<`IEntityStorageConnector`\<`U`\>\>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/entity-storage-connector-cosmosdb",
3
- "version": "0.9.2-next.7",
3
+ "version": "0.9.2-next.8",
4
4
  "description": "Azure Cosmos DB connector for globally distributed persistence.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,7 +19,7 @@
19
19
  "@twin.org/context": "next",
20
20
  "@twin.org/core": "next",
21
21
  "@twin.org/entity": "next",
22
- "@twin.org/entity-storage-models": "0.9.2-next.7",
22
+ "@twin.org/entity-storage-models": "0.9.2-next.8",
23
23
  "@twin.org/logging-models": "next",
24
24
  "@twin.org/nameof": "next"
25
25
  },