@etrigan/config
TypeScript icon, indicating that this package has built-in type declarations

2.0.0 • Public • Published

Etrigan Config

A plugable config management library for your NodeJS applications.

Why

Config management is one of those things which sometimes you don't realise how important it is until you are using it. Some of the reasons to use a config library like Etrigan config is:

  • Eager validation
    • Validate the type and shape of your config on application startup, preventing hard to debug crashes at runtime
    • Very useful for automatic rollback on failed deployment
  • Config heirachy
    • Want to have defaults -> config file -> environmental variables -> command line param heirachy, no problems
  • Easily change config source
    • Want to move some of your config into a config file included in deployment? This is safe and easy using a config management library

Usage

import { environmentConfigDriver, jsonFileConfigDriver, loadConfig } from '@etrigan/config'

// Read raw config values from env variables
const envValues = environmentConfigDriver.read({
    testConfig: 'TEST_CONFIG',
})

// Read raw config values from json file
const fileValues = jsonFileConfigDriver.read('./config.json')

interface MyConfig {
    testItem?: string
    testItem2: string
}

// The load your config from the raw values
const config = loadConfig<MyConfig>({
    // Merge the raw values in the order
    values: { ...fileValues, ...envValues },
    defaults: {
        testItem2: 'some value',
    },
    // Specify validation rules for
    validateConfig: {
        testItem: 'optional-string',
        testItem2: 'required-string',
    },
})

Drivers

The above example loads config directly in code, drivers allow you to load config based on other config values. The two included drivers are quite basic, drivers can be more advanced, loading from APIs.

Example:

const config = loadConfig<MyConfig>({
    // Merge the raw values in the order
    values: getConfigRecords('json://./config.dev.json'),
    defaults: {
        testItem2: 'some value',
    },
    // Specify validation rules for
    validateConfig: {
        testItem: 'optional-string',
        testItem2: 'required-string',
    },
})

You can also register your own drivers, for example:

import {
    environmentConfigDriver,
    loadConfig,
    getConfigRecords,
    registerDriver,
} from '@etrigan/config'
import { parameterStoreConfigDriver } from '@etrigan/config-driver-ssm'

const bootstrapConfig = loadConfig({
    values: await environmentConfigDriver.read({
        configDriver: 'CONFIG_DRIVER',
    }),
    validateConfig: {
        configDriver: 'required-string',
    },
})

registerDriver(parameterStoreConfigDriver)

// CONFIG_DRIVER=ssm://my-app/dev/ region=ap-southeast-2
const config = loadConfig<Config>({
    values: await getConfigRecords(bootstrapConfig.configDriver),
    validateConfig: {
        val: 'required-string',
        secret: 'required-string',
    },
})

The above ensure we have a value for configDriver from an environmental variable CONFIG_DRIVER. It will then load the parameter store driver, getting all config values for the path /my-app/dev and making them available as raw values.

This driver will automatically decode Secure-String values too if KMS is setup.

Config Validation

There are a few built in config validations. They are:

  • required-boolean
  • optional-boolean
  • required-string
  • optional-string
  • non-empty-string
  • optional-int
  • required-int

Custom validations

If the above config validations are not enough, you can specify a function instead.

const config = loadConfig<Config>({
    values,
    validateConfig: {
        // We want validate a required JS object
        val: value => {
            // Some drivers support objects, so we need to handle both
            if (value !== null && typeof value === 'object') {
                return {
                    valid: true,
                    parsedValue: value,
                }
            }

            // If it's a string, assume it's a stringified object and parse it
            if (typeof value === 'string') {
                try {
                    return {
                        valid: true,
                        parsedValue: JSON.parse(value),
                    }
                } catch {}
            }

            return {
                valid: false,
            }
        },
    },
})

Readme

Keywords

none

Package Sidebar

Install

npm i @etrigan/config

Weekly Downloads

777

Version

2.0.0

License

MIT

Unpacked Size

71.6 kB

Total Files

35

Last publish

Collaborators

  • wimomisterx
  • jakeginnivan