Feature request for having decorate be a local "node" function.
Why
Make it easier to define complex behaviors in javascript.
From my understanding the decorate behavior must be a single line function with no external variables. This makes it hard inject any non-trival behavior. It would be nice to be able to pass in a string reference to a local function which can be required by a naming convention. I can work on a pr with it requiring a path local to the current running process.
How
For example if decorate is set to injectScriptToHtml
It would could do something like:
const {join} = require('path');
const fns = require(process.cwd(), 'mbBehaviors');
exports.getDecoratorFn = function (functionName) {
return fns[name];
}
Then behaviors.js would just have to change to allow local functions to be called.
https://github.com/bbyars/mountebank/blob/master/src/models/behaviors.js#L225
try {
var locaFn = getDecoratorFn(fn);
if(localFn) {
result = localFn(request, response, logger);
}
else {
result = eval(injected);
}
//local behaviors that the end user would have on their machine/repo
const cheerio = require('cheerio')
exports.injectScriptToHtml = function(request, response, logger) {
const $ = cheerio.load(response.body)
$.add('head', ...
response.body = $.html()
}
Does this seem like something worth doing? The other two approaches right now require a complex almost near impossible build process to build a single line function that can be eval'd properly or write a shell script in node that read vars in, calls the js function and returns the result to stdout.
Yes, this does look valuable. Happy to accept a PR if you're interested. Thanks for the suggestion.
(One note - I've indexed versions of node that mountebank supports to those still on node's LTS schedule, which at the moment bottoms at out v4. The only reason that matters is that I believe v4 doesn't support a lot of the ES6 syntax like the object destructuring you used above. That doesn't matter for the local function, obviously, as the user can run whatever version of node they want, but it matters for any code added to the core of mountebank since I haven't wired up Babel or anything similar to transpile).
@bbyars I still think this feature would be nice to have but I finally needed to have a conditional response and I was able to do it with a relatively decent hack. I was able to define a function locally that uses libraries, external functions, etc and then require it in the function definition string.
const inject = `(request, state, logger) => require('${__dirname}/conditionalResponse')(request,state,logger)`;
// conditionalResponse.js
module.exports = (request, state, logger) => {
return {
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ count: state.requests })
};
}
This is working because require(/full/path/to/file will work anywhere and __dirname returns a full path.