'use strict' import { existsSync } from 'fs' import { sync } from 'mkdirp' import { Context, Service, ServiceSchema } from 'moleculer' import DbService from 'moleculer-db' import MongooseAdapter from 'moleculer-db-adapter-mongoose' import { Model, Document } from 'mongoose' import { isNil } from 'ramda' import { mongooseOptions } from '../util/mongoose.options' export default class Connection implements Partial, ThisType { private cacheCleanEventName: string private collection: string private schema: Partial & ThisType public constructor(private model: Model) { this.collection = model.modelName this.cacheCleanEventName = `cache.clean.${this.collection}` this.schema = { mixins: [DbService], model: this.model, events: { /** * Subscribe to the cache clean event. If it's triggered * clean the cache entries for this service. */ async [this.cacheCleanEventName](this: DbService.DbService) { if (this.broker.cacher) { await this.broker.cacher.clean(`${this.fullName}.*`) } } }, methods: { /** * Send a cache clearing event when an entity changed. * TODO: Granularise? * @param {String} type * @param {any} json * @param {Context} ctx */ entityChanged: async (type: string, json: any, ctx: Context) => { await ctx.broadcast(this.cacheCleanEventName) }, }, async started() { /* * Check the count of items in the DB. If it's empty, * Call the `seedDB` method of the service. */ if (this.seedDB) { const count = await this.adapter.count() if (count === 0) { this.logger.info(`The '${this.collection}' collection is empty. Seeding the collection...`) await this.seedDB() this.logger.info('Seeding is done. Number of records:', await this.adapter.count()) } } }, } } public start () { /* TODO: Consider using Model.validate on NEDB requests */ this.schema.adapter = this.makeAdapter({ uri: process.env.MONGO_URI, isTest: !isNil(process.env.TEST) || process.env.NODE_ENV === 'test' }) return this.schema } private ensureDevStorage () { /* Create data folder */ if (!existsSync('./data')) { sync('./data') } return `./data/${this.collection}.db` } private makeAdapter ({ uri, isTest }: {uri: string, isTest: boolean}) { return uri ? new MongooseAdapter(uri, mongooseOptions) : new DbService.MemoryAdapter({ filename: isTest ? undefined : this.ensureDevStorage() }) } public get _collection(): string { return this.collection } public set _collection(value: string) { this.collection = value } }