0.0.0-dev • Published 1 year ago

@yaupon/config-manager v0.0.0-dev

Weekly downloads
-
License
-
Repository
-
Last release
1 year ago

Configuration Management

// configuration management // Library will allow to define configuration entries like a interface and variables that later on // are built into schema with use of reflection.

Fully type-safe, easy-to-use and flexible configuration management for your application. Compatible with every back-end framework and up to standards with 12-factor app.

It was created as a replacement for Nest.js s* configuration management which is either safe to be used as allows startup with invalid configuration or lack of it.

  • We do not want to confuse a configuration management with secrets management, this library can be used at fact to provide secrets but overall I'm working on a separate library for that which will be more focused on such, such as async initialization, secrets rotation, etc. For most usecases at back-end usage of this library is good enough, it's based on convict so it's pretty solid.

TODOs

  • Add support for configuration files
  • Add support for custom validation
  • Add support for externalized configuration (ex. Configcat)
  • Add support for creating individual configuration entries (to be rethinked)

Usage

import {defineSchema, ConfigurationManager} from "@yaupon/config";

// It's recommended to keep your configurations "scoped" for the things
// that they are responsible for. This way you can easily manage them
// and keep them organized.
type DatabaseConfig = {
    host: string;
    port: number;
    user: string;
    password: string;
    database: string;
}

// It's recommended to define one entry-point of your configuration
// this one should contain all the other configurations. This way
// you can easily manage them and keep them organized. Also
// it's easier to pass them around and have static type checking.
export type Configuration = {
    stripeKey: string;
    database: DatabaseConfig;
}

// Beside defining the whole schema in one go, you can acually define
// smaller parts of it and later merge them together at ConfiguratonManager.
const databaseSchema = defineSchema<DatabaseConfig>({
    host: {
        env: 'DB_HOST',
        description: 'Database host',
        required: true,
        default: null
    },
    port: {
        env: 'DB_PORT',
        description: 'Database',
    },
    // Etc...
})

const configManager = new ConfigurationManager<Configuration>({
    stripeKey: {
        env: 'STRIPE_KEY',
        description: 'Stripe API key',
        required: true,
        default: null
    },
    database: databaseSchema
})

// Now you can access your configuration like this
// get("string") is a autocompleted path to a variables you
// have defined in interface and output from get is typed.

const config = configManager.get("database.host") // string

// You can also get the whole configuration object
// However that's not recommended as I've wasted hours
// debugging why I can't have damn dot-props.
const wholeConfiguration = configManager.get()

Resolve priority

  1. Arguments
  2. Environment variables
  3. Configuration file
  4. Defaults
export const STRIPE_KEY = ConfigEntry.create<string>('STRIPE_KEY', 'stripe_key', 'Stripe API key');