Socket
Socket
Sign inDemoInstall

@mocks-server/core

Package Overview
Dependencies
96
Maintainers
1
Versions
52
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.2.0 to 1.3.0

src/Loaders.js

24

CHANGELOG.md

@@ -17,2 +17,7 @@ # Change Log

- Remove "onLoadMocks" method, use "onChangeMocks"
- Remove the addition of extra properties when reading files. Define a name for the behavior with a mandatory option.
- Remove "restart" method, use "restartServer"
- Remove behavior "name" property. Use id instead.
- Remove behaviors "currentName" getter. Use "currentId" instead
- Remove behaviors "names" getter. Use "ids" instead

@@ -25,2 +30,21 @@ ## [unreleased]

## [1.3.0] - 2020-01-03
### Added
- Behaviors can now be defined in json format.
- Add behavior "id" property, to be used instead of "name".
- Accept new options object as second argument when defining behaviors programmatically. "id" can be provided as an option.
- Add behaviors "currentId" and "ids" getters, to be used instead of "currentName" and "names"
- Add stop method to plugins.
- Pass new method "load" to plugins, which allows to load fixtures or behaviors definitions programmatically.
- Add "restartServer" method, which should be used instead of "restart".
- Accept "displayName" property in plugins, which improves traces.
- Accept "id" property in fixtures.
### Changed
- Convert filesHandler into a plugin. Load it always internally.
### Fixed
- Plugins start method was not being called again when core "start" method was called.
- Prevent exit process when there is an error loading files.
## [1.2.0] - 2019-12-22

@@ -27,0 +51,0 @@ ### Added

16

