@sprucelabs/data-stores 28.1.333 → 28.1.335

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.
@@ -1,5 +1,5 @@
1
1
  import { MongoClientOptions, MongoClient } from 'mongodb';
2
- import { Database, DatabaseOptions, IndexWithFilter, UniqueIndex } from '../types/database.types';
2
+ import { Database, DatabaseOptions, Index, IndexWithFilter } from '../types/database.types';
3
3
  import { QueryOptions } from '../types/query.types';
4
4
  export declare const MONGO_TEST_URI = "mongodb://localhost:27017";
5
5
  export default class MongoDatabase implements Database {
@@ -26,16 +26,21 @@ export default class MongoDatabase implements Database {
26
26
  dropCollection(name: string): Promise<void>;
27
27
  dropDatabase(): Promise<void>;
28
28
  private listIndexes;
29
- dropIndex(collection: string, index: UniqueIndex): Promise<void>;
30
- getUniqueIndexes(collection: string): Promise<string[][]>;
31
- getIndexes(collection: string, shouldIncludeUnique?: boolean): Promise<any[]>;
32
- createIndex(collection: string, fields: string[]): Promise<void>;
29
+ dropIndex(collection: string, index: Index): Promise<void>;
30
+ getUniqueIndexes(collection: string): Promise<IndexWithFilter[]>;
31
+ getIndexes(collection: string, shouldIncludeUnique?: boolean): Promise<IndexWithFilter[] | {
32
+ fields: string[];
33
+ filter: any;
34
+ }[]>;
35
+ createIndex(collection: string, index: Index): Promise<void>;
33
36
  private assertIndexDoesNotExist;
34
- private doesIndexExist;
35
- syncIndexes(collectionName: string, indexes: string[][]): Promise<void>;
37
+ private doesInclude;
38
+ syncIndexes(collectionName: string, indexes: Index[]): Promise<void>;
39
+ private _syncIndexes;
36
40
  createUniqueIndex(collection: string, index: string[] | IndexWithFilter): Promise<void>;
41
+ private generateIndexName;
37
42
  private normalizeIndex;
38
- syncUniqueIndexes(collectionName: string, indexes: UniqueIndex[]): Promise<void>;
43
+ syncUniqueIndexes(collectionName: string, indexes: Index[]): Promise<void>;
39
44
  update(collection: string, query: Record<string, any>, updates: Record<string, any>): Promise<number>;
40
45
  updateOne(collection: string, query: Record<string, any>, updates: Record<string, any>): Promise<Record<string, any>>;
41
46
  upsertOne(collection: string, query: Record<string, any>, updates: Record<string, any>): Promise<Record<string, any>>;
@@ -16,13 +16,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.MONGO_TEST_URI = void 0;
18
18
  const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils");
19
- const differenceWith_1 = __importDefault(require("lodash/differenceWith"));
20
- const isEqual_1 = __importDefault(require("lodash/isEqual"));
21
19
  const mongodb_1 = require("mongodb");
22
20
  const SpruceError_1 = __importDefault(require("../errors/SpruceError"));
23
21
  const generateId_1 = __importDefault(require("../utilities/generateId"));
24
22
  const mongo_utility_1 = __importDefault(require("../utilities/mongo.utility"));
25
- const normalizeIndex_1 = __importDefault(require("./normalizeIndex"));
23
+ const database_utilities_1 = require("./database.utilities");
26
24
  exports.MONGO_TEST_URI = 'mongodb://localhost:27017';
27
25
  class MongoDatabase {
28
26
  constructor(url, options) {
@@ -226,10 +224,11 @@ class MongoDatabase {
226
224
  }
227
225
  async listIndexes(collection) {
228
226
  try {
229
- return await this.assertDbWhileAttempingTo('get indexes.', collection)
227
+ const indexes = await this.assertDbWhileAttempingTo('get indexes.', collection)
230
228
  .collection(collection)
231
229
  .listIndexes()
232
230
  .toArray();
231
+ return indexes.filter((index) => index.name !== '_id_');
233
232
  }
234
233
  catch (err) {
235
234
  return [];
@@ -237,9 +236,10 @@ class MongoDatabase {
237
236
  }
238
237
  async dropIndex(collection, index) {
239
238
  const indexes = await this.listIndexes(collection);
239
+ const name = this.generateIndexName(this.normalizeIndex(index));
240
240
  let found = false;
241
241
  for (const thisIndex of indexes) {
242
- if ((0, isEqual_1.default)(Object.keys(thisIndex.key), index)) {
242
+ if (thisIndex.name === name) {
243
243
  await this.assertDbWhileAttempingTo('drop a index.', collection)
244
244
  .collection(collection)
245
245
  .dropIndex(thisIndex.name);
@@ -249,7 +249,7 @@ class MongoDatabase {
249
249
  if (!found) {
250
250
  throw new SpruceError_1.default({
251
251
  code: 'INDEX_NOT_FOUND',
252
- missingIndex: (0, normalizeIndex_1.default)(index).fields,
252
+ missingIndex: (0, database_utilities_1.normalizeIndex)(index).fields,
253
253
  collectionName: collection,
254
254
  });
255
255
  }
@@ -260,7 +260,10 @@ class MongoDatabase {
260
260
  const uniqueIndexes = [];
261
261
  for (const index of indexes) {
262
262
  if (index.unique) {
263
- uniqueIndexes.push(Object.keys(index.key));
263
+ uniqueIndexes.push({
264
+ fields: Object.keys(index.key),
265
+ filter: index.partialFilterExpression,
266
+ });
264
267
  }
265
268
  }
266
269
  return uniqueIndexes;
@@ -273,12 +276,18 @@ class MongoDatabase {
273
276
  try {
274
277
  const indexes = await this.listIndexes(collection);
275
278
  if (shouldIncludeUnique) {
276
- return indexes;
279
+ return indexes.map((index) => ({
280
+ fields: Object.keys(index.key),
281
+ filter: index.partialFilterExpression,
282
+ }));
277
283
  }
278
284
  const nonUniqueIndexes = [];
279
285
  for (const index of indexes) {
280
286
  if (!index.unique) {
281
- nonUniqueIndexes.push(Object.keys(index.key));
287
+ nonUniqueIndexes.push({
288
+ fields: Object.keys(index.key),
289
+ filter: undefined,
290
+ });
282
291
  }
283
292
  }
284
293
  return nonUniqueIndexes;
@@ -287,23 +296,25 @@ class MongoDatabase {
287
296
  return [];
288
297
  }
289
298
  }
290
- async createIndex(collection, fields) {
299
+ async createIndex(collection, index) {
291
300
  const currentIndexes = await this.getIndexes(collection);
292
- await this.assertIndexDoesNotExist(currentIndexes, fields, collection);
293
- const index = {};
294
- fields.forEach((name) => {
295
- index[name] = 1;
301
+ this.assertIndexDoesNotExist(currentIndexes, index, collection);
302
+ const indexSpec = {};
303
+ this.normalizeIndex(index).fields.forEach((name) => {
304
+ indexSpec[name] = 1;
296
305
  });
297
306
  try {
298
307
  await this.assertDbWhileAttempingTo('create an index.', collection)
299
308
  .collection(collection)
300
- .createIndex(index);
309
+ .createIndex(indexSpec, {
310
+ name: this.generateIndexName(index),
311
+ });
301
312
  }
302
313
  catch (err) {
303
314
  if ((err === null || err === void 0 ? void 0 : err.code) === 11000) {
304
315
  throw new SpruceError_1.default({
305
316
  code: 'DUPLICATE_KEY',
306
- friendlyMessage: `Could not create index! Index on '${collection}' has duplicate key for "${fields.join(',')}"`,
317
+ friendlyMessage: `Could not create index! Index on '${collection}' has duplicate key for "${this.normalizeIndex(index).fields.join(',')}"`,
307
318
  });
308
319
  }
309
320
  else {
@@ -311,32 +322,29 @@ class MongoDatabase {
311
322
  }
312
323
  }
313
324
  }
314
- assertIndexDoesNotExist(currentIndexes, fields, collectionName) {
315
- if (this.doesIndexExist(currentIndexes, fields)) {
325
+ assertIndexDoesNotExist(currentIndexes, index, collectionName) {
326
+ if (this.doesInclude(currentIndexes, index)) {
316
327
  throw new SpruceError_1.default({
317
328
  code: 'INDEX_EXISTS',
318
- index: fields,
329
+ index: this.normalizeIndex(index).fields,
319
330
  collectionName,
320
331
  });
321
332
  }
322
333
  }
323
- doesIndexExist(currentIndexes, fields) {
324
- for (const index of currentIndexes !== null && currentIndexes !== void 0 ? currentIndexes : []) {
325
- const { fields: normalizedFields } = this.normalizeIndex(index);
326
- if ((0, isEqual_1.default)(normalizedFields, fields)) {
327
- return true;
328
- }
329
- }
330
- return false;
334
+ doesInclude(haystack, needle) {
335
+ return (0, database_utilities_1.doesIndexesInclude)(haystack, needle);
331
336
  }
332
337
  async syncIndexes(collectionName, indexes) {
338
+ await this._syncIndexes(collectionName, indexes, 'createIndex');
339
+ }
340
+ async _syncIndexes(collectionName, indexes, func, shouldIncludeUnique = false) {
333
341
  var _a;
334
- const currentIndexes = await this.getIndexes(collectionName);
335
- const extraIndexes = (0, differenceWith_1.default)(currentIndexes, indexes, isEqual_1.default).filter((i) => !(i.length === 1 && i[0] === '_id'));
342
+ const currentIndexes = await this.getIndexes(collectionName, shouldIncludeUnique);
343
+ const indexesToDelete = (0, database_utilities_1.pluckMissingIndexes)(currentIndexes, indexes);
336
344
  for (const index of indexes) {
337
- if (!this.doesIndexExist(currentIndexes, index)) {
345
+ if (!this.doesInclude(currentIndexes, this.normalizeIndex(index))) {
338
346
  try {
339
- await this.createIndex(collectionName, index);
347
+ await this[func](collectionName, index);
340
348
  }
341
349
  catch (err) {
342
350
  if (((_a = err.options) === null || _a === void 0 ? void 0 : _a.code) !== 'INDEX_EXISTS') {
@@ -345,22 +353,25 @@ class MongoDatabase {
345
353
  }
346
354
  }
347
355
  }
348
- for (const extra of extraIndexes) {
356
+ for (const extra of indexesToDelete) {
349
357
  await this.dropIndex(collectionName, extra);
350
358
  }
351
359
  }
352
360
  async createUniqueIndex(collection, index) {
353
361
  const currentIndexes = await this.getUniqueIndexes(collection);
354
- const { fields, filter } = this.normalizeIndex(index);
355
- this.assertIndexDoesNotExist(currentIndexes, fields, collection);
362
+ const indexWithFilter = this.normalizeIndex(index);
363
+ this.assertIndexDoesNotExist(currentIndexes, indexWithFilter, collection);
356
364
  const created = {};
357
- fields.forEach((name) => {
365
+ indexWithFilter.fields.forEach((name) => {
358
366
  created[name] = 1;
359
367
  });
360
368
  try {
361
- const options = { unique: true };
362
- if (filter) {
363
- options.partialFilterExpression = filter;
369
+ const options = {
370
+ unique: true,
371
+ name: this.generateIndexName(indexWithFilter),
372
+ };
373
+ if (indexWithFilter.filter) {
374
+ options.partialFilterExpression = indexWithFilter.filter;
364
375
  }
365
376
  await this.assertDbWhileAttempingTo('create a unique index.', collection)
366
377
  .collection(collection)
@@ -370,7 +381,8 @@ class MongoDatabase {
370
381
  if ((err === null || err === void 0 ? void 0 : err.code) === 11000) {
371
382
  throw new SpruceError_1.default({
372
383
  code: 'DUPLICATE_KEY',
373
- friendlyMessage: `Could not create index! Unique index on '${collection}' has duplicate key for "${fields.join(',')}"`,
384
+ originalError: err,
385
+ friendlyMessage: `Could not create index! Unique index on '${collection}' has duplicate key for "${indexWithFilter.fields.join(',')}"\n\nOriginal error:\n\n${err.message}`,
374
386
  });
375
387
  }
376
388
  else {
@@ -378,35 +390,15 @@ class MongoDatabase {
378
390
  }
379
391
  }
380
392
  }
393
+ generateIndexName(indexWithFilter) {
394
+ return (0, database_utilities_1.generateIndexName)(this.normalizeIndex(indexWithFilter));
395
+ }
381
396
  normalizeIndex(index) {
382
- const { fields, filter } = (0, normalizeIndex_1.default)(index);
397
+ const { fields, filter } = (0, database_utilities_1.normalizeIndex)(index);
383
398
  return { fields, filter };
384
399
  }
385
400
  async syncUniqueIndexes(collectionName, indexes) {
386
- var _a;
387
- const currentIndexes = await this.getUniqueIndexes(collectionName);
388
- const toDelete = [];
389
- for (const index of currentIndexes) {
390
- if (!this.doesIndexExist(indexes, index)) {
391
- toDelete.push(index);
392
- }
393
- }
394
- for (const index of indexes) {
395
- const { fields } = this.normalizeIndex(index);
396
- if (!this.doesIndexExist(currentIndexes, fields)) {
397
- try {
398
- await this.createUniqueIndex(collectionName, index);
399
- }
400
- catch (err) {
401
- if (((_a = err.options) === null || _a === void 0 ? void 0 : _a.code) !== 'INDEX_EXISTS') {
402
- throw err;
403
- }
404
- }
405
- }
406
- }
407
- for (const extra of toDelete) {
408
- await this.dropIndex(collectionName, extra);
409
- }
401
+ await this._syncIndexes(collectionName, indexes, 'createUniqueIndex', true);
410
402
  }
411
403
  async update(collection, query, updates) {
412
404
  const q = this.toMongoIdAndNull(collection, query);
@@ -1,5 +1,5 @@
1
1
  import AbstractMutexer from '../mutexers/AbstractMutexer';
2
- import { CreateOptions, Database, DatabaseInternalOptions, UniqueIndex } from '../types/database.types';
2
+ import { CreateOptions, Database, DatabaseInternalOptions, Index, IndexWithFilter } from '../types/database.types';
3
3
  import { QueryOptions } from '../types/query.types';
4
4
  export default class NeDbDatabase extends AbstractMutexer implements Database {
5
5
  private collections;
@@ -31,14 +31,15 @@ export default class NeDbDatabase extends AbstractMutexer implements Database {
31
31
  delete(collection: string, query: Record<string, any>): Promise<number>;
32
32
  deleteOne(collection: string, query: Record<string, any>): Promise<number>;
33
33
  private assertPassesUniqueIndexes;
34
- getUniqueIndexes(collection: string): Promise<UniqueIndex[]>;
35
- getIndexes(collection: string, shouldIncludeUnique?: boolean): Promise<UniqueIndex[]>;
36
- dropIndex(collection: string, index: UniqueIndex): Promise<void>;
34
+ getUniqueIndexes(collection: string): Promise<IndexWithFilter[]>;
35
+ getIndexes(collection: string, shouldIncludeUnique?: boolean): Promise<IndexWithFilter[]>;
36
+ dropIndex(collection: string, index: Index): Promise<void>;
37
37
  private assertIndexDoesNotExist;
38
- private doesIndexExist;
39
- createUniqueIndex(collection: string, index: UniqueIndex): Promise<void>;
38
+ private doesInclude;
39
+ createUniqueIndex(collection: string, index: Index): Promise<void>;
40
40
  createIndex(collection: string, fields: string[]): Promise<void>;
41
- syncUniqueIndexes(collectionName: string, indexes: UniqueIndex[]): Promise<void>;
41
+ private normalizeIndex;
42
+ syncUniqueIndexes(collectionName: string, indexes: Index[]): Promise<void>;
42
43
  syncIndexes(collectionName: string, indexes: string[][]): Promise<void>;
43
44
  query<T>(query: string, params?: any[]): Promise<T[]>;
44
45
  private queryToKey;
@@ -16,7 +16,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  var _a;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  const dotenv_1 = __importDefault(require("dotenv"));
19
- const differenceWith_1 = __importDefault(require("lodash/differenceWith"));
20
19
  const get_1 = __importDefault(require("lodash/get"));
21
20
  const isEqual_1 = __importDefault(require("lodash/isEqual"));
22
21
  const isObject_1 = __importDefault(require("lodash/isObject"));
@@ -26,7 +25,7 @@ const SpruceError_1 = __importDefault(require("../errors/SpruceError"));
26
25
  const AbstractMutexer_1 = __importDefault(require("../mutexers/AbstractMutexer"));
27
26
  const generateId_1 = __importDefault(require("../utilities/generateId"));
28
27
  const mongo_utility_1 = __importDefault(require("../utilities/mongo.utility"));
29
- const normalizeIndex_1 = __importDefault(require("./normalizeIndex"));
28
+ const database_utilities_1 = require("./database.utilities");
30
29
  dotenv_1.default.config();
31
30
  class NeDbDatabase extends AbstractMutexer_1.default {
32
31
  constructor() {
@@ -290,7 +289,7 @@ class NeDbDatabase extends AbstractMutexer_1.default {
290
289
  await this.randomDelay();
291
290
  if (col._uniqueIndexes) {
292
291
  for (const index of col._uniqueIndexes) {
293
- const { fields, filter } = (0, normalizeIndex_1.default)(index);
292
+ const { fields, filter } = (0, database_utilities_1.normalizeIndex)(index);
294
293
  if (filter) {
295
294
  let shouldSkip = false;
296
295
  for (const key in filter) {
@@ -348,12 +347,12 @@ class NeDbDatabase extends AbstractMutexer_1.default {
348
347
  async dropIndex(collection, index) {
349
348
  var _a, _b;
350
349
  const col = this.loadCollection(collection);
351
- const { fields } = (0, normalizeIndex_1.default)(index);
350
+ const { fields } = (0, database_utilities_1.normalizeIndex)(index);
352
351
  await this.randomDelay();
353
352
  let found = false;
354
353
  let newIndexes = [];
355
354
  for (const uniq of (_a = col._uniqueIndexes) !== null && _a !== void 0 ? _a : []) {
356
- if (!(0, isEqual_1.default)(uniq, fields)) {
355
+ if (!(0, isEqual_1.default)(uniq.fields, fields)) {
357
356
  newIndexes.push(uniq);
358
357
  }
359
358
  else {
@@ -367,7 +366,7 @@ class NeDbDatabase extends AbstractMutexer_1.default {
367
366
  else {
368
367
  newIndexes = [];
369
368
  for (const index of (_b = col._indexes) !== null && _b !== void 0 ? _b : []) {
370
- if (!(0, isEqual_1.default)(index, fields)) {
369
+ if (!(0, isEqual_1.default)(index.fields, fields)) {
371
370
  newIndexes.push(index);
372
371
  }
373
372
  else {
@@ -385,37 +384,32 @@ class NeDbDatabase extends AbstractMutexer_1.default {
385
384
  collectionName: 'test_collection',
386
385
  });
387
386
  }
388
- assertIndexDoesNotExist(currentIndexes, fields, collectionName) {
389
- if (this.doesIndexExist(currentIndexes, fields)) {
387
+ assertIndexDoesNotExist(currentIndexes, index, collectionName) {
388
+ if (this.doesInclude(currentIndexes, index)) {
390
389
  throw new SpruceError_1.default({
391
390
  code: 'INDEX_EXISTS',
392
- index: fields,
391
+ index: index.fields,
393
392
  collectionName,
394
393
  });
395
394
  }
396
395
  }
397
- doesIndexExist(currentIndexes, index) {
398
- for (const existing of currentIndexes !== null && currentIndexes !== void 0 ? currentIndexes : []) {
399
- if ((0, isEqual_1.default)(existing, index)) {
400
- return true;
401
- }
402
- }
403
- return false;
396
+ doesInclude(haystack, needle) {
397
+ return (0, database_utilities_1.doesIndexesInclude)(haystack, needle);
404
398
  }
405
399
  async createUniqueIndex(collection, index) {
406
400
  const col = this.loadCollection(collection);
407
401
  if (!col._uniqueIndexes) {
408
402
  col._uniqueIndexes = [];
409
403
  }
410
- const { fields, filter } = (0, normalizeIndex_1.default)(index);
404
+ const indexWithFilter = (0, database_utilities_1.normalizeIndex)(index);
411
405
  await this.randomDelay();
412
- this.assertIndexDoesNotExist(col._uniqueIndexes, fields, collection);
413
- if (col._uniqueIndexes && !filter) {
406
+ this.assertIndexDoesNotExist(col._uniqueIndexes, indexWithFilter, collection);
407
+ if (col._uniqueIndexes && !indexWithFilter.filter) {
414
408
  const tempUniqueIndexes = [...col._uniqueIndexes];
415
- tempUniqueIndexes.push(fields);
409
+ tempUniqueIndexes.push(indexWithFilter);
416
410
  const documents = (await this.find(collection)) || [];
417
411
  for (const index of tempUniqueIndexes) {
418
- const { fields: uniqueFields } = (0, normalizeIndex_1.default)(index);
412
+ const { fields: uniqueFields } = (0, database_utilities_1.normalizeIndex)(index);
419
413
  let parsedExisting = [];
420
414
  for (const doc of documents) {
421
415
  const tempDoc = {};
@@ -433,7 +427,7 @@ class NeDbDatabase extends AbstractMutexer_1.default {
433
427
  }
434
428
  }
435
429
  }
436
- col._uniqueIndexes.push(index);
430
+ col._uniqueIndexes.push(indexWithFilter);
437
431
  }
438
432
  async createIndex(collection, fields) {
439
433
  const col = this.loadCollection(collection);
@@ -441,20 +435,19 @@ class NeDbDatabase extends AbstractMutexer_1.default {
441
435
  col._indexes = [];
442
436
  }
443
437
  await this.randomDelay();
444
- this.assertIndexDoesNotExist(col._indexes, fields, collection);
445
- col._indexes.push(fields);
438
+ this.assertIndexDoesNotExist(col._indexes, this.normalizeIndex(fields), collection);
439
+ col._indexes.push({ fields });
440
+ }
441
+ normalizeIndex(index) {
442
+ const { fields, filter } = (0, database_utilities_1.normalizeIndex)(index);
443
+ return { fields, filter };
446
444
  }
447
445
  async syncUniqueIndexes(collectionName, indexes) {
448
446
  var _a;
449
447
  const currentIndexes = await this.getUniqueIndexes(collectionName);
450
- const toDelete = [];
451
- for (const index of currentIndexes) {
452
- if (!this.doesIndexExist(indexes, index)) {
453
- toDelete.push(index);
454
- }
455
- }
448
+ const toDelete = (0, database_utilities_1.pluckMissingIndexes)(currentIndexes, indexes);
456
449
  for (const index of indexes) {
457
- if (!this.doesIndexExist(currentIndexes, index)) {
450
+ if (!this.doesInclude(currentIndexes, index)) {
458
451
  try {
459
452
  await this.createUniqueIndex(collectionName, index);
460
453
  }
@@ -472,9 +465,9 @@ class NeDbDatabase extends AbstractMutexer_1.default {
472
465
  async syncIndexes(collectionName, indexes) {
473
466
  var _a;
474
467
  const currentIndexes = await this.getIndexes(collectionName);
475
- const extraIndexes = (0, differenceWith_1.default)(currentIndexes, indexes, isEqual_1.default);
468
+ const extraIndexes = (0, database_utilities_1.pluckMissingIndexes)(currentIndexes, indexes);
476
469
  for (const index of indexes) {
477
- if (!this.doesIndexExist(currentIndexes, index)) {
470
+ if (!this.doesInclude(currentIndexes, index)) {
478
471
  try {
479
472
  await this.createIndex(collectionName, index);
480
473
  }
@@ -0,0 +1,6 @@
1
+ import { IndexWithFilter, Index } from '../types/database.types';
2
+ export declare function doesIndexesInclude(haystack: Index[], needle: Index): boolean;
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;
6
+ export declare function pluckMissingIndexes(left: Index[], right: Index[]): Index[];
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.doesIndexesInclude = doesIndexesInclude;
7
+ exports.areIndexesEqual = areIndexesEqual;
8
+ exports.generateIndexName = generateIndexName;
9
+ exports.normalizeIndex = normalizeIndex;
10
+ exports.pluckMissingIndexes = pluckMissingIndexes;
11
+ const differenceWith_1 = __importDefault(require("lodash/differenceWith"));
12
+ function doesIndexesInclude(haystack, needle) {
13
+ for (const index of haystack !== null && haystack !== void 0 ? haystack : []) {
14
+ if (areIndexesEqual(index, needle)) {
15
+ return true;
16
+ }
17
+ }
18
+ return false;
19
+ }
20
+ function areIndexesEqual(left, right) {
21
+ const name1 = generateIndexName(normalizeIndex(left));
22
+ const name2 = generateIndexName(normalizeIndex(right));
23
+ return name1 === name2;
24
+ }
25
+ function generateIndexName(indexWithFilter) {
26
+ let name = indexWithFilter.fields.join('_');
27
+ if (indexWithFilter.filter) {
28
+ name += '_filtered';
29
+ }
30
+ return name;
31
+ }
32
+ function normalizeIndex(index) {
33
+ const fields = Array.isArray(index) ? index : index.fields;
34
+ const filter = Array.isArray(index) ? undefined : index.filter;
35
+ fields.sort();
36
+ return { fields, filter };
37
+ }
38
+ function pluckMissingIndexes(left, right) {
39
+ return (0, differenceWith_1.default)(left, right, areIndexesEqual);
40
+ }
@@ -1,5 +1,5 @@
1
1
  import { MongoClientOptions, MongoClient } from 'mongodb';
2
- import { Database, DatabaseOptions, IndexWithFilter, UniqueIndex } from '../types/database.types';
2
+ import { Database, DatabaseOptions, Index, IndexWithFilter } from '../types/database.types';
3
3
  import { QueryOptions } from '../types/query.types';
4
4
  export declare const MONGO_TEST_URI = "mongodb://localhost:27017";
5
5
  export default class MongoDatabase implements Database {
@@ -26,16 +26,21 @@ export default class MongoDatabase implements Database {
26
26
  dropCollection(name: string): Promise<void>;
27
27
  dropDatabase(): Promise<void>;
28
28
  private listIndexes;
29
- dropIndex(collection: string, index: UniqueIndex): Promise<void>;
30
- getUniqueIndexes(collection: string): Promise<string[][]>;
31
- getIndexes(collection: string, shouldIncludeUnique?: boolean): Promise<any[]>;
32
- createIndex(collection: string, fields: string[]): Promise<void>;
29
+ dropIndex(collection: string, index: Index): Promise<void>;
30
+ getUniqueIndexes(collection: string): Promise<IndexWithFilter[]>;
31
+ getIndexes(collection: string, shouldIncludeUnique?: boolean): Promise<IndexWithFilter[] | {
32
+ fields: string[];
33
+ filter: any;
34
+ }[]>;
35
+ createIndex(collection: string, index: Index): Promise<void>;
33
36
  private assertIndexDoesNotExist;
34
- private doesIndexExist;
35
- syncIndexes(collectionName: string, indexes: string[][]): Promise<void>;
37
+ private doesInclude;
38
+ syncIndexes(collectionName: string, indexes: Index[]): Promise<void>;
39
+ private _syncIndexes;
36
40
  createUniqueIndex(collection: string, index: string[] | IndexWithFilter): Promise<void>;
41
+ private generateIndexName;
37
42
  private normalizeIndex;
38
- syncUniqueIndexes(collectionName: string, indexes: UniqueIndex[]): Promise<void>;
43
+ syncUniqueIndexes(collectionName: string, indexes: Index[]): Promise<void>;
39
44
  update(collection: string, query: Record<string, any>, updates: Record<string, any>): Promise<number>;
40
45
  updateOne(collection: string, query: Record<string, any>, updates: Record<string, any>): Promise<Record<string, any>>;
41
46
  upsertOne(collection: string, query: Record<string, any>, updates: Record<string, any>): Promise<Record<string, any>>;