liwi-mongo 8.3.1 → 9.1.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.
- package/.eslintrc.json +1 -1
- package/CHANGELOG.md +35 -0
- package/README.md +3 -0
- package/dist/MongoConnection.d.ts +1 -1
- package/dist/MongoConnection.d.ts.map +1 -1
- package/dist/MongoCursor.d.ts +3 -4
- package/dist/MongoCursor.d.ts.map +1 -1
- package/dist/MongoQueryCollection.d.ts.map +1 -1
- package/dist/MongoStore.d.ts +9 -8
- package/dist/MongoStore.d.ts.map +1 -1
- package/dist/{index-node12-dev.cjs.js → index-node14.cjs} +59 -48
- package/dist/index-node14.cjs.map +1 -0
- package/dist/{index-node12-dev.mjs → index-node14.mjs} +58 -46
- package/dist/index-node14.mjs.map +1 -0
- package/package.json +25 -32
- package/src/.eslintrc.json +20 -3
- package/src/MongoBaseModel.ts +1 -1
- package/src/MongoConnection.ts +23 -16
- package/src/MongoCursor.ts +6 -10
- package/src/MongoQueryCollection.ts +25 -29
- package/src/MongoQuerySingleItem.ts +3 -3
- package/src/MongoStore.ts +72 -42
- package/src/createMongoSubscribeStore.ts +1 -1
- package/dist/index-node12-dev.cjs.js.map +0 -1
- package/dist/index-node12-dev.es.js +0 -658
- package/dist/index-node12-dev.es.js.map +0 -1
- package/dist/index-node12-dev.mjs.map +0 -1
- package/dist/index-node12.cjs.js +0 -672
- package/dist/index-node12.cjs.js.map +0 -1
- package/dist/index-node12.es.js +0 -658
- package/dist/index-node12.es.js.map +0 -1
- package/dist/index-node12.mjs +0 -660
- package/dist/index-node12.mjs.map +0 -1
- package/index.js +0 -6
- package/rollup.config.mjs +0 -3
|
@@ -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
|
|
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
|
|
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
|
-
} =
|
|
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
|
-
|
|
151
|
+
deleted.push(prevObject[this.store.keyPath]);
|
|
152
152
|
} else {
|
|
153
|
-
|
|
153
|
+
updated.push(this.transformer(nextObject));
|
|
154
154
|
}
|
|
155
155
|
} else if (testCriteria(nextObject)) {
|
|
156
|
-
|
|
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) {
|
|
@@ -379,8 +373,9 @@ class MongoQuerySingleItem extends AbstractSubscribableStoreQuery {
|
|
|
379
373
|
|
|
380
374
|
/* eslint-disable max-lines */
|
|
381
375
|
class MongoStore {
|
|
376
|
+
keyPath = '_id';
|
|
377
|
+
|
|
382
378
|
constructor(connection, collectionName) {
|
|
383
|
-
this.keyPath = '_id';
|
|
384
379
|
this.connection = connection;
|
|
385
380
|
|
|
386
381
|
if (!collectionName) {
|
|
@@ -414,17 +409,18 @@ class MongoStore {
|
|
|
414
409
|
|
|
415
410
|
async insertOne(object) {
|
|
416
411
|
if (!object._id) {
|
|
417
|
-
object._id = new mongodb.
|
|
412
|
+
object._id = new mongodb.ObjectId().toString();
|
|
418
413
|
}
|
|
419
414
|
|
|
420
415
|
if (!object.created) object.created = new Date();
|
|
421
416
|
if (!object.updated) object.updated = new Date();
|
|
422
417
|
const collection = await this.collection;
|
|
423
418
|
const {
|
|
424
|
-
|
|
425
|
-
} = await collection.insertOne(
|
|
419
|
+
acknowledged: isAcknowledged
|
|
420
|
+
} = await collection.insertOne( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
421
|
+
object);
|
|
426
422
|
|
|
427
|
-
if (!
|
|
423
|
+
if (!isAcknowledged) {
|
|
428
424
|
throw new Error('Fail to insert');
|
|
429
425
|
}
|
|
430
426
|
|
|
@@ -491,7 +487,7 @@ class MongoStore {
|
|
|
491
487
|
...criteria
|
|
492
488
|
}, partialUpdate);
|
|
493
489
|
|
|
494
|
-
if (!commandResult.
|
|
490
|
+
if (!commandResult.acknowledged) {
|
|
495
491
|
console.error(commandResult);
|
|
496
492
|
throw new Error('Update failed');
|
|
497
493
|
}
|
|
@@ -505,7 +501,8 @@ class MongoStore {
|
|
|
505
501
|
}
|
|
506
502
|
|
|
507
503
|
partialUpdateMany(criteria, partialUpdate) {
|
|
508
|
-
return this.collection.then(collection =>
|
|
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
|
|
509
506
|
}
|
|
510
507
|
|
|
511
508
|
deleteByKey(key, criteria) {
|
|
@@ -523,23 +520,37 @@ class MongoStore {
|
|
|
523
520
|
return this.collection.then(collection => collection.deleteMany(selector)).then(() => undefined);
|
|
524
521
|
}
|
|
525
522
|
|
|
526
|
-
|
|
527
|
-
|
|
523
|
+
async count(filter) {
|
|
524
|
+
const collection = await this.collection;
|
|
525
|
+
return filter ? collection.countDocuments(filter) : collection.countDocuments();
|
|
526
|
+
}
|
|
527
|
+
|
|
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);
|
|
528
533
|
}
|
|
529
534
|
|
|
530
|
-
findByKey(key, criteria) {
|
|
531
|
-
|
|
535
|
+
async findByKey(key, criteria) {
|
|
536
|
+
const collection = await this.collection;
|
|
537
|
+
const result = await collection.findOne({
|
|
532
538
|
_id: key,
|
|
533
539
|
...criteria
|
|
534
|
-
})
|
|
540
|
+
});
|
|
541
|
+
return result || undefined;
|
|
535
542
|
}
|
|
536
543
|
|
|
537
544
|
findAll(criteria, sort) {
|
|
538
545
|
return this.cursor(criteria, sort).then(cursor => cursor.toArray());
|
|
539
546
|
}
|
|
540
547
|
|
|
541
|
-
findOne(
|
|
542
|
-
|
|
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;
|
|
543
554
|
}
|
|
544
555
|
|
|
545
556
|
}
|
|
@@ -562,23 +573,24 @@ class MongoConnection extends AbstractConnection {
|
|
|
562
573
|
throw new Error('Missing config database');
|
|
563
574
|
}
|
|
564
575
|
|
|
565
|
-
const
|
|
566
|
-
|
|
576
|
+
const buildConnectionString = redactCredentials => `mongodb://${config.has('user') ? `${redactCredentials ? `${config.get('user').slice(0, 2)}[redacted]` : config.get('user')}:${redactCredentials ? '[redacted]' : config.get('password')}@` : ''}` + `${config.get('host')}:${config.get('port')}/${config.get('database')}`;
|
|
577
|
+
|
|
578
|
+
const connectionString = buildConnectionString(false);
|
|
579
|
+
const connectionStringRedacted = buildConnectionString(true);
|
|
580
|
+
this.connect(connectionString, connectionStringRedacted);
|
|
567
581
|
}
|
|
568
582
|
|
|
569
|
-
connect(connectionString) {
|
|
583
|
+
connect(connectionString, connectionStringRedacted) {
|
|
570
584
|
logger.info('connecting', {
|
|
571
|
-
|
|
585
|
+
connectionStringRedacted
|
|
572
586
|
});
|
|
573
|
-
const connectPromise = mongodb.MongoClient.connect(connectionString
|
|
574
|
-
useNewUrlParser: true
|
|
575
|
-
}).then(connection => {
|
|
587
|
+
const connectPromise = mongodb.MongoClient.connect(connectionString).then(connection => {
|
|
576
588
|
logger.info('connected', {
|
|
577
|
-
|
|
589
|
+
connectionStringRedacted
|
|
578
590
|
});
|
|
579
591
|
connection.on('close', () => {
|
|
580
592
|
logger.warn('close', {
|
|
581
|
-
|
|
593
|
+
connectionStringRedacted
|
|
582
594
|
});
|
|
583
595
|
this.connectionFailed = true;
|
|
584
596
|
|
|
@@ -588,7 +600,7 @@ class MongoConnection extends AbstractConnection {
|
|
|
588
600
|
});
|
|
589
601
|
connection.on('timeout', () => {
|
|
590
602
|
logger.warn('timeout', {
|
|
591
|
-
|
|
603
|
+
connectionStringRedacted
|
|
592
604
|
});
|
|
593
605
|
this.connectionFailed = true;
|
|
594
606
|
|
|
@@ -598,7 +610,7 @@ class MongoConnection extends AbstractConnection {
|
|
|
598
610
|
});
|
|
599
611
|
connection.on('reconnect', () => {
|
|
600
612
|
logger.warn('reconnect', {
|
|
601
|
-
|
|
613
|
+
connectionStringRedacted
|
|
602
614
|
});
|
|
603
615
|
this.connectionFailed = false;
|
|
604
616
|
|
|
@@ -606,7 +618,7 @@ class MongoConnection extends AbstractConnection {
|
|
|
606
618
|
});
|
|
607
619
|
connection.on('error', err => {
|
|
608
620
|
logger.warn('error', {
|
|
609
|
-
|
|
621
|
+
connectionStringRedacted,
|
|
610
622
|
err
|
|
611
623
|
});
|
|
612
624
|
});
|
|
@@ -618,7 +630,7 @@ class MongoConnection extends AbstractConnection {
|
|
|
618
630
|
return connection;
|
|
619
631
|
}).catch(err => {
|
|
620
632
|
logger.info('not connected', {
|
|
621
|
-
|
|
633
|
+
connectionStringRedacted
|
|
622
634
|
});
|
|
623
635
|
console.error(err.message || err); // throw err;
|
|
624
636
|
|
|
@@ -657,4 +669,4 @@ function createMongoSubscribeStore(mongoStore) {
|
|
|
657
669
|
}
|
|
658
670
|
|
|
659
671
|
export { MongoConnection, MongoStore, createMongoSubscribeStore };
|
|
660
|
-
//# sourceMappingURL=index-
|
|
672
|
+
//# 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 extends Partial<Model> = 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 buildConnectionString = (redactCredentials: boolean): string =>\n `mongodb://${\n config.has('user')\n ? `${\n redactCredentials\n ? `${(config.get('user') as string).slice(0, 2)}[redacted]`\n : (config.get('user') as string)\n }:${\n redactCredentials\n ? '[redacted]'\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 const connectionString = buildConnectionString(false);\n const connectionStringRedacted = buildConnectionString(true);\n\n this.connect(connectionString, connectionStringRedacted);\n }\n\n connect(connectionString: string, connectionStringRedacted: string): void {\n logger.info('connecting', { connectionStringRedacted });\n\n const connectPromise = mongodb.MongoClient.connect(connectionString)\n .then((connection) => {\n logger.info('connected', { connectionStringRedacted });\n connection.on('close', () => {\n logger.warn('close', { connectionStringRedacted });\n this.connectionFailed = true;\n this.getConnection = () => {\n throw new Error('MongoDB connection closed');\n };\n });\n connection.on('timeout', () => {\n logger.warn('timeout', { connectionStringRedacted });\n this.connectionFailed = true;\n this.getConnection = () => {\n throw new Error('MongoDB connection timeout');\n };\n });\n connection.on('reconnect', () => {\n logger.warn('reconnect', { connectionStringRedacted });\n this.connectionFailed = false;\n this.getConnection = () => Promise.resolve(this._connection!);\n });\n connection.on('error', (err) => {\n logger.warn('error', { connectionStringRedacted, 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', { connectionStringRedacted });\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","buildConnectionString","redactCredentials","get","slice","connectionString","connectionStringRedacted","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": "
|
|
3
|
+
"version": "9.1.0",
|
|
4
4
|
"description": "mongo implementation for liwi",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "Christophe Hurpeau <christophe@hurpeau.com> (https://christophe.hurpeau.com)",
|
|
@@ -11,43 +11,38 @@
|
|
|
11
11
|
"directory": "packages/liwi-mongo"
|
|
12
12
|
},
|
|
13
13
|
"homepage": "https://github.com/liwijs/liwi",
|
|
14
|
+
"type": "module",
|
|
14
15
|
"engines": {
|
|
15
|
-
"node": ">=
|
|
16
|
+
"node": "^14.13.1 || >=16.0.0"
|
|
16
17
|
},
|
|
17
|
-
"main": "./index.
|
|
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
|
-
"
|
|
23
|
-
|
|
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-
|
|
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": "
|
|
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": "pob-babel-clean-out dist",
|
|
37
36
|
"lint": "yarn run lint:eslint",
|
|
38
|
-
"lint:eslint": "
|
|
39
|
-
"watch": "
|
|
40
|
-
},
|
|
41
|
-
"prettier": {
|
|
42
|
-
"trailingComma": "all",
|
|
43
|
-
"singleQuote": true,
|
|
44
|
-
"arrowParens": "always"
|
|
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"
|
|
45
39
|
},
|
|
40
|
+
"prettier": "@pob/root/prettier-config",
|
|
46
41
|
"pob": {
|
|
47
42
|
"babelEnvs": [
|
|
48
43
|
{
|
|
49
44
|
"target": "node",
|
|
50
|
-
"version": "
|
|
45
|
+
"version": "14",
|
|
51
46
|
"formats": [
|
|
52
47
|
"cjs",
|
|
53
48
|
"es"
|
|
@@ -59,19 +54,17 @@
|
|
|
59
54
|
]
|
|
60
55
|
},
|
|
61
56
|
"dependencies": {
|
|
62
|
-
"
|
|
63
|
-
"liwi-store": "
|
|
64
|
-
"liwi-
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"nightingale-logger": "^11.6.0"
|
|
57
|
+
"liwi-store": "9.1.0",
|
|
58
|
+
"liwi-subscribe-store": "9.1.0",
|
|
59
|
+
"liwi-types": "9.1.0",
|
|
60
|
+
"mingo": "^6.0.3",
|
|
61
|
+
"mongodb": "^4.0.0",
|
|
62
|
+
"nightingale-logger": "^12.1.4"
|
|
69
63
|
},
|
|
70
64
|
"devDependencies": {
|
|
71
|
-
"@babel/core": "7.
|
|
72
|
-
"babel
|
|
73
|
-
"
|
|
74
|
-
"rollup": "2.43.1"
|
|
65
|
+
"@babel/core": "7.19.3",
|
|
66
|
+
"pob-babel": "34.2.0",
|
|
67
|
+
"typescript": "4.8.4"
|
|
75
68
|
},
|
|
76
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "53bf2c0a8a57b008ede529ed7fad116fbb74b822"
|
|
77
70
|
}
|
package/src/.eslintrc.json
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
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
|
|
10
|
+
"@pob/eslint-config-typescript/node"
|
|
11
11
|
],
|
|
12
12
|
"ignorePatterns": ["*.d.ts"],
|
|
13
13
|
"rules": {
|
|
@@ -16,5 +16,22 @@
|
|
|
16
16
|
"@typescript-eslint/no-unsafe-member-access": "warn",
|
|
17
17
|
"@typescript-eslint/no-unsafe-return": "warn",
|
|
18
18
|
"@typescript-eslint/no-unsafe-call": "warn"
|
|
19
|
-
}
|
|
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
|
+
]
|
|
20
37
|
}
|
package/src/MongoBaseModel.ts
CHANGED
|
@@ -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>;
|
package/src/MongoConnection.ts
CHANGED
|
@@ -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
|
|
|
@@ -25,11 +25,17 @@ export default class MongoConnection extends AbstractConnection {
|
|
|
25
25
|
throw new Error('Missing config database');
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const
|
|
28
|
+
const buildConnectionString = (redactCredentials: boolean): string =>
|
|
29
29
|
`mongodb://${
|
|
30
30
|
config.has('user')
|
|
31
|
-
? `${
|
|
32
|
-
|
|
31
|
+
? `${
|
|
32
|
+
redactCredentials
|
|
33
|
+
? `${(config.get('user') as string).slice(0, 2)}[redacted]`
|
|
34
|
+
: (config.get('user') as string)
|
|
35
|
+
}:${
|
|
36
|
+
redactCredentials
|
|
37
|
+
? '[redacted]'
|
|
38
|
+
: (config.get('password') as string)
|
|
33
39
|
}@`
|
|
34
40
|
: ''
|
|
35
41
|
}` +
|
|
@@ -37,38 +43,39 @@ export default class MongoConnection extends AbstractConnection {
|
|
|
37
43
|
config.get('database') as string
|
|
38
44
|
}`;
|
|
39
45
|
|
|
40
|
-
|
|
46
|
+
const connectionString = buildConnectionString(false);
|
|
47
|
+
const connectionStringRedacted = buildConnectionString(true);
|
|
48
|
+
|
|
49
|
+
this.connect(connectionString, connectionStringRedacted);
|
|
41
50
|
}
|
|
42
51
|
|
|
43
|
-
connect(connectionString: string): void {
|
|
44
|
-
logger.info('connecting', {
|
|
52
|
+
connect(connectionString: string, connectionStringRedacted: string): void {
|
|
53
|
+
logger.info('connecting', { connectionStringRedacted });
|
|
45
54
|
|
|
46
|
-
const connectPromise = mongodb.MongoClient.connect(connectionString
|
|
47
|
-
useNewUrlParser: true,
|
|
48
|
-
})
|
|
55
|
+
const connectPromise = mongodb.MongoClient.connect(connectionString)
|
|
49
56
|
.then((connection) => {
|
|
50
|
-
logger.info('connected', {
|
|
57
|
+
logger.info('connected', { connectionStringRedacted });
|
|
51
58
|
connection.on('close', () => {
|
|
52
|
-
logger.warn('close', {
|
|
59
|
+
logger.warn('close', { connectionStringRedacted });
|
|
53
60
|
this.connectionFailed = true;
|
|
54
61
|
this.getConnection = () => {
|
|
55
62
|
throw new Error('MongoDB connection closed');
|
|
56
63
|
};
|
|
57
64
|
});
|
|
58
65
|
connection.on('timeout', () => {
|
|
59
|
-
logger.warn('timeout', {
|
|
66
|
+
logger.warn('timeout', { connectionStringRedacted });
|
|
60
67
|
this.connectionFailed = true;
|
|
61
68
|
this.getConnection = () => {
|
|
62
69
|
throw new Error('MongoDB connection timeout');
|
|
63
70
|
};
|
|
64
71
|
});
|
|
65
72
|
connection.on('reconnect', () => {
|
|
66
|
-
logger.warn('reconnect', {
|
|
73
|
+
logger.warn('reconnect', { connectionStringRedacted });
|
|
67
74
|
this.connectionFailed = false;
|
|
68
75
|
this.getConnection = () => Promise.resolve(this._connection!);
|
|
69
76
|
});
|
|
70
77
|
connection.on('error', (err) => {
|
|
71
|
-
logger.warn('error', {
|
|
78
|
+
logger.warn('error', { connectionStringRedacted, err });
|
|
72
79
|
});
|
|
73
80
|
|
|
74
81
|
this._connection = connection;
|
|
@@ -77,7 +84,7 @@ export default class MongoConnection extends AbstractConnection {
|
|
|
77
84
|
return connection;
|
|
78
85
|
})
|
|
79
86
|
.catch((err) => {
|
|
80
|
-
logger.info('not connected', {
|
|
87
|
+
logger.info('not connected', { connectionStringRedacted });
|
|
81
88
|
console.error(err.message || err);
|
|
82
89
|
// throw err;
|
|
83
90
|
process.nextTick(() => {
|
package/src/MongoCursor.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { AbstractStoreCursor } from 'liwi-store';
|
|
2
2
|
import type { AllowedKeyValue } from 'liwi-types';
|
|
3
|
-
import type {
|
|
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:
|
|
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:
|
|
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<
|
|
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,10 +42,6 @@ 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
47
|
return Promise.resolve(this._result);
|