This moves the loader code into `core/base-service`, leaving behind in `services/index.js` only the convenience imports. Ref #2832
84 lines
2.3 KiB
JavaScript
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,
|
|
}
|