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

confidence

v5.0.1

Published

Configuration API

Downloads

65,563

Readme

confidence Logo

Confidence is a configuration document format, an API, and a foundation for A/B testing. The configuration format is designed to work with any existing JSON-based configuration, serving values based on object path ('/a/b/c' translates to a.b.c). In addition, confidence defines special $-prefixed keys used to filter values for a given criteria.

Version 5.x only supports node v12 and over. For older versions of node please use version 4.x.

Build Status Coverage Status

Lead Maintainer: Sunny Bhanot

Example

{
    "key1": "abc",
    "key2": {
        "$filter": "env",
        "production": {
            "deeper": {
                "$value": "value"
            }
        },
        "$default": {
            "$filter": "platform",
            "android": 0,
            "ios": 1,
            "$default": 2
        }
    },
    "key3": {
        "sub1": 123,
        "sub2": {
            "$filter": "xfactor",
            "yes": 6
        }
    },
    "ab": {
        "$filter": "random.a",
        "$range": [
            { "limit": 10, "value": 4 },
            { "limit": 20, "value": 5 }
        ],
        "$default": 6
    },
    "$meta": {
        "description": "example file"
    }
}

Without any criteria applied, the above configuration document will result in the following:

{
    "key1": "abc",
    "key2": 2,
    "key3": {
        "sub1": 123
    },
    "ab": 6
}

With the following criteria applied:

{
    "env": "production",
    "platform": "ios",
    "xfactor": "yes",
    "random": {
        "a": 15
    }
}

The result is:

{
    "key1": "abc",
    "key2": {
        "deeper": "value"
    },
    "key3": {
        "sub1": 123,
        "sub2": 6
    },
    "ab": 5
}

Document Format

Confidence builds on top of a Javascript object as its document.

Basic structure

The configuration document starts with a simple object. Key names can only contain alphanumeric characters and '_' with the '$' prefix reserved for special directives. Values can contain any non-object value (e.g. strings, numbers, booleans) as well as arrays.

{
    "key1": "abc",
    "key2": 2
}

Keys can have children:

{
    "key1": "abc",
    "key2": 2,
    "key3": {
        "sub1": 123
    }
}

Environment Variables

In many scenarios, configuration documents may need to pull values from environment variables. Confidence allows you to refer to environment variables using $env directive.

{
    "mysql": {
        "host": { "$env" : "MYSQL_HOST" },
        "port": { "$env" : "MYSQL_PORT" },
        "user": { "$env" : "MYSQL_USER" },
        "password": { "$env" : "MYSQL_PASSWORD" },
        "database": { "$env" : "MYSQL_DATABASE" },
    }
}

With following Enviornment Variables:

MYSQL_HOST=xxx.xxx.xxx.xxx
MYSQL_PORT=3306
MYSQL_USER=user1
MYSQL_PASSWORD=some_password
MYSQL_DATABASE=live_db

The result is:

{
    "mysql": {
        "host": "xxx.xxx.xxx.xxx",
        "port": "3306",
        "user": "user1",
        "password": "some_password",
        "database": "live_db"
    }
}

$default directive allows to fallback to default values in case an environment variable is not set.

{
    "mysql": {
        "host": { "$env" : "MYSQL_HOST" },
        "port": { "$env" : "MYSQL_PORT", "$default": 3306 },
        "user": { "$env" : "MYSQL_USER" },
        "password": { "$env" : "MYSQL_PASSWORD" },
        "database": { "$env" : "MYSQL_DATABASE" },
    }
}

With following Enviornment Variables:

MYSQL_HOST=xxx.xxx.xxx.xxx
MYSQL_USER=user1
MYSQL_PASSWORD=some_password
MYSQL_DATABASE=live_db

The result is:

{
    "mysql": {
        "host": "xxx.xxx.xxx.xxx",
        "port": 3306,
        "user": "user1",
        "password": "some_password",
        "database": "live_db"
    }
}

Coercing value

$coerce directive allows you to coerce values to different types. In case the coercing fails, it falls back to $default directive, if present. Otherwise it return undefined.

{
    "mysql": {
        "host": { "$env" : "MYSQL_HOST" },
        "port": {
            "$env" : "MYSQL_PORT",
            "$coerce": "number",
            "$default": 3306
        },
        "user": { "$env" : "MYSQL_USER" },
        "password": { "$env" : "MYSQL_PASSWORD" },
        "database": { "$env" : "MYSQL_DATABASE" },
    }
}

With following Environment Variables:

MYSQL_HOST=xxx.xxx.xxx.xxx
MYSQL_PORT=3316
MYSQL_USER=user1
MYSQL_PASSWORD=some_password
MYSQL_DATABASE=live_db

