Git Product home page Git Product logo

confidog's Introduction

Confidog

Cascade config loader for typescript from different config providers

Partially inspired by go library confita

Why?

We want hierarchical config collected over different config providers such as environment variables, files, POTO (T for typescript), vault, etcd, consul etc.

Usage

Imagine you have some env file with content like this

DEV_MODE=true
LOG_LEVEL=debug

POSTGRES_DB_HOST=db
POSTGRES_DB=sample
POSTGRES_USER=sample
POSTGRES_PASSWORD=sample
POSTGRES_DB_PORT=5432

MAIL_HOST=mailcatcher
MAIL_PORT=1025
MAIL_USER=
MAIL_PASSWORD=

And you want config class like this

class Config {
    mail: {
        host: string;
        port: number;
        user: string;
        password: string;
    };
    database: {
        name: string;
        host: string;
        port: number;
        user: string;
        password: string;
    };
    crypto: {
        cryptoKey: string;
    };
    devMode: boolean;
    logLevel: string;
}

So you can use classes with property decorators to load config from envs and vault and put it to corresponding properties

import { EnvConfig, VaultConfig, NestedConfig } from 'confidog';

class MailConfig {
    @EnvConfig({ key: 'MAIL_HOST', default: 'localhost' })
    host: string;

    @EnvConfig({ key: 'MAIL_PORT', default: 1025 })
    port: number;

    @EnvConfig({ key: 'MAIL_USER', default: '' })
    user: string;

    @EnvConfig({ key: 'MAIL_PASSWORD', default: '' })
    password: string;
}

class DatabaseConfig {
    @EnvConfig({ key: 'DATABASE_HOST', default: 'localhost' })
    host: string;

    @EnvConfig({ key: 'DATABASE_PORT', default: 5432 })
    port: number;

    @EnvConfig({ key: 'DATABASE_USER', default: 'postgres' })
    user: string;

    @EnvConfig({ key: 'DATABASE_PASSWORD', default: '' })
    password: string;
}

class CryptoConfig {
    @EnvConfig({ key: 'CRYPTO_KEY', default: 'some_not_really_secret_value_for_development' })
    @VaultConfig({ key: 'crypto_key', default: 'unknown_crypto_key' })
    cryptoKey: string;
}

export class Config {
    @NestedConfig()
    mail: MailConfig;

    @NestedConfig()
    database: DatabaseConfig;

    @NestedConfig()
    crypto: CryptoConfig;

    @EnvConfig({ key: 'DEV_MODE', default: false })
    devMode: boolean;

    @EnvConfig({ key: 'LOG_LEVEL', default: 'debug' })
    logLevel: string;
}

Finally you just need to load it. You should define providers in such an order that the following provider get higher priority over the previous one. So in this example if there is a value in env and vault, the vault value (if exists) will override value from env.

import { ConfigLoader, EnvConfigProvider, VaultConfigProvider } from 'confidog';

const config = ConfigLoader.load(new Config(), {
    providers: [
        { key: 'env', value: new EnvConfigProvider() },
        { key: 'value', value: new VaultConfigProvider({ path: 'localhost:8200/kv/my', secret: 'some_vault_secret' }) },
    ]
});

Options

Validate

You can use class-validator decorators to validate loaded config via them For example you have following config

import { IsString } from 'class-validator';

export class Config {
    @EnvConfig({ key: 'DEV_MODE', default: false })
    devMode: boolean;

    @EnvConfig({ key: 'LOG_LEVEL', default: 'debug' })
    @IsString()
    logLevel: string;
}

You can specify option validate set to true

import { ConfigLoader, EnvConfigProvider } from 'confidog';

const config = ConfigLoader.load(new Config(), {
    providers: [{ key: 'env', value: new EnvConfigProvider() }],
    options: {
        validate: true
    }
});

Transform

Freeze

If you want config to be immutable, set option freeze to true. It set to true by default

import { ConfigLoader, EnvConfigProvider } from 'confidog';

const config = ConfigLoader.load(new Config(), {
    providers: [{ key: 'env', value: new EnvConfigProvider() }],
    options: {
        validate: true,
        freeze: true,
    }
});

### Samples

See `samples` directory. Also this samples are used in tests, so you can be sure that it is just working

### Usage with nestjs

See `samples/nestjs` directory.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.