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-configurator

v0.2.7

Published

A generic configuration tool for loading and storing all sorts of configuration sources

Downloads

2

Readme

Configurator

Configurator is a library for organizing, loading, storing and overall dealing with configuration data and files of any kind.

It comes with support for JSON, YAML and INI files, and more can easily be added.

Example usage:


var config = require('configurator').getMainConfig();

//Load in an arbitrary INI file at 'scripts/settings'
config.load('scripts/settings', './app/scripts/settings.ini');

//Prints value loaded from settings.ini
console.log(config.get('scripts/settings/maxAppInstances'));

//Set a new value for maxAppInstances
config.set('scripts/settings/maxAppInstances', 10);

//Store changes to disk for 'scripts/settings',
//which is associated with './app/scripts/settings.ini' behind the scenes
config.store('scripts/settings');

#API Documentation

###Glossary

There is really only one term that may be strange.

####Store

Stores are the routines that control the parsing and stringification/encoding of configuration data.

A typical Store for JSON would look like:

{
    parse: JSON.parse,
    stringify: JSON.stringify,
    extension: '.json'
}

So for that it is pretty 1:1 on the terminology.

The functions that parse are only given a simple string and are expected to return the Object that contained the parsed data.

The functions that stringify are only given the Objects that they are expected to stringify and should return just a string.

Any options given to other parse/stringify functions should be given by wrapping them in a function that does behave as specified above.

For example, if you wanted to have JSON stringify and pretty print it, you would do this:

{
    parse: JSON.parse,
    stringify: function(obj) {
        return JSON.stringify(obj, null, true);
    },
    extension: '.json'
}

And then give that to .addStore with the name 'JSON-pretty' or something similar. Then if you want to store a configuration as pretty printed JSON you would call .store like this:

config.store('something/exports', {
    path: 'exports.json',
    dir: './',
    type: 'JSON-pretty'
});

###Constructor

Returns a new Configurator instance.

The options are, as of now:

{
    separator: '/',
    storeMetadata: true
}

The separator field is how the keys are split apart. For example, the path 'users/john/pictures/' or something like that would split into 'users' -> 'john' -> 'pictures' and be placed there accordingly.

The storeMetadata Boolean value refers to the loading and storing of configuration files, such as YAML, JSON and INI files. If true, the Configurator instance will remember the location of these files and associate them with the key path they are loaded into. This makes for easy storing of configuration files.

###Static methods

If a main instance does not exist, it will create with with any options provided (See Configurator constructor for options details).

Otherwise, it will return the previously created Configurator instance.

###Static members

Contains version information for the module in the format 'major.minor.revision'

###Member methods

Returns the value stored at that key path if there is one, or undefined if there is no associated value.

Sets the value of a key with value and then returns the stored value.

.set will also automatically create any paths between the root path and the provided key.

This acts the same as:

var ret = config.get('test/value'); config.clear('test/value');

But is essentially twice as fast because it removes a call to the internal lookup mechanism.

The load function has some of the more complicated logic.

The key value is optional, but denotes where to store the loaded configuration file. If the key is not present, then it will store the configuration at the root path under the file name.

The filepath or loading options are required, though. If you provide a regular filepath, then the Configurator will load it and parse it with whatever store matched up with the file extension. For example, test.json will use the JSON store.

If an object is passed into .load then it should look something like this:

{
    path: String,
    dir: String,
    type: String
}

For the same JSON file used above, the load options would be:

{
    path: 'test.json',
    dir: './',
    type: 'JSON'
}

Additionally, if a callback is passed last, then it will load the file asynchronously and call the callback when it is done, passing it the parsed configuration.

If no callback is given, it will load and parse the file synchronously.

This is redundant for the simple reason of extensibility. When it comes to adding custom stores, such as loading or saving unsafe YAML files for example, then passing an option object like this makes sense.

See here:

{
    path: 'script_functions.yaml',
    dir: './scripts/',
    type: 'YAML-UNSAFE'
}

Where 'YAML-UNSAFE' is a custom store used to parse/stringify unsafe YAML code. By default, YAML is included with Configurator but uses the safe settings.

NOTE: dir is technically not needed for the load options, but is included in all examples anyway.

.store is the inverse of .load. While the key was optional with .load, it is required here.

However, if the configuration key path you are trying to save is associated with an already loaded file, then the filepath or save options are not needed, but you can provide them anyway if you want to save the file elsewhere or with another Store.

For example, the example given in the glossary with the custom JSON Store that pretty-prints the output:

config.store('something/exports', {
    path: 'exports.json',
    dir: './',
    type: 'JSON-pretty'
});

Assuming you added the 'JSON-pretty' Store to the Configurator.

Additionally, like .load, .store can be executed asynchronously or synchronously, depending on whether or not a callback is given to it.

NOTE: if storeMetadata is set to false, Configurator cannot automatically know the location in which to save the file, so a filepath or save

.parse will parse a string given to it with the store of type type and place it at key.

If merge is specified, it will try to merge the parsed object with whatever already exists at key, if anything.

.stringify will convert a configuration at key into a string by through the Store specified by type

The glossary shows how a store object should be, and this function allows the addition of custom stores.

For example, adding the pretty print JSON store would be as easy as:

config.addStore('JSON-pretty', {
    parse: JSON.parse,
    stringify: function(obj) {
        return JSON.stringify(obj, null, true);
    },
    extension: '.json'
});

And it will be added with the name/type 'JSON-pretty'.

If no name parameter is given, it will look for name and type from the object passed as the Store, in that order.

NOTE: Store names as CASE INSENSITIVE.

Deletes the entire value at the key path. Returns nothing.

Moves the value at fromKey to the location of toKey.

If merge is set to true, if toKey already has a value then it and the value at fromKey will be merged together then stored at toKey.

This will take value and merge it with whatever is at key.

If the value already at key is not an object, then it will create an object and put the previous value in it under the name given by replaceKey.

replaceKey defaults to '_'.

This will completely reset the entire Configurator instance, clearing all data. Use with care.

Exports the entire configuration tree using the stringify method of the store specified with type.

###Private Members

These are internal variables that should not be tampered with, but I'm including documentation of anyway.

#####.root

.root is the root node of the configuration tree. Everything is saved inside it.

#####.meta

.meta acts as a hashtable to store raw information about file loads. It allows for .store to save configuration paths that were created from loaded files automatically.

#####.options

.options is a small object containing only two (as of now) options that are the same as given in the constructor.

NOTE: changing the internal options object can mess up the .meta object. So it should never be changed after construction.

##Changelog

#####0.2.7

  • Added Configurator.config as an alias to Configurator.getMainConfig
  • Added the .pop method for retrieving and deleting values in a single operation
  • Used .pop in .move to remove an iterator lookup

#####0.2.6

  • Fixed bug in .merge with merging into and from non-object values
  • A bit of variable declaration cleanup
  • Added changelog.md file
  • As of now I should consider this relatively stable

#####0.2.5

  • Fixed issue with adding stores. Stupid mistake on my part.
  • Added a few more tests
  • Added changelog

#####0.2.4

  • Added .export

See here for full changelog