The result is:

{
    "mysql": {
        "host": "xxx.xxx.xxx.xxx",
        "port": 3316,
        "user": "user1",
        "password": "some_password",
        "database": "live_db"
    }
}

With following Environment Variables:

MYSQL_HOST=xxx.xxx.xxx.xxx
MYSQL_PORT=unknown
MYSQL_USER=user1
MYSQL_PASSWORD=some_password
MYSQL_DATABASE=live_db

The result is:

{
    "mysql": {
        "host": "xxx.xxx.xxx.xxx",
        "port": 3306,
        "user": "user1",
        "password": "some_password",
        "database": "live_db"
    }
}

Value can be coerced to :

  • number : applying Number(value)
  • boolean : checking whether the value equal true or false case insensitive
  • array : applying a value.split(token) with token (by default ',') modifiable by setting the key $splitToken to either a string or a regex
  • object : applying a JSON.parse(value)

Criteria Parameters

In many scenarios, configuration documents may need to pull values fron criteria. Confidence allows you to refer to criteria using $param directive.

{
    "mysql": {
        "host": { "$param" : "credentials.mysql.host" },
        "port": { "$param" : "credentials.mysql.port" },
        "user": { "$param" : "credentials.mysql.user" },
        "password": { "$param" : "credentials.mysql.password" },
        "database": { "$param" : "credentials.mysql.database" },
    }
}

With following criteria:

{
    "crendentials": {
        "mysql": {
            "host": "xxx.xxx.xxx.xxx",
            "port": 3306,
            "user": "user1",
            "password": "some_password",
            "database": "live_db"
        }
    }
}

The result is:

{
    "mysql": {
        "host": "xxx.xxx.xxx.xxx",
        "port": "3306",
        "user": "user1",
        "password": "some_password",
        "database": "live_db"
    }
}

$default directive allows to fallback to default values in case a criteria is undefined or null.

{
    "mysql": {
        "host": { "$param" : "credentials.mysql.host" },
        "port": { "$param" : "credentials.mysql.port", "$default": 3306 },
        "user": { "$param" : "credentials.mysql.user" },
        "password": { "$param" : "credentials.mysql.password" },
        "database": { "$param" : "credentials.mysql.database" },
    }
}

With following criteria:

{
    "credentials": {
        "mysql": {
            "host": "xxx.xxx.xxx.xxx",
            "port": null,
            "user": "user1",
            "password": "some_password",
            "database": "live_db"
        }
    }
}

The result is:

{
    "mysql": {
        "host": "xxx.xxx.xxx.xxx",
        "port": 3306,
        "user": "user1",
        "password": "some_password",
        "database": "live_db"
    }
}

Filters

A key can have multiple values based on a filter. The filter is a key provided in a criteria object at the time of retrieval. Filter names can only contain alphanumeric characters and '_'.

{
    "key1": "abc",
    "key2": {
        "$filter": "env",
        "production": 1
    }
}

When asking for '/key2', if no criteria set is provided or the criteria set does not include a value for the 'env' filter, no value is available. Only when a criteria set with a key 'env' and value 'production' is provided, the value returned is 1.

Filters can point to a nested value using '.' seperated tokens for accessing child values within the criteria object.

{
    "key1": "abc",
    "key2": {
        "$filter": "system.env",
        "production": 1
    }
}

Filters can have a default value which will be used if the provided criteria set does not include a value for the filter or if the value does not match.

{
    "key1": "abc",
    "key2": {
        "$filter": "system.env",
        "production": 1,
        "$default": 2
    }
}

Filters can also refer to environment variables using $env directive.

{
    "key1": "abc",
    "key2": {
        "$filter": { "$env": "NODE_ENV" },
        "production": {
            "host": { "$env" : "MYSQL_HOST" },
            "port": {
                "$env" : "MYSQL_PORT",
                "$coerce": "number",
                "$default": 3306
            },
            "user": { "$env" : "MYSQL_USER" },
            "password": { "$env" : "MYSQL_PASSWORD" },
            "database": { "$env" : "MYSQL_DATABASE" },
        },
        "$default": {
            "host": "127.0.0.1",
            "port": 3306,
            "user": "dev",
            "password": "password",
            "database": "dev_db"
        }
    }
}

Ranges

Ranges provide a way to filter a value based on numerical buckets. The criteria value must be an integer and be matched against the lowest bucket limit it can fit.

{
    "key1": "abc",
    "key2": {
        "$filter": "system.env",
        "production": 1,
        "$default": 2
    },
    "key3": {
        "$filter": "random.a",
        "$range": [
            { "limit": 10, "value": 4 },
            { "limit": 20, "value": 5 }
        ],
        "$default": 6
    }
}

