opt

A configuration, cmd line options and RESTful web processor module for NodeJS. A simple help text is also automatically generated based if the command line options or RESTful paths you define so you don't have to remember to do that later.

opt ===

There are three reasons I created opt.js

  • I wanted to simplify the boilerplate I used with JSON based configuration files including handling a set of search paths (e.g. look sequentially in a list of paths for a configuration file)
  • I wanted a very simple command line option parser that included automatically generate a help page (I'm forgetful about updating docs outside of my code)
  • I wanted a simple http route library that generate docs like I used for the command line

That was my itch. There are many fine existing options parsing libraries in Node but they didn't quite scratch the itch I had.

Overview

opt is a toolkit for building command line programs and RESTful web services. It uses a common idiom for setting up and processing JSON based configuration files, command line options parsing and defining a RESTful API calls.

Use the module by invoking opt's constructor Opt() or opt.create() method..

var options = require("opt"),
    opt = new options.Opt();
var options = require("opt"),
opt = options.create();

It is available from github at https://github.com/rsdoiel/opt and can be installed using npm

npm install opt

Examples Code

The following examples build by topics

  • configuration processing
  • command line option processing
  • a RESTful Hello World API

This is the synchronous version.

/*jslint node: true */
"use strict";
 
var path = require("path"),
    opt = require("opt").create();
 
    var config = { name: "fred", email: "fred@example.com" },
     search_paths = [ "config-example-1.conf",
path.join(process.env.HOME, ".config-examplerc"),
"/usr/local/etc/config-example.conf",
"/usr/etc/config-example.conf",
"/etc/config-example.conf" ];
 
console.log("Unprocessed config:", config);
opt.config(config, search_paths);
 
opt.on("ready", function (config) {
// config should now hold the merge configuration 
// from default_config and the first configuration file  
// found in the search path list. 
console.log("Processed config: ", config);
});

Display a help message with -h and --help on the command line.

/*jslint node: true */
"use strict";
var path = require("path"),
opt = require("opt").create();
var config = { name: "fred", email: "fred@example.com" },
search_paths = [ "config-example-1.conf",
path.join(process.env.HOME, ".config-examplerc"),
"/usr/local/etc/config-example.conf",
"/usr/etc/config-example.conf",
"/etc/config-example.conf" ];
console.log("Unprocessed config:", config);
opt.config(config, search_paths);
opt.optionHelp("USAGE node " + path.basename(process.argv[1]),
"SYNOPSIS: Demonstrate how opt works to parse command line options.\n\n\t\t node " + path.basename(process.argv[1]) + " --help",
"OPTIONS:",
" copyright (c) 2012 all rights reserved\n" +
" Released under New the BSD License.\n" +
" See: http://opensource.org/licenses/bsd-license.php\n");
opt.on("ready", function (config) {
opt.option(["-n", "--name"], function (param) {
if (param.trim()) {
config.name = param.trim();
}
}, "Set the name parameter");
opt.option(["-e", "--email"], function (param) {
if (param.trim()) {
config.email = param.trim();
}
}, "Set the email parameter");
opt.option(["-g", "--generate"], function (param) {
if (param.trim()) {
fs.writeFile(param.trim(), JSON.stringify(config));
} else {
console.log(JSON.stringify(config));
}
process.exit(0);
}, "Generate a configuration file");
opt.option(["-h", "--help"], function () {
opt.usage();
}, "This help document.");
opt.optionWith(process.argv);
// config should now hold the merge configuration 
// from default_config and the first configuration file  
// found in the search path list. 
console.log("Processed config: ", config);
});
// Importing some modules 
var util = require("util"),
http = require("http"),
path = require("path"),
// import and create the opt object 
opt = require("opt").create();
// Define your configuration defaults and load your local configuration 
// file or it. 
opt.config({ host: "localhost", port: 8080, name: "John Doe"},
[ "/etc/helloworld.json", path.join(process.env.HOME, "etc/helloworld.json") ]);
// When your configuration is "ready" parse the command lines 
// and setup your RESTful hello world web service 
opt.on("ready", function (config) {
// Setup how your help page will look 
opt.optionHelp("USAGE node " + path.basename(process.argv[1]),
"SYNOPSIS:\n\tThis is a simple hello world web service.",
"OPTIONS:",
"this is an opt demo");
// Define your command line options 
opt.option(["-H", "--host"], function (hostname) {
config.host = hostname.trim();
});
opt.option(["-p", "--port"], function (portname) {
config.port = Number(portname.trim());
});
opt.option(["-n", "--name"], function (name) {
config.name = name.trim();
});
opt.option(["-h", "--help"], function () {
opt.usage();
});
// Define you restful service 
var helloworld = function (reqresmatchingrule_no) {
res.writeHead(200, {"content-type": "text/plain"});
res.end("Hello " + config.name + ".\nThis is what I found: " + util.inspect(matching) + "\nRule No.:" + rule_no);
};
opt.rest("get", new RegExp("^$|^/$|^/index.html|^/helloworld.html"), helloworld);
var status404 = function (reqres) {
res.writeHead(404, {"content-type": "text/plain"});
res.end("File not found. " + req.url);
};
opt.rest("get", new RegExp("^/*"), status404);
// Process your command line args. 
opt.optionWith(process.argv);
// Process your restful requets 
console.log("Configuration:", config);
http.createServer(function (reqres) {
console.log("request:", req.url);
opt.restWith(req, res);
}).listen(config.port, config.host);
console.log("Web server listening on " + config.host + ":" + config.port);
});

Simple webserve example

This example sets up a simple hello web server.

var fs = require("fs"),
path = require("path"),
http = require("http"),
url = require("url"),
opt = require("opt").create(),
TBone = require("tbone"),
H = new TBone.HTML(),
config_filename = false,
config = {
port: 8123,
host: "localhost"
};
opt.optionHelp(
"USAGE node " + path.basename(process.argv[1]),
"SYNOPSIS: Demonstrate how opt works to parse command line options.\n" +
"\n\t\t node " + path.basename(process.argv[1]) + " --help",
"OPTIONS:",
"ACME Gelatin Company"
);
opt.consume(true);
opt.option(["-p", "--port"], function (arg) {
try {
config.port = Number(arg);
} catch (err0) {
console.error(err0);
process.exit(1);
}
opt.consume(arg);
}, "Set the port to listen on.");
opt.option(["-c", "--config"], function (arg) {
config_filename = arg;
option.consume(arg);
}, "Set the configuration file to use.");
opt.option(["-h", "--help"], function (arg) {
opt.usage();
}, "This help page.");
opt.optionWith(process.argv);
if (config_filename) {
config = JSON.parse(fs.readFileSync(config_filename).toString());
}
http.createServer(function (request, response) {
console.log("request:", request.url);
response.writeHead(200, "text/html");
response.end(H.html(
H.head(
H.title("Hello World")
),
H.body(
H.h1("Hello World")
)
).attr({lang: "en"}));
}).listen(config.port);