npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

node-program

v0.3.9

Published

A tool for creating nodejs command utilities

Downloads

1

Readme

program.js

This library was originally developed for the arangodep project.

Synopsis

This library attaches a contextual command line interface to programs.

Introduction

When developing command line utilities you often need to parse command line options that gets passed to your functions. The defacto standard is to provide the user with options in the form of arguments prefixed with one or more hyphens.

$> mytool --route --add --network 172.16.1.0 --netmask 255.255.255.0 --gateway 172.16.2.254 
Added route 172.16.1.0/24 -> 172.16.2.254
$>

To get help from a program you have to enter a -hor --helpswitch.

$> mytool --help
...100 lines of help output...

The help-switch typically dumps all the available command line options and often convolutes the output by to much information making the users less comfortable to use it. A better approach and as seen in many larger utilities is to assemble the options into different groups or contexts.

$> my tool --help --route
...only 20 lines of help output...

And this praxis is fine for executables that you run manually but if/when you decide to create a daemon out of your utility program that scheme becomes somewhat inconvenient to use, atleast if you want to interact with your program. Program.js attempts to meet this need by instead creating an interface more resembling the CLI often seen in network appliances such as routers.

$> mytool route add 172.16.1.0 netmask 255.255.255.0 gateway 172.16.2.254 
Added route 172.16.1.0/24 -> 172.16.2.254
$>

To get help you simply enter a questionmark after the relevant option or command '?'.

$> mytool route add?
Help: route add
		add <ipv4>: Network address
	netmask <ipv4>: Netmask
	gateway <ipv4>: Gateway address 
$>

To get initial help you only need to enter the command without any parameters.

$> mytool
Mytool v.1.0.0, (c) Mytool inc 2013, all rights reserved.
Help: 
			route: Network routes
	  		  arp: Address resolution
      		  egp: Exterior gateteway protocols
     		 icmp: Icmp utility  

This produces in my opinion a far better user experience.

Now, to interact with your utility you need to pipe it through standard input/output and perhaps even create a background process using a communications channel such as telnet.

Program.js aims to solve that by daemonizing a program into a backgorund process and at the same time create a telnet interface.

When not being bound by the constraints of a unix shell users can now interact with the software differently. For instance command line options and help can now automatically be expanded by pressing <TAB> instead of the more cumbersome '?' character.

Mytool v.1.0.0, (c) Mytool inc 2013, all rights reserved.
daemon> <TAB>
			route: Network routes
	  		  arp: Address resolution
      		  egp: Exterior gateteway protocols
     		 icmp: Icmp utility  
daemon> ro<TAB>
daemon> route
daemon> route <TAB>
			  add: Add route
	  		  del: Delete route
      		 show: Show routes
daemon> route add<TAB> 			
		add <ipv4>: Network address
	netmask <ipv4>: Netmask
	gateway <ipv4>: Gateway address
daemon> route add <TAB>
	    add <ipv4>: Network address	    

Command line interaction now becomes much more natural and it is much easier to explore commands and options.

Design

Program.js aims to provide a command controller that can be used to attach commands in a contextual tree like structure and provide an interface so that user agents can interact with worker functions or processes. The controller is responsible for parsing input and redirecting input/output through communication channels. Worker processes should be asynchrounous and not interfeer with the CLI, similar to a typical GUI application. The controller interfaces with the user agent over an user communications channel (UC) and with the program/function over an inter process communications channel (IPC).

User Agent <--UC--> Controller <--IPC--> Worker

The IPC can in its simplest form be a proxy function that passes parameters and arguments to the destination function. However a better approach is to provide asynchrounous communications channels so that the user terminal doesn't hang while the command completes its execution.

Controller

###Defining commands

// creates a context node
Program.$("context","A command context");

// creates a command under a context
Program.$("context").$(command,"command","A simple command");

// creates a command taking a say parameter that defaults to "hello world"
Program.$(console_log,"output","Output command",
	{"say":{"string":""},"":"hello world","?":"say something"}
);

// Single non-optional parameter (without a default value)
Program.$(console_log,"test","Test command",
	{"test":{"ipv4":""},"?":"Test something"}
);

// Optional parameters (null default).
Program.$(console_log,"test","Test command",
	{"test":{"ipv4":""},"":null,"?":"Test something"},
	{"test2":{"url":""},"":null,"?":"Url parameter"}
);

// Parameter value list 
Program.$(console_log,"test","Test command",
	{"test":{"string":["open","close"]},"?":"Test"}
);

// Parameter matching (TBD)
Program.$(console_log,"test","Test command",
	{"test":{"string":/[0-9]{4}/},"?":"Test 4 digits"}
);

...More to come...

Worker

TBD

User Agent

TBD

Usage

TODO

Status

  • Design / Prototyping

Contributions

Sharing is caring, contribute with your time & energy.