@6river/configr

Configr is a library that provides a set of TypeScript decorators to inject configuration params into class properties.

Usage no npm install needed!

<script type="module">
  import 6riverConfigr from 'https://cdn.skypack.dev/@6river/configr';
</script>

README

Configr

Configr is a library that provides a set of TypeScript decorators to inject configuration params into class properties.

Basic Usage

// Given is expected configuration received from some remote service or
// is read from the file or....
const config = {
  env: 'debug',
  log: {
    level: 'DEBUG',
    format: '%h %l %u %t \"%r\" %>s %b'
  }
};

// Basic Usage
@Config()
class Foo {
  @ConfigParam()
  readonly env: string;

  // by default property name is used as a path to access config parameter,
  // but path can elso be specified:
  @ConfigParam('log.level')
  readonly logLevel: string;

  // with default specified
  @ConfigParam('log.format')
  readonly logFormat: string = ''%h %l %u';
}

// The root path can be specified on class level
@Config({root: 'log'})
class Logger {
  @ConfigParam()
  level string;

  @ConfigParam()
  format string;
}

// suppose we have configuration fetched from remote service
function loadConfig() {
  return fetch('http://example.com/config.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(cfg) {
    // Apply loaded config to annotated properties.
    // This method should be calledonce.
    // It's not forbidden to call it many times but
    // all subsequent calls just have no effect.
    return configResolve(cfg);
  });
}

// as soon as config is loaded and resolved it's safe to use
// our objects that rely on its parameters:
async function useit() {
  await loadConfig(cfg);

  const foo = new Foo();
  const log = new Logger();
}

Advanced Usage

Specifying Parameter Parser

Parser can be specified as an additional option for @ConfigParam decorator:

const cfg = {
  logLevels: ['ERROR', 'INFO', 'DEBUG']
};

class LogLevel {
  constructor(public label: string) {}
}

function parseLogLevels(levels: string[]): LogLevel[] {
  return labels.map((level) => new LogLevel(level));
}

@Config()
class Foo {
  @ConfigParam({parser: parseLogLevels})
  readonly logLevels: LogLevel[];
}