bin/mb
#!/usr/bin/env node
'use strict';
const mountebank = require('../src/mountebank'),
api = require('../src/cli/api'),
cli = require('../src/cli/cli'),
fs = require('fs-extra');
function processExists (pid) {
try {
// "As a special case, signal 0 can be used to test existence of process"
// https://nodejs.org/api/process.html#process_process_kill_pid_signal
process.kill(pid, 0);
return true;
}
catch (e) {
return false;
}
}
function serverAt (options) {
async function start () {
// Set in case npm dependencies do anything with this
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = 'production';
}
const server = await mountebank.create(options);
function shutdown () {
server.close(() => {
try {
if (fs.existsSync(options.pidfile)) {
fs.unlinkSync(options.pidfile);
}
}
finally {
process.exit(); // eslint-disable-line no-process-exit
}
});
}
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
if (options.configfile) {
await api.loadConfig(options, server);
}
// Useful for build plugins that need to wait for mb to be fully initialized
// They can wait for the pidfile to be written
fs.writeFileSync(options.pidfile, process.pid.toString());
}
function stop () {
if (!fs.existsSync(options.pidfile)) {
return Promise.resolve(true);
}
const pid = fs.readFileSync(options.pidfile);
if (!processExists(pid)) {
fs.unlinkSync(options.pidfile);
return Promise.resolve(true);
}
return new Promise(resolve => {
const startTime = new Date(),
timeout = 1000,
waitForClose = () => {
const elapsedTime = new Date() - startTime;
if (!fs.existsSync(options.pidfile)) {
resolve();
}
else if (elapsedTime > timeout) {
try {
// For Windows, which doesn't register signal handlers
fs.unlinkSync(options.pidfile);
}
catch (err) { /* ignore */ }
finally {
resolve();
}
}
else {
setTimeout(waitForClose, 100);
}
};
process.kill(pid);
waitForClose();
});
}
async function restart () {
await stop();
await start();
}
return {
start: start,
stop: stop,
restart: restart
};
}
try {
const server = serverAt(cli.args);
switch (cli.command) {
case 'start':
server.start();
break;
case 'stop':
server.stop();
break;
case 'restart':
server.restart();
break;
case 'save':
api.save(cli.args);
break;
case 'replay':
api.replay(cli.args);
break;
case 'help':
cli.help();
break;
default:
cli.error(`Invalid command '${cli.command}'.`);
break;
}
}
catch (err) {
cli.error(err.message);
}