File: js/cli.js

Recommend this page to a friend!
  Classes of Till Wehowski  >  Widget CLI  >  js/cli.js  >  Download  
File: js/cli.js
Role: Class source
Content type: text/plain
Description: Class source
Class: Widget CLI
Process commands entered by the user
Author: By
Last change: Update cli.js
Date: 5 years ago
Size: 23,987 bytes
 

Contents

Class file image Download
/* webfan (C) Till Wehowski, Webfan.de - All rights reserved. */ const EXITCODE_OK = 0; const EXITCODE_HALT = 1; const EXITCODE_ERROR = 2; const EXITCODE_NOTREADY = 3; const EXITCODE_SQLERROR = 5; (function(){ 'use strict'; function _cli(argv, options, switches, positionalSwitches, shells){ 'use strict'; function f(code){ return '(function(result){'+code+'})'; } var util = require('util'); /* frdl.util;*/ var escapeshellarg = frdl.escapeshellarg; var fNFin = null; var finalized = false; var _CLI = new frdl.EventEmitter(); _CLI.config = require('../clisetup/clisetup'); var optparse = require('optparse-js/lib/optparse'); if(!util.isArray(argv) && !!util.isString(argv) ){ argv = _CLI.config.parseArgs(argv); } var debug=function(type, obj){ var opts = { showHidden : true, depth : 4 }; try{ var color = 'black'; if('warn'===type)color = 'orange'; if('error'===type || 'fatal'===type)color = 'red'; if('dir'===type)color = 'blue'; var str = '<p><legend style="color:'+color+';">'+type+'</legend>'+util.inspect(obj, opts)+'</p>'; console[type](str); frdl.alert[('error'===type || 'warn'===type)?'error':'log'](str); }catch(err){ console.warn(err); } }; /* try{ var mask = require('16:webfan/webfat/js/flagmask'); console.dir('dir', mask); }catch(err){ frdl.alert.error(err); } */ _CLI.options = _CLI.config.default_options; if(null!==options && 'object' === typeof options){ _CLI.options = frdl.extend(_CLI.options, options); } var doParse = true; var exitcode = EXITCODE_NOTREADY; exitcode=EXITCODE_OK; var parser = null; /* var _CLI = this || Object.create({}); var _CLI = Object.create({}); */ var messageLog = []; var errorlog = []; _CLI.escapeshellarg = escapeshellarg; _CLI.finalState = _CLI.required([ 'firstarg' ], function (dataArray) { console.log('CLI exit with ' + exitcode); if(0<exitcode && 200 !== exitcode){ _CLI.emit('catch', exitcode.toString()+' : '+_CLI.errorlog.join('\s\n\r')); }else{ _CLI.emit('success', _CLI.data.data); } }, _CLI); _CLI.finalState.add('parse'); _CLI.finalState.add('exit'); _CLI.finalState.add('finalize.before'); _CLI.finalState.add('finalize'); _CLI.on('catch', function(err){ try{ _CLI.finalState.cancel(); }catch(err){ } }); if('undefined' === typeof shells && null !== sessionStorage.getItem('webfan/cli $ shells') ){ shells = JSON.parse(sessionStorage.getItem('webfan/cli $ shells')); } _CLI.shell = '$ webfan'; _CLI.shells = $.extend({ '$ webfan' : { url : '16:webfan/cli/commands/webfan/' }, '$ test' : { url : '16:webfan/cli/commands/test/' }, '$ apc' : { url : '16:frdl/webfan/cli/commands/apc/' } //, '$ exampleshell' : { // url : 'http://example.com/example-path/commands/exampleshell/' //} //'$ frdl' : { //error (used by other cli) //}, //'$ flow' : { //}, //'$ js' : { //} }, (shells || {})); sessionStorage.setItem('webfan/cli $ shells', JSON.stringify(_CLI.shells)); if(null !== sessionStorage.getItem('webfan/cli $ shell') && 'undefined' !== typeof _CLI.shells[sessionStorage.getItem('webfan/cli $ shell')]){ _CLI.shell = sessionStorage.getItem('webfan/cli $ shell'); } _CLI.WinID = 'cli.html'; _CLI.cmd = null; _CLI.argv = argv; _CLI.callbackName = false; _CLI.data = { DIRECTORIES : [], FILES : [], URLS : [], ACTION : null, data : null, options : { } }; _CLI.switches = switches || [ // ['--$ [TEXT]', "Change shell"] ]; var _tokensToBuild = []; var _filtersToBuild = []; var _sfn = { }; _CLI.positionalSwitches = positionalSwitches || []; _CLI.addOption = function(optName, description, callback, filterStr, _short){ if('string' !== typeof filterStr)var filterStr = ' [TEXT]'; if('string'===typeof _short){ _CLI.switches.push([_short, '--' + optName + filterStr, description]); }else{ _CLI.switches.push(['--' + optName + filterStr, description]); } _sfn[optName] = callback; return _CLI; }; _CLI.filter = function(filterName, filter){ _filtersToBuild.push([filterName, filter]); return _CLI; }; _CLI.addToken = function(option, arg, fn){ _tokensToBuild.push([option, arg, fn]); return _CLI; }; try{ Object.defineProperty(_CLI, 'exitcode', { get : function(){ return ((0===_CLI.errorlog.length) ? EXITCODE_OK : (EXITCODE_OK<exitcode) ? /* ++exitcode */ exitcode : EXITCODE_ERROR); }, set : function(val){ throw 'write to cli.exitcode from public scope'; } }); Object.defineProperty(_CLI, 'messageLog', { get : function(){ return messageLog; }, set : function(val){ console.warn('Do not set cli.messageLog manually!'); } }); Object.defineProperty(_CLI, 'errorlog', { get : function(){ return errorlog; }, set : function(val){ console.warn('Do not set cli.errorlog manually!'); } }); Object.defineProperty(_CLI, 'util', { get : function(){ return frdl.util; }, set : function(val){ console.warn('Do not set cli.util manually!'); } }); }catch(err){ if(Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { this.__defineGetter__('exitcode', function(){ return ((0===_CLI.errorlog.length) ? 0 : (0===exitcode) ? ++exitcode : exitcode); } ); this.__defineSetter__('exitcode', function(val){ throw 'write to cli.exitcode from public scope'; } ); this.__defineGetter__('messageLog', function(){ return messageLog; } ); this.__defineSetter__('messageLog', function(val){ console.warn('Do not set cli.messageLog manually!'); } ); this.__defineGetter__('errorlog', function(){ return errorlog; } ); this.__defineSetter__('errorlog', function(val){ console.warn('Do not set cli.errorlog manually!'); } ); this.__defineGetter__('util', function(){ return frdl.util; } ); this.__defineSetter__('util', function(val){ console.warn('Do not set cli.util manually!'); } ); }else{ console.deprecated('Missing Object.defineProperty and Object.prototype.__defineGetter__ - Fallback to UNSAFE configuration readable!'); _CLI.exitcode = exitcode; _CLI.messageLog = messageLog; _CLI.errorlog = errorlog; _CLI.util = frdl.util; } } _CLI.log = function(m){ _CLI.emit('log', m); }; _CLI.error = function(m){ _CLI.emit('error', m); }; var Finalize = function(scope, THAT){ if(!!finalized)return; finalized=true; if(true === THAT.options.debug) _CLI.log('>>>Finalize<<<'); if(true === THAT.parser._halt){ // if(true === THAT.options.debug) _CLI.log('>>>HALT<<<'); // return; } /*if(!THAT.parser._halt)*/_CLI.emit('finalize.before', THAT); /* if(!THAT.parser._halt)*/_CLI.emit('finalize', THAT); if(true === THAT.options.debug) _CLI.log('>>>RESULT BEGIN<<<'); if(true === THAT.options.debug) _CLI.log(JSON.stringify(THAT.result)); if(true === THAT.options.debug) _CLI.log('>>>RESULT END<<<'); }; if(!!_CLI.options.defaults.onceFinalize){ _CLI.once('finalize', function(THAT){ if('function'===typeof fNFin && !THAT.parser._halt){ fNFin.call(_CLI, THAT); } _CLI.emit('exit', _CLI.exitcode); }); } var onHalt = function(tokens){ _CLI.emit('exit', EXITCODE_HALT); if(true === THAT.options.debug) _CLI.log('>>>HALT<<<'); if(true === _CLI.options.debug)_CLI.log(JSON.stringify(_CLI.data.rest)); }; var Test=function(THAT){ THAT.result = 'This is any testresult!'; _CLI.log('Run the "test" command'); }; if(!!_CLI.options.defaults.logs){ _CLI.on('log', function(m){ messageLog.push(m); console.log(m); }); _CLI.on('error', function(m){ errorlog.push(m); console.error(m); }); } _CLI.cmd = _CLI.argv[0].trim(); var __changeShell = function(s){ var _shellName = '$ ' + s; if('undefined'===typeof _CLI.shells[_shellName]){ _CLI.emit('error', 'Shell ' + _shellName + ' is not installed!'); return; } _CLI.shell = _shellName; sessionStorage.setItem('webfan/cli $ shell', _shellName); }; // e.g.: --$ webfan _CLI.addToken('$', '*', function(c, result_length, token, current_option){ __changeShell(token); }); if(!!_CLI.options.defaults.sql){ if('noop' === _CLI.cmd.toLowerCase()){ // doParse=false; fNFin = function(){}; } if('frdl' === _CLI.cmd.toLowerCase()){ var _args = frdl.clone(_CLI.argv); _args.shift(); _CLI.finalState.add('api response'); var _cmd = _args.join(' '); _cmd += ' --format="json" '; doParse=false; fNFin = function(){ if(null===sessionStorage.getItem('api_url')){ _CLI.emit('catch', 'No api_url specified'); return; } $.ajax( { url: sessionStorage.getItem('api_url'), crossDomain: true, cache:false, headers: {'X-Requested-With': 'XMLHttpRequest' }, type: 'POST', dataType: 'json', data: { cmd : _cmd, format : 'application/json' } } ) .done(function(response) { _CLI.data.data = response; }) .fail(function(jqXHR, textStatus) { _CLI.emit('catch', 'Error: ' + jqXHR.status+ ' ' + jqXHR.statusText); }) .always(function() { _CLI.emit('api response'); }); }; } frdl.each(_CLI.config.sqlstarts, function(i, command){ if(_CLI.cmd.toLowerCase() === command){ doParse=false; fNFin = function(){ _CLI.emit('sql',_CLI.argv.join(' ')); }; // _CLI.emit('exit'); return false; } }); _CLI.on('sql', function(query){ console.log('cli>sql '+query); try{ var sql = frdl.sql; var _sqlState = 'sql ' + frdl.Sha1.hash(query + '.' + frdl.Guid.newGuid()); _CLI.finalState.add(_sqlState); (function runSQL(){ if(!sql || 'function' !== typeof sql.query){ webfan.$Async(function(){ runSQL(); },1); return; } sql.query(query, function(err, result) { if (err) { _CLI.error(err); _CLI.emit(_sqlState, false); return; } var _Result = result; // _CLI.once('finalize.before', function(THAT){ if(null===_CLI.data.data){ _CLI.data.data =_Result; }else if(true === _Result instanceof Array && true === _CLI.data.data instanceof Array){ _CLI.data.data.push(_Result); }else{ _CLI.data.data =_Result; } //}); _CLI.emit(_sqlState, _Result); }); }()); } catch(err) { _CLI.error(err); } }); } if(!!_CLI.options.defaults.sql){ _CLI.addOption('sql', 'Run a sql query', function(name, value) { _CLI.emit('sql',value, false); }, ' [TEXT]'); } if(!!_CLI.options.defaults.firstArg && '--$' !== _CLI.cmd && '$' !== _CLI.cmd){ try{ var cli; //if(null===fNFin)cli = require('16:webfan/cli/commands/webfan/'+_CLI.cmd); try{ if(null===fNFin)cli = require( _CLI.shells[_CLI.shell].url + _CLI.cmd ); }catch(err){ if(null===fNFin)cli = require('16:webfan/cli/commands/webfan/'+_CLI.cmd); } if('function' === typeof cli.prepare)cli.prepare(_CLI); fNFin = ('function' === typeof cli.finalize) ? cli.finalize : fNFin; }catch(err){ //_CLI.error('Command "'+_CLI.cmd+'" not found. '+err); } } _CLI.emit('firstarg', _CLI.cmd); _CLI.exit = function(exitcode){ _CLI.emit('exit', exitcode) return _CLI; }; _CLI.once('exit', function(_exitcode){ _CLI.parser._halt=true; if('undefined' === typeof _exitcode)_exitcode = _CLI.exitcode; if(isNaN(_exitcode)){ throw 'exitcode is not a number'; } exitcode=_exitcode; // _CLI.parser.on_halt.apply(_CLI.parser, [_CLI.data.data]); // if(0<exitcode && 200 !== exitcode){ // fNFin = null; // _CLI.emit('catch', exitcode.toString()+' : '+_CLI.errorlog.join('\s\n\r')); // }else{ // if(!finalized){ // _CLI.finalize(_CLI); // } // _CLI.emit('success', _CLI.data.data); // } }); if(!!_CLI.options.defaults.standards){ _CLI.addOption('debug', 'Debug mode', function(name, value) { _CLI.options.debug = value; if(!_CLI.options.debug){ frdl.debug.mode(3); } }, ' [SWITCH]', '-d') .addOption('help', 'Shows help', function() { var txt = _CLI.parser.toString(); txt += '\n\r'; txt += Object.keys(_CLI.shells).toString(); _CLI.log(txt); _CLI.data.data=txt; }, ' [SWITCH]', '-h') .addOption('callback', 'Poplulate a callback function to the global.frdl.cbs[CALLBACKVALUE] if not exists already\nand call it with result as arguments finally,\nafter that remove the function from the frdl.cbs stack', function(name, value) { if(/^\w+$/.test(value)){ var c = _CLI.callbackName = value; _CLI.once('finalize', function(r){ if('function'===typeof frdl.cbs[_CLI.callbackName]){ frdl.cbs[_CLI.callbackName].apply(_CLI, [r]); } }); return; } try{ var callback = eval(f(value)); _CLI.once('finalize', function(r){ callback.apply(_CLI, [r]); }); }catch(err){ _CLI.error(err); } /* var fTok = '()=>', fTok2 = '=>'; if(fTok === value.substr(0,fTok.length)){ var t = value.substr(fTok.length,value.length); try{ var callback = eval(f(t)); _CLI.once('finalize', function(r){ callback.apply(_CLI, [r]); }); }catch(err){ console.warn(err); } return; }else if(fTok2 === value.substr(0,fTok2.length)){ var t = value.substr(fTok2.length,value.length); try{ var callback = eval(f(t)); _CLI.once('finalize', function(r){ callback.apply(_CLI, [r]); }); }catch(err){ console.warn(err); } return; } if('undefined' === typeof frdl.cbs[c]){ frdl.cbs[c] = function(result){ var util = require('util'); var opts = { showHidden : true, depth : 4 }; var type = (result && null !== result) ? 'log' : 'error'; try{ var color = 'black'; if('warn'===type)color = 'orange'; if('error'===type || 'fatal'===type)color = 'red'; if('dir'===type)color = 'blue'; frdl.alert[('error'===type)?'error':'log']('<p><legend style="color:'+color+';">'+type+'</legend>'+util.inspect(result, opts)+'</p>'); frdl.cbs[c] = undefined; }catch(err){ console.warn(err); } }; } */ }, ' [CALLBACK]') .addOption('dir', 'Take a directory', function(name, value) { _CLI.data.DIRECTORIES.push(value); _CLI.emit('op.dir', value); }, ' [DIRECTORY]') .addOption('file', 'Take a file', function(name, value) { _CLI.data.FILES.push(value); _CLI.emit('op.file', value); }, ' [FILE]') /** _CLI.addOption('test', 'Run a test', function(name, value) { finalized=true; alert(name+'='+value); }, ' [TEXT]'); frdl.fs5.polyfill.getFiler().cd(frdl.fs5.polyfill.getFiler().fs.root); fs.mkdir(dir, '0755', function(err,dirEntry) { if(err){ console.warn(err); }else{ console.log('mdir ' + dir); } }); */ .addOption('mkdir', 'Create directory', function(name, value) { var fs = require('fs'); frdl.fs5.polyfill.getFiler().cd(frdl.fs5.polyfill.getFiler().fs.root); fs.mkdir(value, '0755', function(err,dirEntry) { if(err){ _CLI.error(err); }else{ _CLI.log('mdir ' + value); _CLI.emit('op.mkdir success', value); } }); _CLI.emit('op.mkdir', value); }, ' [TEXT]') .addOption('rmdir', 'Remove directory', function(name, value) { var fs = require('fs'); frdl.fs5.polyfill.getFiler().cd(frdl.fs5.polyfill.getFiler().fs.root); fs.rmdir(value, function(err,dirEntry) { if(err){ _CLI.error(err); }else{ _CLI.log('rmdir ' + value); _CLI.emit('op.rmdir success', value); } }); _CLI.emit('op.rmdir', value); }, ' [TEXT]') .addOption('unlink', 'Remove file', function(name, value) { var fs = require('fs'); frdl.fs5.polyfill.getFiler().cd(frdl.fs5.polyfill.getFiler().fs.root); fs.unlink(value, function(err,dirEntry) { if(err){ _CLI.error(err); }else{ _CLI.log('unlink ' + value); _CLI.emit('op.unlink success', value); } }); _CLI.emit('op.unlink', value); }, ' [TEXT]') .addToken('*', 'sql_close', function(c, result_length, token, current_option){ frdl.sql.query('COMMIT', function(err, data){ if(err){ console.error(err); return; } frdl.alert.log('Closing sql in 10 seconds...'); webfan.$Async(function(){ frdl.sql.close(); frdl.alert.log('sql closed-'); },10000); }); }) .addOption('sql_free', 'Free a sql table or database from memory', function(name, value) { frdl.sql.sql_free(value); }, ' [TEXT]') .addOption('api_url', 'Set api_url', function(name, value) { sessionStorage.setItem('api_url', value); }, ' [TEXT]') ; } //ende of !!defaults.standards _CLI.parser = parser = new optparse(_CLI.switches); _CLI.parser.banner = 'Usage: webfan.exe [[$|!#]shell] [arguments]'; _CLI.parser.halt(function(tokens) { return onHalt(tokens); }); _CLI.filter('CALLBACK', function(value) { var fTok = '()=>', fTok2 = '=>', t = false; if(fTok === value.substr(0,fTok.length)){ t = value.substr(fTok.length,value.length); }else if(fTok2 === value.substr(0,fTok2.length)){ t = value.substr(fTok2.length,value.length); } try{ return (!t && !!_CLI.util.isString(value) ) || ('string'===typeof t && !!_CLI.util.isFunction(eval(f(t))) ) ? value : undefined ; }catch(err){ if(0<frdl.debug.mode())console.warn(err); return (!t && !!_CLI.util.isString(value) ) ? value : undefined ; } }) .filter('SQLQUERY', function(value) { return value; }) .filter('DIRECTORY', function(value) { //value = _CLI.escapeshellarg (value); if(!frdl.nw)return value; var fs = require('fs'); var stats = fs.statSync(value); if(true !== stats.isDirectory()) throw "Directory "+value+' does not exist.'; return value; }) .filter('FILE', function(value) { // value = _CLI.escapeshellarg (value); if(!frdl.nw)return value; var fs = require('fs'); var stats = fs.statSync(value); if(true !== stats.isFile()) throw "File "+value+' does not exist.'; return value; }) .filter('SWITCH', function(value) { return _CLI.util.StringToBoolean(value); }) ; try{ var parse = function(argv){ frdl.each(_filtersToBuild, function(i, f){ _CLI.parser.filter(f[0], f[1]); }); _CLI.positionalSwitches.forEach(function($switch, $position, $switches){ _CLI.parser.on($position, $switch); }); var k; for(k in _sfn){ _CLI.parser.on(k, _sfn[k]); } frdl.each(_tokensToBuild, function(i, t){ _CLI.parser.token(t[0], t[1], t[2]); }); _CLI.parser.on('*', function(opt, value) { if(true === _CLI.options.debug)_CLI.log('Passing argument ' + opt + '=' + value); if(!_CLI.data.options[opt]){ _CLI.data.options[opt] = value; }else{ if(!_CLI.data.options[opt].length){ _CLI.data.options[opt] = [_CLI.data.options[opt]]; } _CLI.data.options[opt].push(value); } }); var pr = _CLI.parser.parse(_CLI.argv); _CLI.emit('parse', pr); return pr; }; _CLI.finalize = function(scope){ if('undefined' === typeof scope)var scope = _CLI; Finalize(scope, _CLI); }; if(!!doParse){ parse(_CLI.argv); }else{ _CLI.emit('parse', []); } }catch(err){ _CLI.error(err); } return _CLI; } exports = module.exports = _cli; }());