@mocks-server/core
Advanced tools
Comparing version 1.5.2 to 1.5.3
@@ -22,2 +22,3 @@ # Change Log | ||
- Remove behaviors "names" getter. Use "ids" instead | ||
- Remove "serverError" getter. Use alerts instead | ||
@@ -30,2 +31,15 @@ ## [unreleased] | ||
## [1.5.3] - 2020-12-24 | ||
### Added | ||
- feat: Add alerts handler, allowing plugins and other internal pieces to inform about errors or warnings, and let plugins access to the list, so they can display it, for example. (#102) | ||
- chore(lint): Add eslint plugin to avoid the usage of `only`. | ||
### Changed | ||
- feat: Rename filesLoader plugin | ||
- test: Move e2e helpers to a subfolder | ||
### Fixed | ||
- fix: Avoid errors when calling to fixtures and behaviors getters if they are not already initialized | ||
## [1.5.2] - 2020-12-21 | ||
@@ -32,0 +46,0 @@ |
{ | ||
"name": "@mocks-server/core", | ||
"version": "1.5.2", | ||
"version": "1.5.3", | ||
"description": "Pluggable mock server supporting multiple api behaviors", | ||
@@ -58,2 +58,3 @@ "keywords": [ | ||
"eslint": "7.12.0", | ||
"eslint-plugin-no-only-tests": "2.4.0", | ||
"eslint-config-prettier": "6.14.0", | ||
@@ -60,0 +61,0 @@ "eslint-plugin-prettier": "3.1.4", |
@@ -21,4 +21,5 @@ /* | ||
class Config { | ||
constructor(programmaticConfig = {}) { | ||
constructor({ addAlert }, programmaticConfig = {}) { | ||
this._coreOptions = {}; | ||
this._addAlert = addAlert; | ||
this._options = {}; | ||
@@ -35,4 +36,3 @@ this._getCoreOptions(programmaticConfig); | ||
_catchFileConfigError(error) { | ||
tracer.error("Error in configuration file"); | ||
console.log(error); | ||
this._addAlert("file", "Error in configuration file", error); | ||
return Promise.resolve({}); | ||
@@ -39,0 +39,0 @@ } |
@@ -13,3 +13,11 @@ /* | ||
const { INIT, START, STOP, LOAD_MOCKS, CHANGE_MOCKS, CHANGE_SETTINGS } = require("./eventNames"); | ||
const { | ||
INIT, | ||
START, | ||
STOP, | ||
LOAD_MOCKS, | ||
CHANGE_MOCKS, | ||
CHANGE_SETTINGS, | ||
CHANGE_ALERTS, | ||
} = require("./eventNames"); | ||
const tracer = require("./tracer"); | ||
@@ -20,2 +28,3 @@ | ||
const Loaders = require("./Loaders"); | ||
const Alerts = require("./Alerts"); | ||
@@ -27,2 +36,4 @@ const Plugins = require("./plugins/Plugins"); | ||
const { scopedAlertsMethods } = require("./support/helpers"); | ||
class Core { | ||
@@ -32,12 +43,44 @@ constructor(config) { | ||
// TODO, refactor all pieces as the next one. They should receive prepared callbacks | ||
// They should never access directly to the full core | ||
// (expect in cases where it is needed to be passed to plugins or another external pieces) | ||
this._alerts = new Alerts({ | ||
onChangeValues: (alerts) => { | ||
this._eventEmitter.emit(CHANGE_ALERTS, alerts); | ||
}, | ||
}); | ||
// TODO, move loaders inside mocks folder, or rename it | ||
this._loaders = new Loaders(this); | ||
this._config = new Config(config); | ||
this._config = new Config( | ||
scopedAlertsMethods("config", this._alerts.add, this._alerts.remove), | ||
config | ||
); | ||
this._settings = new Settings(this._eventEmitter, this._config); | ||
this._plugins = new Plugins(this._config, this._loaders, this); | ||
this._plugins = new Plugins( | ||
this._config, | ||
this._loaders, | ||
this, | ||
scopedAlertsMethods("plugins", this._alerts.add, this._alerts.remove, this._alerts.rename) | ||
); | ||
this._mocks = new Mocks(this._eventEmitter, this._settings, this._loaders, this); | ||
this._server = new Server(this._eventEmitter, this._settings, this._mocks, this); | ||
this._mocks = new Mocks( | ||
this._eventEmitter, | ||
this._settings, | ||
this._loaders, | ||
this, | ||
scopedAlertsMethods("mocks", this._alerts.add, this._alerts.remove) | ||
); | ||
this._server = new Server( | ||
this._eventEmitter, | ||
this._settings, | ||
this._mocks, | ||
this, | ||
scopedAlertsMethods("server", this._alerts.add, this._alerts.remove) | ||
); | ||
// TODO, rename into eventsOrchestrator, convert into a function | ||
this._orchestrator = new Orchestrator(this._eventEmitter, this._mocks, this._server); | ||
@@ -156,2 +199,10 @@ | ||
onChangeAlerts(cb) { | ||
const removeCallback = () => { | ||
this._eventEmitter.removeListener(CHANGE_ALERTS, cb); | ||
}; | ||
this._eventEmitter.on(CHANGE_ALERTS, cb); | ||
return removeCallback; | ||
} | ||
async stop() { | ||
@@ -176,2 +227,3 @@ await this._server.stop(); | ||
// TODO, deprecate | ||
get serverError() { | ||
@@ -183,2 +235,6 @@ return this._server.error; | ||
get alerts() { | ||
return this._alerts.values; | ||
} | ||
get settings() { | ||
@@ -185,0 +241,0 @@ return this._settings; |
@@ -19,2 +19,3 @@ /* | ||
CHANGE_SETTINGS: "change:settings", | ||
CHANGE_ALERTS: "change:alerts", | ||
}; |
@@ -24,3 +24,3 @@ /* | ||
class Behaviors { | ||
constructor(loaders, settings, eventEmitter) { | ||
constructor(loaders, settings, eventEmitter, { addAlert, removeAlerts }) { | ||
this._loaders = loaders; | ||
@@ -30,2 +30,4 @@ this._settings = settings; | ||
this._noBehavior = new Behavior(); | ||
this._addAlert = addAlert; | ||
this._removeAlerts = removeAlerts; | ||
} | ||
@@ -51,8 +53,20 @@ | ||
this._checkCurrent(this._current); | ||
this._removeAlerts(); | ||
} catch (error) { | ||
tracer.warn(`Defined behavior "${this._current}" was not found.`); | ||
let currentFailed; | ||
if (this._current !== null) { | ||
currentFailed = this._current; | ||
} | ||
this._current = this._ids[0]; | ||
if (this._current) { | ||
tracer.warn(`Inititializing with first found behavior: "${this._ids[0]}"`); | ||
tracer.warn(`Initializing with first found behavior: "${this._ids[0]}"`); | ||
this._settings.set("behavior", this._current); | ||
if (currentFailed) { | ||
this._addAlert( | ||
"current", | ||
`Defined behavior "${currentFailed}" was not found. The first one found was used instead` | ||
); | ||
} | ||
} else { | ||
this._addAlert("empty", `No behaviors found`); | ||
} | ||
@@ -163,2 +177,3 @@ } | ||
this._checkCurrent(behaviorId); | ||
this._removeAlerts("current"); | ||
this._current = behaviorId; | ||
@@ -178,11 +193,11 @@ } | ||
tracer.deprecationWarn("names", "ids"); | ||
return this._ids; | ||
return this._ids || []; | ||
} | ||
get ids() { | ||
return this._ids; | ||
return this._ids || []; | ||
} | ||
get count() { | ||
return this._ids.length; | ||
return this.ids.length; | ||
} | ||
@@ -189,0 +204,0 @@ |
@@ -52,7 +52,7 @@ /* | ||
get count() { | ||
return this._fixtures.collection.length; | ||
return (this._fixtures && this._fixtures.collection && this._fixtures.collection.length) || 0; | ||
} | ||
get collection() { | ||
return this._fixtures.collection; | ||
return (this._fixtures && this._fixtures.collection) || []; | ||
} | ||
@@ -59,0 +59,0 @@ } |
@@ -17,4 +17,6 @@ /* | ||
const { scopedAlertsMethods } = require("../support/helpers"); | ||
class Mocks { | ||
constructor(eventEmitter, settings, loaders, core) { | ||
constructor(eventEmitter, settings, loaders, core, { addAlert, removeAlerts }) { | ||
this._eventEmitter = eventEmitter; | ||
@@ -27,3 +29,5 @@ this._settings = settings; | ||
this._fixtures = new Fixtures(this._loaders); | ||
this._behaviors = new Behaviors(this._loaders, this._settings, this._eventEmitter); | ||
this._behaviors = new Behaviors(this._loaders, this._settings, this._eventEmitter, { | ||
...scopedAlertsMethods("behaviors", addAlert, removeAlerts), | ||
}); | ||
} | ||
@@ -30,0 +34,0 @@ |
@@ -25,2 +25,4 @@ /* | ||
this._load = methods.loadMocks; | ||
this._onAlert = methods.addAlert; | ||
this._removeAlerts = methods.removeAlerts; | ||
this._tracer = core.tracer; | ||
@@ -120,4 +122,5 @@ this._settings = this._core.settings; | ||
this._load(this._contents); | ||
this._removeAlerts("load"); | ||
} catch (error) { | ||
this._tracer.error(`Error loading files from folder ${this._path} with error:`, error); | ||
this._onAlert("load", `Error loading files from folder ${this._path}`, error); | ||
} | ||
@@ -188,3 +191,3 @@ } | ||
get displayName() { | ||
return "@mocks-server/plugin-files-loader"; | ||
return "@mocks-server/core/plugin-files-loader"; | ||
} | ||
@@ -191,0 +194,0 @@ } |
@@ -18,5 +18,9 @@ /* | ||
const FilesLoader = require("./FilesLoader"); | ||
const { scopedAlertsMethods } = require("../support/helpers"); | ||
class Plugins { | ||
constructor(config, loaders, core) { | ||
constructor(config, loaders, core, { addAlert, removeAlerts, renameAlerts }) { | ||
this._addAlert = addAlert; | ||
this._removeAlerts = removeAlerts; | ||
this._renameAlerts = renameAlerts; | ||
this._config = config; | ||
@@ -43,2 +47,3 @@ this._core = core; | ||
init() { | ||
this._removeAlerts("init"); | ||
return this._initPlugins().then(() => { | ||
@@ -51,2 +56,3 @@ tracer.verbose(`Initializated ${this._pluginsInitialized} plugins without errors`); | ||
start() { | ||
this._removeAlerts("start"); | ||
return this._startPlugins().then(() => { | ||
@@ -59,2 +65,3 @@ tracer.verbose(`Started ${this._pluginsStarted} plugins without errors`); | ||
stop() { | ||
this._removeAlerts("stop"); | ||
return this._stopPlugins().then(() => { | ||
@@ -67,12 +74,16 @@ tracer.verbose(`Stopped ${this._pluginsStopped} plugins without errors`); | ||
pluginDisplayName(index) { | ||
return this._pluginsInstances[index].displayName || index; | ||
return (this._pluginsInstances[index] && this._pluginsInstances[index].displayName) || index; | ||
} | ||
_catchRegisterError(error) { | ||
console.log("Error registering plugin"); | ||
console.log(error); | ||
_catchRegisterError(error, index) { | ||
const pluginDisplayName = this.pluginDisplayName(index); | ||
this._addAlert( | ||
`register:${pluginDisplayName}`, | ||
`Error registering plugin "${pluginDisplayName}"`, | ||
error | ||
); | ||
return {}; | ||
} | ||
_registerPlugin(Plugin, pluginMethods) { | ||
_registerPlugin(Plugin, pluginMethods, pluginIndex) { | ||
let pluginInstance; | ||
@@ -93,6 +104,6 @@ if (isObject(Plugin) && !isFunction(Plugin)) { | ||
} catch (err) { | ||
return this._catchRegisterError(err); | ||
return this._catchRegisterError(err, pluginIndex); | ||
} | ||
} else { | ||
return this._catchRegisterError(error); | ||
return this._catchRegisterError(error, pluginIndex); | ||
} | ||
@@ -105,3 +116,3 @@ } | ||
} catch (error) { | ||
this._catchRegisterError(error); | ||
this._catchRegisterError(error, pluginIndex); | ||
this._pluginsRegistered = this._pluginsRegistered - 1; | ||
@@ -120,5 +131,11 @@ } | ||
loadMocks, | ||
...scopedAlertsMethods( | ||
() => this.pluginDisplayName(pluginIndex), | ||
this._addAlert, | ||
this._removeAlerts, | ||
this._renameAlerts | ||
), | ||
}; | ||
this._pluginsMethods.push(pluginMethods); | ||
const plugin = this._registerPlugin(this._plugins[pluginIndex], pluginMethods); | ||
const plugin = this._registerPlugin(this._plugins[pluginIndex], pluginMethods, pluginIndex); | ||
this._pluginsInstances.push(plugin); | ||
@@ -130,3 +147,8 @@ return this._registerPlugins(pluginIndex + 1); | ||
this._pluginsInitialized = this._pluginsInitialized - 1; | ||
tracer.error(`Error initializating plugin ${this.pluginDisplayName(index)}`); | ||
const pluginDisplayName = this.pluginDisplayName(index); | ||
this._addAlert( | ||
`init:${pluginDisplayName}`, | ||
`Error initializating plugin "${pluginDisplayName}"`, | ||
error | ||
); | ||
tracer.debug(error.toString()); | ||
@@ -141,11 +163,15 @@ return Promise.resolve(); | ||
this._pluginsInitialized++; | ||
tracer.debug(`Initializing plugin "${this.pluginDisplayName(pluginIndex)}"`); | ||
const initNextPlugin = () => { | ||
return this._initPlugins(pluginIndex + 1); | ||
}; | ||
const pluginDisplayName = this.pluginDisplayName(pluginIndex); | ||
if (!this._pluginsInstances[pluginIndex].init) { | ||
this._pluginsInitialized = this._pluginsInitialized - 1; | ||
this._addAlert( | ||
`init:${pluginDisplayName}`, | ||
`Plugin "${pluginDisplayName}" has not init method` | ||
); | ||
return initNextPlugin(); | ||
} | ||
tracer.debug(`Initializing plugin "${pluginDisplayName}"`); | ||
let pluginInit; | ||
@@ -173,3 +199,8 @@ try { | ||
this._pluginsStarted = this._pluginsStarted - 1; | ||
tracer.error(`Error starting plugin "${this.pluginDisplayName(index)}"`); | ||
const pluginDisplayName = this.pluginDisplayName(index); | ||
this._addAlert( | ||
`start:${pluginDisplayName}`, | ||
`Error starting plugin "${pluginDisplayName}"`, | ||
error | ||
); | ||
tracer.debug(error.toString()); | ||
@@ -184,11 +215,15 @@ return Promise.resolve(); | ||
this._pluginsStarted++; | ||
tracer.debug(`Starting plugin "${this.pluginDisplayName(pluginIndex)}"`); | ||
const startNextPlugin = () => { | ||
return this._startPlugins(pluginIndex + 1); | ||
}; | ||
const pluginDisplayName = this.pluginDisplayName(pluginIndex); | ||
if (!this._pluginsInstances[pluginIndex].start) { | ||
this._pluginsStarted = this._pluginsStarted - 1; | ||
this._addAlert( | ||
`start:${pluginDisplayName}`, | ||
`Plugin "${pluginDisplayName}" has not start method` | ||
); | ||
return startNextPlugin(); | ||
} | ||
tracer.debug(`Starting plugin "${pluginDisplayName}"`); | ||
let pluginStart; | ||
@@ -216,3 +251,8 @@ try { | ||
this._pluginsStopped = this._pluginsStopped - 1; | ||
tracer.error(`Error stopping plugin "${this.pluginDisplayName(index)}"`); | ||
const pluginDisplayName = this.pluginDisplayName(index); | ||
this._addAlert( | ||
`stop:${pluginDisplayName}`, | ||
`Error stopping plugin "${pluginDisplayName}"`, | ||
error | ||
); | ||
tracer.debug(error.toString()); | ||
@@ -227,3 +267,2 @@ return Promise.resolve(); | ||
this._pluginsStopped++; | ||
tracer.debug(`Stopping plugin "${this.pluginDisplayName(pluginIndex)}"`); | ||
const stopNextPlugin = () => { | ||
@@ -233,6 +272,12 @@ return this._stopPlugins(pluginIndex + 1); | ||
const pluginDisplayName = this.pluginDisplayName(pluginIndex); | ||
if (!this._pluginsInstances[pluginIndex].stop) { | ||
this._pluginsStopped = this._pluginsStopped - 1; | ||
this._addAlert( | ||
`stop:${pluginDisplayName}`, | ||
`Plugin "${pluginDisplayName}" has not stop method` | ||
); | ||
return stopNextPlugin(); | ||
} | ||
tracer.debug(`Stopping plugin "${pluginDisplayName}"`); | ||
let pluginStop; | ||
@@ -239,0 +284,0 @@ try { |
@@ -22,4 +22,4 @@ /* | ||
class Server { | ||
constructor(eventEmitter, settings, mocks, core) { | ||
// TODO, deprecate, the core is being passed only to maintain temporarily backward retrocompaitbility with API plugin. This is not published in documentation. | ||
constructor(eventEmitter, settings, mocks, core, { addAlert, removeAlerts }) { | ||
// TODO, deprecate, the core is being passed only to maintain temporarily backward compatibility with API plugin. This is not published in documentation. | ||
this._core = core; // Use this reference only to provide it to external functions for customization purposes | ||
@@ -31,2 +31,4 @@ this._mocks = mocks; | ||
this._error = null; | ||
this._addAlert = addAlert; | ||
this._removeAlerts = removeAlerts; | ||
@@ -51,3 +53,2 @@ this._startServer = this._startServer.bind(this); | ||
tracer.debug("Initializing server"); | ||
this._serverInitted = true; | ||
this._express = express(); | ||
@@ -69,8 +70,9 @@ | ||
this._server = http.createServer(this._express); | ||
this._removeAlerts("server"); | ||
this._server.on("error", (error) => { | ||
tracer.error(`Server error: ${error.message}`); | ||
this._addAlert("server", `Server error`, error); | ||
this._error = error; | ||
throw error; | ||
}); | ||
this._serverInitted = true; | ||
} | ||
@@ -106,5 +108,5 @@ | ||
if (error) { | ||
tracer.error(`Error starting server: ${error.message}`); | ||
this._serverStarting = false; | ||
this._serverStarted = false; | ||
this._addAlert("start", `Error starting server`, error); | ||
this._error = error; | ||
@@ -117,2 +119,3 @@ reject(error); | ||
this._serverStarted = true; | ||
this._removeAlerts("start"); | ||
resolve(this); | ||
@@ -123,2 +126,3 @@ } | ||
} catch (error) { | ||
this._addAlert("start", `Error starting server`, error); | ||
reject(error); | ||
@@ -125,0 +129,0 @@ } |
@@ -21,2 +21,3 @@ /* | ||
this._optionsHandler = new Options(config); | ||
// TODO, remove next unnecessary bind | ||
this._emitChange = this._emitChange.bind(this); //Add debounce here to group change events | ||
@@ -23,0 +24,0 @@ this._newSettings = {}; |
96599
28
2107
13