nuc
v0.5.2
Published
Configuration via JSON and INI from hierarchy of files.
Downloads
30
Maintainers
Readme
NUC
Configuration via JSON and INI file hierarchy: cli, env, local, user, system, global.
Uses specified app/module id
and process.platform value to look for config files.
Also uses the CLI args and environment values.
Provides a flexible way to specify configuration values in multiple system places in an intuitive hierarchy. This allows users and systems to configure values for apps/modules in simple text files as well as override them with CLI args.
Also provides a nuc
command, installed globally, to review configuration values
and set them at specific levels in the hierarchy.
Install
# Install global for `nuc` command.
npm install -g nuc
# Install locally to get configuration for your module/app
npm install --save nuc
Usage: the values object
The primary use of nuc
is to read a hierarchy of configuration files and combine them along the way into a single object. The final object contains the "configuration" information we want.
I call that the "values" object. It's produced by the "collapse" mode which is enabled by default.
// require module, call it, give it the ID and some defaults
// id is required, defaults are optional.
// values contains all key/value pairs combined into one object.
// later object key/value pairs override earlier ones
var nuc = require('nuc')
, values = nuc({ id:'appid', defaults:{} })
Usage: the ValueStore stack
See ValueStore for a description of that module.
The nuc
module can gather all the configuration files into a ValueStore
instance. Each configuration source remains separate and its hierarchy is maintained.
Each one knows its "source". If it's a cli option then its source is 'cli'. Environment values are from 'env'. Files have a file
property with the path.
The various sources in the ValueStore
can be inspected in many ways. Check out ValueStore for more on that.
To receive only the ValueStore you must enable it and disable the "collapse mode".
var nuc = require('nuc')
, store = nuc({ id:'someid', collapse:false, stack:true });
Usage: Have it both ways
By default, nuc
only produces the single values
object and returns it. I call that "collapse mode".
By default, the ValueStore isn't produced because the "stack mode" is off.
To have both, enable both, and the returned result will contain both a values
property and a store
property.
Because "collapse" is enabled by default, just enable "stack" and you get both.
var nuc = require('nuc')
, both = nuc({ id:'someid', defaults:{}, collapse:true, stack:true });
Usage: CLI
The nuc
module has a cli tool also named "nuc". You may use it locally or install it globally.
It has multiple subcommands which you may recognize from other configuration tools such as npm config
for "npmrc".
One major difference between nuc
and all the others is nuc
requires an "id" be specified which is used in many ways, one of them is as part of the file names. This means different applications may have their own configuration file inside a user's home directory. They are separate.
For example, a user may have a configuration folder in their home directory at /home/username/conf
. Inside it, there may be many files which will be loaded by nuc
when their corresponding app "id" is used.
The help information and usage displayed by the command itself is more descriptive than the documentation here. Install it and check it out :)
The first three commands in the list below are informational tasks which don't require an app "id". The later ones all require an app "id" to perform. The app "id" can be specified on the command line each time as the first arg to nuc
, and, it must have an @ symbol in front of it.
For example:
nuc @someid list each
nuc @someid get somekey
nuc @someid add somekey somevalue
It may become tedious typing the "id" for each command. As a shortcut I've added the ability to specify the "id" in a file. When you run nuc
commands it will look in the current working directory for a file named '.nuc.name'. If it finds it, it will read its contents expecting to find a single word which it will use as the app "id".
For example, if the PWD had a .nuc.name
file like:
theapp
Then, when you're in that same directory, you can leave out the app "id" from the command and it will use that. For example, now you can do:
nuc list each
nuc get somekey
nuc add somekey somevalue
It will use "theapp" as the app "id" for those commands the same as if you typed "@theapp" as the second arg to the nuc
command.
The cli subcommands are:
- version - prints the version to the console
- usage - prints the commands which can be used with nuc. This is the default subcommand. (alias = 'use')
- help - prints general help info, or, info about specific things when passed as an arg, such as
nuc help list
ornuc help scope
- list - list the contents of the
values
object or of thestore
object. You may limit it to a single scope instead of all scopes. Usesutil.inspect
to add colors to the output. (alias = 'show'). - get - get the value for a key for the first scope where the key exists, or, for the scope you specify.
- set - sets the key/value pair you specify into the first configuration file found within all writable scopes, or the one scope you specify. If no file is found, then a default file location is used to write out a new file with the key/value pair. It defaults to a path in the user's home directory where they're sure to have permission to write a file. These values may be overridden by using
nuc
itself to set their configuration values with app id "nuc". Because,nuc
uses itself for its own configuration. - add - similar to
set
except it combines your new value and the existing value into an array. If the key doesn't exist yet, then this command is the same asset
. - remove - the opposite of
set
, it will remove the key from the first scope it is found. You may specific the scope to remove it from, or, scope 'all' to remove it from all scopes. (As I write this, I realize I haven't completed the "remove from all" functionality yet.)
TODO: list the values used by nuc
by default and what the keys are to override them.
These are not all the commands. Just a minimum of examples...
nuc version
nuc usage
# there's more help info than these...
nuc help
nuc help usage
nuc help list
nuc help scope
# list all scopes together, or, a single scope, or each scope separately
nuc @someid list
nuc @someid list local
nuc @someid list each
# get a key's value from anywhere it's found, or look in a specific scope...
nuc @someid get somekey
nuc @someid get somekey user
# set into an existing file, or create a new one, or into a specific scope
nuc @someid set somekey value
nuc @someid set key2 value2 local
# key 'somekey' will then have the value: [ 'value', 'value2' ]
nuc @someid add somekey value2
# remove a key from the first scope it's found in, or, from a specific scope
nuc @someid remove somekey
nuc @someid remove somekey user
# there's more...
Value Hierarchy
Values are loaded from multiple scopes. Items higher in this list override those below them.
- cli - command line arguments override all other sources of values. Provided in
process.argv
. These are read-only. - env - environment values are prepared by the OS and override all but CLI args. Provided in node as
process.env
. These are read-only. - local - find config files in the local current working directory and up the path to root. Their accessibility depend on the user permissions.
- user - look in user's home directory. These are read/write accessible.
- system - system configuration directories, such as
/etc
andc:\ProgramData
. These values are writable if the user has access to them. - global - where modules are installed with
npm install -g
. These values are read-only.
Keys
The id
specified to nuc
is used as the base name to produce keys and file names.
cli key is the uppercase form of the
id
, prepended with two dashes, followed by an underscore, then the keys, an equal sign, and the value, like:--ID_KEY=value
Keys can be nested by using two underscores together. For example:
// key: --ID_ONE__TWO__THREE=value is interpreted as:
result = {
ONE: {
TWO: {
THREE: 'value'
}
}
}
- env keys are the same as cli keys, without the '--' in front:
process.env.ID_ONE__TWO__THREE
.
File names
Many files are searched for with various patterns using the id
in it. See below for complete list.
On Windows platforms:
- look for
ini
files. env.USERPROFILE
is used instead ofenv.HOME
for 'user' scopeenv.ALLUSERPROFILE
is used instead of/etc
for 'system' scope- ??? what should be used instead of
/usr/lib
and/usr/local/lib
for 'global' ?
On *nix platforms:
- look for dot files (filename starts with a dot)
- look for files suffixed with
rc
, like:.idrc
- look in
/etc
,/usr/lib/node_modules
, and/usr/local/lib/node_modules
Using 'id'
for the id
these are all the files searched for:
NOTE: This is an outdated list... but, it gives you an idea of it, so, I'll leave it for now. Look at windows-bases, nix-bases, and path-generator to get a better idea.
- '/usr/lib/node_modules/id/id.conf'
- '/usr/lib/node_modules/id/id.json'
- '/usr/lib/node_modules/id/.idrc'
- '/usr/lib/node_modules/id/idrc'
- '/usr/local/lib/node_modules/id/id.conf'
- '/usr/local/lib/node_modules/id/id.json'
- '/usr/local/lib/node_modules/id/.idrc'
- '/usr/local/lib/node_modules/id/idrc'
- '/etc/id.conf'
- '/etc/id.json'
- '/etc/.idrc'
- '/etc/idrc'
- '/etc/id/id.conf'
- '/etc/id/id.json'
- '/etc/id/.idrc'
- '/etc/id/idrc'
- env.HOME + '/id.ini'
- env.HOME + '/id.conf'
- env.HOME + '/id.json'
- env.HOME + '/.idrc'
- env.HOME + '/idrc'
- env.HOME + '/id/id.ini'
- env.HOME + '/id/id.conf'
- env.HOME + '/id/id.json'
- env.HOME + '/id/.idrc'
- env.HOME + '/id/idrc'
- CWD + '/id.ini'
- CWD + '/id.conf'
- CWD + '/id.json'
- CWD + '/.idrc'
- CWD + '/idrc'
- CWD + '/id/id.ini'
- CWD + '/id/id.conf'
- CWD + '/id/id.json'
- CWD + '/id/.idrc'
- CWD + '/id/idrc'
Why name it nuc ?
Chance, mostly. I began the nup project and wanted to read my configuration from multiple places on the system. I reviewed a bunch of modules providing configuration methods. The one I liked the most was one I saw long ago when I first moved to node: the npmrc stuff. I decided I wanted to make a module I could use with any app or module I made.
So, I needed a name for this new project coming directly from the nu
(nup
) project. Add a 'c' for configuration, and, it
sounds like "nook", which, may be where we find all the configuration information, in the "nook and crannies"?
I basically wanted to stop thinking about a name and begin writing the code. So, nuc
it is.