// import RxClass from '@uci-utils/rx-class' import path from 'path' import { path as root } from 'app-root-path' import json from 'jsonfile' import to from 'await-to-js' const internal = Symbol('token for Notifier Instance') let inst class Notifier { constructor(token,opts={}){ if(token !== internal) { throw new Error('\'new Notifer\' not supported. Use the \'await Notifier.create()\' async static method') } // super(opts) this._services = {} this._disabled = [] this.services = opts.services || {} } // end constructor static async create(opts){ inst = new Notifier(internal,opts) console.log('notifcation service registrations:', await Promise.all( Object.entries(inst.services).map(async service => { return await inst.registerService.call(inst,service[0],service[1]) } ) ) ) return inst } async registerService(name,opts) { let mod; let file let dir = `${root}/node_modules/${opts.module || name}` let [err,pkg] = await to(json.readFile(dir+'/package.json')) if (!err) { file = (dir + '/' + (pkg.main ? pkg.main : 'index.js')) // eslint-disable-next-line let [err,res] = await to(import(file)) if (err) return `${name} failed - no file at ${file}` mod = res } else { // try in service directory for baked in plugins console.log(opts.module||name, ': no plugin found in node_modules, looking for internal module') let file = (`${path.dirname(__dirname)}/services/${name}.js`) // eslint-disable-next-line let [err,res] = await to(import(file)) if (err) return `${name} failed - no file at ${file}` mod = res } // delete opts.module const Service = mod.Service || mod.default if (!Service.prototype.constructor) { console.log('no default or "Service" class was exported from plugin') return `${name} failed` } else this._services[name] = new Service(opts) return `${name} registered` } disableService(name) { this._disabled.push(name) } enableService(name) { this._disabled= this._disabled.filter(service=>service!==name) } async send (msg,service,opts={}) { if (service!==null || service==='!email') { if (this._services[service]) return await this._services[service].send(msg,opts) } let response = {} let services = Object.entries(this._services) if (service==='!email') services = services.filter(service => service[0]!=='email') // console.log('services for message send', services.map(service=>service[0])) await Promise.all( services.map(async service => { let res = this._disabled.includes(service[0]) ? 'disabled' : await service[1].send(msg,opts[service[0]]) if (res.error) response.error ? response.error[service[0]] = res.error : response = { error:{[service[0]]:res.error}} response[service[0]]=res } ) ) return response } getServicesList() { return Object.keys(this._services) } getService(name) { if (name==null) return this._services return this._services[name] } } // end Notifier class export default Notifier export { Notifier }