@twin.org/entity-storage-connector-cosmosdb 0.9.2-next.6 → 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.
- package/dist/es/cosmosDbEntityStorageConnector.js +216 -51
- package/dist/es/cosmosDbEntityStorageConnector.js.map +1 -1
- package/dist/es/models/ICosmosDbEntityStorageConnectorConfig.js.map +1 -1
- package/dist/types/cosmosDbEntityStorageConnector.d.ts +11 -0
- package/dist/types/models/ICosmosDbEntityStorageConnectorConfig.d.ts +4 -0
- package/docs/changelog.md +33 -0
- package/docs/reference/classes/CosmosDbEntityStorageConnector.md +44 -0
- package/docs/reference/interfaces/ICosmosDbEntityStorageConnectorConfig.md +8 -0
- package/locales/en.json +2 -0
- package/package.json +2 -2
|
@@ -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, GeneralError, Guards, Is, 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
|
|
@@ -49,21 +59,26 @@ export class CosmosDbEntityStorageConnector {
|
|
|
49
59
|
* @internal
|
|
50
60
|
*/
|
|
51
61
|
_primaryKey;
|
|
62
|
+
/**
|
|
63
|
+
* The name of the version property, if any.
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
_versionKey;
|
|
52
67
|
/**
|
|
53
68
|
* The configuration for the connector.
|
|
54
69
|
* @internal
|
|
55
70
|
*/
|
|
56
71
|
_config;
|
|
57
72
|
/**
|
|
58
|
-
*
|
|
73
|
+
* Milliseconds to wait for optimistic-lock mutexes before throwing.
|
|
59
74
|
* @internal
|
|
60
75
|
*/
|
|
61
|
-
|
|
76
|
+
_mutexTimeoutMs;
|
|
62
77
|
/**
|
|
63
|
-
*
|
|
78
|
+
* Unique identifier for this connector instance, used to track references in SharedStore.
|
|
64
79
|
* @internal
|
|
65
80
|
*/
|
|
66
|
-
|
|
81
|
+
_instanceId;
|
|
67
82
|
/**
|
|
68
83
|
* Create a new instance of CosmosDbEntityStorageConnector.
|
|
69
84
|
* @param options The options for the connector.
|
|
@@ -80,17 +95,18 @@ export class CosmosDbEntityStorageConnector {
|
|
|
80
95
|
this._entitySchemaName = options.entitySchema;
|
|
81
96
|
this._partitionContextIds = options.partitionContextIds;
|
|
82
97
|
this._primaryKey = EntitySchemaHelper.getPrimaryKey(this._entitySchema);
|
|
98
|
+
this._versionKey = EntitySchemaHelper.findVersionProperty(this._entitySchema);
|
|
83
99
|
this._config = options.config;
|
|
84
|
-
this.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
100
|
+
this._mutexTimeoutMs = Coerce.integer(options.config.mutexTimeoutMs);
|
|
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());
|
|
94
110
|
}
|
|
95
111
|
/**
|
|
96
112
|
* Initialize the Cosmos DB environment.
|
|
@@ -99,6 +115,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
99
115
|
*/
|
|
100
116
|
async bootstrap(nodeLoggingComponentType) {
|
|
101
117
|
const nodeLogging = ComponentFactory.getIfExists(nodeLoggingComponentType);
|
|
118
|
+
const client = await this.getClient();
|
|
102
119
|
// Create the database if it does not exist
|
|
103
120
|
try {
|
|
104
121
|
const databaseExists = await this.databaseExists();
|
|
@@ -123,7 +140,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
123
140
|
databaseId: this._config.databaseId
|
|
124
141
|
}
|
|
125
142
|
});
|
|
126
|
-
await
|
|
143
|
+
await client.databases.create({
|
|
127
144
|
id: this._config.databaseId
|
|
128
145
|
});
|
|
129
146
|
await this.waitForDatabaseExists();
|
|
@@ -166,7 +183,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
166
183
|
containerId: this._config.containerId
|
|
167
184
|
}
|
|
168
185
|
});
|
|
169
|
-
await
|
|
186
|
+
await client.database(this._config.databaseId).containers.create({
|
|
170
187
|
id: this._config.containerId,
|
|
171
188
|
partitionKey: {
|
|
172
189
|
kind: PartitionKeyKind.Hash,
|
|
@@ -205,10 +222,8 @@ export class CosmosDbEntityStorageConnector {
|
|
|
205
222
|
*/
|
|
206
223
|
async health() {
|
|
207
224
|
try {
|
|
208
|
-
await this.
|
|
209
|
-
|
|
210
|
-
.container(this._config.containerId)
|
|
211
|
-
.read();
|
|
225
|
+
const container = await this.getContainer();
|
|
226
|
+
await container.read();
|
|
212
227
|
return [
|
|
213
228
|
{
|
|
214
229
|
source: CosmosDbEntityStorageConnector.CLASS_NAME,
|
|
@@ -252,11 +267,15 @@ export class CosmosDbEntityStorageConnector {
|
|
|
252
267
|
const contextIds = await ContextIdStore.getContextIds();
|
|
253
268
|
const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
|
|
254
269
|
try {
|
|
270
|
+
const container = await this.getContainer();
|
|
255
271
|
// No secondary index or conditions
|
|
256
272
|
if (Is.empty(secondaryIndex) && !Is.arrayValue(conditions)) {
|
|
257
|
-
const { resource: item } = await
|
|
273
|
+
const { resource: item } = await container
|
|
258
274
|
.item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE)
|
|
259
275
|
.read();
|
|
276
|
+
if (Is.empty(item)) {
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
260
279
|
return this.itemToEntity(item);
|
|
261
280
|
}
|
|
262
281
|
const conditionValues = [];
|
|
@@ -290,7 +309,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
290
309
|
query: `SELECT * FROM c WHERE ${whereQuery.join(" AND ")}`,
|
|
291
310
|
parameters: conditionValues
|
|
292
311
|
};
|
|
293
|
-
const { resources: items } = await
|
|
312
|
+
const { resources: items } = await container.items.query(query).fetchAll();
|
|
294
313
|
if (items.length === 1) {
|
|
295
314
|
return this.itemToEntity(items[0]);
|
|
296
315
|
}
|
|
@@ -318,25 +337,66 @@ export class CosmosDbEntityStorageConnector {
|
|
|
318
337
|
EntityStorageHelper.validateConditions(this._entitySchema, conditions);
|
|
319
338
|
const contextIds = await ContextIdStore.getContextIds();
|
|
320
339
|
const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
|
|
340
|
+
const submittedVersion = Is.stringValue(this._versionKey)
|
|
341
|
+
? ObjectHelper.propertyGet(entity, this._versionKey)
|
|
342
|
+
: undefined;
|
|
343
|
+
const hasVersionCheck = !Is.empty(this._versionKey) && !Is.empty(submittedVersion) && submittedVersion > 0;
|
|
321
344
|
const prepared = EntityStorageHelper.prepareEntity(entity, this._entitySchema, undefined, {
|
|
322
345
|
nullBehavior: "omit"
|
|
323
346
|
});
|
|
324
347
|
const id = prepared[this._primaryKey.property];
|
|
348
|
+
const optimisticMutexKey = Is.stringValue(this._versionKey)
|
|
349
|
+
? this.buildOptimisticMutexKey(partitionKey, id)
|
|
350
|
+
: undefined;
|
|
351
|
+
if (Is.stringValue(optimisticMutexKey)) {
|
|
352
|
+
await Mutex.lock(optimisticMutexKey, {
|
|
353
|
+
throwOnTimeout: true,
|
|
354
|
+
timeoutMs: this._mutexTimeoutMs
|
|
355
|
+
});
|
|
356
|
+
}
|
|
325
357
|
try {
|
|
326
|
-
|
|
327
|
-
|
|
358
|
+
const container = await this.getContainer();
|
|
359
|
+
let itemEtag;
|
|
360
|
+
if (Is.stringValue(this._versionKey) || Is.arrayValue(conditions)) {
|
|
361
|
+
const item = container.item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE);
|
|
328
362
|
const { resource: itemData } = await item.read();
|
|
329
|
-
if (Is.
|
|
330
|
-
|
|
363
|
+
if (!Is.empty(itemData)) {
|
|
364
|
+
if (hasVersionCheck) {
|
|
365
|
+
const storedVersion = ObjectHelper.propertyGet(itemData, this._versionKey) ?? 0;
|
|
366
|
+
if (storedVersion !== submittedVersion) {
|
|
367
|
+
throw new ConflictError(CosmosDbEntityStorageConnector.CLASS_NAME, "optimisticLockFailed", id);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (Is.arrayValue(conditions) && !this.verifyConditions(conditions, itemData)) {
|
|
371
|
+
if (Is.stringValue(this._versionKey)) {
|
|
372
|
+
throw new ConflictError(CosmosDbEntityStorageConnector.CLASS_NAME, "conditionFailed", id);
|
|
373
|
+
}
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
itemEtag = ObjectHelper.propertyGet(itemData, "_etag");
|
|
377
|
+
}
|
|
378
|
+
if (Is.stringValue(this._versionKey)) {
|
|
379
|
+
const storedVersion = !Is.empty(itemData)
|
|
380
|
+
? (ObjectHelper.propertyGet(itemData, this._versionKey) ?? 0)
|
|
381
|
+
: 0;
|
|
382
|
+
ObjectHelper.propertySet(prepared, this._versionKey, storedVersion + 1);
|
|
331
383
|
}
|
|
332
384
|
}
|
|
333
|
-
await
|
|
385
|
+
await container.items.upsert({
|
|
334
386
|
id,
|
|
335
387
|
[CosmosDbEntityStorageConnector._PARTITION_KEY]: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE,
|
|
336
388
|
...prepared
|
|
337
|
-
})
|
|
389
|
+
}, Is.stringValue(itemEtag)
|
|
390
|
+
? { accessCondition: { type: "IfMatch", condition: itemEtag } }
|
|
391
|
+
: undefined);
|
|
338
392
|
}
|
|
339
393
|
catch (err) {
|
|
394
|
+
if (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {
|
|
395
|
+
throw err;
|
|
396
|
+
}
|
|
397
|
+
if (Is.object(err) && err.code === 412) {
|
|
398
|
+
throw new ConflictError(CosmosDbEntityStorageConnector.CLASS_NAME, "optimisticLockFailed", id);
|
|
399
|
+
}
|
|
340
400
|
if (BaseError.isAggregateError(err)) {
|
|
341
401
|
const errors = BaseError.fromAggregate(err);
|
|
342
402
|
if (BaseError.someErrorCode(errors, "ResourceNotFoundException")) {
|
|
@@ -349,6 +409,11 @@ export class CosmosDbEntityStorageConnector {
|
|
|
349
409
|
id
|
|
350
410
|
}, err);
|
|
351
411
|
}
|
|
412
|
+
finally {
|
|
413
|
+
if (Is.stringValue(optimisticMutexKey)) {
|
|
414
|
+
Mutex.unlock(optimisticMutexKey);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
352
417
|
}
|
|
353
418
|
/**
|
|
354
419
|
* Set multiple entities in a batch.
|
|
@@ -363,15 +428,30 @@ export class CosmosDbEntityStorageConnector {
|
|
|
363
428
|
nullBehavior: "omit"
|
|
364
429
|
}));
|
|
365
430
|
try {
|
|
366
|
-
await this.
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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
|
+
})());
|
|
373
452
|
}
|
|
374
|
-
|
|
453
|
+
await Promise.all(sends);
|
|
454
|
+
}
|
|
375
455
|
}
|
|
376
456
|
catch (err) {
|
|
377
457
|
throw new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, "setBatchFailed", undefined, err);
|
|
@@ -386,10 +466,11 @@ export class CosmosDbEntityStorageConnector {
|
|
|
386
466
|
const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
|
|
387
467
|
const pk = partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE;
|
|
388
468
|
try {
|
|
469
|
+
const container = await this.getContainer();
|
|
389
470
|
let continuationToken;
|
|
390
471
|
do {
|
|
391
472
|
const feedOptions = { maxItemCount: 100, continuationToken };
|
|
392
|
-
const { resources, continuationToken: nextToken } = await
|
|
473
|
+
const { resources, continuationToken: nextToken } = await container.items
|
|
393
474
|
.query({
|
|
394
475
|
query: `SELECT c.id FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @pk`,
|
|
395
476
|
parameters: [{ name: "@pk", value: pk }]
|
|
@@ -402,7 +483,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
402
483
|
id: r.id,
|
|
403
484
|
partitionKey: pk
|
|
404
485
|
}));
|
|
405
|
-
await
|
|
486
|
+
await container.items.executeBulkOperations(operations);
|
|
406
487
|
}
|
|
407
488
|
} while (Is.stringValue(continuationToken));
|
|
408
489
|
}
|
|
@@ -421,17 +502,33 @@ export class CosmosDbEntityStorageConnector {
|
|
|
421
502
|
EntityStorageHelper.validateConditions(this._entitySchema, conditions);
|
|
422
503
|
const contextIds = await ContextIdStore.getContextIds();
|
|
423
504
|
const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
|
|
505
|
+
const optimisticMutexKey = Is.stringValue(this._versionKey)
|
|
506
|
+
? this.buildOptimisticMutexKey(partitionKey, id)
|
|
507
|
+
: undefined;
|
|
508
|
+
if (Is.stringValue(optimisticMutexKey)) {
|
|
509
|
+
await Mutex.lock(optimisticMutexKey, {
|
|
510
|
+
throwOnTimeout: true,
|
|
511
|
+
timeoutMs: this._mutexTimeoutMs
|
|
512
|
+
});
|
|
513
|
+
}
|
|
424
514
|
try {
|
|
425
|
-
const
|
|
515
|
+
const container = await this.getContainer();
|
|
516
|
+
const item = container.item(id, partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE);
|
|
426
517
|
const { resource: itemData } = await item.read();
|
|
427
518
|
if (Is.notEmpty(itemData)) {
|
|
428
519
|
if (Is.arrayValue(conditions) && !this.verifyConditions(conditions, itemData)) {
|
|
520
|
+
if (Is.stringValue(this._versionKey)) {
|
|
521
|
+
throw new ConflictError(CosmosDbEntityStorageConnector.CLASS_NAME, "conditionFailed", id);
|
|
522
|
+
}
|
|
429
523
|
return;
|
|
430
524
|
}
|
|
431
525
|
await item.delete();
|
|
432
526
|
}
|
|
433
527
|
}
|
|
434
528
|
catch (err) {
|
|
529
|
+
if (BaseError.isErrorName(err, ConflictError.CLASS_NAME)) {
|
|
530
|
+
throw err;
|
|
531
|
+
}
|
|
435
532
|
if (BaseError.fromError(err) &&
|
|
436
533
|
Is.object(err) &&
|
|
437
534
|
err.body?.code === "NotFound") {
|
|
@@ -441,6 +538,11 @@ export class CosmosDbEntityStorageConnector {
|
|
|
441
538
|
id
|
|
442
539
|
}, err);
|
|
443
540
|
}
|
|
541
|
+
finally {
|
|
542
|
+
if (Is.stringValue(optimisticMutexKey)) {
|
|
543
|
+
Mutex.unlock(optimisticMutexKey);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
444
546
|
}
|
|
445
547
|
/**
|
|
446
548
|
* Remove multiple entities by id.
|
|
@@ -452,12 +554,13 @@ export class CosmosDbEntityStorageConnector {
|
|
|
452
554
|
const contextIds = await ContextIdStore.getContextIds();
|
|
453
555
|
const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
|
|
454
556
|
try {
|
|
557
|
+
const container = await this.getContainer();
|
|
455
558
|
const operations = ids.map(id => ({
|
|
456
559
|
operationType: BulkOperationType.Delete,
|
|
457
560
|
id,
|
|
458
561
|
partitionKey: partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE
|
|
459
562
|
}));
|
|
460
|
-
await
|
|
563
|
+
await container.items.executeBulkOperations(operations);
|
|
461
564
|
}
|
|
462
565
|
catch (err) {
|
|
463
566
|
throw new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, "removeBatchFailed", undefined, err);
|
|
@@ -478,8 +581,9 @@ export class CosmosDbEntityStorageConnector {
|
|
|
478
581
|
data: { containerId: this._config.containerId }
|
|
479
582
|
});
|
|
480
583
|
try {
|
|
584
|
+
const container = await this.getContainer();
|
|
481
585
|
if (await this.containerExists()) {
|
|
482
|
-
await
|
|
586
|
+
await container.delete();
|
|
483
587
|
await this.waitForContainerNotExists();
|
|
484
588
|
}
|
|
485
589
|
await nodeLogging?.log({
|
|
@@ -535,6 +639,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
535
639
|
Validation.asValidationError(CosmosDbEntityStorageConnector.CLASS_NAME, "query", validationFailures);
|
|
536
640
|
}
|
|
537
641
|
try {
|
|
642
|
+
const container = await this.getContainer();
|
|
538
643
|
const returnSize = limit ?? CosmosDbEntityStorageConnector._DEFAULT_LIMIT;
|
|
539
644
|
let orderByClause = "";
|
|
540
645
|
if (Is.arrayValue(sortProperties)) {
|
|
@@ -570,7 +675,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
570
675
|
const startIndex = Coerce.number(cursor) ?? 0;
|
|
571
676
|
sql = `${baseQuery} ${orderByClause} OFFSET ${startIndex} LIMIT ${returnSize + 1}`;
|
|
572
677
|
const sortedQuerySpecs = { query: sql, parameters: queryParameters };
|
|
573
|
-
const sortedResponse = await
|
|
678
|
+
const sortedResponse = await container.items
|
|
574
679
|
.query(sortedQuerySpecs, {
|
|
575
680
|
partitionKey: queryPartitionKey,
|
|
576
681
|
maxItemCount: returnSize + 1
|
|
@@ -595,6 +700,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
595
700
|
async count(conditions) {
|
|
596
701
|
EntityStorageHelper.validateConditionProperties(this._entitySchema, conditions);
|
|
597
702
|
try {
|
|
703
|
+
const container = await this.getContainer();
|
|
598
704
|
const contextIds = await ContextIdStore.getContextIds();
|
|
599
705
|
const partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);
|
|
600
706
|
const attributeNames = {};
|
|
@@ -615,7 +721,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
615
721
|
...Object.keys(attributeValues).map(key => ({ name: `@${key}`, value: attributeValues[key] }))
|
|
616
722
|
]
|
|
617
723
|
};
|
|
618
|
-
const { resources } = await
|
|
724
|
+
const { resources } = await container.items.query(querySpec).fetchAll();
|
|
619
725
|
return resources[0] ?? 0;
|
|
620
726
|
}
|
|
621
727
|
catch (err) {
|
|
@@ -632,7 +738,8 @@ export class CosmosDbEntityStorageConnector {
|
|
|
632
738
|
return undefined;
|
|
633
739
|
}
|
|
634
740
|
try {
|
|
635
|
-
const
|
|
741
|
+
const container = await this.getContainer();
|
|
742
|
+
const { resources: partitionIds } = await container.items
|
|
636
743
|
.query({
|
|
637
744
|
query: `SELECT DISTINCT VALUE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} FROM c`
|
|
638
745
|
})
|
|
@@ -645,6 +752,13 @@ export class CosmosDbEntityStorageConnector {
|
|
|
645
752
|
throw new GeneralError(CosmosDbEntityStorageConnector.CLASS_NAME, "getPartitionContextIdsFailed", undefined, err);
|
|
646
753
|
}
|
|
647
754
|
}
|
|
755
|
+
/**
|
|
756
|
+
* Get the connector implementation version.
|
|
757
|
+
* @returns The connector implementation version.
|
|
758
|
+
*/
|
|
759
|
+
connectorVersion() {
|
|
760
|
+
return 0;
|
|
761
|
+
}
|
|
648
762
|
/**
|
|
649
763
|
* Create the target connector for performing the migration using a temporary container.
|
|
650
764
|
* @param newEntitySchema The name of the new entity schema to create the connector for.
|
|
@@ -722,7 +836,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
722
836
|
let continuationToken;
|
|
723
837
|
do {
|
|
724
838
|
const feedOptions = { maxItemCount: batchSize, continuationToken };
|
|
725
|
-
const { resources, continuationToken: nextToken } = await sourceConnector.
|
|
839
|
+
const { resources, continuationToken: nextToken } = await (await sourceConnector.getContainer()).items
|
|
726
840
|
.query({
|
|
727
841
|
query: `SELECT * FROM c WHERE c.${CosmosDbEntityStorageConnector._PARTITION_KEY} = @partitionId`,
|
|
728
842
|
parameters: [{ name: "@partitionId", value: partitionKey }]
|
|
@@ -735,7 +849,7 @@ export class CosmosDbEntityStorageConnector {
|
|
|
735
849
|
partitionKey,
|
|
736
850
|
resourceBody: rest
|
|
737
851
|
}));
|
|
738
|
-
await destConnector.
|
|
852
|
+
await (await destConnector.getContainer()).items.executeBulkOperations(operations);
|
|
739
853
|
}
|
|
740
854
|
} while (Is.stringValue(continuationToken));
|
|
741
855
|
}
|
|
@@ -963,6 +1077,16 @@ export class CosmosDbEntityStorageConnector {
|
|
|
963
1077
|
verifyConditions(conditions, obj) {
|
|
964
1078
|
return conditions.every(condition => ObjectHelper.propertyGet(obj, condition.property) === condition.value);
|
|
965
1079
|
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Build a mutex key for optimistic-locking critical sections.
|
|
1082
|
+
* @param partitionKey The resolved partition key.
|
|
1083
|
+
* @param id The entity id.
|
|
1084
|
+
* @returns The mutex key.
|
|
1085
|
+
* @internal
|
|
1086
|
+
*/
|
|
1087
|
+
buildOptimisticMutexKey(partitionKey, id) {
|
|
1088
|
+
return `${CosmosDbEntityStorageConnector.CLASS_NAME}:optimistic:${this._config.databaseId}:${this._config.containerId}:${partitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE}:${id}`;
|
|
1089
|
+
}
|
|
966
1090
|
/**
|
|
967
1091
|
* Convert an entity to an item.
|
|
968
1092
|
* @param item The item to convert.
|
|
@@ -979,6 +1103,38 @@ export class CosmosDbEntityStorageConnector {
|
|
|
979
1103
|
"_ts"
|
|
980
1104
|
]);
|
|
981
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
|
+
}
|
|
982
1138
|
/**
|
|
983
1139
|
* Check if the database exists.
|
|
984
1140
|
* @returns True if the database exists, false otherwise.
|
|
@@ -986,7 +1142,8 @@ export class CosmosDbEntityStorageConnector {
|
|
|
986
1142
|
*/
|
|
987
1143
|
async databaseExists() {
|
|
988
1144
|
try {
|
|
989
|
-
const
|
|
1145
|
+
const client = await this.getClient();
|
|
1146
|
+
const { resources: databaseList } = await client.databases.readAll().fetchAll();
|
|
990
1147
|
return databaseList.some((db) => db.id === this._config.databaseId);
|
|
991
1148
|
}
|
|
992
1149
|
catch {
|
|
@@ -1033,7 +1190,14 @@ export class CosmosDbEntityStorageConnector {
|
|
|
1033
1190
|
}
|
|
1034
1191
|
}
|
|
1035
1192
|
}
|
|
1036
|
-
return compositeIndexes.length > 0
|
|
1193
|
+
return compositeIndexes.length > 0
|
|
1194
|
+
? {
|
|
1195
|
+
indexingMode: "consistent",
|
|
1196
|
+
automatic: true,
|
|
1197
|
+
includedPaths: [{ path: "/*" }],
|
|
1198
|
+
compositeIndexes
|
|
1199
|
+
}
|
|
1200
|
+
: undefined;
|
|
1037
1201
|
}
|
|
1038
1202
|
/**
|
|
1039
1203
|
* Check if the container exists.
|
|
@@ -1042,7 +1206,8 @@ export class CosmosDbEntityStorageConnector {
|
|
|
1042
1206
|
*/
|
|
1043
1207
|
async containerExists() {
|
|
1044
1208
|
try {
|
|
1045
|
-
const
|
|
1209
|
+
const client = await this.getClient();
|
|
1210
|
+
const { resources: containers } = await client
|
|
1046
1211
|
.database(this._config.databaseId)
|
|
1047
1212
|
.containers.readAll()
|
|
1048
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\tGeneralError,\n\tGuards,\n\tIs,\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 configuration for the connector.\n\t * @internal\n\t */\n\tprivate readonly _config: ICosmosDbEntityStorageConnectorConfig;\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\n\t\tthis._config = options.config;\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\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 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\n\t\ttry {\n\t\t\tif (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.notEmpty(itemData) && !this.verifyConditions(conditions, itemData as T)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait this._container.items.upsert({\n\t\t\t\tid,\n\t\t\t\t[CosmosDbEntityStorageConnector._PARTITION_KEY]:\n\t\t\t\t\tpartitionKey ?? CosmosDbEntityStorageConnector._PARTITION_KEY_VALUE,\n\t\t\t\t...prepared\n\t\t\t});\n\t\t} catch (err) {\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}\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\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\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 (\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}\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 * 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 ? { compositeIndexes } : 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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ICosmosDbEntityStorageConnectorConfig.js","sourceRoot":"","sources":["../../../src/models/ICosmosDbEntityStorageConnectorConfig.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Configuration for the Cosmos DB Entity Storage Connector.\n */\nexport interface ICosmosDbEntityStorageConnectorConfig {\n\t/**\n\t * The endpoint for the Cosmos DB instance.\n\t */\n\tendpoint: string;\n\n\t/**\n\t * The primary key for the Cosmos DB instance.\n\t */\n\tkey: string;\n\n\t/**\n\t * The ID of the database to be used.\n\t */\n\tdatabaseId: string;\n\n\t/**\n\t * The ID of the container for the storage.\n\t */\n\tcontainerId: string;\n\n\t/**\n\t * The offer throughput for the container.\n\t */\n\tofferThroughput?: number;\n\n\t/**\n\t * Disable endpoint discovery so the SDK always uses the configured endpoint.\n\t * Required when using the CosmosDB emulator behind a port-mapped Docker container,\n\t * because the emulator's account response advertises its internal container port\n\t * instead of the mapped host port.\n\t */\n\tdisableEndpointDiscovery?: boolean;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ICosmosDbEntityStorageConnectorConfig.js","sourceRoot":"","sources":["../../../src/models/ICosmosDbEntityStorageConnectorConfig.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Configuration for the Cosmos DB Entity Storage Connector.\n */\nexport interface ICosmosDbEntityStorageConnectorConfig {\n\t/**\n\t * The endpoint for the Cosmos DB instance.\n\t */\n\tendpoint: string;\n\n\t/**\n\t * The primary key for the Cosmos DB instance.\n\t */\n\tkey: string;\n\n\t/**\n\t * The ID of the database to be used.\n\t */\n\tdatabaseId: string;\n\n\t/**\n\t * The ID of the container for the storage.\n\t */\n\tcontainerId: string;\n\n\t/**\n\t * The offer throughput for the container.\n\t */\n\tofferThroughput?: number;\n\n\t/**\n\t * Disable endpoint discovery so the SDK always uses the configured endpoint.\n\t * Required when using the CosmosDB emulator behind a port-mapped Docker container,\n\t * because the emulator's account response advertises its internal container port\n\t * instead of the mapped host port.\n\t */\n\tdisableEndpointDiscovery?: boolean;\n\n\t/**\n\t * Milliseconds to wait for connector mutex locks before throwing.\n\t */\n\tmutexTimeoutMs?: number;\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,38 @@
|
|
|
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
|
+
|
|
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)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* optimistic locking ([#201](https://github.com/iotaledger/twin-entity-storage/issues/201)) ([80cbe3b](https://github.com/iotaledger/twin-entity-storage/commit/80cbe3b611c47b16328bceab02cfb8423fe1bbcd))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Dependencies
|
|
29
|
+
|
|
30
|
+
* The following workspace dependencies were updated
|
|
31
|
+
* dependencies
|
|
32
|
+
* @twin.org/entity-storage-models bumped from 0.9.2-next.6 to 0.9.2-next.7
|
|
33
|
+
* devDependencies
|
|
34
|
+
* @twin.org/entity-storage-connector-memory bumped from 0.9.2-next.6 to 0.9.2-next.7
|
|
35
|
+
|
|
3
36
|
## [0.9.2-next.6](https://github.com/iotaledger/twin-entity-storage/compare/entity-storage-connector-cosmosdb-v0.9.2-next.5...entity-storage-connector-cosmosdb-v0.9.2-next.6) (2026-08-07)
|
|
4
37
|
|
|
5
38
|
|
|
@@ -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`\>\>
|
|
@@ -52,3 +52,11 @@ Disable endpoint discovery so the SDK always uses the configured endpoint.
|
|
|
52
52
|
Required when using the CosmosDB emulator behind a port-mapped Docker container,
|
|
53
53
|
because the emulator's account response advertises its internal container port
|
|
54
54
|
instead of the mapped host port.
|
|
55
|
+
|
|
56
|
+
***
|
|
57
|
+
|
|
58
|
+
### mutexTimeoutMs? {#mutextimeoutms}
|
|
59
|
+
|
|
60
|
+
> `optional` **mutexTimeoutMs?**: `number`
|
|
61
|
+
|
|
62
|
+
Milliseconds to wait for connector mutex locks before throwing.
|
package/locales/en.json
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
},
|
|
12
12
|
"error": {
|
|
13
13
|
"cosmosDbEntityStorageConnector": {
|
|
14
|
+
"optimisticLockFailed": "The entity \"{conflictId}\" could not be written because the optimistic lock check failed",
|
|
15
|
+
"conditionFailed": "The entity \"{conflictId}\" could not be updated because the supplied conditions did not match the stored state",
|
|
14
16
|
"setFailed": "Unable to set entity \"{id}\"",
|
|
15
17
|
"getFailed": "Unable to get entity \"{id}\"",
|
|
16
18
|
"removeFailed": "Unable to remove entity \"{id}\"",
|
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.
|
|
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.
|
|
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
|
},
|