app-etc

1.0.0 • Public • Published

etc

NPM version Build Status Coverage Status Dependencies

Application configuration.

Installation

$ npm install app-etc

Usage

var etc = require( 'app-etc' );

etc( [options] )

Returns an application configuration.

var config = etc();

The function accepts the following options:

  • local: local application configuration directory. Default: ./etc.
  • defaultsFile: basename of a file within the local application configuration directory which contains default application settings. Default: defaults.
  • schemaFile: basename of a file within the local application configuration directory which contains a configuration schema.
  • etc: application configuration directory. Default: /etc.
  • etcFile: basename of a file within an application configuration directory which contains application settings. The default value is the application name.
  • user: user configuration directory. The default value is determined according to the host OS.
  • userFile: basename of a file within the user configuration directory which contains user application settings. The default value is the application name.
  • userFormat: user configuration file format. The default value is either determined from a basename filename extension or ini.
  • env: application runtime environment. Default: dev.
  • envFile: basename of a file within the local application configuration directory which maps environment variables to application settings. Default: env.
  • argvFile: basename of a file within the local application configuration directory which maps command-line arguments to application settings. Default: argv.
  • order: defines the configuration hierarchy. Default: ['defaults','app','local','user','env','argv'].

Notes:

  • If a file extension is omitted when specifying file basenames, this module will search for the first file having the basename and a supported extension. For supported extensions, see app-etc-load.
  • If a file basename does not begin with a ., this module will search for both hidden and non-hidden files. This also applies for inferred basenames; e.g., env. If env is dev, this module will search for and load either an .dev.<ext> or a dev.<ext> file.
Local Configuration Directory

By default, the local application configuration directory is a directory named etc located in the application's root directory. This directory may contain default configuration settings, mappings between environment variables and configuration settings, various application-specific configuration files tailored for different runtime environments, and more. To specify a different directory, set the local option:

var config = etc({
    'local': './config'
});
Default Configuration

A defaults file should contain default application configuration settings; e.g., if applicable, a default log level, port, etc. By default, this module looks for a file with the basename defaults. To specify a different basename, set the defaultsFile option:

var config = etc({
    'defaultsFile': 'shared_settings'
});
Application Configuration

The etc directory option specifies the location of a directory containing application-specific configuration files. The default value is /etc, but this may not apply for all operating systems (e.g., Windows). To specify a different directory, set the etc option:

var config = etc({
    'etc': '/config'
});

An etc file should contain application-specific configuration settings. By default, this module searches for a file having a basename equal to the application name. To specify a different basename, set the etcFile option:

var config = etc({
    'etcFile': 'appname/config.alce' 
});
User Configuration

The user directory option specifies the location of a directory containing user-specific configuration files. The location of this directory is typically OS specific. To specify a directory, set the user option:

var config = etc({
    'user': '~/'
});

A user file should contain user-specific configuration settings. By default, this module searches for a file having a basename equal to the application name. To specify a different basename, set the userFile option:

var config = etc({
    'userFile': '.appname.json' 
});

If a basename does not include a filename extension, the module parses a configuration file as INI. To specify a configuration file format, set the userFormat option:

var config = etc({
    'userFile': '.appname',
    'userFormat': 'toml'
});

For details on how user configuration files are resolved, see find-user-app-config.

Runtime Configuration

Often different runtime environments require different application configurations. For example, in development, the application may connect to local resources; whereas, in production, the application may connect to various remote endpoints. To handle the different runtimes, applications will utilize environment specific configuration files; e.g., production.json, development.json, test.json, local.json, etc. This module sets the default runtime environment to dev and looks for a corresponding configuration file of the same name in the local application configuration directory. To override this option, either set the NODE_ENV environment variable or set the env option:

var config = etc({
    'env': 'local'
});

Runtime environments (e.g., containers) frequently use environment variables for configuration. To map environment variables to configuration settings, this module searches the local application configuration directory for a file which maps each environment variable to a particular setting. By default, this module looks for a file having the basename env. To specify a different basename, set the envFile option:

var config = etc({
    'envFile': 'env_mapping'
});

The file contents should include each relevant environment variable and a corresponding setting. For example, a JSON mapping file:

