kopia lustrzana https://github.com/c9/core
218 wiersze
8.9 KiB
JavaScript
218 wiersze
8.9 KiB
JavaScript
define(function(require, exports, module) {
|
|
main.consumes = ["Plugin", "proc"];
|
|
main.provides = ["proc.apigen"];
|
|
return main;
|
|
|
|
function main(options, imports, register) {
|
|
var proc = imports.proc;
|
|
var Plugin = imports.Plugin;
|
|
|
|
function ApiGenerator(options) {
|
|
var runtime = options.runtime;
|
|
var basepath = options.basepath;
|
|
var errorCheck = options.errorCheck;
|
|
var env = options.env;
|
|
|
|
/***** Initialization *****/
|
|
|
|
var plugin = new Plugin("Ajax.org", main.consumes);
|
|
// var emit = plugin.getEmitter();
|
|
|
|
/***** Methods *****/
|
|
|
|
function spawn(args, callback, cbExit, noAuthCheck) {
|
|
proc.pty(runtime, {
|
|
args: args,
|
|
cwd: basepath,
|
|
env: env
|
|
}, function(err, pty) {
|
|
if (err)
|
|
return callback(err);
|
|
|
|
var control = {
|
|
kill: function(){ pty.kill() },
|
|
write: function(value){ pty.write(value) },
|
|
discard: function(keep) {
|
|
if (keep) pty.off("data", ondata);
|
|
pty.off("exit", onexit);
|
|
}
|
|
};
|
|
|
|
function ondata(data) {
|
|
var err = errorCheck(data, noAuthCheck, control);
|
|
if (err) {
|
|
control.discard();
|
|
return callback(err);
|
|
}
|
|
|
|
callback(null, data, control);
|
|
}
|
|
function onexit(data) {
|
|
return cbExit ? cbExit() : callback("No data received");
|
|
}
|
|
|
|
pty.on("data", ondata);
|
|
pty.on("exit", onexit);
|
|
});
|
|
}
|
|
|
|
function parseArg(options, arg, found, data) {
|
|
if (arg instanceof RegExp) {
|
|
var m = data.match(arg);
|
|
return m.length > 1 ? m[1] : m[0];
|
|
}
|
|
else if (typeof arg == "object") {
|
|
var obj = {};
|
|
for (var prop in arg)
|
|
obj[prop] = parseArg(options, arg[prop], found, data);
|
|
return obj;
|
|
}
|
|
else if (typeof arg == "string") {
|
|
return arg.replace(/\\\{|\{(.*?)\}/g, function(m, name) {
|
|
if (m == "\\{") return m;
|
|
// Replace $n in regexpses
|
|
if (name.charAt(0) == "$")
|
|
return found[name.substr(1)];
|
|
// Replace {name} in strings
|
|
return options[name];
|
|
});
|
|
}
|
|
return arg;
|
|
}
|
|
|
|
function createMethod(def) {
|
|
return function(options, callback) {
|
|
var parse = parseArg.bind(this, options);
|
|
var args = typeof def.args == "function"
|
|
? def.args(options)
|
|
: def.args.map(parse);
|
|
|
|
var buffer = "";
|
|
spawn(args, function(err, data, control) {
|
|
if (err)
|
|
return callback(err);
|
|
|
|
if (def.buffer) {
|
|
buffer += data;
|
|
return;
|
|
}
|
|
|
|
if (def.write) {
|
|
def.write.forEach(function(item) {
|
|
var found;
|
|
if (typeof item.match == "string")
|
|
found = data.indexOf(item.match) > -1;
|
|
else
|
|
found = data.match(item.match);
|
|
|
|
if (found)
|
|
control.write(parse(item.text, found, data));
|
|
});
|
|
}
|
|
if (def.exit) {
|
|
var found;
|
|
|
|
for (var i = 0; i < def.exit.length; i++) {
|
|
var item = def.exit[i];
|
|
|
|
if (typeof item.match == "string")
|
|
found = data.indexOf(item.match) > -1;
|
|
else
|
|
found = data.match(item.match);
|
|
|
|
if (found) {
|
|
if (item.error)
|
|
callback(item.result
|
|
? parse(item.result, found, data)
|
|
: data);
|
|
else
|
|
callback(null, parse(item.result, found, data));
|
|
|
|
control.discard();
|
|
if (item.error || item.kill)
|
|
control.kill();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (def.stream) {
|
|
callback(null, data, control);
|
|
return;
|
|
}
|
|
}, function(){
|
|
if (def.buffer) {
|
|
try {
|
|
callback(null,
|
|
def.parse ? def.parse(buffer) : buffer);
|
|
}
|
|
catch (e) {
|
|
console.error(e);
|
|
callback(e);
|
|
}
|
|
}
|
|
else {
|
|
callback(def.defaultSuccess ? null : "No proper data received");
|
|
}
|
|
}, def.noauth);
|
|
}
|
|
}
|
|
|
|
/***** Register and define API *****/
|
|
|
|
/**
|
|
* Factory object for the {@link ApiGenerator}.
|
|
* @class proc.apigen
|
|
* @extends Object
|
|
*/
|
|
/**
|
|
* Create an instance of ApiGenerator.
|
|
* @method create
|
|
* @param {Object} options
|
|
* @param {String} options.runtime The path to the CLI in the workspace
|
|
* @param {String} options.basepath The basepath to the file in the workspace
|
|
* @param {Object} [options.env] Key value pairs of strings that
|
|
* specify the environment variables to set when executing the CLI.
|
|
* @param {Function} options.errorCheck This function is
|
|
* called when data comes in from a command and should be used to
|
|
* check for errors. This function should not return an object
|
|
* or string when an error has occured. When an auth error has
|
|
* occurred return an Error object with a property "code" set to
|
|
* 100.
|
|
* @param {String} options.errorCheck.data The output from the command.
|
|
* @param {Boolean} options.errorCheck.noAuthCheck Whether to ignore any auth check.
|
|
* @return {ApiGenerator}
|
|
*/
|
|
/**
|
|
* Helps to create an API based on a CLI.
|
|
* @class ApiGenerator
|
|
**/
|
|
plugin.freezePublicAPI({
|
|
/**
|
|
* Start the CLI process and process it's output.
|
|
* @param {Array} args The arguments to send to the CLI
|
|
* @param {Function} callback Called each time data is received from the process
|
|
* @param {String} callback.data The data received
|
|
* @param {Object} callback.control
|
|
* @param {Function} callback.control.kill Kills the process
|
|
* @param {Function} callback.control.write Write to the process
|
|
* @param {Function} callback.control.discard Discard any further changes
|
|
* @param {Function} cbExit This callback is called when the process exits successfully.
|
|
* @param {Boolean} [noAuthCheck=false] Whether to perform a check for authentication
|
|
*/
|
|
spawn: spawn,
|
|
|
|
/**
|
|
*
|
|
*/
|
|
createMethod: createMethod
|
|
});
|
|
|
|
return plugin;
|
|
}
|
|
|
|
register(null, {
|
|
"proc.apigen" : { create: ApiGenerator }
|
|
});
|
|
}
|
|
}); |