Files
shields/core/base-service/loader.js
Paul Melnikow be7cb93773 Refactor service loader (#2861)
This moves the loader code into `core/base-service`, leaving behind in `services/index.js` only the convenience imports.

Ref #2832
2019-01-24 22:55:10 -05:00

84 lines
2.3 KiB
JavaScript

'use strict'
const path = require('path')
const glob = require('glob')
const { categories } = require('../../services/categories')
const BaseService = require('./base')
const { assertValidServiceDefinitionExport } = require('./service-definitions')
const serviceDir = path.join(__dirname, '..', '..', 'services')
class InvalidService extends Error {
constructor(message) {
super(message)
this.name = 'InvalidService'
}
}
function loadServiceClasses(servicePaths) {
if (!servicePaths) {
servicePaths = glob.sync(path.join(serviceDir, '**', '*.service.js'))
}
const serviceClasses = []
servicePaths.forEach(path => {
const module = require(path)
if (
!module ||
(module.constructor === Array && module.length === 0) ||
(module.constructor === Object && Object.keys(module).length === 0)
) {
throw new InvalidService(
`Expected ${path} to export a service or a collection of services`
)
} else if (module.prototype instanceof BaseService) {
serviceClasses.push(module)
} else if (module.constructor === Array || module.constructor === Object) {
for (const key in module) {
const serviceClass = module[key]
if (serviceClass.prototype instanceof BaseService) {
serviceClasses.push(serviceClass)
} else {
throw new InvalidService(
`Expected ${path} to export a service or a collection of services; one of them was ${serviceClass}`
)
}
}
} else {
throw new InvalidService(
`Expected ${path} to export a service or a collection of services; got ${module}`
)
}
})
serviceClasses.forEach(ServiceClass => ServiceClass.validateDefinition())
return serviceClasses
}
function collectDefinitions() {
const services = loadServiceClasses()
// flatMap.
.map(ServiceClass => ServiceClass.getDefinition())
.reduce((accum, these) => accum.concat(these), [])
const result = { schemaVersion: '0', categories, services }
assertValidServiceDefinitionExport(result)
return result
}
function loadTesters() {
return glob
.sync(path.join(serviceDir, '**', '*.tester.js'))
.map(path => require(path))
}
module.exports = {
InvalidService,
loadServiceClasses,
collectDefinitions,
loadTesters,
}