If the criteria includes a value for random.a, that value is matched against the sorted range entries. The criterion value will match the entry with lowest limit it is still less than or equal the limit of. For example, a criterion value of 5 will return a key value for '/key3' of 4. A criterion value of 15 will return a key value for '/key3' of 5, and a criterion value of 50 will return a key value for '/key3' of 6.

Metadata

The configuration file can be annotated with metadata that is ignored (and removed) by the parser. Metadata is useful for human readable information as well as to enable other tools such as configuration editors and validators, going beyond the basic parsing specified here.

{
    "key1": "abc",
    "key2": {
        "$filter": "system.env",
        "production": 1,
        "$default": 2
    },
    "key3": {
        "$filter": "random.a",
        "$range": [
            { "limit": 10, "value": 4 },
            { "limit": 20, "value": 5 }
        ],
        "$default": 6
    },
    "$meta": {
        "anything": "really"
    }
}

To annotate non object values, any value can be wrapped in an object and provided using the $value directive.

{
    "key1": {
        "$value": "abc",
        "$meta": "whatever"
    },
    "key2": {
        "$filter": "system.env",
        "production": 1,
        "$default": 2
    },
    "key3": {
        "$filter": "random.a",
        "$range": [
            { "limit": 10, "value": 4 },
            { "limit": 20, "value": 5 }
        ],
        "$default": 6
    },
    "$meta": {
        "anything": "really"
    }
}

Shared values

If you have values that you would like to share between various configuration objects without duplicating them for each option, you can create a $base object.

{
  "$filter": "env",
  "$base": {
      "logLocation": "/logs",
      "flags": ["a", "b"],
      "tags": {
          "$value": ["DEBUG"],
          "$replace": true
      }
  },
  "production":  {
      "logLevel": "error",
      "flags": ["c", "d"],
      "tags": ["INFO", "ERROR"]
  },
  "qa":  {
      "logLevel": "info",
      "logLocation": "/qa/logs",
      "flags": ["e", "f"],
      "tags": ["DEBUG"]
  },
  "staging":  {
      "logLevel": "debug"
  }
}

When requesting the key / with:

  • criteria of { "env" : "production" }
  • Result will be:
{
	"logLevel": "error",
	"logLocation": "/logs",
    "flags": ["a", "b", "c", "d"],
    "tags": ["INFO", "ERROR"]
}

However when requesting the key / with:

  • criteria of { "env" : "staging" }
  • Result will be:
{
	"logLevel": "debug",
	"logLocation": "/logs",
    "flags": ["a", "b"],
    "tags": ["DEBUG"],
}

If the same key occurs in $base and the filtered value:

  • for objects, the value in $base will be overridden.
  • for arrays, the arrays are merged unless the $base array is specified with the $value key and the $replace flag as shown above.

In the above sample, when requesting the key / with:

  • criteria of { "env": "qa" }

  • Result will be:

{
	"logLevel": "info",
	"logLocation": "/qa/logs"
}

API

Confidence.Store

The configuration parser used to load the configuration document and apply criteria to get values based on keys.

new Store([document])

Creates an empty configuration storage container where:

  • document - an optional object containing a confidence configuration object generated from a parsed JSON document. If the document is invalid, will throw an error. Defaults to {}.
const Confidence = require('confidence');

const store = new Confidence.Store();

store.load(document)

Validates the provided configuration, clears any existing configuration, then loads the configuration where:

  • document - an object containing a confidence configuration object generated from a parsed JSON document. If the document is invalid, will throw an error.
const document = {
    a: 1,
    b: 2,
    c: {
        $filter: 'size',
        big: 100,
        small: 1,
        $default: 50
    }
};

store.load(document);

store.get(key, [criteria])

Retrieves a value from the configuration document after applying the provided criteria where:

  • key - the requested key path. All keys must begin with '/'. '/' returns the the entire document.
  • criteria - optional object used as criteria for applying filters in the configuration document. Defaults to {}.

Returns the value found after applying the criteria. If the key is invalid or not found, returns undefined.

const value = store.get('/c', { size: 'big' });

store.meta(key, [criteria])

Retrieves the metadata (if any) from the configuration document after applying the provided criteria where:

  • key - the requested key path. All keys must begin with '/'. '/' returns the the entire document.
  • criteria - optional object used as criteria for applying filters in the configuration document. Defaults to {}.

Returns the metadata found after applying the criteria. If the key is invalid or not found, or if no metadata is available, returns undefined.

const value = store.meta('/c', { size: 'big' });