98 lines
2.7 KiB
TypeScript
98 lines
2.7 KiB
TypeScript
|
'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<ServiceSchema>, ThisType<Service> {
|
||
|
|
||
|
private cacheCleanEventName: string
|
||
|
private collection: string
|
||
|
private schema: Partial<ServiceSchema> & ThisType<Service>
|
||
|
|
||
|
public constructor(private model: Model<Document>) {
|
||
|
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
|
||
|
}
|
||
|
}
|