UNPKG

@amaui/mongo

Version:

Utils for easier using of mongodb library.

140 lines (136 loc) 4.98 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import * as mongodb from 'mongodb'; import { merge } from '@amaui/utils'; import { Query } from '@amaui/models'; import { ConnectionError } from '@amaui/errors'; import AmauiLog from '@amaui/log'; import AmauiSubscription from '@amaui/subscription'; export const mongoOptionsDefault = {}; export class Mongo { get options() { return this.options_; } set options(options) { this.options_ = merge(options, mongoOptionsDefault); } constructor() { let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : mongoOptionsDefault; _defineProperty(this, "db", void 0); _defineProperty(this, "connected", false); _defineProperty(this, "client", void 0); _defineProperty(this, "amauiLog", void 0); _defineProperty(this, "options_", mongoOptionsDefault); _defineProperty(this, "collections", void 0); // For listening on mongo events _defineProperty(this, "subscription", new AmauiSubscription()); this.options = options; this.amauiLog = new AmauiLog(_objectSpread({ arguments: { pre: ['Mongo'] } }, options.log_options)); } async createIndexes() { if (this.options.indexes?.length) { for (const item of this.options.indexes) { const name = item.name; if (name && item.indexes?.length) { for (const index of item.indexes) { await this.db.collection(name).createIndex(index.keys, index.options); } } } } return true; } get connection() { return new Promise(async resolve => { if (this.connected) return resolve(this.db); try { const db = await this.connect(); // Create indexes await this.createIndexes(); return resolve(db); } catch (error) { throw error; } }); } get disconnect() { return new Promise(async resolve => { if (this.client && this.client.close) { await this.client.close(); this.amauiLog.important(`Disconnected`); this.connected = false; this.db = undefined; this.client = undefined; this.subscription.emit('disconnected'); return resolve(); } resolve(); }); } getCollections() { let refetch = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; return new Promise(async resolve => { try { if (this.collections && !refetch) return resolve(this.collections); this.collections = await this.db.listCollections().toArray(); return resolve(this.collections); } catch (error) { throw error; } }); } // Be very careful with this one, // it drops the entire database, // usually used for testing only async reset(name) { if (this.db && name && this.db.databaseName === name) { await this.db.dropDatabase(); this.amauiLog.important(`Reset`); this.subscription.emit('reset'); } } connect() { return new Promise(async resolve => { const { uri, name } = this.options; try { this.client = await mongodb.MongoClient.connect(uri); this.db = this.client.db(name); this.connected = true; this.amauiLog.info(`Connected`); this.client.on('close', event => { this.amauiLog.warn(`Connection closed`, event); this.subscription.emit('disconnected'); this.connected = false; setTimeout(() => { if (!this.connected) throw new ConnectionError(`Reconnect failed`); }, 1e4); }); // Get meta about existing collections const collections = await this.getCollections(true); // Add collections to Query model Query.collections = collections.map(collection => collection.name); this.subscription.emit('connected'); return resolve(this.db); } catch (error) { this.amauiLog.warn(`Connection error`, error); this.subscription.emit('error', error); throw new ConnectionError(error); } }); } } _defineProperty(Mongo, "defaults", { aggregateOptions: { allowDiskUse: false }, limitCount: 1e3 }); export default Mongo;