Security News
Combatting Alert Fatigue by Prioritizing Malicious Intent
In 2023, data breaches surged 78% from zero-day and supply chain attacks, but developers are still buried under alerts that are unable to prevent these threats.
Shell brings a Connect inspired API, Express inspired routing, and other similar functionality to console based applications.
Shell is open source and licensed under the new BSD license.
npm install shell
var shell = require('shell');
// Initialization
var app = new shell( { chdir: __dirname } )
// Middleware registration
app.configure(function() {
app.use(function(req, res, next){
app.client = require('redis').createClient()
next()
});
app.use(shell.history({
shell: app
}));
app.use(shell.completer({
shell: app
}));
app.use(shell.redis({
config: 'redis.conf',
pidfile: 'redis.pid'
}));
app.use(shell.router({
shell: app
}));
app.use(shell.help({
shell: app,
introduction: true
}));
});
// Command registration
app.cmd('redis keys :pattern', 'Find keys', function(req, res, next){
app.client.keys(req.params.pattern, function(err, keys){
if(err){ return res.styles.red(err.message), next(); }
res.cyan(keys.join('\n')||'no keys');
res.prompt();
});
});
// Event notification
app.on('quit', function(){
app.client.quit();
});
var app = shell();
app.configure(function() {
app.use(shell.history({shell: app}));
app.use(shell.completer({shell: app}));
app.use(shell.help({shell: app, introduction: true}));
});
app.configure('prod', function() {
app.set('title', 'Production Mode');
});
The constructor shell
takes an optional object. Options are:
chdir
, Changes the current working directory of the process, a string of the directory, boolean true will default to the workspace
(in which case workspace
must be provided or discoverable)prompt
, Character for command prompt, Defaults to ">>"stdin
, Source to read fromstdout
, Destination to write toenv
, Running environment, Defaults to the env
setting (or NODE_ENV
if defined, eg: production
, develepment
).isShell
, Detect whether the command is runned inside a shell are as a single command.noPrompt
, Do not prompt the user for a command, usefull to plug your own starting mechanisme (eg: starting with a question).workspace
, Project root directory or null if none was found. The discovery strategy start from the current working directory and traverse each parent dir looking for a node_module
directory or a package.json
file.Shell settings may be set by calling app.set('key', value)
. They can be retrieved by calling the same function without a second argument.
var app = new shell({
chdir: true
});
app.set('env', 'prod');
app.configure('prod', function() {
console.log(app.set('env'));
});
As with Express, app.configure
allows the customization of plugins for all or specific environments, while app.use
registers plugins.
If app.configure
is called without specifying the environment as the first argument, the provided callback is always called. Otherwise, the environment must match the env
setting or the global variable NODE_ENV
.
Shell is build on a middleware architecute. When a command is issued, multiple callbacks are executed sequentially until one decide to stop the process (calling res.prompt()
or shell.quit
. Those callbacks are called middlewares. A callback recieve 3 arguments: a request
object, a response
object and the next callback. Traditionnaly, request
deals with stdin
while response
deals with stdout
.
A plugin is simply a function which configure and return a middleware. Same plugin also enrich the Shell application with new routes and functions.
The following events may be emitted:
"command"
, listen to all executed commands, provide the command name as first argument.#{command}
, listen to a particular event."quit"
, called when the application is about to quit."error"
, called on error providing the error object as the first callback argument."exit"
, called when the process exit.The request object contains the following properties:
shell
, (required) A reference to your shell application.command
, Command entered by the userparams
, Parameters object extracted from the command, defined by the shell.router
middlewareqestion
, Ask questions with optionally suggested and default answersconfirm
, Ask a question expecting a boolean answerThe response object inherits from styles containing methods for printing, coloring and bolding:
Colors:
black
white
yellow
blue
cyan
green
magenta
red
bgcolor
color
nocolor
Style:
regular
weight
bold
Display:
prompt
, Exits the current command and return user to the prompt.ln
, Print a new lineprint
, Print a textprintln
, Print a text followed by a new linereset
, Stop any formating like color or boldpad
, Print a text with a fixed paddingraw
, Return a textThe functionality provided by the 'routes' module is very similar to that of express. Options passed during creation are:
shell
, (required) A reference to your shell application.sensitive
, (optional) Defaults to false
, set to true
if the match should be case sensitive.New routes are defined with the cmd
method. A route is made of pattern against which the user command is matched, an optional description and one or more route specific middlewares to handle the command. The pattern is either a string or a regular expression. Middlewares receive three parameters: a request object, a response object, and a function. Command parameters are substituted and made available in the params
object of the request parameter.
Parameters can have restrictions in parenthesis immediately following the
keyword, as in express: :id([0-9]+)
. See the list
route in the example:
var app = new shell();
app.configure(function(){
app.use(shell.router({
shell: app
}));
});
// Route middleware
var auth = function(req, res, next){
if(req.params.uid == process.getuid()){
next()
}else{
throw new Error('Not me');
}
}
// Global parameter substitution
app.param('uid', function(req, res, next){
exec('whoami', function(err, stdout, sdterr){
req.params.username = stdout;
next();
});
});
// Simple command
app.cmd('help', function(req, res){
res.cyan('Run this command `./ami user ' + process.getuid() + '`');
res.prompt()
});
// Command with parameter
app.cmd('user :uid', auth, function(req, res){
res.cyan('Yes, you are ' + req.params.username);
});
// Command with contrained parameter
app.cmd('user :id([0-9]+)', function(req, res) {
res.cyan('User id is ' + req.params.id);
res.prompt();
});
FAQs
Command line arguments parser and stringifier
The npm package shell receives a total of 5,564 weekly downloads. As such, shell popularity was classified as popular.
We found that shell demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
In 2023, data breaches surged 78% from zero-day and supply chain attacks, but developers are still buried under alerts that are unable to prevent these threats.
Security News
Solo open source maintainers face burnout and security challenges, with 60% unpaid and 60% considering quitting.
Security News
License exceptions modify the terms of open source licenses, impacting how software can be used, modified, and distributed. Developers should be aware of the legal implications of these exceptions.