0.4.70 • Published 5 months ago

appcfg v0.4.70

Weekly downloads
10
License
MIT
Repository
github
Last release
5 months ago

Application Configuration Library for Node.js and Browser

Build Status NPM version

About

Load and Combine Configuration from many sources:

  • Files
    • JavaScript Module
    • JSON
    • Yaml
    • ENV + .env
    • S3 Storage
  • Directory (combine files)
  • MongoDB

Additional features:

When combining objects from many sources, deep copy is used:

// a
{ sub: { foo: 'foo' }, arr: [ 'foo' ] }
// b
{ sub: { bar: 'bar' }, arr: [ 'bar' ] }

// combined (a + b)
{
    sub: { foo: 'foo', bar: 'bar'},
    arr: ['foo', 'bar']
}

// E.g you want completely to overwrite `arr` property, then prefix the key's name with `!`

// a
{ sub: { foo: 'foo' }, arr: [ 'foo' ] }
// b
{ sub: { bar: 'bar' }, '!arr': [ 'bar' ] }

// combined (a + b)
{
    sub: { foo: 'foo', bar: 'bar'},
    arr: ['bar']
}

Example:

import AppCfg from 'appcfg'

const config = await AppCfg.fetch([
    // from file. (with Special Folder format syntax support)
    {
        path: '%APPDATA%/.appName/config.yml',

        // set this source as writable for configuration persistance
        writable: true
    },
    // ENV + .env
    {
        dotenv: true,
        // per default CWD is checked, can be overriden
        path: './foo/bar/'
    },
    // directory
    {
        path: 'defaults/**.yml'
    },
    // mongodb
    {
        mongo: 'barSettings'
    },
    // from file, but use only nested property
    {
        path: 'package.json',
        getterProperty: 'atma'
    }
]);
Command Line overrides

Command line arguments are parsed and also set to the configuration object.

$ node app --foo.bar barValue --debug
let config = await Config.fetch(someSources);

assert.has(config, {
    foo: {
        bar: 'barValue'
    },
    debug: true
})
Conditions

Yaml conditions example. (same is also for json format)

# conditional root configuration example
'#if debug':
    name: Foo
    host: dev.example.com
'#if test':
    name: Baz
    host: localhost

# conditional property example
port:
    '#if debug': 5000
    '#if test': 5030
    'default': 8080

# conditional array item example
scipts:
    - lib.js
    - '#if debug || test'
        - lib.debug-extension.js

Arguments lookup:

  • in configuration object
  • in cli overrides
  • in process.env
  • compare value as string from process.env.ENV
# from cli example
$ node app --debug

# from environment
$ set ENV=DEBUG
$ node app
{
    name: 'Foo',
    host: 'localhost',
    port: 5000,
    scripts: [
        "lib.js",
        "lib.debug-extension.js"
    ]
}
Special Folder

Use special folders for loading/writing configurations, like %APPDATA% or %HOME%. Is system agnostic and is parsed from the environment variables.

Config.fetch({
    path: '%APPDATA%/.myApplication/global.yml',
    writable: true
});

Interpolations

Sometimes to not repeat the configuration it is convenient to use interpolations. It will embed configuration from itself.

# someConfig.yml
name: 'Foo'
A:
    lorem: '#[name]'
B:
    ipsum: '#[A.lorem]'
let config = await Config.fetch({
    path: 'someConfig.yml'
});

assert.has(config, {
    name: 'Foo',
    A: { lorem: 'Foo' },
    B: { ipsum: 'Foo' }
});

API

Config

static

.fetch(Array<Source>) => Config Instance

Start loading the configuration from specified sources, returns new deferrable configuration instance

methods