package.json
{
"name": "@mocks-server/core",
"version": "1.2.0",
"version": "1.3.0",
"description": "Pluggable mocks server supporting multiple api behaviors",

@@ -57,14 +57,14 @@ "keywords": [

"devDependencies": {
"coveralls": "^3.0.7",
"eslint": "6.6.0",
"eslint-config-prettier": "6.5.0",
"eslint-plugin-prettier": "^3.1.1",
"husky": "3.0.9",
"coveralls": "^3.0.9",
"eslint": "6.8.0",
"eslint-config-prettier": "6.9.0",
"eslint-plugin-prettier": "^3.1.2",
"husky": "3.1.0",
"is-promise": "^2.1.0",
"jest": "24.9.0",
"lint-staged": "^9.4.2",
"lint-staged": "^9.5.0",
"prettier": "^1.19.1",
"request": "^2.88.0",
"request-promise": "^4.2.5",
"sinon": "^7.5.0",
"sinon": "^8.0.1",
"strip-ansi": "6.0.0",

@@ -71,0 +71,0 @@ "tree-kill-sync": "^1.0.0"

@@ -19,4 +19,7 @@ [![Build status][travisci-image]][travisci-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Quality Gate][quality-gate-image]][quality-gate-url]

* [Get started](https://www.mocks-server.org/docs/get-started-intro)
* [Tutorials](https://www.mocks-server.org/docs/tutorials-static)
* [Guides](https://www.mocks-server.org/docs/guides-defining-fixtures)
* [Configuration](https://www.mocks-server.org/docs/configuration-options)
* [Plugins](https://www.mocks-server.org/docs/plugins-inquirer-cli)
* [Integrations](https://www.mocks-server.org/docs/integrations-cypress)
* [Api](https://www.mocks-server.org/docs/advanced-programmatic-usage)

@@ -23,0 +26,0 @@ ## Contributing

@@ -13,8 +13,12 @@ /*

const { INIT, START, LOAD_FILES, CHANGE_MOCKS, CHANGE_SETTINGS } = require("./eventNames");
const { INIT, START, STOP, LOAD_MOCKS, CHANGE_MOCKS, CHANGE_SETTINGS } = require("./eventNames");
const tracer = require("./tracer");
const Orchestrator = require("./Orchestrator");
const Loaders = require("./Loaders");
const Plugins = require("./plugins/Plugins");
const Server = require("./server/Server");
const tracer = require("./tracer");
const Mocks = require("./mocks/Mocks");
const Settings = require("./settings/Settings");
const Plugins = require("./Plugins");

@@ -24,11 +28,14 @@ class Core {

this._eventEmitter = new EventEmitter();
this._settings = new Settings(
{
onlyProgrammaticOptions: coreOptions.onlyProgrammaticOptions
},
this._eventEmitter
);
this._mocks = new Mocks(this._settings, this._eventEmitter, this);
this._server = new Server(this._mocks, this._settings, this._eventEmitter, this);
this._plugins = new Plugins(coreOptions.plugins, this);
this._settings = new Settings(this._eventEmitter, {
onlyProgrammaticOptions: coreOptions.onlyProgrammaticOptions
});
this._loaders = new Loaders(this);
this._plugins = new Plugins(coreOptions.plugins, this._loaders, this);
this._mocks = new Mocks(this._eventEmitter, this._settings, this._loaders, this);
this._server = new Server(this._eventEmitter, this._settings, this._mocks, this);
this._orchestrator = new Orchestrator(this._eventEmitter, this._mocks, this._server);
this._inited = false;

@@ -57,3 +64,2 @@ this._startPluginsPromise = null;

await this.init(); // in case it has not been initializated manually before
await this._mocks.start();
await this._server.start();

@@ -69,5 +75,16 @@ return this._startPlugins().then(() => {

}
return this._startPluginsPromise;
return this._startPluginsPromise.then(() => {
this._startPluginsPromise = null;
});
}
async _stopPlugins() {
if (!this._stopPluginsPromise) {
this._stopPluginsPromise = this._plugins.stop();
}
return this._stopPluginsPromise.then(() => {
this._stopPluginsPromise = null;
});
}
// TODO, deprecate method, use addRouter

@@ -105,6 +122,7 @@ addCustomRouter(path, router) {

onLoadFiles(cb) {
tracer.deprecationWarn("onLoadFiles", "onChangeMocks");
const removeCallback = () => {
this._eventEmitter.removeListener(LOAD_FILES, cb);
this._eventEmitter.removeListener(LOAD_MOCKS, cb);
};
this._eventEmitter.on(LOAD_FILES, cb);
this._eventEmitter.on(LOAD_MOCKS, cb);
return removeCallback;

@@ -135,10 +153,18 @@ }

async stop() {
await this._server.stop();
return this._stopPlugins().then(() => {
this._eventEmitter.emit(STOP, this);
});
}
// Expose Server methods and getters
stop() {
this._mocks.stop();
return this._server.stop();
// TODO, deprecate method, use restartServer
restart() {
tracer.deprecationWarn("restart", "restartServer");
return this.restartServer();
}
restart() {
restartServer() {
return this._server.restart();

@@ -145,0 +171,0 @@ }

@@ -14,3 +14,4 @@ /*

START: "start",
LOAD_FILES: "load:files",
STOP: "stop",
LOAD_MOCKS: "load:mocks",
CHANGE_FIXTURES: "change:fixtures",

@@ -17,0 +18,0 @@ CHANGE_MOCKS: "change:mocks",

@@ -14,6 +14,9 @@ /*

const tracer = require("../tracer");
const FixturesGroup = require("./FixturesGroup");
class Behavior {
constructor(fixtures = [], parent = null) {
constructor(fixtures = [], options = {}, parent = null) {
this._id = options.id;
this._initialFixtures = [...fixtures];

@@ -24,8 +27,8 @@ this._fixtures = new FixturesGroup(this._initialFixtures);

extend(fixtures) {
return new Behavior(this._initialFixtures.concat(fixtures), this);
extend(fixtures, options) {
return new Behavior(this._initialFixtures.concat(fixtures), options, this);
}
async init(fixturesHandler) {
await this._fixtures.init(fixturesHandler);
async init(fixturesHandler, allFixtures) {
await this._fixtures.init(fixturesHandler, allFixtures);
return Promise.resolve(this);

@@ -38,3 +41,3 @@ }

get isMocksServerBehavior() {
get isBehaviorInstance() {
return true;

@@ -48,14 +51,26 @@ }

get extendedFrom() {
return this._parent ? this._parent.name : null;
return this._parent ? this._parent.id : null;
}
// TODO, deprecate. Use id instead
get name() {
return this._name; // Prepared for defining behavior names based on property, file name, etc.
tracer.deprecationWarn("name", "id");
return this._id;
}
set name(name) {
this._name = name;
// TODO, deprecate. Use id instead
set name(id) {
tracer.deprecationWarn("name", "id");
this._id = id;
}
get id() {
return this._id;
}
set id(id) {
this._id = id;
}
}
module.exports = Behavior;

@@ -16,3 +16,3 @@ /*

const { compact } = require("lodash");
const { compact, uniqBy } = require("lodash");

@@ -22,11 +22,9 @@ const tracer = require("../tracer");

const { CHANGE_MOCKS, CHANGE_FIXTURES, CHANGE_SETTINGS } = require("../eventNames");
const { CHANGE_MOCKS } = require("../eventNames");
class Behaviors {
constructor(filesHandler, settings, eventEmitter) {
this._filesHandler = filesHandler;
constructor(loaders, settings, eventEmitter) {
this._loaders = loaders;
this._settings = settings;
this._eventEmitter = eventEmitter;
this._onLoadFixtures = this._onLoadFixtures.bind(this);
this._onChangeSettings = this._onChangeSettings.bind(this);
this._noBehavior = new Behavior();

@@ -38,17 +36,14 @@ }

this._allFixtures = allFixtures;
this._eventEmitter.on(CHANGE_FIXTURES, this._onLoadFixtures);
this._eventEmitter.on(CHANGE_SETTINGS, this._onChangeSettings);
await this._noBehavior.init(this._fixturesHandler);
return this._loadBehaviors();
await this._noBehavior.init(this._fixturesHandler, allFixtures);
return Promise.resolve();
}
async _loadBehaviors() {
async process() {
tracer.debug("Processing behaviors");
this._collection = await this._getBehaviorsCollection();
this._filesHandler.cleanContentsCustomProperties();
this._behaviors = this._getBehaviorsObject();
this._names = Object.keys(this._behaviors);
this._ids = Object.keys(this._behaviors);
this._current = this._settings.get("behavior");
tracer.verbose(`Loaded ${this._collection.length} behaviors`);
tracer.verbose(`Processed ${this._collection.length} behaviors`);

@@ -59,5 +54,5 @@ try {

tracer.warn(`Defined behavior "${this._current}" was not found.`);
this._current = this._names[0];
this._current = this._ids[0];
if (this._current) {
tracer.warn(`Inititializing with first found behavior: "${this._names[0]}"`);
tracer.warn(`Inititializing with first found behavior: "${this._ids[0]}"`);
this._settings.set("behavior", this._current);

@@ -71,38 +66,81 @@ }

_onLoadFixtures() {
this._loadBehaviors();
_isBehaviorDefinition(object) {
return !!(
!(object instanceof Behavior) &&
object.fixtures &&
Array.isArray(object.fixtures) &&
object.id
);
}
_onChangeSettings(changeDetails) {
if (changeDetails.hasOwnProperty("behavior")) {
this.current = changeDetails.behavior;
}
_factorial(number) {
if (number <= 1) return 1;
return number * this._factorial(number - 1);
}
_getBehaviorsCollection() {
const mocksFolderContents = this._filesHandler.contents;
const initBehaviors = [];
const behaviors = {};
mocksFolderContents.forEach(object => {
// TODO, register more behavior parsers
if (object.isMocksServerBehavior) {
initBehaviors.push(
object
.init(this._fixturesHandler)
.then(initedBehavior => {
initedBehavior.name = initedBehavior.name || object._mocksServer_lastPath;
behaviors[initedBehavior.name] = initedBehavior.name;
this._allFixtures.add(initedBehavior.fixtures);
return Promise.resolve(initedBehavior);
})
.catch(err => {
tracer.error("Error initializing behavior");
tracer.debug(err.toString());
return Promise.resolve();
})
_areAllCandidatesChecked() {
return this._behaviorsCandidates.length > this._factorial(this._loaders.contents.length);
}
_initBehavior(index, initedBehaviors) {
const object = this._behaviorsCandidates[index];
let behaviorCandidate = object;
// Behaviors defined in json file
if (this._isBehaviorDefinition(object)) {
if (object.from) {
const parentBehavior = initedBehaviors.find(
behavior => behavior && behavior.id === object.from
);
if (parentBehavior) {
behaviorCandidate = parentBehavior.extend(object.fixtures);
behaviorCandidate.id = object.id;
} else {
if (!this._areAllCandidatesChecked()) {
this._behaviorsCandidates.push(object);
}
return Promise.resolve();
}
} else {
behaviorCandidate = new Behavior(object.fixtures, { id: object.id });
}
}
// Behaviors instantiated directly in JS files
if (behaviorCandidate.isBehaviorInstance) {
return behaviorCandidate
.init(this._fixturesHandler, this._allFixtures)
.then(initedBehavior => {
// TODO, remove the addition of extra properties when reading files. Define a mandatory id for the behavior.
initedBehavior.id = initedBehavior.id || object._mocksServer_lastPath;
this._allFixtures.add(initedBehavior.fixtures);
return Promise.resolve(initedBehavior);
})
.catch(err => {
tracer.error("Error initializing behavior");
tracer.debug(err.toString());
return Promise.resolve();
});
}
return Promise.resolve();
}
_initBehaviors(index = 0, initedBehaviors = []) {
if (index >= this._behaviorsCandidates.length) {
return Promise.resolve(initedBehaviors);
}
return this._initBehavior(index, initedBehaviors).then(initedBehavior => {
initedBehaviors.push(initedBehavior);
return this._initBehaviors(index + 1, initedBehaviors);
});
return Promise.all(initBehaviors).then(initedBehaviors => {
return Promise.resolve(compact(initedBehaviors));
}
_getBehaviorsCollection() {
this._behaviorsCandidates = [...this._loaders.contents];
return this._initBehaviors().then(initedBehaviors => {
// TODO, remove the addition of extra properties when reading files. Define mandatory id for the behavior.
this._loaders.contents.forEach(content => {
if (content._mocksServer_lastPath) {
delete content._mocksServer_lastPath;
}
});
return Promise.resolve(uniqBy(compact(initedBehaviors), behavior => behavior.id));
});

@@ -112,18 +150,18 @@ }

_getBehaviorsObject() {
const behaviorsByName = {};
const behaviorsById = {};
this._collection.map(behavior => {
behaviorsByName[behavior.name] = behavior;
behaviorsById[behavior.id] = behavior;
});
return behaviorsByName;
return behaviorsById;
}
_checkCurrent(behaviorName) {
if (!this._names.includes(behaviorName)) {
throw Boom.badData(`Behavior not found: ${behaviorName}`);
_checkCurrent(behaviorId) {
if (!this._ids.includes(behaviorId)) {
throw Boom.badData(`Behavior not found: ${behaviorId}`);
}
}
set current(behaviorName) {
this._checkCurrent(behaviorName);
this._current = behaviorName;
set current(behaviorId) {
this._checkCurrent(behaviorId);
this._current = behaviorId;
}

@@ -139,14 +177,26 @@

// TODO, deprecate, use ids instead
get names() {
return this._names;
tracer.deprecationWarn("names", "ids");
return this._ids;
}
get ids() {
return this._ids;
}
get count() {
return this._names.length;
return this._ids.length;
}
// TODO, deprecate, use currentId instead
get currentName() {
tracer.deprecationWarn("currentName", "currentId");
return this._current;
}
get currentId() {
return this._current;
}
get collection() {

@@ -153,0 +203,0 @@ return this._collection;

@@ -17,10 +17,5 @@ /*

const { LOAD_FILES, CHANGE_FIXTURES } = require("../eventNames");
class Fixtures {
constructor(filesHandler, settings, eventEmitter) {
this._filesHandler = filesHandler;
this._settings = settings;
this._eventEmitter = eventEmitter;
this._onLoadFiles = this._onLoadFiles.bind(this);
constructor(loaders) {
this._loaders = loaders;
}

@@ -30,4 +25,3 @@

this._fixturesHandler = fixturesHandler;
this._eventEmitter.on(LOAD_FILES, this._onLoadFiles);
return this._loadFixtures();
return Promise.resolve();
}

@@ -47,16 +41,11 @@

async _loadFixtures() {
async process() {
tracer.debug("Processing fixtures");
this._fixtures = await this._getFixtures();
this._eventEmitter.emit(CHANGE_FIXTURES);
tracer.verbose(`Processed ${this._fixtures.collection.length} fixtures`);
return Promise.resolve();
}
_onLoadFiles() {
this._loadFixtures();
}
_getFixtures() {
const fixtures = new FixturesGroup(this._filesHandler.contents);
const fixtures = new FixturesGroup(this._loaders.contents);
return fixtures.init(this._fixturesHandler);

@@ -63,0 +52,0 @@ }

@@ -14,2 +14,5 @@ /*

const { compact } = require("lodash");
const tracer = require("../tracer");
class FixturesGroup {

@@ -20,3 +23,23 @@ constructor(fixtures = []) {

async init(fixturesHandler) {
_convertStringReferences(allFixtures) {
if (allFixtures) {
this._fixtures = compact(
this._fixtures.map(fixture => {
if (typeof fixture === "string") {
const realFixture = allFixtures.collection.find(existantFixture => {
return existantFixture.id === fixture;
});
if (!realFixture) {
tracer.debug(`Fixture with id "${fixture}" was not found and will be ignored`);
}
return realFixture;
}
return fixture;
})
);
}
}
async init(fixturesHandler, allFixtures) {
this._convertStringReferences(allFixtures);
this._collection = await fixturesHandler.getCollection(this._fixtures);

@@ -23,0 +46,0 @@ return Promise.resolve(this);

@@ -36,2 +36,5 @@ /*

fixtures.map(fixture => {
if (fixture && fixture.isFixtureHandler) {
return fixture;
}
const Handler = this._getHandler(fixture);

@@ -44,2 +47,3 @@ if (Handler) {

}
newFixture.isFixtureHandler = true;
addedFixtures.push(newFixture);

@@ -46,0 +50,0 @@ return newFixture;

@@ -13,3 +13,2 @@ /*

const Behaviors = require("./Behaviors");
const FilesHandler = require("./FilesHandler");
const FixturesHandler = require("./FixturesHandler");

@@ -20,14 +19,14 @@ const FixtureHandler = require("./FixtureHandler");

class Mocks {
constructor(settings, eventEmitter, core) {
constructor(eventEmitter, settings, loaders, core) {
this._eventEmitter = eventEmitter;
this._settings = settings;
this._eventEmitter = eventEmitter;
this._loaders = loaders;
this._fixturesHandler = new FixturesHandler(core);
this._fixturesHandler.addHandler(FixtureHandler);
this._filesHandler = new FilesHandler(this._settings, this._eventEmitter);
this._fixtures = new Fixtures(this._filesHandler, this._settings, this._eventEmitter);
this._behaviors = new Behaviors(this._filesHandler, this._settings, this._eventEmitter);
this._fixtures = new Fixtures(this._loaders);
this._behaviors = new Behaviors(this._loaders, this._settings, this._eventEmitter);
}
async init() {
await this._filesHandler.init();
await this._fixtures.init(this._fixturesHandler);

@@ -38,14 +37,11 @@ await this._behaviors.init(this._fixturesHandler, this._fixtures);

async stop() {
await this._filesHandler.stop();
addFixturesHandler(Handler) {
this._fixturesHandler.addHandler(Handler);
}
async start() {
await this._filesHandler.start();
async processLoadedMocks() {
await this._fixtures.process();
return this._behaviors.process();
}
addFixturesHandler(Handler) {
this._fixturesHandler.addHandler(Handler);
}
get behaviors() {

@@ -52,0 +48,0 @@ return this._behaviors;

@@ -21,7 +21,5 @@ /*

const { CHANGE_SETTINGS } = require("../eventNames");
class Server {
constructor(mocks, settings, eventEmitter, core) {
// TODO, deprecate, the core is being passed only to maintain temporarily backward retrocompaitbility with API. This is not published in documentation.
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.
this._core = core; // Use this reference only to provide it to external functions for customization purposes

@@ -35,3 +33,2 @@ this._mocks = mocks;

this._startServer = this._startServer.bind(this);
this._onChangeSettings = this._onChangeSettings.bind(this);
}

@@ -46,12 +43,5 @@

});
this._eventEmitter.on(CHANGE_SETTINGS, this._onChangeSettings);
return Promise.resolve();
}
_onChangeSettings(changeDetails) {
if (changeDetails.hasOwnProperty("port") || changeDetails.hasOwnProperty("host")) {
this.restart();
}
}
_initServer() {

@@ -58,0 +48,0 @@ if (this._serverInitted) {

@@ -18,3 +18,3 @@ /*

class Settings {
constructor(coreOptions, eventEmitter) {
constructor(eventEmitter, coreOptions) {
this._eventEmitter = eventEmitter;

@@ -21,0 +21,0 @@ this._optionsHandler = new Options(coreOptions);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc