liwi-mongo 8.1.1 → 9.0.0

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.
@@ -2,7 +2,7 @@ import mongodb from 'mongodb';
2
2
  import { AbstractStoreCursor, AbstractConnection } from 'liwi-store';
3
3
  import { AbstractSubscribableStoreQuery, SubscribeStore } from 'liwi-subscribe-store';
4
4
  import mingo from 'mingo';
5
- import Logger from 'nightingale-logger';
5
+ import { Logger } from 'nightingale-logger';
6
6
 
7
7
  class MongoCursor extends AbstractStoreCursor {
8
8
  // key in AbstractCursor
@@ -18,7 +18,7 @@ class MongoCursor extends AbstractStoreCursor {
18
18
  next() {
19
19
  return this.cursor.next().then(value => {
20
20
  this._result = value;
21
- this.key = value === null || value === void 0 ? void 0 : value._id;
21
+ this.key = value?._id;
22
22
  return this.key;
23
23
  });
24
24
  }
@@ -28,10 +28,6 @@ class MongoCursor extends AbstractStoreCursor {
28
28
  return Promise.resolve(this);
29
29
  }
30
30
 
31
- count(applySkipLimit = false) {
32
- return this.cursor.count(applySkipLimit);
33
- }
34
-
35
31
  result() {
36
32
  if (!this._result) throw new Error('Cannot call result() before next()');
37
33
  return Promise.resolve(this._result);
@@ -77,8 +73,7 @@ class MongoQueryCollection extends AbstractSubscribableStoreQuery {
77
73
  }
78
74
 
79
75
  async fetch(onFulfilled) {
80
- const cursor = await this.createMongoCursor();
81
- const [result, count] = await Promise.all([cursor.toArray(), cursor.count()]);
76
+ const [result, count] = await Promise.all([this.createMongoCursor().then(cursor => cursor.toArray()), this.store.count()]);
82
77
  return onFulfilled({
83
78
  result: result.map(this.transformer),
84
79
  meta: {
@@ -145,22 +140,21 @@ class MongoQueryCollection extends AbstractSubscribableStoreQuery {
145
140
  deleted,
146
141
  updated,
147
142
  inserted
148
- } = action.changes.reduce((acc, [prevObject, nextObject]) => {
143
+ } = {
144
+ deleted: [],
145
+ updated: [],
146
+ inserted: []
147
+ };
148
+ action.changes.forEach(([prevObject, nextObject]) => {
149
149
  if (testCriteria(prevObject)) {
150
150
  if (!testCriteria(nextObject)) {
151
- acc.deleted.push(prevObject[this.store.keyPath]);
151
+ deleted.push(prevObject[this.store.keyPath]);
152
152
  } else {
153
- acc.updated.push(this.transformer(nextObject));
153
+ updated.push(this.transformer(nextObject));
154
154
  }
155
155
  } else if (testCriteria(nextObject)) {
156
- acc.inserted.push(this.transformer(nextObject));
156
+ inserted.push(this.transformer(nextObject));
157
157
  }
158
-
159
- return acc;
160
- }, {
161
- deleted: [],
162
- updated: [],
163
- inserted: []
164
158
  });
165
159
 
166
160
  if (deleted.length > 0) {
@@ -246,18 +240,17 @@ class MongoQuerySingleItem extends AbstractSubscribableStoreQuery {
246
240
  this.transformer = transformer;
247
241
  }
248
242
 
249
- createMingoQuery() {
250
- if (!this.mingoQuery) {
243
+ createMingoTestCriteria() {
244
+ if (!this.testCriteria) {
251
245
  if (!this.options.criteria) {
252
- return {
253
- test: () => true
254
- };
246
+ return () => true;
255
247
  }
256
248
 
257
- this.mingoQuery = new mingo.Query(this.options.criteria);
249
+ const mingoQuery = new mingo.Query(this.options.criteria);
250
+ this.testCriteria = mingoQuery.test.bind(mingoQuery);
258
251
  }
259
252
 
260
- return this.mingoQuery;
253
+ return this.testCriteria;
261
254
  }
262
255
 
263
256
  async fetch(onFulfilled) {
@@ -280,7 +273,7 @@ class MongoQuerySingleItem extends AbstractSubscribableStoreQuery {
280
273
 
281
274
  _subscribe(callback, _includeInitial) {
282
275
  const store = super.getSubscribeStore();
283
- const mingoQuery = this.createMingoQuery();
276
+ const testCriteria = this.createMingoTestCriteria();
284
277
  const promise = _includeInitial ? this.fetch(({
285
278
  result,
286
279
  meta,
@@ -299,7 +292,7 @@ class MongoQuerySingleItem extends AbstractSubscribableStoreQuery {
299
292
  switch (action.type) {
300
293
  case 'inserted':
301
294
  {
302
- const filtered = action.next.filter(mingoQuery.test);
295
+ const filtered = action.next.filter(testCriteria);
303
296
 
304
297
  if (filtered.length > 0) {
305
298
  changes.push({
@@ -313,7 +306,7 @@ class MongoQuerySingleItem extends AbstractSubscribableStoreQuery {
313
306
 
314
307
  case 'deleted':
315
308
  {
316
- const filtered = action.prev.filter(mingoQuery.test);
309
+ const filtered = action.prev.filter(testCriteria);
317
310
 
318
311
  if (filtered.length > 0) {
319
312
  changes.push({
@@ -327,7 +320,7 @@ class MongoQuerySingleItem extends AbstractSubscribableStoreQuery {
327
320
 
328
321
  case 'updated':
329
322
  {
330
- const filtered = action.changes.filter(([prev, next]) => mingoQuery.test(prev));
323
+ const filtered = action.changes.filter(([prev, next]) => testCriteria(prev));
331
324
 
332
325
  if (filtered.length > 0) {
333
326
  if (this.options.sort) {
@@ -344,7 +337,7 @@ class MongoQuerySingleItem extends AbstractSubscribableStoreQuery {
344
337
  const [, next] = filtered[0];
345
338
  changes.push({
346
339
  type: 'updated',
347
- result: mingoQuery.test(next) ? this.transformer(next) : null
340
+ result: testCriteria(next) ? this.transformer(next) : null
348
341
  });
349
342
  }
350
343
  } else if (filtered.length === 0) ;
@@ -380,8 +373,9 @@ class MongoQuerySingleItem extends AbstractSubscribableStoreQuery {
380
373
 
381
374
  /* eslint-disable max-lines */
382
375
  class MongoStore {
376
+ keyPath = '_id';
377
+
383
378
  constructor(connection, collectionName) {
384
- this.keyPath = '_id';
385
379
  this.connection = connection;
386
380
 
387
381
  if (!collectionName) {
@@ -415,17 +409,18 @@ class MongoStore {
415
409
 
416
410
  async insertOne(object) {
417
411
  if (!object._id) {
418
- object._id = new mongodb.ObjectID().toString();
412
+ object._id = new mongodb.ObjectId().toString();
419
413
  }
420
414
 
421
415
  if (!object.created) object.created = new Date();
422
416
  if (!object.updated) object.updated = new Date();
423
417
  const collection = await this.collection;
424
418
  const {
425
- result
426
- } = await collection.insertOne(object);
419
+ acknowledged: isAcknowledged
420
+ } = await collection.insertOne( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
421
+ object);
427
422
 
428
- if (!result.ok || result.n !== 1) {
423
+ if (!isAcknowledged) {
429
424
  throw new Error('Fail to insert');
430
425
  }
431
426
 
@@ -492,7 +487,7 @@ class MongoStore {
492
487
  ...criteria
493
488
  }, partialUpdate);
494
489
 
495
- if (!commandResult.result.ok) {
490
+ if (!commandResult.acknowledged) {
496
491
  console.error(commandResult);
497
492
  throw new Error('Update failed');
498
493
  }
@@ -506,7 +501,8 @@ class MongoStore {
506
501
  }
507
502
 
508
503
  partialUpdateMany(criteria, partialUpdate) {
509
- return this.collection.then(collection => collection.updateMany(criteria, partialUpdate)).then(() => undefined); // TODO return updated object
504
+ return this.collection.then(collection => // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
505
+ collection.updateMany(criteria, partialUpdate)).then(() => undefined); // TODO return updated object
510
506
  }
511
507
 
512
508
  deleteByKey(key, criteria) {
@@ -524,23 +520,37 @@ class MongoStore {
524
520
  return this.collection.then(collection => collection.deleteMany(selector)).then(() => undefined);
525
521
  }
526
522
 
527
- cursor(criteria, sort) {
528
- return this.collection.then(collection => collection.find(criteria)).then(sort && (cursor => cursor.sort(sort))).then(cursor => new MongoCursor(this, cursor));
523
+ async count(filter) {
524
+ const collection = await this.collection;
525
+ return filter ? collection.countDocuments(filter) : collection.countDocuments();
529
526
  }
530
527
 
531
- findByKey(key, criteria) {
532
- return this.collection.then(collection => collection.findOne({
528
+ async cursor(filter, sort) {
529
+ const collection = await this.collection;
530
+ const findCursor = filter ? collection.find(filter) : collection.find();
531
+ if (sort) findCursor.sort(sort);
532
+ return new MongoCursor(this, findCursor);
533
+ }
534
+
535
+ async findByKey(key, criteria) {
536
+ const collection = await this.collection;
537
+ const result = await collection.findOne({
533
538
  _id: key,
534
539
  ...criteria
535
- })).then(result => result || undefined);
540
+ });
541
+ return result || undefined;
536
542
  }
537
543
 
538
544
  findAll(criteria, sort) {
539
545
  return this.cursor(criteria, sort).then(cursor => cursor.toArray());
540
546
  }
541
547
 
542
- findOne(criteria, sort) {
543
- return this.collection.then(collection => collection.find(criteria)).then(sort && (cursor => cursor.sort(sort))).then(cursor => cursor.limit(1).next());
548
+ async findOne(filter, sort) {
549
+ const collection = await this.collection;
550
+ const result = await collection.findOne(filter, {
551
+ sort
552
+ });
553
+ return result || undefined;
544
554
  }
545
555
 
546
556
  }
@@ -571,9 +581,7 @@ class MongoConnection extends AbstractConnection {
571
581
  logger.info('connecting', {
572
582
  connectionString
573
583
  });
574
- const connectPromise = mongodb.MongoClient.connect(connectionString, {
575
- useNewUrlParser: true
576
- }).then(connection => {
584
+ const connectPromise = mongodb.MongoClient.connect(connectionString).then(connection => {
577
585
  logger.info('connected', {
578
586
  connectionString
579
587
  });
@@ -658,4 +666,4 @@ function createMongoSubscribeStore(mongoStore) {
658
666
  }
659
667
 
660
668
  export { MongoConnection, MongoStore, createMongoSubscribeStore };
661
- //# sourceMappingURL=index-node12-dev.mjs.map
669
+ //# sourceMappingURL=index-node14.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-node14.mjs","sources":["../src/MongoCursor.ts","../src/MongoQueryCollection.ts","../src/MongoQuerySingleItem.ts","../src/MongoStore.ts","../src/MongoConnection.ts","../src/createMongoSubscribeStore.ts"],"sourcesContent":["import { AbstractStoreCursor } from 'liwi-store';\nimport type { AllowedKeyValue } from 'liwi-types';\nimport type { FindCursor } from 'mongodb';\nimport type { MongoBaseModel } from './MongoBaseModel';\nimport type MongoStore from './MongoStore';\n\nexport default class MongoCursor<\n Model extends MongoBaseModel<KeyValue>,\n Result extends Partial<Model> = Model,\n KeyValue extends AllowedKeyValue = Model['_id'],\n> extends AbstractStoreCursor<\n MongoStore<Model, KeyValue>,\n KeyValue,\n Model,\n Result\n> {\n // key in AbstractCursor\n\n private readonly cursor: FindCursor<Result>;\n\n private _result?: Result | null;\n\n constructor(store: MongoStore<Model, KeyValue>, cursor: FindCursor<Result>) {\n super(store);\n this.cursor = cursor;\n }\n\n advance(count: number): void {\n this.cursor.skip(count);\n }\n\n next(): Promise<KeyValue | undefined> {\n return this.cursor.next().then((value) => {\n this._result = value;\n this.key = value?._id;\n return this.key;\n });\n }\n\n limit(newLimit: number): Promise<this> {\n this.cursor.limit(newLimit);\n return Promise.resolve(this);\n }\n\n result(): Promise<Result> {\n if (!this._result) throw new Error('Cannot call result() before next()');\n return Promise.resolve(this._result);\n }\n\n close(): Promise<void> {\n if (this.cursor) {\n this.cursor.close();\n }\n\n return Promise.resolve();\n }\n\n toArray(): Promise<Result[]> {\n return this.cursor.toArray();\n }\n}\n","/* eslint-disable complexity, max-lines */\nimport type {\n QuerySubscription,\n SubscribeCallback,\n QueryResult,\n QueryParams,\n} from 'liwi-store';\nimport type { Actions } from 'liwi-subscribe-store';\nimport { AbstractSubscribableStoreQuery } from 'liwi-subscribe-store';\nimport type {\n Changes,\n QueryOptions,\n Transformer,\n AllowedKeyValue,\n} from 'liwi-types';\nimport mingo from 'mingo';\nimport type {\n MongoBaseModel,\n MongoInsertType,\n MongoKeyPath,\n} from './MongoBaseModel';\nimport type MongoCursor from './MongoCursor';\nimport type MongoStore from './MongoStore';\n\nconst identityTransformer = <\n Model extends MongoBaseModel<any>,\n Transformed = Model,\n>(\n model: Model,\n): Transformed => model as unknown as Transformed;\n\ntype TestCriteria = (obj: any) => boolean;\n\nexport default class MongoQueryCollection<\n Model extends MongoBaseModel<KeyValue>,\n Params extends QueryParams<Params> = never,\n KeyValue extends AllowedKeyValue = Model['_id'],\n Item extends Record<MongoKeyPath, KeyValue> = Model,\n> extends AbstractSubscribableStoreQuery<\n MongoKeyPath,\n KeyValue,\n Model,\n MongoInsertType<Model, KeyValue>,\n Params,\n Item[]\n> {\n private readonly store: MongoStore<Model, KeyValue>;\n\n private readonly options: QueryOptions<Model>;\n\n private testCriteria?: TestCriteria;\n\n private readonly transformer: Transformer<Model, Item>;\n\n constructor(\n store: MongoStore<Model, KeyValue>,\n options: QueryOptions<Model>,\n transformer: Transformer<Model, Item> = identityTransformer,\n ) {\n super();\n this.store = store;\n this.options = options;\n this.transformer = transformer;\n }\n\n createTestCriteria(): TestCriteria {\n if (!this.testCriteria) {\n if (!this.options.criteria) {\n return () => true;\n }\n\n const mingoQuery = new mingo.Query(this.options.criteria);\n this.testCriteria = mingoQuery.test.bind(mingoQuery);\n }\n return this.testCriteria;\n }\n\n async fetch<T>(onFulfilled: (result: QueryResult<Item[]>) => T): Promise<T> {\n const [result, count] = await Promise.all([\n this.createMongoCursor().then((cursor) => cursor.toArray()),\n this.store.count(),\n ]);\n\n return onFulfilled({\n result: result.map(this.transformer),\n meta: { total: count },\n info: {\n sort: this.options.sort,\n limit: this.options.limit,\n keyPath: this.store.keyPath,\n },\n });\n }\n\n _subscribe(\n callback: SubscribeCallback<KeyValue, Item[]>,\n _includeInitial: boolean,\n ): QuerySubscription {\n const store = super.getSubscribeStore();\n const testCriteria: TestCriteria = this.createTestCriteria();\n\n const promise: Promise<void> = _includeInitial\n ? this.fetch(({ result, meta, info }: QueryResult<Item[]>) => {\n callback(null, [\n {\n type: 'initial',\n initial: result,\n queryInfo: info,\n meta,\n },\n ]);\n })\n : Promise.resolve();\n\n const unsubscribe = store.subscribe((action: Actions<Model>) => {\n const changes: Changes<KeyValue, Item[]> = [];\n switch (action.type) {\n case 'inserted': {\n const filtered = action.next.filter(testCriteria);\n if (filtered.length > 0) {\n changes.push({\n type: 'inserted',\n result: filtered.map(this.transformer),\n });\n }\n break;\n }\n case 'deleted': {\n const filtered = action.prev.filter(testCriteria);\n if (filtered.length > 0) {\n changes.push({\n type: 'deleted',\n keys: filtered.map((object) => object[this.store.keyPath]),\n });\n }\n break;\n }\n case 'updated': {\n const {\n deleted,\n updated,\n inserted,\n }: {\n deleted: KeyValue[];\n updated: Item[];\n inserted: Item[];\n } = { deleted: [], updated: [], inserted: [] };\n\n action.changes.forEach(([prevObject, nextObject]: [Model, Model]) => {\n if (testCriteria(prevObject)) {\n if (!testCriteria(nextObject)) {\n deleted.push(prevObject[this.store.keyPath]);\n } else {\n updated.push(this.transformer(nextObject));\n }\n } else if (testCriteria(nextObject)) {\n inserted.push(this.transformer(nextObject));\n }\n });\n\n if (deleted.length > 0) {\n changes.push({ type: 'deleted', keys: deleted });\n }\n if (updated.length > 0) {\n changes.push({ type: 'updated', result: updated });\n }\n if (inserted.length > 0) {\n changes.push({ type: 'inserted', result: inserted });\n }\n\n break;\n }\n default:\n throw new Error('Unsupported type');\n }\n\n if (changes.length === 0) return;\n\n callback(null, changes);\n });\n // let _feed;\n // const promise = this.queryCallback(this.store.query(), this.store.r)\n // .changes({\n // includeInitial: _includeInitial,\n // includeStates: true,\n // includeTypes: true,\n // includeOffsets: true,\n // })\n // .then((feed) => {\n // if (args.length === 0) {\n // _feed = feed;\n // delete this._promise;\n // }\n //\n // feed.each(callback);\n // return feed;\n // });\n //\n // if (args.length === 0) this._promise = promise;\n\n return {\n stop: unsubscribe,\n cancel: unsubscribe,\n then: <T, U>(\n onFulfilled: () => T | Promise<T>,\n onRejected?: (error: any) => U | Promise<U>,\n ): Promise<T | U> => promise.then(onFulfilled, onRejected),\n };\n }\n\n private async createMongoCursor(): Promise<\n MongoCursor<Model, Model, KeyValue>\n > {\n const cursor = await this.store.cursor(\n this.options.criteria,\n this.options.sort,\n );\n\n if (this.options.skip) {\n cursor.advance(this.options.skip);\n }\n\n if (this.options.limit) {\n await cursor.limit(this.options.limit);\n }\n\n return cursor;\n }\n}\n","import type {\n QuerySubscription,\n SubscribeCallback,\n QueryResult,\n QueryParams,\n} from 'liwi-store';\nimport type { Actions } from 'liwi-subscribe-store';\nimport { AbstractSubscribableStoreQuery } from 'liwi-subscribe-store';\nimport type {\n Changes,\n QueryOptions,\n Transformer,\n AllowedKeyValue,\n} from 'liwi-types';\nimport mingo from 'mingo';\nimport type {\n MongoBaseModel,\n MongoInsertType,\n MongoKeyPath,\n} from './MongoBaseModel';\nimport type MongoCursor from './MongoCursor';\nimport type MongoStore from './MongoStore';\n\nconst identityTransformer = <\n Model extends MongoBaseModel<any>,\n Transformed = Model,\n>(\n model: Model,\n): Transformed => model as unknown as Transformed;\n\ntype TestCriteria = (obj: any) => boolean;\n\nexport default class MongoQuerySingleItem<\n Model extends MongoBaseModel<KeyValue>,\n Params extends QueryParams<Params> = never,\n Result extends Record<MongoKeyPath, KeyValue> | null = Model | null,\n KeyValue extends AllowedKeyValue = Model['_id'],\n> extends AbstractSubscribableStoreQuery<\n MongoKeyPath,\n KeyValue,\n Model,\n MongoInsertType<Model, KeyValue>,\n Params,\n Result\n> {\n private readonly store: MongoStore<Model, KeyValue>;\n\n private readonly options: QueryOptions<Model>;\n\n private testCriteria?: TestCriteria;\n\n private readonly transformer: Transformer<Model, Result>;\n\n constructor(\n store: MongoStore<Model, KeyValue>,\n options: QueryOptions<Model>,\n transformer: Transformer<Model, Result> = identityTransformer,\n ) {\n super();\n this.store = store;\n this.options = options;\n this.transformer = transformer;\n }\n\n createMingoTestCriteria(): TestCriteria {\n if (!this.testCriteria) {\n if (!this.options.criteria) {\n return () => true;\n }\n\n const mingoQuery = new mingo.Query(this.options.criteria);\n this.testCriteria = mingoQuery.test.bind(mingoQuery);\n }\n\n return this.testCriteria;\n }\n\n async fetch<T>(onFulfilled: (result: QueryResult<Result>) => T): Promise<T> {\n const cursor = await this.createMongoCursor();\n await cursor.limit(1);\n return cursor.toArray().then((result: Model[]) => {\n const item: Result =\n result.length === 0 ? (null as Result) : this.transformer(result[0]);\n return onFulfilled({\n result: item,\n meta: { total: result === null ? 0 : 1 },\n info: {\n limit: 1,\n keyPath: this.store.keyPath,\n },\n });\n });\n }\n\n _subscribe(\n callback: SubscribeCallback<KeyValue, Result>,\n _includeInitial: boolean,\n ): QuerySubscription {\n const store = super.getSubscribeStore();\n const testCriteria: TestCriteria = this.createMingoTestCriteria();\n\n const promise: Promise<void> = _includeInitial\n ? this.fetch(({ result, meta, info }: QueryResult<Result>) => {\n callback(null, [\n {\n type: 'initial',\n initial: result,\n queryInfo: info,\n meta,\n },\n ]);\n })\n : Promise.resolve();\n\n const unsubscribe = store.subscribe(async (action: Actions<Model>) => {\n const changes: Changes<KeyValue, Result> = [];\n switch (action.type) {\n case 'inserted': {\n const filtered = action.next.filter(testCriteria);\n if (filtered.length > 0) {\n changes.push({\n type: 'updated',\n result: this.transformer(filtered[0]),\n });\n }\n break;\n }\n case 'deleted': {\n const filtered = action.prev.filter(testCriteria);\n if (filtered.length > 0) {\n changes.push({\n type: 'deleted',\n keys: filtered.map((object) => object[this.store.keyPath]),\n });\n }\n break;\n }\n case 'updated': {\n const filtered = action.changes.filter(([prev, next]) =>\n testCriteria(prev),\n );\n if (filtered.length > 0) {\n if (this.options.sort) {\n const { result } = await this.fetch((res) => res);\n changes.push({\n type: 'updated',\n result,\n });\n } else if (filtered.length !== 1) {\n throw new Error(\n 'should not match more than 1, use sort if you can have multiple match',\n );\n } else {\n const [, next] = filtered[0];\n changes.push({\n type: 'updated',\n result: testCriteria(next) ? this.transformer(next) : null!,\n });\n }\n } else if (filtered.length === 0) {\n }\n break;\n }\n default:\n throw new Error('Unsupported type');\n }\n\n if (changes.length === 0) return;\n\n callback(null, changes);\n });\n\n return {\n stop: unsubscribe,\n cancel: unsubscribe,\n then: <T, U>(\n onFulfilled: () => T | Promise<T>,\n onRejected?: (error: any) => U | Promise<U>,\n ): Promise<T | U> => promise.then(onFulfilled, onRejected),\n };\n }\n\n private async createMongoCursor(): Promise<\n MongoCursor<Model, Model, KeyValue>\n > {\n const cursor = await this.store.cursor(\n this.options.criteria,\n this.options.sort,\n );\n\n if (this.options.limit) {\n await cursor.limit(this.options.limit);\n }\n\n return cursor;\n }\n}\n","/* eslint-disable max-lines */\nimport type {\n UpsertResult,\n SubscribableStore,\n QueryParams,\n UpsertPartialObject,\n} from 'liwi-store';\nimport type {\n Criteria,\n Sort,\n Update,\n QueryOptions,\n Transformer,\n AllowedKeyValue,\n OptionalBaseModelKeysForInsert,\n} from 'liwi-types';\nimport type {\n Collection,\n FindCursor,\n MongoClient,\n UpdateFilter,\n} from 'mongodb';\nimport mongodb from 'mongodb';\nimport type {\n MongoBaseModel,\n MongoKeyPath,\n MongoInsertType,\n} from './MongoBaseModel';\nimport type MongoConnection from './MongoConnection';\nimport MongoCursor from './MongoCursor';\nimport MongoQueryCollection from './MongoQueryCollection';\nimport MongoQuerySingleItem from './MongoQuerySingleItem';\n\nexport interface MongoUpsertResult<\n KeyValue extends AllowedKeyValue,\n Model extends MongoBaseModel<KeyValue>,\n> extends UpsertResult<Model> {\n object: Model;\n inserted: boolean;\n}\n\nexport default class MongoStore<\n Model extends MongoBaseModel<KeyValue>,\n KeyValue extends AllowedKeyValue = Model[MongoKeyPath],\n> implements\n SubscribableStore<\n MongoKeyPath,\n KeyValue,\n Model,\n MongoInsertType<Model>,\n MongoConnection\n >\n{\n readonly keyPath: MongoKeyPath = '_id';\n\n readonly connection: MongoConnection;\n\n private _collection: Collection<Model> | Promise<Collection<Model>>;\n\n constructor(connection: MongoConnection, collectionName: string) {\n this.connection = connection;\n\n if (!collectionName) {\n throw new Error(`Invalid collectionName: \"${collectionName}\"`);\n }\n\n this._collection = connection.getConnection().then(\n (client: MongoClient) => {\n this._collection = client.db().collection(collectionName);\n return this._collection;\n },\n (err: any) => {\n this._collection = Promise.reject(err);\n return this._collection;\n },\n );\n }\n\n get collection(): Promise<Collection<Model>> {\n if (this.connection.connectionFailed) {\n return Promise.reject(new Error('MongoDB connection failed'));\n }\n\n return Promise.resolve(this._collection);\n }\n\n createQuerySingleItem<\n Result extends Record<MongoKeyPath, KeyValue> = Model,\n Params extends QueryParams<Params> = never,\n >(\n options: QueryOptions<Model>,\n transformer?: Transformer<Model, Result>,\n ): MongoQuerySingleItem<Model, Params, Result, KeyValue> {\n return new MongoQuerySingleItem<Model, Params, Result, KeyValue>(\n this,\n options,\n transformer,\n );\n }\n\n createQueryCollection<\n Item extends Record<MongoKeyPath, KeyValue> = Model,\n Params extends QueryParams<Params> = never,\n >(\n options: QueryOptions<Model>,\n transformer?: Transformer<Model, Item>,\n ): MongoQueryCollection<Model, Params, Model['_id'], Item> {\n return new MongoQueryCollection<Model, Params, KeyValue, Item>(\n this,\n options,\n transformer,\n );\n }\n\n async insertOne(object: MongoInsertType<Model>): Promise<Model> {\n if (!object._id) {\n object._id = new mongodb.ObjectId().toString() as Model['_id'];\n }\n\n if (!object.created) object.created = new Date();\n if (!object.updated) object.updated = new Date();\n\n const collection = await this.collection;\n const { acknowledged: isAcknowledged } = await collection.insertOne(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n object as any,\n );\n if (!isAcknowledged) {\n throw new Error('Fail to insert');\n }\n\n return object as Model;\n }\n\n async replaceOne(object: Model): Promise<Model> {\n if (!object.updated) object.updated = new Date();\n\n const collection = await this.collection;\n await collection.replaceOne({ _id: object._id } as Criteria<Model>, object);\n return object;\n }\n\n async upsertOne<\n K extends Exclude<\n keyof Model,\n MongoKeyPath | OptionalBaseModelKeysForInsert\n >,\n >(\n object: UpsertPartialObject<MongoKeyPath, KeyValue, Model, K>,\n setOnInsertPartialObject?: Update<Model>['$setOnInsert'],\n ): Promise<Model> {\n const result = await this.upsertOneWithInfo(\n object,\n setOnInsertPartialObject,\n );\n return result.object;\n }\n\n async upsertOneWithInfo<\n K extends Exclude<\n keyof Model,\n MongoKeyPath | OptionalBaseModelKeysForInsert\n >,\n >(\n object: UpsertPartialObject<MongoKeyPath, KeyValue, Model, K>,\n setOnInsertPartialObject?: Update<Model>['$setOnInsert'],\n ): Promise<MongoUpsertResult<KeyValue, Model>> {\n const $setOnInsert = {\n created: object.created || new Date(),\n ...setOnInsertPartialObject,\n };\n\n if (!object.updated) {\n (object as MongoBaseModel).updated = new Date();\n }\n\n const $set: Partial<typeof object> = { ...object };\n delete $set.created;\n\n const collection = await this.collection;\n\n const { upsertedCount } = await collection.updateOne(\n { _id: object._id } as Criteria<Model>,\n { $set, $setOnInsert } as UpdateFilter<Model>,\n { upsert: true },\n );\n\n if (upsertedCount) {\n Object.assign(object, $setOnInsert);\n }\n\n return { object: object as unknown as Model, inserted: !!upsertedCount };\n }\n\n replaceSeveral(objects: Model[]): Promise<Model[]> {\n return Promise.all(objects.map((object: Model) => this.replaceOne(object)));\n }\n\n async partialUpdateByKey(\n key: KeyValue,\n partialUpdate: Update<Model>,\n criteria?: Criteria<Model>,\n ): Promise<Model> {\n const collection = await this.collection;\n const commandResult = await collection.updateOne(\n { _id: key, ...criteria } as Criteria<Model>,\n partialUpdate as UpdateFilter<Model>,\n );\n if (!commandResult.acknowledged) {\n console.error(commandResult);\n throw new Error('Update failed');\n }\n const object = await this.findByKey(key);\n return object!;\n }\n\n partialUpdateOne(\n object: Model,\n partialUpdate: Update<Model>,\n ): Promise<Model> {\n return this.partialUpdateByKey(object._id, partialUpdate);\n }\n\n partialUpdateMany(\n criteria: Criteria<Model>,\n partialUpdate: Update<Model>,\n ): Promise<void> {\n return this.collection\n .then((collection) =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n collection.updateMany(criteria, partialUpdate as any),\n )\n .then((res) => undefined); // TODO return updated object\n }\n\n deleteByKey(key: KeyValue, criteria?: Criteria<Model>): Promise<void> {\n return this.collection\n .then((collection) =>\n collection.deleteOne({ _id: key, ...criteria } as Criteria<Model>),\n )\n .then(() => undefined);\n }\n\n deleteOne(object: Model): Promise<void> {\n return this.deleteByKey(object._id);\n }\n\n deleteMany(selector: Criteria<Model>): Promise<void> {\n return this.collection\n .then((collection) => collection.deleteMany(selector))\n .then(() => undefined);\n }\n\n async count(filter?: Criteria<Model>): Promise<number> {\n const collection = await this.collection;\n return filter\n ? collection.countDocuments(filter)\n : collection.countDocuments();\n }\n\n async cursor<Result = Model>(\n filter?: Criteria<Model>,\n sort?: Sort<Model>,\n ): Promise<MongoCursor<Model, Result, KeyValue>> {\n const collection = await this.collection;\n const findCursor = filter\n ? collection.find<Result>(filter)\n : (collection.find() as unknown as FindCursor<Result>);\n if (sort) findCursor.sort(sort);\n return new MongoCursor<Model, Result, KeyValue>(this, findCursor);\n }\n\n async findByKey(\n key: KeyValue,\n criteria?: Criteria<Model>,\n ): Promise<Model | undefined> {\n const collection = await this.collection;\n const result = await collection.findOne<Model>({\n _id: key,\n ...criteria,\n } as Criteria<Model>);\n return result || undefined;\n }\n\n findAll(criteria?: Criteria<Model>, sort?: Sort<Model>): Promise<Model[]> {\n return this.cursor<Model>(criteria, sort).then((cursor) =>\n cursor.toArray(),\n );\n }\n\n async findOne(\n filter: Criteria<Model>,\n sort?: Sort<Model>,\n ): Promise<Model | undefined> {\n const collection = await this.collection;\n const result = await collection.findOne<Model>(filter, {\n sort,\n });\n return result || undefined;\n }\n}\n","import { AbstractConnection } from 'liwi-store';\nimport mongodb from 'mongodb';\nimport { Logger } from 'nightingale-logger';\n\nconst logger = new Logger('liwi:mongo:MongoConnection');\n\nexport default class MongoConnection extends AbstractConnection {\n _connection?: mongodb.MongoClient;\n\n _connecting?: Promise<mongodb.MongoClient>;\n\n connectionFailed?: boolean;\n\n // TODO interface\n constructor(config: Map<string, string | number>) {\n super();\n\n if (!config.has('host')) {\n config.set('host', 'localhost');\n }\n if (!config.has('port')) {\n config.set('port', '27017');\n }\n if (!config.has('database')) {\n throw new Error('Missing config database');\n }\n\n const connectionString =\n `mongodb://${\n config.has('user')\n ? `${config.get('user') as string}:${\n config.get('password') as string\n }@`\n : ''\n }` +\n `${config.get('host') as string}:${config.get('port') as string}/${\n config.get('database') as string\n }`;\n\n this.connect(connectionString);\n }\n\n connect(connectionString: string): void {\n logger.info('connecting', { connectionString });\n\n const connectPromise = mongodb.MongoClient.connect(connectionString)\n .then((connection) => {\n logger.info('connected', { connectionString });\n connection.on('close', () => {\n logger.warn('close', { connectionString });\n this.connectionFailed = true;\n this.getConnection = () => {\n throw new Error('MongoDB connection closed');\n };\n });\n connection.on('timeout', () => {\n logger.warn('timeout', { connectionString });\n this.connectionFailed = true;\n this.getConnection = () => {\n throw new Error('MongoDB connection timeout');\n };\n });\n connection.on('reconnect', () => {\n logger.warn('reconnect', { connectionString });\n this.connectionFailed = false;\n this.getConnection = () => Promise.resolve(this._connection!);\n });\n connection.on('error', (err) => {\n logger.warn('error', { connectionString, err });\n });\n\n this._connection = connection;\n this._connecting = undefined;\n this.getConnection = () => Promise.resolve(this._connection!);\n return connection;\n })\n .catch((err) => {\n logger.info('not connected', { connectionString });\n console.error(err.message || err);\n // throw err;\n process.nextTick(() => {\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(1);\n });\n\n throw err;\n });\n\n this.getConnection = () => Promise.resolve(connectPromise);\n this._connecting = this.getConnection();\n }\n\n getConnection(): Promise<mongodb.MongoClient> {\n throw new Error('call connect()');\n }\n\n async close(): Promise<void> {\n this.getConnection = () => Promise.reject(new Error('Connection closed'));\n if (this._connection) {\n await this._connection.close();\n this._connection = undefined;\n } else if (this._connecting) {\n await this._connecting;\n await this.close();\n }\n }\n}\n","import { SubscribeStore } from 'liwi-subscribe-store';\nimport type { AllowedKeyValue } from 'liwi-types';\nimport type {\n MongoBaseModel,\n MongoInsertType,\n MongoKeyPath,\n} from './MongoBaseModel';\nimport type MongoConnection from './MongoConnection';\nimport type MongoStore from './MongoStore';\n\nexport default function createMongoSubscribeStore<\n Model extends MongoBaseModel<KeyValue>,\n KeyValue extends AllowedKeyValue = Model[MongoKeyPath],\n>(\n mongoStore: MongoStore<Model, KeyValue>,\n): SubscribeStore<\n MongoKeyPath,\n KeyValue,\n Model,\n MongoInsertType<Model, KeyValue>,\n MongoConnection,\n MongoStore<Model, KeyValue>\n> {\n return new SubscribeStore(mongoStore);\n}\n"],"names":["MongoCursor","AbstractStoreCursor","constructor","store","cursor","advance","count","skip","next","then","value","_result","key","_id","limit","newLimit","Promise","resolve","result","Error","close","toArray","identityTransformer","model","MongoQueryCollection","AbstractSubscribableStoreQuery","options","transformer","createTestCriteria","testCriteria","criteria","mingoQuery","mingo","Query","test","bind","fetch","onFulfilled","all","createMongoCursor","map","meta","total","info","sort","keyPath","_subscribe","callback","_includeInitial","getSubscribeStore","promise","type","initial","queryInfo","unsubscribe","subscribe","action","changes","filtered","filter","length","push","prev","keys","object","deleted","updated","inserted","forEach","prevObject","nextObject","stop","cancel","onRejected","MongoQuerySingleItem","createMingoTestCriteria","item","res","MongoStore","connection","collectionName","_collection","getConnection","client","db","collection","err","reject","connectionFailed","createQuerySingleItem","createQueryCollection","insertOne","mongodb","ObjectId","toString","created","Date","acknowledged","isAcknowledged","replaceOne","upsertOne","setOnInsertPartialObject","upsertOneWithInfo","$setOnInsert","$set","upsertedCount","updateOne","upsert","Object","assign","replaceSeveral","objects","partialUpdateByKey","partialUpdate","commandResult","console","error","findByKey","partialUpdateOne","partialUpdateMany","updateMany","undefined","deleteByKey","deleteOne","deleteMany","selector","countDocuments","findCursor","find","findOne","findAll","logger","Logger","MongoConnection","AbstractConnection","config","has","set","connectionString","get","connect","connectPromise","MongoClient","on","warn","_connection","_connecting","catch","message","process","nextTick","exit","createMongoSubscribeStore","mongoStore","SubscribeStore"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "liwi-mongo",
3
- "version": "8.1.1",
3
+ "version": "9.0.0",
4
4
  "description": "mongo implementation for liwi",
5
5
  "keywords": [],
6
6
  "author": "Christophe Hurpeau <christophe@hurpeau.com> (https://christophe.hurpeau.com)",
@@ -11,32 +11,31 @@
11
11
  "directory": "packages/liwi-mongo"
12
12
  },
13
13
  "homepage": "https://github.com/liwijs/liwi",
14
+ "type": "module",
14
15
  "engines": {
15
- "node": ">=12.10.0"
16
+ "node": "^14.13.1 || >=16.0.0"
16
17
  },
17
- "main": "./index.js",
18
+ "main": "./dist/index-node14.mjs",
18
19
  "types": "./dist/index.d.ts",
19
20
  "exports": {
21
+ "./package.json": "./package.json",
20
22
  ".": {
21
23
  "node": {
22
- "development": {
23
- "import": "./dist/index-node12-dev.mjs",
24
- "require": "./dist/index-node12-dev.cjs.js"
25
- },
26
- "import": "./dist/index-node12.mjs",
27
- "require": "./dist/index-node12.cjs.js"
24
+ "import": "./dist/index-node14.mjs",
25
+ "require": "./dist/index-node14.cjs"
28
26
  }
29
27
  }
30
28
  },
31
- "module:node": "./dist/index-node12.mjs",
32
- "module:node-dev": "./dist/index-node12-dev.mjs",
29
+ "module:node": "./dist/index-node14.mjs",
33
30
  "sideEffects": false,
34
31
  "scripts": {
35
- "build": "pob-build && yarn run build:definitions",
32
+ "build": "yarn clean:build && rollup --config rollup.config.mjs && yarn run build:definitions",
36
33
  "build:definitions": "tsc -p tsconfig.build.json",
34
+ "clean": "yarn clean:build",
35
+ "clean:build": "rm -Rf dist",
37
36
  "lint": "yarn run lint:eslint",
38
- "lint:eslint": "yarn --cwd ../.. run eslint --ext .js,.mjs,.ts --report-unused-disable-directives --quiet packages/liwi-mongo",
39
- "watch": "pob-watch"
37
+ "lint:eslint": "cd ../.. && yarn run eslint --report-unused-disable-directives --resolve-plugins-relative-to . --quiet packages/liwi-mongo",
38
+ "watch": "yarn clean:build && rollup --config rollup.config.mjs --watch"
40
39
  },
41
40
  "prettier": {
42
41
  "trailingComma": "all",
@@ -47,7 +46,7 @@
47
46
  "babelEnvs": [
48
47
  {
49
48
  "target": "node",
50
- "version": "12",
49
+ "version": "14",
51
50
  "formats": [
52
51
  "cjs",
53
52
  "es"
@@ -59,19 +58,17 @@
59
58
  ]
60
59
  },
61
60
  "dependencies": {
62
- "@types/mongodb": "^3.6.10",
63
- "liwi-store": "^8.1.0",
64
- "liwi-subscribe-store": "^8.1.0",
65
- "liwi-types": "^8.0.4",
66
- "mingo": "^4.1.2",
67
- "mongodb": "^3.6.5",
68
- "nightingale-logger": "^11.6.0"
61
+ "liwi-store": "9.0.0",
62
+ "liwi-subscribe-store": "9.0.0",
63
+ "liwi-types": "9.0.0",
64
+ "mingo": "^6.0.3",
65
+ "mongodb": "^4.0.0",
66
+ "nightingale-logger": "^12.1.4"
69
67
  },
70
68
  "devDependencies": {
71
- "@babel/core": "7.13.13",
72
- "babel-preset-latest-node": "5.5.1",
73
- "pob-babel": "26.8.0",
74
- "rollup": "2.43.1"
69
+ "@babel/core": "7.17.5",
70
+ "pob-babel": "32.2.0",
71
+ "typescript": "4.6.2"
75
72
  },
76
- "gitHead": "0c2dba32a4f6980d5028a63a7fe11a4a8372ca34"
73
+ "gitHead": "b587af1aee4cfead212586e3cd41e3c3d8227801"
77
74
  }
@@ -0,0 +1,5 @@
1
+ import createRollupConfig from 'pob-babel/createRollupConfig.js';
2
+
3
+ export default createRollupConfig({
4
+ cwd: new URL('.', import.meta.url).pathname,
5
+ });
@@ -2,20 +2,36 @@
2
2
  "root": true,
3
3
  "parser": "@typescript-eslint/parser",
4
4
  "parserOptions": {
5
- "project": "packages/liwi-mongo/tsconfig.json"
5
+ "project": "packages/liwi-mongo/tsconfig.eslint.json"
6
6
  },
7
7
  "plugins": ["@typescript-eslint"],
8
8
  "extends": [
9
9
  "@pob/eslint-config-typescript",
10
- "@pob/eslint-config-typescript-node"
10
+ "@pob/eslint-config-typescript/node"
11
11
  ],
12
12
  "ignorePatterns": ["*.d.ts"],
13
13
  "rules": {
14
- "import/no-cycle": "off",
15
14
  "@typescript-eslint/no-floating-promises": "warn",
16
15
  "@typescript-eslint/no-unsafe-assignment": "warn",
17
16
  "@typescript-eslint/no-unsafe-member-access": "warn",
18
17
  "@typescript-eslint/no-unsafe-return": "warn",
19
18
  "@typescript-eslint/no-unsafe-call": "warn"
20
- }
19
+ },
20
+ "overrides": [
21
+ {
22
+ "files": ["**/*.test.ts", "__tests__/**/*.ts"],
23
+ "extends": ["@pob/eslint-config-typescript/test"],
24
+ "env": {
25
+ "jest": true
26
+ },
27
+ "rules": {
28
+ "import/no-extraneous-dependencies": [
29
+ "error",
30
+ {
31
+ "devDependencies": true
32
+ }
33
+ ]
34
+ }
35
+ }
36
+ ]
21
37
  }
@@ -9,5 +9,5 @@ export interface MongoBaseModel<KeyValue extends AllowedKeyValue = string>
9
9
 
10
10
  export type MongoInsertType<
11
11
  Model extends MongoBaseModel<KeyValue>,
12
- KeyValue extends AllowedKeyValue = Model[MongoKeyPath]
12
+ KeyValue extends AllowedKeyValue = Model[MongoKeyPath],
13
13
  > = InsertType<Model, MongoKeyPath>;
@@ -1,6 +1,6 @@
1
1
  import { AbstractConnection } from 'liwi-store';
2
2
  import mongodb from 'mongodb';
3
- import Logger from 'nightingale-logger';
3
+ import { Logger } from 'nightingale-logger';
4
4
 
5
5
  const logger = new Logger('liwi:mongo:MongoConnection');
6
6
 
@@ -43,9 +43,7 @@ export default class MongoConnection extends AbstractConnection {
43
43
  connect(connectionString: string): void {
44
44
  logger.info('connecting', { connectionString });
45
45
 
46
- const connectPromise = mongodb.MongoClient.connect(connectionString, {
47
- useNewUrlParser: true,
48
- })
46
+ const connectPromise = mongodb.MongoClient.connect(connectionString)
49
47
  .then((connection) => {
50
48
  logger.info('connected', { connectionString });
51
49
  connection.on('close', () => {
@@ -1,13 +1,13 @@
1
1
  import { AbstractStoreCursor } from 'liwi-store';
2
2
  import type { AllowedKeyValue } from 'liwi-types';
3
- import type { Cursor } from 'mongodb';
3
+ import type { FindCursor } from 'mongodb';
4
4
  import type { MongoBaseModel } from './MongoBaseModel';
5
5
  import type MongoStore from './MongoStore';
6
6
 
7
7
  export default class MongoCursor<
8
8
  Model extends MongoBaseModel<KeyValue>,
9
9
  Result extends Partial<Model> = Model,
10
- KeyValue extends AllowedKeyValue = Model['_id']
10
+ KeyValue extends AllowedKeyValue = Model['_id'],
11
11
  > extends AbstractStoreCursor<
12
12
  MongoStore<Model, KeyValue>,
13
13
  KeyValue,
@@ -16,11 +16,11 @@ export default class MongoCursor<
16
16
  > {
17
17
  // key in AbstractCursor
18
18
 
19
- private readonly cursor: Cursor;
19
+ private readonly cursor: FindCursor<Result>;
20
20
 
21
- private _result?: Result;
21
+ private _result?: Result | null;
22
22
 
23
- constructor(store: MongoStore<Model, KeyValue>, cursor: Cursor) {
23
+ constructor(store: MongoStore<Model, KeyValue>, cursor: FindCursor<Result>) {
24
24
  super(store);
25
25
  this.cursor = cursor;
26
26
  }
@@ -29,7 +29,7 @@ export default class MongoCursor<
29
29
  this.cursor.skip(count);
30
30
  }
31
31
 
32
- next(): Promise<any> {
32
+ next(): Promise<KeyValue | undefined> {
33
33
  return this.cursor.next().then((value) => {
34
34
  this._result = value;
35
35
  this.key = value?._id;
@@ -42,13 +42,9 @@ export default class MongoCursor<
42
42
  return Promise.resolve(this);
43
43
  }
44
44
 
45
- count(applySkipLimit = false): Promise<number> {
46
- return this.cursor.count(applySkipLimit);
47
- }
48
-
49
45
  result(): Promise<Result> {
50
46
  if (!this._result) throw new Error('Cannot call result() before next()');
51
- return Promise.resolve(this._result!);
47
+ return Promise.resolve(this._result);
52
48
  }
53
49
 
54
50
  close(): Promise<void> {