{
    "GITHUB_API_KEY": {
        "keypath": "gKey"
    },
    "DEBUG_LEVEL": {
        "keypath": "logger.level"
    },
    "PORT": {
        "keypath": "server.port",
        "type": "number"
    },
    "SSL_KEY": {
        "keypath": "server.key",
        "type": "string"
    },
    "SSL_CERT": {
        "keypath": "server.cert",
        "type": "string"
}

A TOML mapping file:

# A TOML file which maps environment variables to configuration settings...
 
[GITHUB_API_KEY]
keypath = "gKey"
 
# Logger environment variables:
[DEBUG_LEVEL]
keypath = "logger.level"
 
# Server environment variables:
[PORT]
keypath = "server.port"
type = "number"
 
[SSL_KEY]
keypath = "server.key"
type = "string"
 
[SSL_CERT]
keypath = "server.cert"
type = "string"

See env-to-object for more information. Note that, if an environment variable cannot be cast as a specified type, the module will throw an error.

When scripting or running an application from the command-line, command-line arguments are commonly used to configure an application. To map command-line arguments to configuration settings, this module searches the local application configuration directory for a file which maps each command-line argument to a particular setting. By default, this module looks for a file having the basename argv. To specify a different basename, set the argvFile option:

var config = etc({
    'argvFile': 'argv_mapping'
});

The file contents should include each relevant command-line argument and a corresponding setting. For example, a JSON mapping file:

{
    "api-key": {
        "keypath": "gKey"
    },
    "loglevel": {
        "keypath": "logger.level",
        "default": "info"
    },
    "port": {
        "keypath": "server.port",
        "type": "integer",
        "alias": [
            "p"
        ]
    },
    "ssl": {
        "keypath": "server.ssl",
        "type": "boolean"
    },
    "key": {
        "keypath": "server.key",
        "type": "string"
    },
    "cert": {
        "keypath": "server.cert",
        "type": "string"
}

See argv-to-object for more information. Note that, if a command-line argument cannot be cast as a specified type, the module will throw an error.

Configuration Hierarchy

Configuration sources are many; e.g., user-specific, application-specific, runtime-specific, environment variables, command-line arguments, and more. The following sources are supported:

  • defaults: default application settings
  • app : application-specific settings
  • local: local application-specific settings
  • user: user-specific settings
  • env: environment variable runtime settings
  • argv: command-line arguments

The order option exists to impose a configuration hierarchy. By default, the hierarchy is biased toward Linux systems:

[
    'defaults', // read first
    'app',
    'local',
    'user',
    'env',
    'argv'      // read last
]

To specify a different order, set the order option:

// Only use local application configuration and environment variables as configuration sources...
var config = etc({
    'order': [
        'local',
        'env'
    ]
});
Configuration Schema

As more configuration sources are compiled into a single application configuration, the probability of a misconfiguration increases. Misconfiguration can be problematic as downstream application configuration consumers often make assumptions regarding configuration structure, types, and properties. To enforce a configuration schema and ensure that these assumptions are not violated, specify the basename of a JSON schema file located in the local application configuration directory.

var config = etc({
    'schemaFile': 'schema.json'
});

Notes:

  • If a schemaFile is a valid JSON schema, the module validates the application configuration after loading all configuration sources.
  • If a configuration is invalid, the module will throw.
  • If a configuration is valid, the module returns an application configuration as per normal operation.
  • If a schemaFile does not exist, the module will not perform validation. Depending on your view, you may consider this behavior a silent error.
  • See the examples for a sample JSON schema.

===

etc.parser( extname[, parser] )

Returns a parser for the specified extension.

var parser = etc.parser( '.json' );

Including the . when specifying an extension is optional.

var parser = etc.parser( 'json' );

To support additional file formats or to override a parser, provide a parser function for an associated extension.

var parser = require( 'my-special-fmt-parser' );
 
etc.parser( '<my-ext>', parser );

Once a parser is set, all configuration instances will parse provided files accordingly.

config.load( './file.<my-ext>' );

For more details, see app-etc-load.


Examples

var path = require( 'path' ),
    etc = require( 'app-etc' );
 
var config = etc({
    'local': path.join( __dirname, 'etc' ),
    'schemaFile': 'schema.json'
});
console.dir( config.get() );
/*
    {
        'server': {
            'port': 8080,
            'address': '127.0.0.1',
            'ssl': true,
            'key': '',
            'cert': ''
        },
        'logger': {
            'level': 'debug'
        },
        'env': 'dev'
    }
*/

To run the example code from the top-level application directory,

$ DEBUG=* NODE_ENV=dev PORT=8080 node ./examples/index.js --ssl

Tests

Unit

Unit tests use the Mocha test framework with Chai assertions. To run the tests, execute the following command in the top-level application directory:

$ make test

All new feature development should have corresponding unit tests to validate correct functionality.

Test Coverage

This repository uses Istanbul as its code coverage tool. To generate a test coverage report, execute the following command in the top-level application directory:

$ make test-cov

Istanbul creates a ./reports/coverage directory. To access an HTML version of the report,

$ make view-cov

License

MIT license.

Copyright

Copyright © 2015. Athan Reines.

Package Sidebar

Install

npm i app-etc

Weekly Downloads

2

Version

1.0.0

License

MIT

Last publish

Collaborators

  • kgryte