Build a processing pipeline with transforms
A transform is a named chain of steps. NEWTRANSFORM(name, fn, [id]) adds a step to the chain name; steps run in the order they were registered, and each one receives the options object $ and the current value. Change the value with $.value = ... and call $.next() to continue with the next step. $.invalid(message) adds an error. TRANSFORM(name, value) starts the chain and returns a promise with the final value; the promise rejects when a step has reported an error. With a callback instead, TRANSFORM(name, value, function(err, value) {}). A name without any step returns the value as it is.
Use it for work that has to be extended from several places, such as cleaning a comment before it is saved: a spam filter, a trimmer and a link checker can each live in their own file and be added or removed without touching the code that calls TRANSFORM(). The optional id lets you remove one step later with NEWTRANSFORM(name, null, id).
NEWTRANSFORM('comment', function($, value) {
$.value = value.trim();
$.next();
}, 'trim');
NEWTRANSFORM('comment', function($, value) {
if (/spam/i.test(value))
$.invalid('Spam is not allowed');
$.next();
}, 'spam');
NEWTRANSFORM('comment', function($, value) {
$.value = value.replace(/\s+/g, ' ');
$.next();
}, 'spaces');exports.install = function() {
ROUTE('POST /comment/ @json', comment);
ROUTE('DELETE /comment/spaces/', remove_step);
};
async function comment($) {
try {
var text = await TRANSFORM('comment', $.body.text);
$.json({ text: text });
} catch (err) {
$.json({ error: true });
}
}
function remove_step($) {
NEWTRANSFORM('comment', null, 'spaces');
$.success();
}