104 lines
3.1 KiB
JavaScript
104 lines
3.1 KiB
JavaScript
// 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 }
|