"use strict"; const path = require("path"), { isString, isFunction, noop } = require("lodash"), Validator = require("fastest-validator"), v = new Validator(); import { ServiceBroker } from "moleculer"; import { AppError } from "../errors"; const { isClass } = require("../utils/isClass"); import * as PrometheusService from "../mixins/metrics.prometheus.service"; const DefaultServiceStarterSchema = { services: { type: "array", items: "any", //string, function, or obj min: 1 } }; let DefaultServiceBroker; const DefaultInternalServices = []; const DefaultMixins = [PrometheusService]; /** * [CreateServiceStarter description] * @param {[type]} _servicebroker_ [description] * @param {[type]} _metricsreporter_ [description] * @param {[type]} _tracer_ [description] */ export function CreateServiceStarter(_servicebroker_?) { DefaultServiceBroker = _servicebroker_ || ServiceBroker; //or fallback to default return ServiceStarter; } /** * [ServiceStarter description] * @param {[type]} services [description] * @param {[type]} broker [description] * * return [Broker, loadedServices, internalServices] tuple; */ async function ServiceStarter(services, broker?) { services = Array.isArray(services) ? services : [services]; //validate let checker = v.validate( { services: services }, DefaultServiceStarterSchema ); if (checker !== true) { throw new AppError(`Cannot start services, ${checker[0].message}`); } // Create broker let Broker = broker || new DefaultServiceBroker(); //priorotize custom supplied broker //or use default binded broker //load default internal services, e.g dino ...etc let internals = loadServices( DefaultInternalServices, DefaultMixins, Broker, true ); //load user services let loadeds = loadServices(services, DefaultMixins, Broker, false); await Broker.start(); //return Broker; return [Broker, loadeds, internals]; } /** syntax desugaring */ function loadServices(services, mixins, broker, local = false) { return services.map(service => { let serviceSchema = isString(service) ? require(path.resolve(local ? __dirname : process.cwd(), service)) //start('my.service.js') : service; if (!isClass(serviceSchema) && isFunction(serviceSchema)) { serviceSchema = serviceSchema(); } //injecting default mixins if (Array.isArray(mixins)) { serviceSchema.mixins = serviceSchema.mixins && Array.isArray(serviceSchema.mixins) ? mixins.concat(serviceSchema.mixins) : mixins; } return broker.createService(serviceSchema); //Service instance }); }