├── .gitignore
├── LICENSE
├── README.md
├── bower.json
├── docs
├── commands.md
├── design.md
├── env.md
├── extend.md
├── pinPannel.md
├── plugins.md
└── tabs.md
├── images
├── demo1.png
├── demo2.png
└── web-cli-demo.gif
├── lib
├── acli.css
└── acli.js
└── samples
├── basic
├── README.md
├── bower.json
├── console.js
└── index.html
└── plugins
├── README.md
├── api
└── someplugin.js
├── index.js
├── package.json
└── static
├── bower.json
├── console.js
├── index.html
└── plugins
├── someplugin.css
└── someplugin.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | node_modules
28 | bower_components
29 |
30 | # Optional npm cache directory
31 | .npm
32 |
33 | # Optional REPL history
34 | .node_repl_history
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2012 Saar Yahalom
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Anode Command Line Interface
2 | =============================
3 | ACLI is a command line interface, developed mainly for the use in the [anode project](http://anodejs.org).
4 |
5 | __A [Polymer](https://www.polymer-project.org/1.0/) control wrapping this component is now available [here](https://github.com/amiturgman/web-cli)__
6 |
7 | Why developing a new CLI component?
8 | -----------------------------------
9 | Before starting to work on this module, few other existing open source CLI (command line interface) components were evaluated, like
10 |
11 | * [GCLI](https://github.com/mozilla/gcli)
12 | * [JQuery Terminal](http://terminal.jcubic.pl/examples.php)
13 | * [JQuery Console](http://neocotic.com/jquery-console)
14 | * [JS Sandbox Console](http://josscrowcroft.github.com/javascript-sandbox-console)
15 | * and more...
16 |
17 | Each of the above components and the others that were examined had some of the required functionality, but did not support other features that we needed.
18 | The most suitable library for this task was the [GCLI](https://github.com/mozilla/gcli) component, which was the main inspiration for implementing ACLI, mostly at the area of the commands structure.
19 |
20 | Features
21 | --------
22 | * Manages environment variables and use them as part of the command line.
23 | * Supports plugins- remote commands integrated into the console, using [docRouter](https://github.com/anodejs/node-docrouter) metadata.
24 | Supporting plugins with client side processing and styling.
25 | * Keeps command line history, plugins and environment variables in offline storage.
26 | * _Pin Panel_ feature to keep command execution results on-screen.
27 | * Visualizes json data as an html table with auto collapsing deep elements.
28 | * Supports working in parallel with few instances/tabs of the console.
29 | * Supports broadcasting requests when working on a farm.
30 |
31 | __Extended documentation is available in the [docs](docs) folder__
32 |
33 | 
34 |
35 | 
36 |
37 | Getting Started
38 | ---------------
39 | The following is an example of how to quickly start using the component.
40 | See the `basic` sample under the `samples` directory.
41 |
42 | html file:
43 |
44 |
45 |
46 |
47 |
48 | js file:
49 |
50 | var cli = $(".cli-control").cli(
51 | {
52 | environment: {user: { type: 'string', value: '', description: 'The current user' }},
53 | commands: getCommands(),
54 | context: { some: 'object' },
55 | welcomeMessage: "Welcome to anode console! . Type help to start exploring the commands currently supported! "
56 | }
57 | );
58 |
59 | // create default commands
60 | function getCommands() {
61 | var commands = [];
62 |
63 | var addCommand = {
64 | name: 'add',
65 | description: 'add two numbers',
66 | usage: 'add num1 num2',
67 | example: 'add 4 5',
68 | params: [
69 | {
70 | name: 'num1',
71 | description: 'first number',
72 | type: 'number'
73 | },
74 | {
75 | name: 'num2',
76 | description: 'second number',
77 | type: 'number'
78 | }
79 | ],
80 | exec: function(args, context) {
81 | return args.num1 + args.num2;
82 | }
83 | }
84 |
85 | var asyncCommand = {
86 | name: 'async',
87 | description: 'simulates async command',
88 | usage: 'async [text]',
89 | example: 'async',
90 | params: [
91 | {
92 | name: 'text',
93 | description: 'some text to show',
94 | type: 'string',
95 | defaultValue: null // make this an optional argument
96 | }
97 | ],
98 | exec: function(args, context) {
99 | var promise = context.createPromise();
100 |
101 | // simulating some async long-processing action
102 | setTimeout(function(){
103 | var result = args.text || "you didn't enter text";
104 | promise.resolve(result);
105 | }, 1000);
106 |
107 | return promise;
108 | }
109 | }
110 |
111 | commands.push(addCommand);
112 | commands.push(asyncCommand);
113 |
114 | return commands;
115 | }
116 |
117 |
118 | Advanced Use
119 | ------------
120 | See `plugins` under `samples` folder for a node JS sample application that extends the console with commands from the server (plug-ins)!
121 |
122 |
123 | Main Requirements
124 | -----------------
125 | Main requirements and detailed design can be found in the [design](docs/design.md) file.
126 |
127 | Enjoy!
128 |
129 |
130 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "acli",
3 | "version": "0.0.12",
4 | "homepage": "https://github.com/amiturgman/aCLI",
5 | "authors": [
6 | "Ami Turgman "
7 | ],
8 | "description": "web based command line interface",
9 | "main": "lib/acli.js",
10 | "license": "MIT",
11 | "ignore": [
12 | "**/.*",
13 | "node_modules",
14 | "bower_components",
15 | "test",
16 | "tests"
17 | ],
18 | "dependencies": {
19 | "jquery": "2.2.4",
20 | "jquery-ui": "1.12.1",
21 | "query-object": "2.0.3",
22 | "underscore": "1.9.1",
23 | "urijs": "1.19.1"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/docs/commands.md:
--------------------------------------------------------------------------------
1 | Command Line
2 | ============
3 | Each command has its own format based on the command definition.
4 | A command may have a single action, such as the `log` command that gets logs, or multiple actions (sub-commands) such as the `pipeline` command (`pipeline trigger`, `pipeline rescore` and more).
5 | To see the list of parameters for a command, type `help commandName`, or `help commandName subCommand` for commands with more than one action.
6 | Typing `help command` on a command with more than one actions, will display the list of sub commands.
7 |
8 | Command Parameters
9 | ------------------
10 | Each command may define parameters, used by the command to execute an action.
11 | Each parameter defines
12 |
13 | * `name`- the name of the parameter.
14 | * `description`- short description for the parameter.
15 | * `type`- currently supporting `string`, `number` and `boolean` types.
16 | * an optional `default value`- if defined, the parameter is automatically considered as optional, otherwise it is required.
17 | * an optional `Default Environment Variable`- if defined, the environment variable defined will be used to get the value needed for the command. If it does not exist in the environment variables, the `default value` will be used as described above.
18 |
19 | Executing a Command
20 | -------------------
21 | To execute a command, simply type its name, ie. `log`. If the command has sub-commands, the name will be composed of the command name and the sub-command name, ie. `deploy status`.
22 | Following the command name, type the values for the command parameters, as described in the command's help parameters list.
23 |
24 | There are several ways to provide parameters to a command-
25 |
26 | * __By parameter index__- base on the order of the parameters defined for a command, type the command name and after that provide the values for each parameter, for example `log rp.sys warn anodejs.cloudapp.net` will match the `rp.sys` to the `app` parameter, the `warn` to the `level` parameter, and the `anodejs` to the `farm` parameter. Indexed values should always be provided first after the command name.
27 | * __By the parameter name__- base on the parameter's name, type `--`+parameter name to provide its value. This can be anywhere in the command line, but always after the indexed parameters values if provided.
28 | * __By the parameter switch__- base on the parameter's switch, type `-`+parameter switch to provide its value. This can be anywhere in the command line, but always after the indexed parameters values if provided.
29 |
30 | The following commands are equivalent:
31 |
32 | plugins install plugin1 api/plugin1/!! --persist
33 | plugins install --url api/plugin1/!! --name plugin1 -p
34 |
35 | * A `boolean` parameter is always optional and defaults to `false`.
36 | To set an optional parameter to `true`, simply add `--`+parameter name or `-`+parameter switch to the command line. No need to provide `true` after that.
37 | for example `set farm -c` or `set farm --clear` will clear the farm environment value, by setting the `clear` boolean parameter to `true`.
38 | * A string value containing space charachters can be provided by wrapping it with the `"` or `'` charachters as the following
39 |
40 | log --message "some text to filter"
41 | log --message 'some text to filter'
42 |
43 | Using Environment Variables
44 | ---------------------------
45 | Providing a value for a command line parameter is easy as typing `$`+environment variable name.
46 | For example, the following will use the `mytop` environment variable as a value for the log command
47 |
48 | set mytop 10
49 | log --top $mytop
50 |
51 |
--------------------------------------------------------------------------------
/docs/design.md:
--------------------------------------------------------------------------------
1 | Anode Command Line Interface
2 | =============================
3 | ACLI is a command line interface, developed mainly for the use in the anode project (link was removed since project is end-of-life).
4 |
5 | **This document content was mostly copied from the original [aCLI repository](https://github.com/amiturgman/aCLI)**
6 |
7 |
8 | Main Requirements
9 | -----------------
10 | In addition to the obvious requirements like adding commands, executing commands, command line history and so on, the following are the main requirements from this component
11 |
12 | 8. __Basic Commands__
13 | Basic implementation for the `help`, `clear`, `cls` commands should be available in the component.
14 |
15 | 2. __Command Response__
16 | A command can return any type of data like `html`, `text`, `json` or `jquery` object.
17 |
18 | 4. __Generic json view control__
19 | 1. Provide a generic json-view control that visualizes a json object as an html table, that will be used when commands return `json` object as the execution result.
20 | 2. The json view control will auto collapse data items that are deeper than a defined environment variable.
21 |
22 | 8. __Context__
23 | The prompt label which is the label on the left side of the input text box, will show the current context of the console.
24 | The context itself will be set by the code hosting acli, and will be copied to the results panel on each command execution to indicate the context in which the command was executed in.
25 |
26 | 1. __Manage environment variables__
27 | Using the known `set` command
28 | 1. Publish/Subscribe to environment variables `Change` event.
29 | 2. Use these variables as part of commands, using the `$` sign.
30 | 3. Define these variables as default values for command arguments.
31 | 4. User can define new environment variables.
32 | 5. User can not delete environment variables not created by him.
33 | 6. Environment variables can be _read-only_ to users, which means that the user will not be able to change them.
34 | 7. Environment variable can be defined to be auto added to web requests when executing commands.
35 |
36 | 5. __Persistency__
37 | 1. Command line history is persistent and loaded whenever the console is started, to reflect last history state.
38 | 2. Plugins should be persistent, allowing each developer to plug-in his own commands.
39 | 3. Environment variables should be persistent, and loaded when the console is started to reflect the last settings state.
40 |
41 | 3. __Extending the console with remote APIs exposing [docRouter](https://github.com/anodejs/node-docrouter) metadata__
42 | 1. Provide the ability to integrate server-side commands (plugins) exposing docRouter meta data into the console.
43 | 1. Plugins expose meta data with all required information for the console to compile it into a command.
44 | 2. Commands can be invoked using `GET` or `POST` methods.
45 | 3. Commands can define parameters that are sent as part of the `url template`, `query string` or in the `body`.
46 | 2. Plugin commands can return any type of value (json, html).
47 | 3. Plugin commands can define a client side handler method that will get the execution result and do some more processing before sending the result to be shown in the console.
48 | 4. Plugin commands can define their style classes, if they return `html` result by either providing the style classes as part of the meta data, or providing the url to a `css` file.
49 | 2. Manage plugins (install/uninstall) with persistency.
50 |
51 | 6. __Tabs__
52 | 1. A user will be able to work with few tabs _(sessions)_ of the console in parallel.
53 | 2. All persistent data is stored per session.
54 | 3. Sessions(and their persistent data) can be restored easilty based on the session id.
55 | 4. Session can be created by opening a new browser tab, or by a programatically initialize another `acli` jquery plugin, with a new session id.
56 |
57 | 7. __Broadcast requrests__
58 | [anode](http://anodejs.org) hosts its apps on top of azure, distributing the apps runing on top of it to all servers on the farm.
59 | We need a way to invoke requests to all instances of the farm, collect the data and present it after it is collected.
60 | This feature will mostly be used when collecting performance statistics, when we want to know the state of the app on all servers all together, and so.
61 |
62 | 8. __Docker panel__
63 | Sometimes, we would want to keep some of the results in front of us, rather than let them scroll out of the window and disapear.
64 | We need a way to dock such desired command results to keep them _always on_ screen.
65 |
66 | Design Solution
67 | ---------------
68 | The `web-cli` component is a Polymer component wrapping the aCLI jquery plugin.
69 | The following option arguments may be provided when initializing the plugin:
70 |
71 | * `environmentVars`- a collection of a pre-defined set of environment variables.
72 | * `plugins`- a collection of a pre-defined urls for plugins to load.
73 | * `commands`- a collection of client-sode commands to add to the console.
74 | * `welcomeMessage`- a message that will appear whenever the console starts.
75 |
76 | The following is an example for a basic initialization:
77 |
78 |
79 |
80 |
81 | corpus to graph admin console
82 |
83 |
84 |
89 |
90 |
91 |
92 |
93 |
199 |
200 |
201 |
202 | Web-cli API
203 | --------
204 | The following APIs are exposed to the application hosting the component:
205 |
206 | * `env(setting, val, appOriginated, isEmpty)`- used to control the environment variables.
207 | When called with no parameters, returns a copy of the current variables collection.
208 | * `setting`- the name of the environment variable. When this is the only parameter that is passed, this is a `get` action which returns the variable value.
209 | * `val`- the value of the environment variable. Used to set an existing environment variable or create a new one.
210 | * `appOriginated`- applicative flag indicating whether the environment value was set by the application code or by the user. This is used to prevent users from changing _read-only_ environment variables.
211 | * `isEmpty`- applicative flag indicating if the value should be set to an empty value.
212 | * 'addEventListener'- listening for events emmited by the control, for example- `envChanged` event
213 |
214 | var webCli = $('web-cli')[0];
215 | webCli.addEventListener('envChanged', function(e) {
216 | console.log('envChanged!', e.detail);
217 | updatePrompt();
218 | });
219 |
220 | * `prompt(val)`- used to change the cli's prompt value.
221 |
222 | Commands
223 | --------
224 |
225 | ### Writing a command
226 |
227 | A command contains the following properties:
228 |
229 | * `name`- the name of the command. When a command is part of a group of commands, the name of the command will be preceded by the group name : 'commandGroupName commandName' (example in the above code).
230 | * `description`- description of the command, which will be displayed when the user view the command help.
231 | * `usage`- description of how to use the command.
232 | * `example`- an example of a concrete command execution.
233 | * `params`- a hash of parameters the command supports (detailed explanation later).
234 | * `exec`- the function that will be called when the command was invoked by the user, passing the parsed arguments and context.
235 | * `hidden`- boolean value indicates whether the command is listed when runing `help`.
236 |
237 | #### The _params_ property
238 | Each parameter defines the following properties:
239 |
240 | * `name`- the name of the parameter.
241 | * `short`- an optional switch that will be used to reference the parameter.
242 | * `description`- description for the parameter.
243 | * `type`- the type of the parameter, now supporting `string`, `number` and `boolean`.
244 | * `defaultValue`- a default value for an argument, in case it was not provided in the command line
245 | __Notes__
246 | * `boolean` parameter always defaults to `false` and ignores `defaultValue` property.
247 | * A parameter with no `defaultValue` is considered as `required`, while by providing a `defaultValue`, a parameter is considered as `optional`.
248 |
249 | #### The _exec_ method
250 | The exec method is the handler that is called to handle the command execution, and have two arguments:
251 |
252 | * `args`- a collection of the arguments and their values, after parsing the command line and validating their type.
253 | * `context`- contains the following objects and methods
254 | * `appcontext`- the context that the `cli` component was initialized with.
255 | * `command`- a copy of the command object.
256 | * `env`- a copy of the environment variables collection.
257 | * `createPromise`- returns an object that supports long-processing/async commands, contains the following methods
258 | * `setProgress(progress)`- sets an indicator with a number in the range [0, 100] to indicate the progress.
259 | * `resolve(result)`- when the process completes, this methods trasfers the final result to be displayed on the results panel.
260 | The result can be `text`, `html`, `jquery object` which will be displayed as is, or a `json` object which will be displayed using a generic internal json-view control.
261 | * `scrollDown()`- scrolls the console to the bottom of the screen.
262 |
263 | #### Group of commands
264 | To add a group of commands, we define a virtual _parent_ command, containing the group command name, and then all the sub-commands' name, will be preceeded by the group command name.
265 | The following is an example for a group command with two subcommands:
266 |
267 | // this is a group of commands, under the `group` name
268 | var groupCommand = {
269 | name: 'group',
270 | description: 'some group command'
271 | }
272 | var subCommand1 = {
273 | name: 'group command1',
274 | description: 'first command in group',
275 | usage: 'group command [param]',
276 | example: 'group command someParamValue',
277 | params: [{
278 | name: 'param',
279 | type: 'string',
280 | defaultValue: null // make it optional argument
281 | }],
282 | exec: function(args, context) {
283 | return args.param || 'param not provided';
284 | }
285 | }
286 | var subCommand2 = {
287 | name: 'group command2',
288 | description: 'second command in group',
289 | usage: 'group command2',
290 | example: 'group command2',
291 | exec: function(args, context) {
292 | return 'no parameters here, hello from exec method!';
293 | }
294 | }
295 |
296 | // add commands to array
297 | commands.push(groupCommand);
298 | commands.push(subCommand1);
299 | commands.push(subCommand2);
300 |
301 | The following command will be used in further discussions and examples. It is also part of the basic sample package.
302 |
303 | var sampleCommand = {
304 | name: 'sample',
305 | description: 'Sample command',
306 | usage: 'sample [requiredString1] [requiredString2] [requiredNumber1] [optionalNumber1] [optionalNumber2]',
307 | example: 'sample aa bb 444 333 -l ffff -r',
308 | params: [
309 | {
310 | name: 'requiredString1',
311 | description: 'required string 1',
312 | type: 'string'
313 | },
314 | {
315 | name: 'requiredString2',
316 | description: 'required string 2',
317 | type: 'string'
318 | },
319 | {
320 | name: 'requiredNumber1',
321 | description: 'required number 1',
322 | type: 'number'
323 | },
324 | {
325 | name: 'optString1',
326 | description: 'optional string 1',
327 | type: 'string',
328 | defaultValue: 'optString1'
329 | },
330 | {
331 | name: 'optString2',
332 | short: 'a',
333 | description: 'optional string 2',
334 | type: 'string',
335 | defaultValue: 'optString2'
336 | },
337 | {
338 | name: 'optionalNumber1',
339 | short: 'b',
340 | description: 'optional number 1',
341 | type: 'number',
342 | defaultValue: 1234
343 | },
344 | {
345 | name: 'optionalNumber2',
346 | short: 'c',
347 | description: 'optional number 2',
348 | type: 'number',
349 | defaultValue: 222
350 | },
351 | {
352 | name: 'optionalNullNumber',
353 | short: 'd',
354 | description: 'optional null number 1',
355 | type: 'number',
356 | defaultValue: null
357 | },
358 | {
359 | name: 'switchBool1',
360 | short: 'e',
361 | description: 'boolean switch',
362 | type: 'boolean'
363 | },
364 | {
365 | name: 'switchBool2',
366 | short: 'f',
367 | description: 'boolean switch',
368 | type: 'boolean'
369 | }
370 |
371 | ],
372 | exec: function(args, context) {
373 | return "sample command args: " + JSON.stringify(args);
374 | }
375 | }
376 |
377 | ### Displaying a command execution result
378 |
379 | Text, html or jquery objects returned from command execution methods are automatically added to a container that was pre-allocated for the
380 | command execution and was placed on the DOM where we would expect the result to be displayed.
381 | This cli should also support `json` result (hash object) to be returned from a command execution method. In this case, a generic json-view control should display the json object.
382 |
383 | The json-view control logic:
384 |
385 | * for each property, create a new table line with a name and value cells.
386 | * if the value is another hash object, it recursively calls the same method for the value and displays the result table in the value cell, otherwise, it prints the value.
387 |
388 | In addition to that, there's a pre-defined environment variable called `jsonViewCollapseLevel` which can be set, and controls the level of depth,
389 | after which the results in a json-view control are collapsed automatically.
390 |
391 | ### Executing a command
392 |
393 | To execute a command, simply type its name, ie. `clear`. If the command has sub-commands, the name will be composed of the command name and the sub-command name, ie. `GroupCommandName subCommand`.
394 | Following the command name, type the values for the command parameters, as described in the command's help parameters list.
395 |
396 | There are several ways to provide parameters to a command-
397 |
398 | * __By parameter index__- base on the order of the parameters defined for a command, type the command name and after that provide the values for each parameter, for example `sample aa bb 444` will match the `aa` to the `requiredString1` parameter, the `bb` to the `requiredString2` parameter, and the `444` to the `requiredNumber1` parameter. __Indexed values should always be provided first after the command name__.
399 | * __By the parameter name__- base on the parameter's name, type `--`+parameter name to provide its value. This can be anywhere in the command line, but always after the indexed parameters values if provided.
400 | * __By the parameter switch__- base on the parameter's switch, type `-`+parameter switch to provide its value. This can be anywhere in the command line, but always after the indexed parameters values if provided.
401 |
402 | The following commands are equivalent:
403 |
404 | sample aa bb 444 cc -e --optionalNumber1 10 --switchBool2
405 | sample aa bb 444 -b 10 --optString1 cc -e -f
406 | sample aa bb --requiredNumber1 444 -b 10 --optString1 cc -e -f
407 |
408 | * A `boolean` parameter is always optional and defaults to `false`.
409 | To set an optional parameter to `true`, simply add `--`+parameter name or `-`+parameter switch to the command line. No need to provide `true` after that.
410 | for example `set envParam -c` or `set envParam --clear` will clear the envParam environment value, by setting the `clear` boolean parameter to `true`.
411 | * A string value containing space charachters can be provided by wrapping it with the `"` or `'` charachters as the following
412 |
413 |
414 | sample 'string 1' "string 2" 444
415 |
416 |
417 | ### Live command
418 | When executing commands, you can use the `live` system flag to keep refreshing the command's result every few seconds.
419 | `live` is a special flag that can be used with all commands.
420 | To use it, add `---live x` where `x` is the number of seconds between each refresh.
421 | The number of times the command refreshes itself is defined in the `liveIterationsCount` environment variable.
422 | Change this variable to control the number of times the command refreshes itself.
423 |
424 | pipeline status ---live 5
425 |
426 |
427 | Environment
428 | -----------
429 | The console maintains environment variables, used to control its behaviour as well as by the different commands.
430 | The following list is the current predefined environment variables designed to be included in the cli:
431 |
432 | * `maxResults` used to control the max number of results being displayed.
433 | * `maxHistory` used to control the max number of commands kept in history.
434 | * `jsonViewCollapseLevel` used to control the level of depth after which the result in a json-view control are collapsed automatically.
435 | * `liveIterationsCount` used to control the number of command refreshes when using the `---live` flag.
436 |
437 | ### Managing environment variables
438 | The idea is to use the known `set` command from other consoles. For that, an internal `set` command will be implemented in the cli component.
439 | The `set` command will work in 3 modes, _list_, _set_ and _get_:
440 | * `set`- get list of all existing environment variables
441 | * `set varname varvalue`- create a new environment variables `varname` and set it to `varvalue`.
442 | * `set varname`- display the current value of `varname`.
443 |
444 | More options in the `set command`
445 | * use `set varname -c`, `set varname --clear` or `set varname ''` to clear an environment variable.
446 | * use `set varname -d` or `set varname --delete` to remove an environment variable from the list.
447 | * use `set -r` or `set --restore` to restore the environment variables collection to the original values.
448 | * use `set -o` or `set --online` to get a settings panel that gets updated online when an environment variable is changed.
449 | * use `set -x` or `set --extend` to get an extended version of the settings collection.
450 |
451 | ### Environment variables as inputs for the command line
452 | Environment variables will also be used as inputs for a command line parameter values.
453 | For example, the following will use the `str1` environment variable as a value for the `sample` command
454 |
455 | set str1 "some string"
456 | sample $str1 "string 2" 444
457 |
458 | ### Environment Variables Options
459 | When the cli is initialized, a pre-defined set of environment variables can be provided. Each of the environment variable can contain the following properties:
460 |
461 | * `type`- one of the following `string`, `number` or `boolean`.
462 | * `value`- the initial value.
463 | * `description`- short description for the use of this variable.
464 | * `options`- an array of valid options which will be validated before changing the setting value, mostly used with `string` variables.
465 | * `min`- minimum value for a `number` variable.
466 | * `max`- maximum value for a `number` variable.
467 | * `userReadOnly`- indicates that the user will not be able to change the value of this setting, and its value is managed by the application itself.
468 | * `useAtQuery`- indicates that the value, if not empty or null, will be added to the query string when calling a plugin API via a web request.
469 |
470 | ### Persistency
471 | The environment variables will be persistent. Whenever the console is started, the environment variables will be initialized with the last state from the
472 | browser's local storage.
473 |
474 | ### Context
475 | It is reasonable that the console's context will be dependant on the environment values.
476 | For that, after the application starts the cli component, it will be able to register for environment settings state change events, and then construct the `prompt` label based on them.
477 | The above code shows an example for doing this.
478 |
479 |
480 | Tabs / Sessions and Persistency
481 | -------------------------------
482 | As any other jQuery component, ACLI should support initializing few parallel controls at the same time, on the same page.
483 | Since the component persists its state (command line history, environment variables and plugins data) in the browser's local storage, it needs a way to partition this data per each component instance.
484 | For that, when initializing a component, we can transfer a unique `sid` options variable for each instance, and it will be used to partition the offline storage data.
485 | This will be mostly used when creating few instances of the component on the same page.
486 |
487 | In addition to that, in cases that there's only one ACLI component initialized on a page, the component will support an internal command named `tab`
488 | that will use a new browser tab for creating a new session, passing the session id value as part of the command.
489 | The new page will look for the value provided in the query string, and use this value for partitioning the offline data as described above.
490 | Having this value on the query string, gives the developer the option to keep the session in his browser's favourites, and create different sessions for different applications.
491 |
492 |
493 | Docking Elements
494 | ----------------
495 | Sometimes, we want to keep command execution results on screen. For that, a panel called `Pin Panel` is implemented.
496 | An example for such use is the `set --online` command that results in the environment variables table, which is updated on every environment state change.
497 | The internal command `panel` will toggle the _Pin Panel_, which will be positioned on the right side of the screen.
498 |
499 | There should be two ways of docking items in the _Pin Panel_:
500 | * run `panel --pin` to take the last command result and move it into the _Pin Panel_.
501 | * _experimental_- use the `CTRL` + mouse double click to make any command result draggable, and then drag it into the _Pin Panel_.
502 |
503 | To remove an item from the _Pin Panel_, `CTRL` + mouse double click the item.
504 |
505 | Clicking the _Pin Panel_ title, will maximize/minimize the panel, while keeping it on screen.
506 | To close _Pin Panel_, click the `X` button, that will appear when hovering the panel.
507 |
508 | An example:
509 |
510 | panel
511 | set --online
512 | panel --pin
513 |
514 |
515 | Plugins
516 | -------
517 | The console will enable extending it with commands generated out of metadata defined by the docRouter decorating a server side API.
518 |
519 | The sample package contains a `plugins` directory, with a _node_ application, using ACLI and extending it with a `someplugin` command.
520 | run `node index.js` and navigate your browser to `localhost:4000`, which will open the command line.
521 |
522 | The following scenarios and examples are taken from the sample application:
523 |
524 | ### Adding Simple Commands
525 |
526 | Simple commands are commands that get parameters and return json/html to be displayed in the console as a result of executing the command with the provided parameters.
527 | These commands do not require any client side logics. They are called by the console with the neccessary parameters provided, process the request and return the __final__ result which is displayed as is.
528 | A command that returns a `json` result, will use a generic json-view control to display the object, any other result will be displayed as is (`html`).
529 |
530 | In this manual we will refer to the `someplugin.js` file as an example to extending the console.
531 |
532 | As can be seen, the file begins with the docRouter definition:
533 |
534 | app.use(docRouter(app, '/api/someplugin', function(app) {
535 |
536 |
537 | Each method in the api file defines
538 |
539 | * a Verb- `GET` or `POST`- The console uses this info to invoke the method
540 | * a set of parameters- Parameters are optional. Each parameter defines its
541 | * `type`- The parameter type: `string`, `int`, `bool`.
542 | * `required`- `true`/`false`.
543 | * `style`- `template`- this parameter is expected to be provided as part if the url, `query`- as part of the querystring or `body`- as part of the post body.
544 | * `short`- an optional switch that will be used to refer that parameter in the command line.
545 | * `defaultValue`- a value that will be used if the parameter was not provided as part of the command line. In this case, the value is automatically considered as an optional parameter.
546 | * `defaultEnvVar`- defines an environment variable parameter name that will be used as a default value if the parameter was not provided. If it does not exist or empty, the default value will be used if provided as described above.
547 |
548 | #### Sample 1:
549 |
550 | The following is an example for a command that gets 3 parameters: `tparam1` and `tparam2` which are defined as a `template` parameters, and `qparam` which is defined as a `qurtystring` parameter.
551 | The `tparam2` parameter has a `defaultValue` set, which means that as far of the console's concern, this is an optional parameter that will get the value provided in the `defaultValue` if not provided
552 | in the command line.
553 |
554 | app.get('/json/:tparam1/:tparam2', function(req, res) {
555 | var tparam1 = req.params.tparam1;
556 | var tparam2 = req.params.tparam2;
557 | var qparam = req.query['qparam'];
558 |
559 | var o = {tparam1: tparam1, tparam2: tparam2, qparam: qparam};
560 | res.writeHead(200, {'Content-Type': 'application/json' });
561 | res.end(JSON.stringify(o));
562 | },
563 | {
564 | id: 'sample_json',
565 | name: 'json',
566 | usage: 'json tparam1 qparam [tparam2]',
567 | example: 'json tparam1 qparamValue',
568 | doc: 'sample for a GET command getting template params and a query param',
569 | params: {
570 | "tparam1" : {
571 | "short": "b",
572 | "type": "string",
573 | "doc": "template param",
574 | "style": "template",
575 | "required": "true"
576 | },
577 | "qparam" : {
578 | "short": "q",
579 | "type": "string",
580 | "doc": "querty string param",
581 | "style": "query",
582 | "required": "true"
583 | },
584 | tparam2 : {
585 | "short": "a",
586 | "type": "string",
587 | "doc": "template param",
588 | "style": "template",
589 | "required": "true",
590 | "defaultValue": "someTemplateValue"
591 | }
592 | }
593 | }
594 | );
595 |
596 |
597 | * The following command: `someplugin json 1 2` calls `GET /api/someplugin/json/1/someTemplateValue?qparam=2` and returns the result `{"tparam1":"1","tparam2":"someTemplateValue","qparam":"2"}`.
598 | * The following command: `someplugin json 1 2 3` calls `GET /api/someplugin/json/1/3?qparam=2` and returns the following result `{"tparam1":"1","tparam2":"3","qparam":"2"}`.
599 |
600 | __Required parameters should always be provided at the begining of the command__
601 |
602 | #### Sample 2:
603 |
604 | The following `someplugin html` command defines a required body parameter `bparam` and also an optional boolean parameter `flag`.
605 | Boolean parameters are always considered as optional and defaults to `false`. To set them to `true`, we should only add them to the command line.
606 | Notice that this time, the method uses the `POST` verb, and that the `bparam` parameter will be sent as part of the request's body.
607 |
608 | app.post('/html', function(req, res) {
609 | var flag = req.query.flag;
610 | res.writeHead(200, {'Content-Type': 'text/html' });
611 | res.end("
HTML output: Template Param: "+req.params.tparam+
612 | " Flag: " + flag +"
`.
641 | * The following command: `someplugin html 1` calls `/api/someplugin/html` with a body `{bparam: 1}` and returns the following result `
HTML output: Template Param: 1 Flag: undefined
`.
642 |
643 |
644 | ### Advanced Commands
645 |
646 | Commands that need any processing on the client side, are considered as advanced commands.
647 | Such commands may be for example, commands that get `json` and present charts, or any other command that gets the results and make some further processing before displaying it to the user.
648 |
649 | Advanced command will define a `controller` attribute, in which a javascript file and a handler method name will be set.
650 | The following `sample handler` command, will get two parameters, and the returned result will be transfered to the `handler` method in the `/plugins/someplugin.js` file.
651 | The `controller.handler` attribute is optional and will override the default handler name which is the command name if defined.
652 |
653 |
654 | app.get('/handler/:tparam', function(req, res) {
655 | var tparam = req.params.tparam;
656 | var qparam = req.query['qparam'];
657 |
658 | var o = {tparam: tparam};
659 | res.writeHead(200, {'Content-Type': 'application/json' });
660 | res.end(JSON.stringify(o));
661 | },
662 | {
663 | id: 'sample_handler',
664 | name: 'handler',
665 | usage: 'handler',
666 | example: 'handler',
667 | doc: 'sample for a GET command using external handler',
668 | params: {
669 | "tparam" : {
670 | "short": "t",
671 | "type": "string",
672 | "doc": "template param",
673 | "style": "template",
674 | "required": "true"
675 | }
676 | },
677 | controller: {
678 | url: '../../plugins/someplugin.js',
679 | handler: 'handler' // this is optional, the default will be the command name
680 | }
681 | }
682 | );
683 |
684 | The following is the `/plugins/someplugin.js` file.
685 |
686 | console.info('sample handler loaded');
687 |
688 | this.handler = function(error, response){
689 | if ($.query.get('debug')) debugger;
690 | var args = response.args;
691 | var context = response.context;
692 | var url = context.url;
693 | var env = context.env;
694 | var command = context.command;
695 | var data = response.data;
696 |
697 | var progress = 0;
698 | var intrvl = setInterval(function(){
699 | response.promise.setProgress(progress);
700 | if(progress==100) {
701 | clearInterval(intrvl);
702 | response.promise.resolve(
703 | $("
").addClass('anode-sample').html(
704 | 'this is the client side plugin handler speaking.. got the following parametrs:' + JSON.stringify(args) +
705 | '. got the following response: ' + JSON.stringify(data)));
706 | }
707 | progress+=10;
708 | }, 200);
709 | }
710 |
711 | When the script is loaded, it is wrapped in a function and called with a `call` method, providing the context object. All handlers will be added to this context when executing the wrapped code.
712 | Since the script is loaded dynamically, you wan't be able to see it in the developer tools of Chrome/FireFox. One solution for this issue, is adding `if ($.query.get('debug')) debugger;`
713 | statement to the begining of the method, and load the console with `?debug` at the query string. This will make the browser to stop at this line and allow you to debug it.
714 | When the script is loaded, it is attached as the command execute method.
715 | When the console calls this method, it will pass an `error` and a `response` object.
716 | The `response` object contains the following parameters:
717 |
718 | * `args`- contains all arguments provided as part of the command line.
719 | * `data`- contains the data returned from the api call.
720 | * `promise`- an object that helps us manage the command response. This object contains the following methods:
721 | * `setProgress(percent)`- set a percentage indicator, use when the processing might be long and we would like to update the user on the progress that is made.
722 | * `resolve(res)`- used to end the command processing by passing the final result to the console. The result may be any string or html element.
723 | * `context`- contains command execution related objects such as
724 | * `url`- the url that was called .
725 | * `env`- a copy of the environment variable collection (so it won't be able to change it).
726 | * `command`- a copy of the command object if there's any need for details from it.
727 |
728 | Try executing `someplugin handler val` to see how it behaves.
729 |
730 | ### Adding A Command Custom Style
731 |
732 | If the controller needs any special stylesheet, on the server side, use the `cssUrl` or the `css` attributes as can be seen in the sample file for the `htmlbcast` and `handler` commands.
733 |
734 | controller: {
735 | css: '.anode-sample-class{ background-color: green; }'
736 | }
737 |
738 | controller: {
739 | url: '../../plugins/someplugin.js',
740 | cssUrl: '../../plugins/someplugin.css'
741 | }
742 |
743 |
744 | __Note:__ It is very important to namespace your css classes to avoid impact on other elements in the DOM. In the example above, the style is namespaced with the `anode-sample` class.
745 |
--------------------------------------------------------------------------------
/docs/env.md:
--------------------------------------------------------------------------------
1 | Environment Variables
2 | =====================
3 | The console maintains environment variables, used to control its behaviour as well as by the different commands.
4 | The following list is the current predefined environment variables, type `set` to see it:
5 |
6 | * `maxResults` used to control the max number of results being displayed.
7 | * `maxHistory` used to control the max number of commands kept in history.
8 | * `jsonViewCollapseLevel` used to control the level of depth after which the result in a json-view control are collapsed automatically.
9 | * `liveIterationsCount` used to control the number of command refreshes when using the `---live` flag.
10 | * `app` defines the application on which we would like to act upon; used by most of the app-related commands as a default value.
11 |
12 | Console's Context
13 | -----------------
14 | The prompt label on the left side of the command line, is the __context__ of the commands invoked.
15 |
16 | For example, a command which defines a required parameter named `app`, will automatically use the value
17 | from the environment variable if available, without the need to provide it as part of the command line.
18 | If the environment variable is not present or contains an empty value, a value will have to be provided
19 | as part of the command line.
20 |
21 | `
22 | There's currently no validations for the environment values.
23 | `
24 |
25 | Adding Environment Variables
26 | ----------------------------
27 | You can create new environment variables by simply typing `set name value`.
28 | Using environment values as part of a command is easy as typing `$varname`, for example `log --top $mytop` will use the `mytop` value from
29 | the environment variable when parsing and executing the command.
30 |
31 | Managing Environment Variables
32 | ------------------------------
33 | Type `set varname -c`, `set varname --clear` or `set varname ''` to clear an environment variable.
34 | Type `set varname -d` or `set varname --delete` to remove an environment variable from the list.
35 | Type `set -r` or `set --restore` to restore the environment variables collection to the original values.
36 |
37 | Persistency
38 | -----------
39 | The environment variables are persistent. Whenever the console is started, the environment variables are initialized with the last state from the
40 | browser's local storage, keeping the context used last time.
41 |
42 |
--------------------------------------------------------------------------------
/docs/extend.md:
--------------------------------------------------------------------------------
1 | Extending The Console
2 | =====================
3 | __Extending the console is easy!__
4 |
5 | The console uses metadata defined by the docRouter module to generate the commands.
6 | In order to create another command, add a new file under the `repo/sys/console/api` folder. The command will be named after the new api file name.
7 |
8 | The api file should expose the following structure:
9 |
10 | module.exports = { console: { autoLoad: true, router: expressRouter } };
11 |
12 | When the `autoLoad` flag is set to `true`, it will make the plugin to be automatically integrated into the console when it is started.
13 | The `router` parameter is the express `router` object. Look at the api files for an example of how the apis are exposed.
14 |
15 | Each API can contain any number of commands, all namespaced by the api file name. The console will generate a command for each of the methods in the api file.
16 | To execute a method (command), type the api file name and then the method name. ie, to execute `command1` in file `api1`, type `api1 command1` and then provide the params if required.
17 |
18 | Adding Simple Commands
19 | ----------------------
20 | Simple commands are commands that get parameters and return json/html to be displayed in the console as a result of executing the command with the provided parameters.
21 | These commands do not require any client side logics. They are called by the console with the neccessary parameters provided, process the request and return the __final__ result which is displayed as is.
22 | A command that returns a `json` result, will use a generic json-view control to display the object, any other result will be displayed as is (`html`).
23 |
24 | Most of the commands currently implemented are _simple_ commands.
25 |
26 | In this manual we will refer to the `sample.js` file as an example to extending the console.
27 |
28 | As can be seen, the file begins with the docRouter definition, defining `/api/sample` as the root for this api:
29 |
30 | docRouter(router, '/api/sample', function (router) {
31 |
32 |
33 | Each method in the api file defines
34 |
35 | * a Verb- `GET` or `POST`- The console uses this info to invoke the method
36 | * a set of parameters- Parameters are optional. Each parameter defines its
37 | * `type`- The parameter type: `string`, `int`, `bool`.
38 | * `required`- `true`/`false`.
39 | * `style`- `template`- this parameter is expected to be provided as part if the url, `query`- as part of the querystring or `body`- as part of the post body.
40 | * `short`- an optional switch that will be used to refer that parameter in the command line.
41 | * `defaultValue`- a value that will be used if the parameter was not provided as part of the command line. In this case, the value is automatically considered as an optional parameter.
42 | * `defaultEnvVar`- defines an environment variable parameter name that will be used as a default value if the parameter was not provided. If it does not exist or empty, the default value will be used if provided as described above.
43 | An example to using this option can be found in the `log.js` api file.
44 |
45 |
46 | Sample 1:
47 | ---------
48 | The following is an example for a command that gets 3 parameters: `tparam1` and `tparam2` which are defined as a `template` parameters, and `qparam` which is defined as a `qurtystring` parameter.
49 | The `tparam2` parameter has a `defaultValue` set, which means that as far of the console's concern, this is an optional parameter that will get the value provided in the `defaultValue` if not provided
50 | in the command line.
51 |
52 | app.get('/json/:tparam1/:tparam2', function(req, res) {
53 | var tparam1 = req.params.tparam1;
54 | var tparam2 = req.params.tparam2;
55 | var qparam = req.query['qparam'];
56 |
57 | var o = {tparam1: tparam1, tparam2: tparam2, qparam: qparam};
58 | res.writeHead(200, {'Content-Type': 'application/json' });
59 | res.end(JSON.stringify(o));
60 | },
61 | {
62 | id: 'sample_json',
63 | name: 'json',
64 | usage: 'json tparam1 qparam [tparam2]',
65 | example: 'json tparam1 qparamValue',
66 | doc: 'sample for a GET command getting template params and a query param',
67 | params: {
68 | "tparam1" : {
69 | "short": "b",
70 | "type": "string",
71 | "doc": "template param",
72 | "style": "template",
73 | "required": "true"
74 | },
75 | "qparam" : {
76 | "short": "q",
77 | "type": "string",
78 | "doc": "querty string param",
79 | "style": "query",
80 | "required": "true"
81 | },
82 | tparam2 : {
83 | "short": "a",
84 | "type": "string",
85 | "doc": "template param",
86 | "style": "template",
87 | "required": "true",
88 | "defaultValue": "someTemplateValue"
89 | }
90 | }
91 | }
92 | );
93 |
94 |
95 | * The following command: `sample json 1 2` calls `GET /api/sample/json/1/someTemplateValue?qparam=2` and returns the result `{"tparam1":"1","tparam2":"someTemplateValue","qparam":"2"}`.
96 | * The following command: `sample json 1 2 3` calls `GET /api/sample/json/1/3?qparam=2` and returns the following result `{"tparam1":"1","tparam2":"3","qparam":"2"}`.
97 |
98 | __Required parameters should always be provided at the begining of the command__
99 |
100 | Sample 2:
101 | ---------
102 | The following `sample html` command defines a required bosy parameter `bparam` and also an optional boolean parameter `flag`.
103 | Boolean parameters are always considered as optional and defaults to `false`. To set them to `true`, we should only add them to the command line.
104 | Notice that this time, the method uses the `POST` verb, and that the `bparam` parameter will be sent as part of the request's body.
105 |
106 | app.post('/html', function(req, res) {
107 | var flag = req.query.flag;
108 | res.writeHead(200, {'Content-Type': 'text/html' });
109 | res.end("
HTML output: Template Param: "+req.params.tparam+
110 | " Flag: " + flag +"
`.
139 | * The following command: `sample html 1` calls `/api/sample/html` with a body `{bparam: 1}` and returns the following result `
HTML output: Template Param: 1 Flag: undefined
`.
140 |
141 | Advanced Commands
142 | =================
143 | Commands that need any processing on the client side, are considered as advanced commands.
144 | Such commands may be for example, commands that get `json` and present charts, or the current log command that gets the results and make some further processing before displaying it to the user.
145 |
146 | Advanced command will define a `controller` attribute, in which a javascript file and a handler method name will be set.
147 | The following `sample handler` command, will get two parameters, and the returned result will be transfered to the `handler` method in the `/plugins/sample.js` file.
148 | The `controller.handler` attribute is optional and will override the default handler name which is the command name if defined.
149 |
150 |
151 | app.get('/handler/:tparam', function(req, res) {
152 | var tparam = req.params.tparam;
153 | var qparam = req.query['qparam'];
154 |
155 | var o = {tparam: tparam};
156 | res.writeHead(200, {'Content-Type': 'application/json' });
157 | res.end(JSON.stringify(o));
158 | },
159 | {
160 | id: 'sample_handler',
161 | name: 'handler',
162 | usage: 'handler',
163 | example: 'handler',
164 | doc: 'sample for a GET command using external handler',
165 | params: {
166 | "tparam" : {
167 | "short": "t",
168 | "type": "string",
169 | "doc": "template param",
170 | "style": "template",
171 | "required": "true"
172 | }
173 | },
174 | controller: {
175 | url: '../../plugins/sample.js',
176 | handler: 'handler' // this is optional, the default will be the command name
177 | }
178 | }
179 | );
180 |
181 | The following is the `/plugins/sample.js` file.
182 | The `anode.loadCss` and `anode.addCss` are discussed later on in the _Adding A Command Custom Style_ section.
183 |
184 | console.info('sample handler loaded');
185 |
186 | // the following 2 lines are possible. in this case, the css are defined on the server side
187 | //anode.loadCss('plugins/sample.css');
188 | //anode.addCss(".anode-sample {width: 300px;border: 1px solid gray;background-color: rgba(236, 255, 117, 0.60);padding: 4px;}")
189 |
190 | // anode will always be in the global context in this stage as this script always loaded after anode is already initialized
191 | this.handler = function(error, response){
192 | if ($.query.get('debug')) debugger;
193 | var args = response.args;
194 | var context = response.context;
195 | var url = context.url;
196 | var env = context.env;
197 | var command = context.command;
198 | var data = response.data;
199 |
200 | var progress = 0;
201 | var intrvl = setInterval(function(){
202 | response.promise.setProgress(progress);
203 | if(progress==100) {
204 | clearInterval(intrvl);
205 | response.promise.resolve(
206 | $("
").addClass('anode-sample').html(
207 | 'this is the client side plugin handler speaking.. got the following parametrs:' + JSON.stringify(args) +
208 | '. got the following response: ' + JSON.stringify(data)));
209 | }
210 | progress+=10;
211 | }, 200);
212 | }
213 |
214 | When the script is loaded, it is wrapped in a function and called with a `call` method, providing the context object. All handlers will be added to this context when executing the wrapped code.
215 | Since the script is loaded dynamically, you wan't be able to see it in the developer tools of Chrome/FireFox. One solution for this issue, is adding `if ($.query.get('debug')) debugger;`
216 | statement to the begining of the method, and load the console with `?debug` at the query string. This will make the browser to stop at this line and allow you to debug it.
217 | When the script is loaded, it is attached as the command execute method.
218 | When the console calls this method, it will pass an `error` and a `response` object.
219 | The `response` object contains the following parameters:
220 |
221 |
222 | * `args`- contains all arguments provided as part of the command line.
223 | * `data`- contains the data returned from the api call.
224 | * `promise`- an object that helps us manage the command response. This object contains the following methods:
225 | * `setProgress(percent)`- set a percentage indicator, use when the processing might be long and we would like to update the user on the progress that is made.
226 | * `resolve(res)`- used to end the command processing by passing the final result to the console. The result may be any string or html element.
227 | * `context`- contains command execution related objects such as
228 | * `url`- the url that was called .
229 | * `env`- a copy of the environment variable collection (so it won't be able to change it).
230 | * `command`- a copy of the command object if there's any need for details from it.
231 |
232 | Try executing `sample handler val` to see how it behaves.
233 |
234 | Adding A Command Custom Style
235 | -----------------------------
236 | If the controller needs any special stylesheet, it can do so in few ways
237 |
238 | * Use the `anode.loadCss(url)` command to load a css file and add it to the DOM.
239 | * Use the `anode.addCss(style)` command to embed style classes.
240 | * On the server side, use the `cssUrl` or the `css` attributes as can be seen in the sample file for the `htmlbcast` and `handler` commands.
241 |
242 |
243 | controller: {
244 | css: '.anode-sample-class{ background-color: green; }'
245 | }
246 |
247 | controller: {
248 | url: '../../plugins/sample.js',
249 | cssUrl: '../../plugins/sample.css'
250 | }
251 |
252 |
253 | __Note:__ It is very important to namespace your css classes to avoid impact on other elements in the DOM. In the example above, the style is namespaced with the `anode-sample` class.
254 |
255 |
256 | Adding Remote Management API
257 | ============================
258 | Please type `man plugins` for information about how to create your own remote management API and integrate it into the console.
259 |
260 |
--------------------------------------------------------------------------------
/docs/pinPannel.md:
--------------------------------------------------------------------------------
1 | Managing The Pin Panel
2 | =========================
3 |
4 | _Pin Panel_ is a panel on the right side of the screen, letting you keep command results always visible to you.
5 | Think of Performance monitor charts, long processing test execution commands, placing these manuals always-on and more.
6 |
7 | To make the board visible, execute the `panel` command. Whenever executed, this command will toggle the visibility state of the board.
8 |
9 | There are two ways to pin command results on _Pin Panel':
10 |
11 | * After the command execution, type `panel --pin`. This will take the last result and move it to the _Pin Panel' panel.
12 | * While pressing the `ctrl` key, double click the result item. This will make the item _draggable_. You are now able to drag the item and drop on _Pin Panel' panel.
13 |
14 |
15 | Actions
16 | -------
17 | * To cancel an item from being _draggable_, just `ctrl`+double click on that item again.
18 | * To delete an item from _Pin Panel' panel, `ctrl`+double click that item.
19 |
20 |
21 | You can leave _Pin Panel' opened on screen, minimized or maximize by clicking the `panel` title.
22 | To close _Pin Panel' panel, click the X button which will apear when hovering the panel.
23 |
24 | Example
25 | -------
26 | Try the following
27 |
28 | ```
29 | panel
30 | man pinPanel
31 | pinPanel --pin
32 | ```
33 |
34 | Notice that this manual is now always on in the _Pin Panel'.
35 |
36 | Another Example
37 | ---------------
38 | Type `set -o`. `ctrl`+double click the result and release the buttons. Now, drag the result panel to _Pin Panel' panel, and relase the mouse.
39 | Notice the settings panel is pinned on _Pin Panel' panel.
40 |
41 | Now try to change a setting variable, for example, change the application context by typing `set app console.sys`.
42 | Notice that the settings panel is updated and always displays the updated settings state.
43 |
44 | Have fun!
45 |
46 |
--------------------------------------------------------------------------------
/docs/plugins.md:
--------------------------------------------------------------------------------
1 | Creating Management API For My App
2 | ==================================
3 | __Note:__ Please make sure to read the _extend_ manual (type `man extend`) before you continue.
4 |
5 | Creating your own management API and integrating it into the console is as easy as extending the console, as described in the `extend` manual.
6 | The only diffrence is that the API is implemented as part of your application and exposes the docRouter information as discussed earlier.
7 |
8 | In order to _plug-in_ the API into the console, use the `plugins install` command.
9 | In the following example, we're installing `mysample` API:
10 |
11 | `
12 | plugins install mysample http://mysample.com/!! -p
13 | `
14 |
15 | After executing this command, the console will get the docRouter data, compile the commands and add them to the commands available for execution.
16 | Type `help` or `help mysample` to see how this command is now part of the console command list.
17 | The `-p` switch makes the plugin persistent. This means that next time when opening the console (from the same machine), the plugin will be automatically be integrated into the console.
18 | Not using this switch will make the command available only for this session. Closing and opening the console will not load this command.
19 |
20 | This feature allows you to create your own set of APIs integrated into the console.
21 |
22 | * In order to _uninstall_ a plugin, use the `plugins uninstall` command.
23 | * In order to remove all plugins currently installed, use the `plugins reset` command.
24 |
25 | __Notes:__
26 |
27 | * The API exposed to the console should be publicly available to the console. No authentication is currently supported.
28 | * This works best in Chrome browser. IE for example has Cross Site Origin issue loading plugins from other domains.
29 |
--------------------------------------------------------------------------------
/docs/tabs.md:
--------------------------------------------------------------------------------
1 | Managing Parallel Console Sessions
2 | ==================================
3 | As you probably already know by now, the console keeps the commands history, environment variables and the installed plugins in the browser's local storage, used to restore its state when initialized.
4 |
5 | The `tabs` feature allows you to open few console `sessions`. Each such session will keep all of the storage data listed above, partitioned by the optional `name` argument.
6 | Any time, you can go back to a session by just executing the command with the same session name.
7 | This way you will be able to create few sessions, each with its own set of environment variables, history and plugins related to it.
8 |
9 | For example, the following commands will create two sessions
10 |
11 | ```
12 | tabs app1
13 | tabs app2
14 |
15 | ```
16 |
17 | Now, in each _session_ you are now able to create your own set of environment variables and install plugins.
18 |
19 |
--------------------------------------------------------------------------------
/images/demo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amiturgman/aCLI/e133c0cb043433da2b65c318448780d41a8d0a1d/images/demo1.png
--------------------------------------------------------------------------------
/images/demo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amiturgman/aCLI/e133c0cb043433da2b65c318448780d41a8d0a1d/images/demo2.png
--------------------------------------------------------------------------------
/images/web-cli-demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amiturgman/aCLI/e133c0cb043433da2b65c318448780d41a8d0a1d/images/web-cli-demo.gif
--------------------------------------------------------------------------------
/lib/acli.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | .cli-control {
4 | font-family: courier;
5 | font-size: 1.1em;
6 | margin: 0;
7 | color: #3d3d3d;
8 | display: block;
9 | height: 100%;
10 | }
11 |
12 | .cli-promptText {
13 | color: #808080;
14 | margin-right: 5px;
15 | float: left;
16 | }
17 |
18 | .cli-input-wrapper {
19 | overflow: hidden;
20 | }
21 |
22 | .cli-input-container-clear {
23 | clear: both;
24 | }
25 |
26 | .cli-commandRow {
27 | margin-top: 10px;
28 | }
29 |
30 | .cli-commandText {
31 | font-weight: bold;
32 | }
33 |
34 | .cli-output-warn {
35 | color: orange;
36 | }
37 |
38 | .cli-output-info {
39 | color: auto;
40 | }
41 | .cli-output-error {
42 | font-weight: bold;
43 | color: red;
44 | }
45 |
46 | .cli-tab-container {
47 | border: 1px solid #008000;
48 | background-color: red;
49 | position: absolute;
50 | top: 100px;
51 | left: 100px;
52 | width: 300px;
53 | height: 500px;
54 | }
55 |
56 |
57 |
58 | .cli-output {
59 | font-size: 1.1em;
60 | position: absolute;
61 | top: 0;
62 | bottom: 26px;
63 | left: 0;
64 | right: 0;
65 | width: 100%;
66 | overflow: auto;
67 | }
68 |
69 | .cli-output > div {
70 | padding: 5px;
71 | }
72 |
73 | .cli-pinPanel {
74 | position: absolute;
75 | top: 0;
76 | bottom: 26px;
77 | width: 40%;
78 | right: 10px;
79 | padding: 3px;
80 | background-color: #ffffef;
81 | border: 1px solid #d3d3d3;
82 | opacity: 0.9;
83 | display: none;
84 | overflow: auto;
85 | }
86 |
87 | .cli-pinPanel-close {
88 | display: none;
89 | background-image: url(data:image/png;base64,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);
90 | height: 30px;
91 | width: 30px;
92 | background-color: transparent;
93 | position: absolute;
94 | left: 3px;
95 | top: 2px;
96 | }
97 |
98 | .cli-pinPanel:hover .cli-pinPanel-close { /* when hovering a note- display its close button */
99 | display: block;
100 | }
101 |
102 | .cli-pinPanel-title {
103 | background-color: #ffffad;
104 | font-weight: bold;;
105 | text-align: center;
106 | font-size: 1.2em;
107 | cursor: pointer;
108 | padding: 5px;
109 | }
110 |
111 | .cli-pinPanel-item {
112 | margin-top: 5px;
113 | }
114 |
115 | .cli-input-container {
116 | position: absolute;
117 | height: 22px;
118 | bottom: 0;
119 | left: 0;
120 | right: 0;
121 | border: 1px solid #808080;
122 | vertical-align: bottom;
123 | background-color: white;
124 | padding: 3px 2px 0 2px;
125 | text-align: left;
126 | }
127 |
128 | .cli-input{
129 | font-size: 0.9em;
130 | border: 0px solid black;
131 | outline: none;
132 | background-color: transparent;
133 | font-family: courier new;
134 | font-weight: bold;
135 | width: 100%;
136 | color: black;
137 | }
138 |
139 | .cli-table {
140 | border-collapse: collapse;
141 | empty-cells: show;
142 | border: 1px solid gray;
143 | }
144 |
145 | .cli-table td, th {
146 | padding: 2px 3px 2px 3px;
147 | vertical-align: top;
148 | text-align: left;
149 | }
150 | .cli-table td {
151 | background-color: #eeeeee;
152 | }
153 | .cli-table th {
154 | color: blue;
155 | background-color: #eeeeda;
156 | }
157 |
158 | .cli-jsonview-control .metadataField
159 | {
160 | background-color: #eeeeee;
161 | font-weight: bold;
162 | }
163 |
164 | .cli-jsonview-control .metadataFieldCollapsed
165 | {
166 | background-color: #edd3d6;
167 | }
168 |
169 | .cli-jsonview-control .metadataValue
170 | {
171 | background-color: #eeeeda;
172 | }
173 |
174 | .cli-jsonview-control table {
175 | border-collapse:collapse;
176 | empty-cells:show;
177 | font-family: courier;
178 | }
179 |
180 | .cli-jsonview-control table td {
181 | border: 1px silver solid;
182 | padding: 2px 3px 2px 3px;
183 | vertical-align: top;
184 | text-align: left;
185 | word-wrap: normal;
186 | }
187 |
--------------------------------------------------------------------------------
/lib/acli.js:
--------------------------------------------------------------------------------
1 |
2 | (function( $ ){
3 | var defaultSessionIdCounter = 0;
4 |
5 | function invoke(context, method) {
6 | methods[method]()
7 | }
8 |
9 | var methods = {
10 | init: function(opts){
11 |
12 | // for each selected control, initialize.
13 | // return the wrapped collection
14 | return this.each(function(){
15 |
16 | var $this = $(this),
17 | data = $this.data('cli');
18 |
19 | // control already initialized, return it
20 | if (data) return $this;
21 |
22 | // construct internal elements
23 | var cliOutput = $('