@sprucelabs/data-stores 31.0.8 → 31.0.10

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.
@@ -36,7 +36,6 @@ export default class MongoDatabase implements Database {
36
36
  syncIndexes(collectionName: string, indexes: Index[]): Promise<void>;
37
37
  private _syncIndexes;
38
38
  createUniqueIndex(collection: string, index: string[] | IndexWithFilter): Promise<void>;
39
- private generateIndexName;
40
39
  private normalizeIndex;
41
40
  syncUniqueIndexes(collectionName: string, indexes: Index[]): Promise<void>;
42
41
  update(collection: string, query: Record<string, any>, updates: Record<string, any>): Promise<number>;
@@ -236,10 +236,11 @@ class MongoDatabase {
236
236
  }
237
237
  async dropIndex(collection, index) {
238
238
  const indexes = await this.listIndexes(collection);
239
- const name = this.generateIndexName(this.normalizeIndex(index));
239
+ const name = this.normalizeIndex(index).name;
240
240
  let found = false;
241
241
  for (const thisIndex of indexes) {
242
- if (thisIndex.name === name) {
242
+ if (this.normalizeIndex(this.mongoIndexToIndexWithFilter(thisIndex))
243
+ .name === name) {
243
244
  await this.assertDbWhileAttempingTo('drop a index.', collection)
244
245
  .collection(collection)
245
246
  .dropIndex(thisIndex.name);
@@ -260,10 +261,10 @@ class MongoDatabase {
260
261
  const uniqueIndexes = [];
261
262
  for (const index of indexes) {
262
263
  if (index.unique) {
263
- uniqueIndexes.push({
264
+ uniqueIndexes.push(this.normalizeIndex({
264
265
  fields: Object.keys(index.key),
265
266
  filter: index.partialFilterExpression,
266
- });
267
+ }));
267
268
  }
268
269
  }
269
270
  return uniqueIndexes;
@@ -291,31 +292,32 @@ class MongoDatabase {
291
292
  }
292
293
  }
293
294
  mongoIndexToIndexWithFilter(index) {
294
- return {
295
+ return (0, database_utilities_1.normalizeIndex)({
295
296
  fields: Object.keys(index.key),
296
297
  filter: index.partialFilterExpression,
297
298
  name: index.name,
298
- };
299
+ });
299
300
  }
300
301
  async createIndex(collection, index) {
301
302
  const currentIndexes = await this.getIndexes(collection);
302
303
  this.assertIndexDoesNotExist(currentIndexes, index, collection);
303
304
  const indexSpec = {};
304
- this.normalizeIndex(index).fields.forEach((name) => {
305
+ const normalized = this.normalizeIndex(index);
306
+ normalized.fields.forEach((name) => {
305
307
  indexSpec[name] = 1;
306
308
  });
307
309
  try {
308
310
  await this.assertDbWhileAttempingTo('create an index.', collection)
309
311
  .collection(collection)
310
312
  .createIndex(indexSpec, {
311
- name: this.generateIndexName(index),
313
+ name: normalized.name,
312
314
  });
313
315
  }
314
316
  catch (err) {
315
317
  if ((err === null || err === void 0 ? void 0 : err.code) === 11000) {
316
318
  throw new SpruceError_1.default({
317
319
  code: 'DUPLICATE_KEY',
318
- friendlyMessage: `Could not create index! Index on '${collection}' has duplicate key for "${this.normalizeIndex(index).fields.join(',')}"`,
320
+ friendlyMessage: `Could not create index! Index on '${collection}' has duplicate key for "${normalized.fields.join(',')}"`,
319
321
  });
320
322
  }
321
323
  else {
@@ -338,15 +340,17 @@ class MongoDatabase {
338
340
  async syncIndexes(collectionName, indexes) {
339
341
  await this._syncIndexes(collectionName, indexes, 'createIndex');
340
342
  }
341
- async _syncIndexes(collectionName, indexes, func, shouldIncludeUnique = false) {
343
+ async _syncIndexes(collectionName, indexes, func, isSyncingUniqueIndexes = false) {
342
344
  var _a;
343
- const currentIndexes = await this.getIndexes(collectionName, shouldIncludeUnique);
345
+ const currentIndexes = isSyncingUniqueIndexes
346
+ ? await this.getUniqueIndexes(collectionName)
347
+ : await this.getIndexes(collectionName);
344
348
  const indexesToDelete = (0, database_utilities_1.pluckMissingIndexes)(currentIndexes, indexes);
345
349
  for (const extra of indexesToDelete) {
346
350
  await this.dropIndex(collectionName, extra);
347
351
  }
348
352
  for (const index of indexes) {
349
- if (!this.doesInclude(currentIndexes, this.normalizeIndex(index))) {
353
+ if (!this.doesInclude(currentIndexes, this.normalizeIndex(index, isSyncingUniqueIndexes))) {
350
354
  try {
351
355
  await this[func](collectionName, index);
352
356
  }
@@ -360,7 +364,7 @@ class MongoDatabase {
360
364
  }
361
365
  async createUniqueIndex(collection, index) {
362
366
  const currentIndexes = await this.getUniqueIndexes(collection);
363
- const indexWithFilter = this.normalizeIndex(index);
367
+ const indexWithFilter = this.normalizeIndex(index, true);
364
368
  this.assertIndexDoesNotExist(currentIndexes, indexWithFilter, collection);
365
369
  const created = {};
366
370
  indexWithFilter.fields.forEach((name) => {
@@ -369,7 +373,7 @@ class MongoDatabase {
369
373
  try {
370
374
  const options = {
371
375
  unique: true,
372
- name: this.generateIndexName(indexWithFilter),
376
+ name: indexWithFilter.name,
373
377
  };
374
378
  if (indexWithFilter.filter) {
375
379
  options.partialFilterExpression = indexWithFilter.filter;
@@ -391,11 +395,8 @@ class MongoDatabase {
391
395
  }
392
396
  }
393
397
  }
394
- generateIndexName(indexWithFilter) {
395
- return (0, database_utilities_1.generateIndexName)(this.normalizeIndex(indexWithFilter));
396
- }
397
- normalizeIndex(index) {
398
- return (0, database_utilities_1.normalizeIndex)(index);
398
+ normalizeIndex(index, isUnique) {
399
+ return (0, database_utilities_1.normalizeIndex)(index, isUnique);
399
400
  }
400
401
  async syncUniqueIndexes(collectionName, indexes) {
401
402
  await this._syncIndexes(collectionName, indexes, 'createUniqueIndex', true);
@@ -440,31 +440,37 @@ class NeDbDatabase extends AbstractMutexer_1.default {
440
440
  col._indexes = [];
441
441
  }
442
442
  await this.randomDelay();
443
- this.assertIndexDoesNotExist(col._indexes, this.normalizeIndex(fields), collection);
444
- col._indexes.push({ fields });
443
+ const normalized = this.normalizeIndex(fields);
444
+ this.assertIndexDoesNotExist(col._indexes, normalized, collection);
445
+ col._indexes.push(normalized);
445
446
  }
446
447
  normalizeIndex(index) {
447
- const { fields, filter } = (0, database_utilities_1.normalizeIndex)(index);
448
- return { fields, filter };
448
+ return (0, database_utilities_1.normalizeIndex)(index);
449
449
  }
450
450
  async syncUniqueIndexes(collectionName, indexes) {
451
451
  var _a;
452
+ await this.lock('syncUniqueIndexesMutex');
452
453
  const currentIndexes = await this.getUniqueIndexes(collectionName);
453
454
  const toDelete = (0, database_utilities_1.pluckMissingIndexes)(currentIndexes, indexes);
454
- for (const index of indexes) {
455
- if (!this.doesInclude(currentIndexes, index)) {
456
- try {
457
- await this.createUniqueIndex(collectionName, index);
458
- }
459
- catch (err) {
460
- if (((_a = err.options) === null || _a === void 0 ? void 0 : _a.code) !== 'INDEX_EXISTS') {
461
- throw err;
455
+ try {
456
+ for (const index of indexes) {
457
+ if (!this.doesInclude(currentIndexes, index)) {
458
+ try {
459
+ await this.createUniqueIndex(collectionName, index);
460
+ }
461
+ catch (err) {
462
+ if (((_a = err.options) === null || _a === void 0 ? void 0 : _a.code) !== 'INDEX_EXISTS') {
463
+ throw err;
464
+ }
462
465
  }
463
466
  }
464
467
  }
468
+ for (const extra of toDelete) {
469
+ await this.dropIndex(collectionName, extra);
470
+ }
465
471
  }
466
- for (const extra of toDelete) {
467
- await this.dropIndex(collectionName, extra);
472
+ finally {
473
+ this.unlock('syncUniqueIndexesMutex');
468
474
  }
469
475
  }
470
476
  async syncIndexes(collectionName, indexes) {
@@ -1,6 +1,5 @@
1
1
  import { IndexWithFilter, Index } from '../types/database.types';
2
2
  export declare function doesIndexesInclude(haystack: Index[], needle: Index): boolean;
3
3
  export declare function areIndexesEqual(left: Index, right: Index): boolean;
4
- export declare function generateIndexName(indexWithFilter: IndexWithFilter): string;
5
- export declare function normalizeIndex(index: Index): IndexWithFilter;
4
+ export declare function normalizeIndex(index: Index, isUnique?: boolean): IndexWithFilter;
6
5
  export declare function pluckMissingIndexes(left: Index[], right: Index[]): Index[];
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.doesIndexesInclude = doesIndexesInclude;
7
7
  exports.areIndexesEqual = areIndexesEqual;
8
- exports.generateIndexName = generateIndexName;
9
8
  exports.normalizeIndex = normalizeIndex;
10
9
  exports.pluckMissingIndexes = pluckMissingIndexes;
11
10
  const differenceWith_1 = __importDefault(require("lodash/differenceWith"));
@@ -22,7 +21,7 @@ function areIndexesEqual(left, right) {
22
21
  const name2 = generateIndexName(normalizeIndex(right));
23
22
  return name1 === name2;
24
23
  }
25
- function generateIndexName(indexWithFilter) {
24
+ function generateIndexName(indexWithFilter, isUnique) {
26
25
  if (indexWithFilter.name) {
27
26
  return indexWithFilter.name;
28
27
  }
@@ -30,18 +29,23 @@ function generateIndexName(indexWithFilter) {
30
29
  if (indexWithFilter.filter) {
31
30
  name += '_filtered';
32
31
  }
32
+ if (isUnique) {
33
+ name += '_unique';
34
+ }
33
35
  return name;
34
36
  }
35
- function normalizeIndex(index) {
36
- var _a;
37
+ function normalizeIndex(index, isUnique) {
37
38
  const fields = Array.isArray(index) ? index : index.fields;
38
39
  const filter = Array.isArray(index) ? undefined : index.filter;
39
40
  fields.sort();
40
- return {
41
+ const normalized = {
41
42
  fields,
42
- filter,
43
- name: (_a = index.name) !== null && _a !== void 0 ? _a : undefined,
44
43
  };
44
+ if (filter) {
45
+ normalized.filter = filter;
46
+ }
47
+ normalized.name = generateIndexName(normalized, isUnique);
48
+ return normalized;
45
49
  }
46
50
  function pluckMissingIndexes(left, right) {
47
51
  return (0, differenceWith_1.default)(left, right, areIndexesEqual);
@@ -36,7 +36,6 @@ export default class MongoDatabase implements Database {
36
36
  syncIndexes(collectionName: string, indexes: Index[]): Promise<void>;
37
37
  private _syncIndexes;
38
38
  createUniqueIndex(collection: string, index: string[] | IndexWithFilter): Promise<void>;
39
- private generateIndexName;
40
39
  private normalizeIndex;
41
40
  syncUniqueIndexes(collectionName: string, indexes: Index[]): Promise<void>;
42
41
  update(collection: string, query: Record<string, any>, updates: Record<string, any>): Promise<number>;
@@ -23,7 +23,7 @@ import { MongoClient, MongoError, } from 'mongodb';
23
23
  import SpruceError from '../errors/SpruceError.js';
24
24
  import generateId from '../utilities/generateId.js';
25
25
  import mongoUtil from '../utilities/mongo.utility.js';
26
- import { doesIndexesInclude, generateIndexName, normalizeIndex, pluckMissingIndexes, } from './database.utilities.js';
26
+ import { doesIndexesInclude, normalizeIndex, pluckMissingIndexes, } from './database.utilities.js';
27
27
  export const MONGO_TEST_URI = 'mongodb://localhost:27017';
28
28
  export default class MongoDatabase {
29
29
  constructor(url, options) {
@@ -262,10 +262,11 @@ export default class MongoDatabase {
262
262
  dropIndex(collection, index) {
263
263
  return __awaiter(this, void 0, void 0, function* () {
264
264
  const indexes = yield this.listIndexes(collection);
265
- const name = this.generateIndexName(this.normalizeIndex(index));
265
+ const name = this.normalizeIndex(index).name;
266
266
  let found = false;
267
267
  for (const thisIndex of indexes) {
268
- if (thisIndex.name === name) {
268
+ if (this.normalizeIndex(this.mongoIndexToIndexWithFilter(thisIndex))
269
+ .name === name) {
269
270
  yield this.assertDbWhileAttempingTo('drop a index.', collection)
270
271
  .collection(collection)
271
272
  .dropIndex(thisIndex.name);
@@ -288,10 +289,10 @@ export default class MongoDatabase {
288
289
  const uniqueIndexes = [];
289
290
  for (const index of indexes) {
290
291
  if (index.unique) {
291
- uniqueIndexes.push({
292
+ uniqueIndexes.push(this.normalizeIndex({
292
293
  fields: Object.keys(index.key),
293
294
  filter: index.partialFilterExpression,
294
- });
295
+ }));
295
296
  }
296
297
  }
297
298
  return uniqueIndexes;
@@ -322,32 +323,33 @@ export default class MongoDatabase {
322
323
  });
323
324
  }
324
325
  mongoIndexToIndexWithFilter(index) {
325
- return {
326
+ return normalizeIndex({
326
327
  fields: Object.keys(index.key),
327
328
  filter: index.partialFilterExpression,
328
329
  name: index.name,
329
- };
330
+ });
330
331
  }
331
332
  createIndex(collection, index) {
332
333
  return __awaiter(this, void 0, void 0, function* () {
333
334
  const currentIndexes = yield this.getIndexes(collection);
334
335
  this.assertIndexDoesNotExist(currentIndexes, index, collection);
335
336
  const indexSpec = {};
336
- this.normalizeIndex(index).fields.forEach((name) => {
337
+ const normalized = this.normalizeIndex(index);
338
+ normalized.fields.forEach((name) => {
337
339
  indexSpec[name] = 1;
338
340
  });
339
341
  try {
340
342
  yield this.assertDbWhileAttempingTo('create an index.', collection)
341
343
  .collection(collection)
342
344
  .createIndex(indexSpec, {
343
- name: this.generateIndexName(index),
345
+ name: normalized.name,
344
346
  });
345
347
  }
346
348
  catch (err) {
347
349
  if ((err === null || err === void 0 ? void 0 : err.code) === 11000) {
348
350
  throw new SpruceError({
349
351
  code: 'DUPLICATE_KEY',
350
- friendlyMessage: `Could not create index! Index on '${collection}' has duplicate key for "${this.normalizeIndex(index).fields.join(',')}"`,
352
+ friendlyMessage: `Could not create index! Index on '${collection}' has duplicate key for "${normalized.fields.join(',')}"`,
351
353
  });
352
354
  }
353
355
  else {
@@ -374,15 +376,17 @@ export default class MongoDatabase {
374
376
  });
375
377
  }
376
378
  _syncIndexes(collectionName_1, indexes_1, func_1) {
377
- return __awaiter(this, arguments, void 0, function* (collectionName, indexes, func, shouldIncludeUnique = false) {
379
+ return __awaiter(this, arguments, void 0, function* (collectionName, indexes, func, isSyncingUniqueIndexes = false) {
378
380
  var _a;
379
- const currentIndexes = yield this.getIndexes(collectionName, shouldIncludeUnique);
381
+ const currentIndexes = isSyncingUniqueIndexes
382
+ ? yield this.getUniqueIndexes(collectionName)
383
+ : yield this.getIndexes(collectionName);
380
384
  const indexesToDelete = pluckMissingIndexes(currentIndexes, indexes);
381
385
  for (const extra of indexesToDelete) {
382
386
  yield this.dropIndex(collectionName, extra);
383
387
  }
384
388
  for (const index of indexes) {
385
- if (!this.doesInclude(currentIndexes, this.normalizeIndex(index))) {
389
+ if (!this.doesInclude(currentIndexes, this.normalizeIndex(index, isSyncingUniqueIndexes))) {
386
390
  try {
387
391
  yield this[func](collectionName, index);
388
392
  }
@@ -398,7 +402,7 @@ export default class MongoDatabase {
398
402
  createUniqueIndex(collection, index) {
399
403
  return __awaiter(this, void 0, void 0, function* () {
400
404
  const currentIndexes = yield this.getUniqueIndexes(collection);
401
- const indexWithFilter = this.normalizeIndex(index);
405
+ const indexWithFilter = this.normalizeIndex(index, true);
402
406
  this.assertIndexDoesNotExist(currentIndexes, indexWithFilter, collection);
403
407
  const created = {};
404
408
  indexWithFilter.fields.forEach((name) => {
@@ -407,7 +411,7 @@ export default class MongoDatabase {
407
411
  try {
408
412
  const options = {
409
413
  unique: true,
410
- name: this.generateIndexName(indexWithFilter),
414
+ name: indexWithFilter.name,
411
415
  };
412
416
  if (indexWithFilter.filter) {
413
417
  options.partialFilterExpression = indexWithFilter.filter;
@@ -430,11 +434,8 @@ export default class MongoDatabase {
430
434
  }
431
435
  });
432
436
  }
433
- generateIndexName(indexWithFilter) {
434
- return generateIndexName(this.normalizeIndex(indexWithFilter));
435
- }
436
- normalizeIndex(index) {
437
- return normalizeIndex(index);
437
+ normalizeIndex(index, isUnique) {
438
+ return normalizeIndex(index, isUnique);
438
439
  }
439
440
  syncUniqueIndexes(collectionName, indexes) {
440
441
  return __awaiter(this, void 0, void 0, function* () {
@@ -485,33 +485,39 @@ export default class NeDbDatabase extends AbstractMutexer {
485
485
  col._indexes = [];
486
486
  }
487
487
  yield this.randomDelay();
488
- this.assertIndexDoesNotExist(col._indexes, this.normalizeIndex(fields), collection);
489
- col._indexes.push({ fields });
488
+ const normalized = this.normalizeIndex(fields);
489
+ this.assertIndexDoesNotExist(col._indexes, normalized, collection);
490
+ col._indexes.push(normalized);
490
491
  });
491
492
  }
492
493
  normalizeIndex(index) {
493
- const { fields, filter } = normalizeIndex(index);
494
- return { fields, filter };
494
+ return normalizeIndex(index);
495
495
  }
496
496
  syncUniqueIndexes(collectionName, indexes) {
497
497
  return __awaiter(this, void 0, void 0, function* () {
498
498
  var _a;
499
+ yield this.lock('syncUniqueIndexesMutex');
499
500
  const currentIndexes = yield this.getUniqueIndexes(collectionName);
500
501
  const toDelete = pluckMissingIndexes(currentIndexes, indexes);
501
- for (const index of indexes) {
502
- if (!this.doesInclude(currentIndexes, index)) {
503
- try {
504
- yield this.createUniqueIndex(collectionName, index);
505
- }
506
- catch (err) {
507
- if (((_a = err.options) === null || _a === void 0 ? void 0 : _a.code) !== 'INDEX_EXISTS') {
508
- throw err;
502
+ try {
503
+ for (const index of indexes) {
504
+ if (!this.doesInclude(currentIndexes, index)) {
505
+ try {
506
+ yield this.createUniqueIndex(collectionName, index);
507
+ }
508
+ catch (err) {
509
+ if (((_a = err.options) === null || _a === void 0 ? void 0 : _a.code) !== 'INDEX_EXISTS') {
510
+ throw err;
511
+ }
509
512
  }
510
513
  }
511
514
  }
515
+ for (const extra of toDelete) {
516
+ yield this.dropIndex(collectionName, extra);
517
+ }
512
518
  }
513
- for (const extra of toDelete) {
514
- yield this.dropIndex(collectionName, extra);
519
+ finally {
520
+ this.unlock('syncUniqueIndexesMutex');
515
521
  }
516
522
  });
517
523
  }
@@ -1,6 +1,5 @@
1
1
  import { IndexWithFilter, Index } from '../types/database.types';
2
2
  export declare function doesIndexesInclude(haystack: Index[], needle: Index): boolean;
3
3
  export declare function areIndexesEqual(left: Index, right: Index): boolean;
4
- export declare function generateIndexName(indexWithFilter: IndexWithFilter): string;
5
- export declare function normalizeIndex(index: Index): IndexWithFilter;
4
+ export declare function normalizeIndex(index: Index, isUnique?: boolean): IndexWithFilter;
6
5
  export declare function pluckMissingIndexes(left: Index[], right: Index[]): Index[];
@@ -12,7 +12,7 @@ export function areIndexesEqual(left, right) {
12
12
  const name2 = generateIndexName(normalizeIndex(right));
13
13
  return name1 === name2;
14
14
  }
15
- export function generateIndexName(indexWithFilter) {
15
+ function generateIndexName(indexWithFilter, isUnique) {
16
16
  if (indexWithFilter.name) {
17
17
  return indexWithFilter.name;
18
18
  }
@@ -20,18 +20,23 @@ export function generateIndexName(indexWithFilter) {
20
20
  if (indexWithFilter.filter) {
21
21
  name += '_filtered';
22
22
  }
23
+ if (isUnique) {
24
+ name += '_unique';
25
+ }
23
26
  return name;
24
27
  }
25
- export function normalizeIndex(index) {
26
- var _a;
28
+ export function normalizeIndex(index, isUnique) {
27
29
  const fields = Array.isArray(index) ? index : index.fields;
28
30
  const filter = Array.isArray(index) ? undefined : index.filter;
29
31
  fields.sort();
30
- return {
32
+ const normalized = {
31
33
  fields,
32
- filter,
33
- name: (_a = index.name) !== null && _a !== void 0 ? _a : undefined,
34
34
  };
35
+ if (filter) {
36
+ normalized.filter = filter;
37
+ }
38
+ normalized.name = generateIndexName(normalized, isUnique);
39
+ return normalized;
35
40
  }
36
41
  export function pluckMissingIndexes(left, right) {
37
42
  return differenceWith(left, right, areIndexesEqual);
@@ -1,6 +1,6 @@
1
1
  import { Database, IndexWithFilter, TestConnect } from '../types/database.types';
2
2
  import { DataStore } from '../types/stores.types';
3
- declare const methods: readonly ["assertThrowsWithInvalidConnectionString", "assertThrowsWhenCantConnect", "assertThrowsWithBadDatabaseName", "assertKnowsIfConnectionClosed", "assertCanSortDesc", "assertCanSortAsc", "assertCanSortById", "assertCanQueryWithOr", "assertGeneratesIdDifferentEachTime", "assertInsertingGeneratesId", "assertCanCreateMany", "assertCanCreateWithObjectField", "assertCanCountOnId", "assertCanCount", "assertThrowsWhenUpdatingRecordNotFound", "assertCanUpdate", "assertCanUpdateMany", "assertCanPushOntoArrayValue", "assertCanUpdateWithObjectField", "assertCanUpdateFieldInObjectFieldWithTargettedWhere", "assertCanSaveAndGetNullAndUndefined", "assertUpdateReturnsMatchedCounts", "assertCanUpsertOne", "assertCanUpsertNull", "assertCanPushToArrayOnUpsert", "assertCanSyncUniqueIndexesWithFilterExpression", "assertEmptyDatabaseReturnsEmptyArray", "assertFindOneOnEmptyDatabaseReturnsNull", "assertCanLimitResults", "assertCanLimitResultsToZero", "assertCanFindWithBooleanField", "assertCanQueryByGtLtGteLteNe", "assertCanQueryPathWithDotSyntax", "assertCanReturnOnlySelectFields", "assertCanSearchByRegex", "assertCanFindWithNe", "assertCanFindWithIn", "assertCanFindOrWithBadIdField", "assertCanDeleteRecord", "assertCanDeleteOne", "assertHasNoUniqueIndexToStart", "assertCanCreateUniqueIndex", "assertCanCreateMultiFieldUniqueIndex", "assertCantCreateUniqueIndexTwice", "assertCanDropUniqueIndex", "assertCanDropCompoundUniqueIndex", "assertCantDropUniqueIndexThatDoesntExist", "assertCantDropIndexWhenNoIndexExists", "assertCantDropCompoundUniqueIndexThatDoesntExist", "assertSyncingUniqueIndexesAddsMissingIndexes", "assertSyncingUniqueIndexesSkipsExistingIndexes", "assertSyncingUniqueIndexesRemovesExtraIndexes", "assertSyncingUniqueIndexesIsRaceProof", "assertSyncingIndexesDoesNotAddAndRemove", "assertUniqueIndexBlocksDuplicates", "assertDuplicateKeyThrowsOnInsert", "assertSettingUniqueIndexViolationThrowsSpruceError", "assertCanCreateUniqueIndexOnNestedField", "assertUpsertWithUniqueIndex", "assertNestedFieldIndexUpdates", "assertHasNoIndexToStart", "assertCanCreateIndex", "assertCantCreateSameIndexTwice", "assertCanCreateMultiFieldIndex", "assertCanDropIndex", "assertCanDropCompoundIndex", "assertCantDropCompoundIndexThatDoesNotExist", "assertSyncIndexesSkipsExisting", "assertSyncIndexesRemovesExtraIndexes", "assertSyncIndexesHandlesRaceConditions", "assertSyncIndexesDoesNotRemoveExisting", "assertDuplicateFieldsWithMultipleUniqueIndexesWorkAsExpected", "assertCanSyncIndexesWithoutPartialThenAgainWithProperlyUpdates"];
3
+ declare const methods: readonly ["assertThrowsWithInvalidConnectionString", "assertThrowsWhenCantConnect", "assertThrowsWithBadDatabaseName", "assertKnowsIfConnectionClosed", "assertCanSortDesc", "assertCanSortAsc", "assertCanSortById", "assertCanQueryWithOr", "assertGeneratesIdDifferentEachTime", "assertInsertingGeneratesId", "assertCanCreateMany", "assertCanCreateWithObjectField", "assertCanCountOnId", "assertCanCount", "assertThrowsWhenUpdatingRecordNotFound", "assertCanUpdate", "assertCanUpdateMany", "assertCanPushOntoArrayValue", "assertCanUpdateWithObjectField", "assertCanUpdateFieldInObjectFieldWithTargettedWhere", "assertCanSaveAndGetNullAndUndefined", "assertUpdateReturnsMatchedCounts", "assertCanUpsertOne", "assertCanUpsertNull", "assertCanPushToArrayOnUpsert", "assertCanSyncUniqueIndexesWithFilterExpression", "assertEmptyDatabaseReturnsEmptyArray", "assertFindOneOnEmptyDatabaseReturnsNull", "assertCanLimitResults", "assertCanLimitResultsToZero", "assertCanFindWithBooleanField", "assertCanQueryByGtLtGteLteNe", "assertCanQueryPathWithDotSyntax", "assertCanReturnOnlySelectFields", "assertCanSearchByRegex", "assertCanFindWithNe", "assertCanFindWithIn", "assertCanFindOrWithBadIdField", "assertCanDeleteRecord", "assertCanDeleteOne", "assertHasNoUniqueIndexToStart", "assertCanCreateUniqueIndex", "assertCanCreateMultiFieldUniqueIndex", "assertCantCreateUniqueIndexTwice", "assertCanDropUniqueIndex", "assertCanDropCompoundUniqueIndex", "assertCantDropUniqueIndexThatDoesntExist", "assertCantDropIndexWhenNoIndexExists", "assertCantDropCompoundUniqueIndexThatDoesntExist", "assertSyncingUniqueIndexesAddsMissingIndexes", "assertSyncingUniqueIndexesSkipsExistingUniqueIndexes", "assertSyncingUniqueIndexesRemovesExtraUniqueIndexes", "assertSyncingUniqueIndexesIsRaceProof", "assertSyncUniqueIndexesSkipsOnesThatExist", "assertCanHaveUniqueIndexOnFieldThatIsAlreadyInIndex", "assertUniqueIndexBlocksDuplicates", "assertDuplicateKeyThrowsOnInsert", "assertSettingUniqueIndexViolationThrowsSpruceError", "assertCanCreateUniqueIndexOnNestedField", "assertUpsertWithUniqueIndex", "assertNestedFieldIndexUpdates", "assertHasNoIndexToStart", "assertCanCreateIndex", "assertCantCreateSameIndexTwice", "assertCanCreateMultiFieldIndex", "assertCanDropIndex", "assertCanDropCompoundIndex", "assertCantDropCompoundIndexThatDoesNotExist", "assertSyncIndexesSkipsExisting", "assertSyncIndexesRemovesExtraIndexes", "assertSyncIndexesHandlesRaceConditions", "assertSyncIndexesDoesNotRemoveExisting", "assertDuplicateFieldsWithMultipleUniqueIndexesWorkAsExpected", "assertCanSyncIndexesWithoutPartialThenAgainWithProperlyUpdates"];
4
4
  type OriginalMethods = (typeof methods)[number];
5
5
  type BangMethods = `!${OriginalMethods}`;
6
6
  export type DatabaseAssertionName = OriginalMethods | BangMethods;
@@ -37,9 +37,10 @@ declare const databaseAssertUtil: {
37
37
  assertCanCreateMultiFieldUniqueIndex(connect: TestConnect): Promise<void>;
38
38
  assertSettingUniqueIndexViolationThrowsSpruceError(connect: TestConnect): Promise<void>;
39
39
  assertDuplicateKeyThrowsOnInsert(connect: TestConnect): Promise<void>;
40
- assertSyncingIndexesDoesNotAddAndRemove(connect: TestConnect): Promise<void>;
41
- assertSyncingUniqueIndexesRemovesExtraIndexes(connect: TestConnect): Promise<void>;
42
- assertSyncingUniqueIndexesSkipsExistingIndexes(connect: TestConnect): Promise<void>;
40
+ assertSyncUniqueIndexesSkipsOnesThatExist(connect: TestConnect): Promise<void>;
41
+ assertCanHaveUniqueIndexOnFieldThatIsAlreadyInIndex(connect: TestConnect): Promise<void>;
42
+ assertSyncingUniqueIndexesRemovesExtraUniqueIndexes(connect: TestConnect): Promise<void>;
43
+ assertSyncingUniqueIndexesSkipsExistingUniqueIndexes(connect: TestConnect): Promise<void>;
43
44
  assertSyncingUniqueIndexesAddsMissingIndexes(connect: TestConnect): Promise<void>;
44
45
  assertCantDropCompoundUniqueIndexThatDoesntExist(connect: TestConnect): Promise<void>;
45
46
  assertCantDropIndexWhenNoIndexExists(connect: TestConnect): Promise<void>;
@@ -49,6 +50,7 @@ declare const databaseAssertUtil: {
49
50
  assertCantCreateUniqueIndexTwice(connect: TestConnect): Promise<void>;
50
51
  assertSyncingUniqueIndexesIsRaceProof(connect: TestConnect): Promise<void>;
51
52
  assertUniqueIndexBlocksDuplicates(connect: TestConnect): Promise<void>;
53
+ syncingUniqueIndexDoesNotTouchNonUniqueIndexes(connect: TestConnect): Promise<void>;
52
54
  assertCanCreateUniqueIndexOnNestedField(connect: TestConnect): Promise<void>;
53
55
  assertCanPushToArrayOnUpsert(connect: TestConnect): Promise<void>;
54
56
  assertCanSearchByRegex(connect: TestConnect): Promise<void>;
@@ -70,10 +70,11 @@ const methods = [
70
70
  'assertCantDropIndexWhenNoIndexExists',
71
71
  'assertCantDropCompoundUniqueIndexThatDoesntExist',
72
72
  'assertSyncingUniqueIndexesAddsMissingIndexes',
73
- 'assertSyncingUniqueIndexesSkipsExistingIndexes',
74
- 'assertSyncingUniqueIndexesRemovesExtraIndexes',
73
+ 'assertSyncingUniqueIndexesSkipsExistingUniqueIndexes',
74
+ 'assertSyncingUniqueIndexesRemovesExtraUniqueIndexes',
75
75
  'assertSyncingUniqueIndexesIsRaceProof',
76
- 'assertSyncingIndexesDoesNotAddAndRemove',
76
+ 'assertSyncUniqueIndexesSkipsOnesThatExist',
77
+ 'assertCanHaveUniqueIndexOnFieldThatIsAlreadyInIndex',
77
78
  'assertUniqueIndexBlocksDuplicates',
78
79
  'assertDuplicateKeyThrowsOnInsert',
79
80
  'assertSettingUniqueIndexViolationThrowsSpruceError',
@@ -747,7 +748,7 @@ const databaseAssertUtil = {
747
748
  yield this.shutdown(db);
748
749
  });
749
750
  },
750
- assertSyncingIndexesDoesNotAddAndRemove(connect) {
751
+ assertSyncUniqueIndexesSkipsOnesThatExist(connect) {
751
752
  return __awaiter(this, void 0, void 0, function* () {
752
753
  const db = yield connectToDabatase(connect);
753
754
  yield db.createUniqueIndex(this.collectionName, ['otherField']);
@@ -765,7 +766,17 @@ const databaseAssertUtil = {
765
766
  yield this.shutdown(db);
766
767
  });
767
768
  },
768
- assertSyncingUniqueIndexesRemovesExtraIndexes(connect) {
769
+ assertCanHaveUniqueIndexOnFieldThatIsAlreadyInIndex(connect) {
770
+ return __awaiter(this, void 0, void 0, function* () {
771
+ const db = yield connectToDabatase(connect);
772
+ yield db.syncIndexes(this.collectionName, [
773
+ ['nested.field1'],
774
+ ['nested.field2'],
775
+ ]);
776
+ yield db.syncUniqueIndexes(this.collectionName, [['nested.field1']]);
777
+ });
778
+ },
779
+ assertSyncingUniqueIndexesRemovesExtraUniqueIndexes(connect) {
769
780
  return __awaiter(this, void 0, void 0, function* () {
770
781
  const db = yield connectToDabatase(connect);
771
782
  yield db.syncUniqueIndexes(this.collectionName, [
@@ -800,7 +811,7 @@ const databaseAssertUtil = {
800
811
  yield this.shutdown(db);
801
812
  });
802
813
  },
803
- assertSyncingUniqueIndexesSkipsExistingIndexes(connect) {
814
+ assertSyncingUniqueIndexesSkipsExistingUniqueIndexes(connect) {
804
815
  return __awaiter(this, void 0, void 0, function* () {
805
816
  const db = yield connectToDabatase(connect);
806
817
  yield db.syncUniqueIndexes(this.collectionName, [['uniqueField']]);
@@ -925,6 +936,7 @@ const databaseAssertUtil = {
925
936
  assertSyncingUniqueIndexesIsRaceProof(connect) {
926
937
  return __awaiter(this, void 0, void 0, function* () {
927
938
  const db = yield connectToDabatase(connect);
939
+ debugger;
928
940
  const syncs = [
929
941
  db.syncUniqueIndexes(this.collectionName, [
930
942
  ['otherField', 'otherField2'],
@@ -958,6 +970,9 @@ const databaseAssertUtil = {
958
970
  ]),
959
971
  ];
960
972
  yield Promise.all(syncs);
973
+ const saved = yield db.getUniqueIndexes(this.collectionName);
974
+ assert.isLength(saved, 1, 'After many simultaneous syncUniqueIndexes() calls, there should only be one unique index created.');
975
+ assert.isEqualDeep(saved[0].fields, ['otherField', 'otherField2'], 'After many simultaneous syncUniqueIndexes() calls, the unique index created does not have the expected fields.');
961
976
  yield this.shutdown(db);
962
977
  });
963
978
  },
@@ -1017,6 +1032,28 @@ const databaseAssertUtil = {
1017
1032
  yield this.shutdown(db);
1018
1033
  });
1019
1034
  },
1035
+ syncingUniqueIndexDoesNotTouchNonUniqueIndexes(connect) {
1036
+ return __awaiter(this, void 0, void 0, function* () {
1037
+ const db = yield connectToDabatase(connect);
1038
+ yield db.createIndex(this.collectionName, ['someField']);
1039
+ yield db.syncUniqueIndexes(this.collectionName, [['uniqueField']]);
1040
+ const indexes = yield db.getIndexes(this.collectionName);
1041
+ const uniqueIndexes = yield db.getUniqueIndexes(this.collectionName);
1042
+ assert.isEqualDeep(indexes, [
1043
+ {
1044
+ fields: ['someField'],
1045
+ name: 'someField',
1046
+ },
1047
+ ], 'index was modified when syncing unique indexes');
1048
+ assert.isEqualDeep(uniqueIndexes, [
1049
+ {
1050
+ fields: ['uniqueField'],
1051
+ name: 'uniqueField',
1052
+ },
1053
+ ], 'unique indexes are not as expected after syncing unique indexes');
1054
+ yield this.shutdown(db);
1055
+ });
1056
+ },
1020
1057
  assertCanCreateUniqueIndexOnNestedField(connect) {
1021
1058
  return __awaiter(this, void 0, void 0, function* () {
1022
1059
  var _a;
@@ -42,6 +42,7 @@ export interface IndexWithFilter {
42
42
  fields: string[];
43
43
  filter?: Record<string, any>;
44
44
  name?: string;
45
+ isUnique?: boolean;
45
46
  }
46
47
  export type Index = string[] | IndexWithFilter;
47
48
  export interface CreateOptions extends DatabaseInternalOptions {
@@ -1,6 +1,6 @@
1
1
  import { Database, IndexWithFilter, TestConnect } from '../types/database.types';
2
2
  import { DataStore } from '../types/stores.types';
3
- declare const methods: readonly ["assertThrowsWithInvalidConnectionString", "assertThrowsWhenCantConnect", "assertThrowsWithBadDatabaseName", "assertKnowsIfConnectionClosed", "assertCanSortDesc", "assertCanSortAsc", "assertCanSortById", "assertCanQueryWithOr", "assertGeneratesIdDifferentEachTime", "assertInsertingGeneratesId", "assertCanCreateMany", "assertCanCreateWithObjectField", "assertCanCountOnId", "assertCanCount", "assertThrowsWhenUpdatingRecordNotFound", "assertCanUpdate", "assertCanUpdateMany", "assertCanPushOntoArrayValue", "assertCanUpdateWithObjectField", "assertCanUpdateFieldInObjectFieldWithTargettedWhere", "assertCanSaveAndGetNullAndUndefined", "assertUpdateReturnsMatchedCounts", "assertCanUpsertOne", "assertCanUpsertNull", "assertCanPushToArrayOnUpsert", "assertCanSyncUniqueIndexesWithFilterExpression", "assertEmptyDatabaseReturnsEmptyArray", "assertFindOneOnEmptyDatabaseReturnsNull", "assertCanLimitResults", "assertCanLimitResultsToZero", "assertCanFindWithBooleanField", "assertCanQueryByGtLtGteLteNe", "assertCanQueryPathWithDotSyntax", "assertCanReturnOnlySelectFields", "assertCanSearchByRegex", "assertCanFindWithNe", "assertCanFindWithIn", "assertCanFindOrWithBadIdField", "assertCanDeleteRecord", "assertCanDeleteOne", "assertHasNoUniqueIndexToStart", "assertCanCreateUniqueIndex", "assertCanCreateMultiFieldUniqueIndex", "assertCantCreateUniqueIndexTwice", "assertCanDropUniqueIndex", "assertCanDropCompoundUniqueIndex", "assertCantDropUniqueIndexThatDoesntExist", "assertCantDropIndexWhenNoIndexExists", "assertCantDropCompoundUniqueIndexThatDoesntExist", "assertSyncingUniqueIndexesAddsMissingIndexes", "assertSyncingUniqueIndexesSkipsExistingIndexes", "assertSyncingUniqueIndexesRemovesExtraIndexes", "assertSyncingUniqueIndexesIsRaceProof", "assertSyncingIndexesDoesNotAddAndRemove", "assertUniqueIndexBlocksDuplicates", "assertDuplicateKeyThrowsOnInsert", "assertSettingUniqueIndexViolationThrowsSpruceError", "assertCanCreateUniqueIndexOnNestedField", "assertUpsertWithUniqueIndex", "assertNestedFieldIndexUpdates", "assertHasNoIndexToStart", "assertCanCreateIndex", "assertCantCreateSameIndexTwice", "assertCanCreateMultiFieldIndex", "assertCanDropIndex", "assertCanDropCompoundIndex", "assertCantDropCompoundIndexThatDoesNotExist", "assertSyncIndexesSkipsExisting", "assertSyncIndexesRemovesExtraIndexes", "assertSyncIndexesHandlesRaceConditions", "assertSyncIndexesDoesNotRemoveExisting", "assertDuplicateFieldsWithMultipleUniqueIndexesWorkAsExpected", "assertCanSyncIndexesWithoutPartialThenAgainWithProperlyUpdates"];
3
+ declare const methods: readonly ["assertThrowsWithInvalidConnectionString", "assertThrowsWhenCantConnect", "assertThrowsWithBadDatabaseName", "assertKnowsIfConnectionClosed", "assertCanSortDesc", "assertCanSortAsc", "assertCanSortById", "assertCanQueryWithOr", "assertGeneratesIdDifferentEachTime", "assertInsertingGeneratesId", "assertCanCreateMany", "assertCanCreateWithObjectField", "assertCanCountOnId", "assertCanCount", "assertThrowsWhenUpdatingRecordNotFound", "assertCanUpdate", "assertCanUpdateMany", "assertCanPushOntoArrayValue", "assertCanUpdateWithObjectField", "assertCanUpdateFieldInObjectFieldWithTargettedWhere", "assertCanSaveAndGetNullAndUndefined", "assertUpdateReturnsMatchedCounts", "assertCanUpsertOne", "assertCanUpsertNull", "assertCanPushToArrayOnUpsert", "assertCanSyncUniqueIndexesWithFilterExpression", "assertEmptyDatabaseReturnsEmptyArray", "assertFindOneOnEmptyDatabaseReturnsNull", "assertCanLimitResults", "assertCanLimitResultsToZero", "assertCanFindWithBooleanField", "assertCanQueryByGtLtGteLteNe", "assertCanQueryPathWithDotSyntax", "assertCanReturnOnlySelectFields", "assertCanSearchByRegex", "assertCanFindWithNe", "assertCanFindWithIn", "assertCanFindOrWithBadIdField", "assertCanDeleteRecord", "assertCanDeleteOne", "assertHasNoUniqueIndexToStart", "assertCanCreateUniqueIndex", "assertCanCreateMultiFieldUniqueIndex", "assertCantCreateUniqueIndexTwice", "assertCanDropUniqueIndex", "assertCanDropCompoundUniqueIndex", "assertCantDropUniqueIndexThatDoesntExist", "assertCantDropIndexWhenNoIndexExists", "assertCantDropCompoundUniqueIndexThatDoesntExist", "assertSyncingUniqueIndexesAddsMissingIndexes", "assertSyncingUniqueIndexesSkipsExistingUniqueIndexes", "assertSyncingUniqueIndexesRemovesExtraUniqueIndexes", "assertSyncingUniqueIndexesIsRaceProof", "assertSyncUniqueIndexesSkipsOnesThatExist", "assertCanHaveUniqueIndexOnFieldThatIsAlreadyInIndex", "assertUniqueIndexBlocksDuplicates", "assertDuplicateKeyThrowsOnInsert", "assertSettingUniqueIndexViolationThrowsSpruceError", "assertCanCreateUniqueIndexOnNestedField", "assertUpsertWithUniqueIndex", "assertNestedFieldIndexUpdates", "assertHasNoIndexToStart", "assertCanCreateIndex", "assertCantCreateSameIndexTwice", "assertCanCreateMultiFieldIndex", "assertCanDropIndex", "assertCanDropCompoundIndex", "assertCantDropCompoundIndexThatDoesNotExist", "assertSyncIndexesSkipsExisting", "assertSyncIndexesRemovesExtraIndexes", "assertSyncIndexesHandlesRaceConditions", "assertSyncIndexesDoesNotRemoveExisting", "assertDuplicateFieldsWithMultipleUniqueIndexesWorkAsExpected", "assertCanSyncIndexesWithoutPartialThenAgainWithProperlyUpdates"];
4
4
  type OriginalMethods = (typeof methods)[number];
5
5
  type BangMethods = `!${OriginalMethods}`;
6
6
  export type DatabaseAssertionName = OriginalMethods | BangMethods;
@@ -37,9 +37,10 @@ declare const databaseAssertUtil: {
37
37
  assertCanCreateMultiFieldUniqueIndex(connect: TestConnect): Promise<void>;
38
38
  assertSettingUniqueIndexViolationThrowsSpruceError(connect: TestConnect): Promise<void>;
39
39
  assertDuplicateKeyThrowsOnInsert(connect: TestConnect): Promise<void>;
40
- assertSyncingIndexesDoesNotAddAndRemove(connect: TestConnect): Promise<void>;
41
- assertSyncingUniqueIndexesRemovesExtraIndexes(connect: TestConnect): Promise<void>;
42
- assertSyncingUniqueIndexesSkipsExistingIndexes(connect: TestConnect): Promise<void>;
40
+ assertSyncUniqueIndexesSkipsOnesThatExist(connect: TestConnect): Promise<void>;
41
+ assertCanHaveUniqueIndexOnFieldThatIsAlreadyInIndex(connect: TestConnect): Promise<void>;
42
+ assertSyncingUniqueIndexesRemovesExtraUniqueIndexes(connect: TestConnect): Promise<void>;
43
+ assertSyncingUniqueIndexesSkipsExistingUniqueIndexes(connect: TestConnect): Promise<void>;
43
44
  assertSyncingUniqueIndexesAddsMissingIndexes(connect: TestConnect): Promise<void>;
44
45
  assertCantDropCompoundUniqueIndexThatDoesntExist(connect: TestConnect): Promise<void>;
45
46
  assertCantDropIndexWhenNoIndexExists(connect: TestConnect): Promise<void>;
@@ -49,6 +50,7 @@ declare const databaseAssertUtil: {
49
50
  assertCantCreateUniqueIndexTwice(connect: TestConnect): Promise<void>;
50
51
  assertSyncingUniqueIndexesIsRaceProof(connect: TestConnect): Promise<void>;
51
52
  assertUniqueIndexBlocksDuplicates(connect: TestConnect): Promise<void>;
53
+ syncingUniqueIndexDoesNotTouchNonUniqueIndexes(connect: TestConnect): Promise<void>;
52
54
  assertCanCreateUniqueIndexOnNestedField(connect: TestConnect): Promise<void>;
53
55
  assertCanPushToArrayOnUpsert(connect: TestConnect): Promise<void>;
54
56
  assertCanSearchByRegex(connect: TestConnect): Promise<void>;
@@ -66,10 +66,11 @@ const methods = [
66
66
  'assertCantDropIndexWhenNoIndexExists',
67
67
  'assertCantDropCompoundUniqueIndexThatDoesntExist',
68
68
  'assertSyncingUniqueIndexesAddsMissingIndexes',
69
- 'assertSyncingUniqueIndexesSkipsExistingIndexes',
70
- 'assertSyncingUniqueIndexesRemovesExtraIndexes',
69
+ 'assertSyncingUniqueIndexesSkipsExistingUniqueIndexes',
70
+ 'assertSyncingUniqueIndexesRemovesExtraUniqueIndexes',
71
71
  'assertSyncingUniqueIndexesIsRaceProof',
72
- 'assertSyncingIndexesDoesNotAddAndRemove',
72
+ 'assertSyncUniqueIndexesSkipsOnesThatExist',
73
+ 'assertCanHaveUniqueIndexOnFieldThatIsAlreadyInIndex',
73
74
  'assertUniqueIndexBlocksDuplicates',
74
75
  'assertDuplicateKeyThrowsOnInsert',
75
76
  'assertSettingUniqueIndexViolationThrowsSpruceError',
@@ -683,7 +684,7 @@ const databaseAssertUtil = {
683
684
  });
684
685
  await this.shutdown(db);
685
686
  },
686
- async assertSyncingIndexesDoesNotAddAndRemove(connect) {
687
+ async assertSyncUniqueIndexesSkipsOnesThatExist(connect) {
687
688
  const db = await connectToDabatase(connect);
688
689
  await db.createUniqueIndex(this.collectionName, ['otherField']);
689
690
  await db.createUniqueIndex(this.collectionName, ['someField']);
@@ -699,7 +700,15 @@ const databaseAssertUtil = {
699
700
  ]);
700
701
  await this.shutdown(db);
701
702
  },
702
- async assertSyncingUniqueIndexesRemovesExtraIndexes(connect) {
703
+ async assertCanHaveUniqueIndexOnFieldThatIsAlreadyInIndex(connect) {
704
+ const db = await connectToDabatase(connect);
705
+ await db.syncIndexes(this.collectionName, [
706
+ ['nested.field1'],
707
+ ['nested.field2'],
708
+ ]);
709
+ await db.syncUniqueIndexes(this.collectionName, [['nested.field1']]);
710
+ },
711
+ async assertSyncingUniqueIndexesRemovesExtraUniqueIndexes(connect) {
703
712
  const db = await connectToDabatase(connect);
704
713
  await db.syncUniqueIndexes(this.collectionName, [
705
714
  ['uniqueField'],
@@ -732,7 +741,7 @@ const databaseAssertUtil = {
732
741
  test_utils_1.assert.isLength(indexes, 2, `Syncing unique indexes with filter is not removing extra indexes.`);
733
742
  await this.shutdown(db);
734
743
  },
735
- async assertSyncingUniqueIndexesSkipsExistingIndexes(connect) {
744
+ async assertSyncingUniqueIndexesSkipsExistingUniqueIndexes(connect) {
736
745
  const db = await connectToDabatase(connect);
737
746
  await db.syncUniqueIndexes(this.collectionName, [['uniqueField']]);
738
747
  let indexes = await db.getUniqueIndexes(this.collectionName);
@@ -840,6 +849,7 @@ const databaseAssertUtil = {
840
849
  },
841
850
  async assertSyncingUniqueIndexesIsRaceProof(connect) {
842
851
  const db = await connectToDabatase(connect);
852
+ debugger;
843
853
  const syncs = [
844
854
  db.syncUniqueIndexes(this.collectionName, [
845
855
  ['otherField', 'otherField2'],
@@ -873,6 +883,9 @@ const databaseAssertUtil = {
873
883
  ]),
874
884
  ];
875
885
  await Promise.all(syncs);
886
+ const saved = await db.getUniqueIndexes(this.collectionName);
887
+ test_utils_1.assert.isLength(saved, 1, 'After many simultaneous syncUniqueIndexes() calls, there should only be one unique index created.');
888
+ test_utils_1.assert.isEqualDeep(saved[0].fields, ['otherField', 'otherField2'], 'After many simultaneous syncUniqueIndexes() calls, the unique index created does not have the expected fields.');
876
889
  await this.shutdown(db);
877
890
  },
878
891
  async assertUniqueIndexBlocksDuplicates(connect) {
@@ -929,6 +942,26 @@ const databaseAssertUtil = {
929
942
  test_utils_2.errorAssert.assertError(err, 'DUPLICATE_RECORD');
930
943
  await this.shutdown(db);
931
944
  },
945
+ async syncingUniqueIndexDoesNotTouchNonUniqueIndexes(connect) {
946
+ const db = await connectToDabatase(connect);
947
+ await db.createIndex(this.collectionName, ['someField']);
948
+ await db.syncUniqueIndexes(this.collectionName, [['uniqueField']]);
949
+ const indexes = await db.getIndexes(this.collectionName);
950
+ const uniqueIndexes = await db.getUniqueIndexes(this.collectionName);
951
+ test_utils_1.assert.isEqualDeep(indexes, [
952
+ {
953
+ fields: ['someField'],
954
+ name: 'someField',
955
+ },
956
+ ], 'index was modified when syncing unique indexes');
957
+ test_utils_1.assert.isEqualDeep(uniqueIndexes, [
958
+ {
959
+ fields: ['uniqueField'],
960
+ name: 'uniqueField',
961
+ },
962
+ ], 'unique indexes are not as expected after syncing unique indexes');
963
+ await this.shutdown(db);
964
+ },
932
965
  async assertCanCreateUniqueIndexOnNestedField(connect) {
933
966
  var _a;
934
967
  const db = await connectToDabatase(connect);
@@ -42,6 +42,7 @@ export interface IndexWithFilter {
42
42
  fields: string[];
43
43
  filter?: Record<string, any>;
44
44
  name?: string;
45
+ isUnique?: boolean;
45
46
  }
46
47
  export type Index = string[] | IndexWithFilter;
47
48
  export interface CreateOptions extends DatabaseInternalOptions {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "31.0.8",
6
+ "version": "31.0.10",
7
7
  "files": [
8
8
  "build/**/*",
9
9
  "!build/__tests__",