tooljs-tool
Version:
Composible Tooling for JavaScript
97 lines (77 loc) • 1.93 kB
JavaScript
/**
* Module dependencies.
*/
var statics = require('./lib/statics');
var proto = require('./lib/proto');
var Emitter = require('events').Emitter;
var debug = require('debug');
/**
* Expose `tool`.
*/
module.exports = tool;
/**
* Create a new `Tool` constructor.
*
* @param {String} [name]
* @return {Function}
*/
function tool(name) {
/**
* Initialize a new `Tool`.
*
* @param {Object} opts
* @param {Tool} parent
*/
function Tool(opts, parent) {
if (!(this instanceof Tool)) return new Tool(opts);
this.opts = opts = opts || {};
this.debug = debug(name || 'tool');
this.parent = parent;
var self = this;
var inputs = this.constructor.inputs;
each(inputs, function(key){
self[key] = opts[key] || parse(inputs[key].value);
});
// TODO: templatize / expressions
var attrs = this.constructor.attrs;
each(attrs, function(key){
self[key] = opts[key] || parse(attrs[key].value);
});
function parse(val) {
if ('string' != typeof val) return val;
return val.replace(/\{\{\ *(\w+)\ *\}\}/g, function(_, $1){
return self[$1];
});
}
// TODO: pipe parent outputs to child inputs
if (parent) {
var outputs = parent.constructor.outputs;
each(outputs, function(key){
if (self.constructor.inputs[key] && null != parent[key]) {
self[key] = parent[key];
}
});
}
}
// mixin `Emitter`.
//Tool.__proto__ = Emitter.prototype;
// statics
Tool.isTool = true;
Tool.id = name;
Tool.attrs = {};
Tool.inputs = {};
Tool.outputs = {};
Tool.middleware = [];
for (var key in statics) Tool[key] = statics[key];
// prototype
Tool.prototype = {};
Tool.prototype.constructor = Tool;
for (var key in proto) Tool.prototype[key] = proto[key];
return Tool;
}
/**
* Each.
*/
function each(obj, fn) {
Object.keys(obj).forEach(fn);
}