npm package: @smpx/cfg
Description: Configuration management for node.js
Author: Hitesh Khandelwal
Latest version: 1.4.1

# cfg

Configuration management for node.js.

Example config:

```js
// config.js
module.exports = {
    db: {
        password: 'abcde',
        host: '127.0.0.1',
    },
    port: 3000,
    hosts: ['127.0.0.1'],
    logsDir: `${__dirname}/logs`,

    $env_production: {
        port: 80,
        logsDir: '/home/app/logs',
    },

    $env_test: {
        port: 5000,
    },

    $env_CI: {
        db: {
            // Docker image hostname
            host: 'postgresql',
        },
    },
};
```

Usage:

```js
const cfg = require('@smpx/cfg');

const dbConf = cfg('db'); // { password: 'abcde', host: '127.0.0.1' }
const dbPassword = cfg('db.password');

```

## Docs

It reads values from `config.js` file from project directory, but they can be overwritten with another `config.js` in the `private` folder in the project directory. Or through env vars in this format:

```sh
# Overwriting password (db.password):
CFG__DB__PASSWORD='password' yarn start
# Adding host to posiition 1 (hosts.1):
CFG__HOSTS__1='new-host.region.rds.amazonaws.com' yarn start
# Override all hosts
CFG__HOSTS='@JSON:["a.b", "c.d"]' yarn start
```

> NOTE: ENV VARS override might only work with camelCase keys

It basically uses lodash.set internally. The path is generated by removing the `CFG__` prefix and replacing `__` with `.` and converting each word in between to camelCase (also through lodash). If the value starts with `@JSON:`, it will be parsed as JSON (after removing `@JSON:`), so you can use it to set arrays, objects and numbers.

### NODE_ENV & CI overrides

cfg also allows overriding config according to NODE_ENV or CI environment variables. For example if NODE_ENV="production", then if a `$env_production` key exists it's value gets merged over existing conf (this happens before merging any `private/config.js` file).

Similarly in CI environments, the value in `$env_CI` is merged.

## API

Please check out the typescript definition file: [index.d.ts](./index.d.ts) for an overview of all the functions provided.

### Typescript

For getting types of the output types, you can define a typedef in your `config.js` file like:

```js
//config.js

const config = {
    db: {
        password: 'abcde',
        host: '127.0.0.1',
    },
};

/** @typedef {typeof config} ConfigType */

module.exports = config;
```

And in a global typings file in your project, like `global.d.ts`, import it and set this as the BaseConfig:

```ts
// global.d.ts
import { ConfigType } from './config';

declare global {
  interface BaseConfig extends ConfigType {}
}
```

This will be automatically picked by cfg. You can also modify this type with some custom keys available only through env vars:

```ts
// global.d.ts
import { ConfigType } from './config';

declare global {
    interface BaseConfig extends ConfigType {
       envVarOnlyKey?: string;
    }
}
```

## CLI

Get a value from cfg.js

```sh
# Installed globally
cfg get redis.port
cfg get logsDir

# See how ENV_VAR will override config
CFG__DB__PASSWORD='password' cfg get "db.password"

# Through npx or yarn (when installed locally)
npx cfg get redis.port
yarn cfg get logsDir

```