<Constructor> (Array<Source>)
  • .$read(?Mix)

    • Mix:
      • String: File/Directory/Glob path
      • Source: Source object
      • Array<Source>
      • @default - Array taken from constructor
    • @return: self. Is deferrable, so you can attach done callbacks to it.

      Load configuration from sources

  • .$write(config:Object [, ?deepExtend:Boolean, ?setterPath:String):Deferred

    Update and save the configuration. Use first matched writable source.

    • deepExtend: complex objects and arrays are merged
    • setterPath: define nested object in current configuration
  • .$get(property:String)

    • property: Dot delimited accessor config.$get('foo.bar.quux')

      // is the same as you if you would write null-check expressions yourself:
      var quuxVal = config.foo && config.foo.bar && config.foo.bar.quux;
    • @return: null or value

  • .$is(name:String):Boolean

    Check conditional environment variable, e.g.: config.$is('debug')

    Ways to define the variables. (Example defines DEBUG and TEST flags)

    • directly in the configuration
      // foo.yml
      debug: true
      test: true
    • from the command line:
      > node index --debug --test
    • using environment configuration(comma delimited)
      $ set ENV=DEBUG,TEST
      # also
      $ set NODE_ENV=DEBUG,TEST
      $ node index
  • .toJSON():Object

    Returns clean json configuration object.

  • .done(callback)

    Fire the callback when the configuration is loaded

Source

Common properties for all source types
{
    // Define specific property to extract SUB-JSON from the loaded configuration
    // @default: null
    getterProperty: String

    // Define specific property in the root configuration,
    // where the loaded configuration should be inserted into
    // @default: null
    setterProperty: String

    // Specify if this source can be used for persistence
    // @default: false
    writable: Boolean

    // Fires before source $read function is called
    // (e.g. change this.path property or any other things)
    beforeRead: Function<Source, RootConfig>

    // Fires after source completes reading
    // (e.g. access config object in `Source.config`)
    afterRead: Function<Source, RootConfig>

    // If true, do not log any warning if the source returns 404
    // @default: false
    optional: true

    // If true, then waits until all previous sources are loaded
    // @default: false
    sync: true
}
FileSource
{
    // File path
    path: String
}
DirectorySource

It will be mapped to multiple FileSources

{
    // Directory path with GLOB look-up, e.g. 'configs/**.json'
    path: String
}
MongoDBSource

Depends on ClassJS

{
    // Collection name
    mongo: String,

    // if source is writable
    // @default: true
    writable: Boolean

    // MongoDB Connection Settings
    // It can be also specified in previous configuration source, under `mongodb` property
    // @default: null -
    settings: {
        // connection string
        connection: String
        // or

        // Port, default 27017
        port: Number,
        // IP, default '127.0.0.1'
        ip: String,

        // Database name, no default
        db: String
    }
}
CustomSource

This source type can suit any needs.

// Constructor with the Deferrable Interface and the method `read`
Function

class Foo {
    config: any
    async read (){
        // do any reads and calcs, after that resolve the source
        this.config = await loadConfig();
    }
}
Embedded

Include config direct into the source

{
    config: Object
}

Test

$ npm install
$ npm test

(c) 2014-2022 MIT License

0.4.70

5 months ago

0.4.69

1 year ago

0.4.68

2 years ago

0.4.67

2 years ago

0.4.64

2 years ago

0.4.65

2 years ago

0.4.62

2 years ago

0.4.63

2 years ago

0.4.61

2 years ago

0.4.59

2 years ago

0.4.54

2 years ago

0.4.58

2 years ago

0.4.53

3 years ago

0.4.51

3 years ago

0.4.52

3 years ago

0.4.5

3 years ago

0.4.4

3 years ago

0.3.3

3 years ago

0.3.2

3 years ago

0.2.56

5 years ago

0.2.55

5 years ago

0.2.54

5 years ago

0.2.53

5 years ago

0.2.52

5 years ago

0.2.51

6 years ago

0.2.50

6 years ago

0.2.48

6 years ago

0.2.47

6 years ago

0.2.46

7 years ago

0.2.45

7 years ago

0.2.44

7 years ago

0.2.43

7 years ago

0.2.42

9 years ago

0.2.41

9 years ago

0.1.41

10 years ago

0.1.40

10 years ago

0.1.39

10 years ago

0.1.38

10 years ago

0.1.37

10 years ago

0.1.36

10 years ago

0.1.35

10 years ago

0.1.34

10 years ago

0.1.33

10 years ago

0.1.32

10 years ago

0.1.30

10 years ago

0.1.28

10 years ago

0.1.26

10 years ago

0.1.24

10 years ago

0.1.23

10 years ago

0.1.22

10 years ago

0.1.21

10 years ago

0.1.20

10 years ago

0.1.19

10 years ago

0.1.18

10 years ago

0.1.17

10 years ago

0.1.16

10 years ago

0.1.15

10 years ago

0.1.14

10 years ago

0.1.13

10 years ago

0.1.12

10 years ago

0.1.11

10 years ago

0.1.10

10 years ago

0.1.9

10 years ago

0.1.8

10 years ago

0.1.7

10 years ago

0.1.6

10 years ago

0.1.5

10 years ago

0.1.4

10 years ago

0.1.3

10 years ago

0.1.2

10 years ago