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

0.3.1 • Public • Published

Node Config Processor

npm version License

This repository is part of a collection of my personal node.js libraries and templates. I am making them available to the public - feel free to offer suggestions, report issues, or make PRs via GitHub.

This project is a utility to process a configuration file to allow for basic templating, including obfuscation and loading variables from the environment. Note that the system does NOT require the use of any specific configuration system.

Operations

Each string value in a config object is evaluated and processed. Prefix values are evaluated to check for processing.

  • RAW: indicates that the remainder of the string should be used unaltered. Useful if your value starts with the same value as one of these prefixes.
  • HEXSTR: indicates that the remainder of the string is a hex encoded UTF8 string. The decoded value is used raw and NOT recursively processed.
  • B64STR: indicates that the remainder of the string is a base64 encoded UTF8 string. The decoded value is used raw and NOT recursively processed.
  • ENV: indicates that the value should be pulled from the environment. The value is recursively processed, allowing it to be a FILE: for example.
    • ENV may optionally be used as: ENV:envVarName:default to provide a default if the variable is not found or is empty.
  • BOOL: indicates that the value should be converted to a boolean. The value is recursively processed.
  • INT: indicates that the value should be converted to an integer. Strings are converted as base-10. The value is recursively processed.
  • INT16: indicates that the value should be converted to an integer. Strings are converted as base-16. The value is recursively processed.
  • INT8: indicates that the value should be converted to an integer. Strings are converted as base-8. The value is recursively processed.
  • FILE: indicates that the value should be read from a file. The value is recursively processed.
  • SFILE##: indicates that the value should be read from a file but if the file does not exist, a ## byte random hex value will be written to the file. Useful to allow applications to create random tokens on first startup.
    • ie: SFILE8:/home/app/.myapp/.admin.password would read the value from this file or generate an 8-byte (16 character) hex value.
  • OBF: indicates that the value is obfuscated. The decoded value is used raw and NOT recursively processed.
  • CONFIG: indicates that the value should be pulled from another config value. This is intended for simple replication of a value.
    • It cannot be used in a recursive command (like ENV: BOOL: FILE: etc...)
    • The behavior is not defined or guarenteed if the target is also defined with a CONFIG
    • The target config should be specified in a syntax compatible with object-path

Recommended Usage

The following example shows using this module for configuring a main application using dotenv an config. Other modules can be used and other patterns are psosible.

Setup:

# For main applications
npm install @msamblanet/node-config-processor config json5 js-yaml dotenv extend
npm install --save-dev @types/extend

# For modules
npm install extend
npm install --save-dev @msamblanet/node-config-processor @types/extend
// moduleConfig.ts
import dotenv from 'dotenv';
dotenv.config();

import type { Config } from "@msamblanet/node-config-processor";
import nodeConfig from "config";
import ConfigProcessor from "@msamblanet/node-config-processor";

export interface ModuleConfig extends Config {
    a: number,
    b: number
};

export const config = new ConfigProcessor<ModuleConfig>(nodeConfig).process();
export default config;

// main.ts
import config from "./moduleConfig"

import Foo from "./Foo";
const foo = new Foo(config.foo);

console.log(foo.doStuff());

// Or if you need programatic injection also...later configs take precidence over earlier ones
const foo2 = new Foo(config.foo, { b: 30127 });
console.log(foo2.doStuff());
// Foo.ts
import extend from "extend";
import type { Config, AllOptional } from "@msamblanet/node-config-processor";

export interface FooConfig extends Config {
    a: number;
    b: number;
}
// Note: If you have deep structure and you need it all optional on overides, use RecursiveAllOptional instead
export type FooConfigOverrides = AllOptional<FooConfig>;

export class Foo {
    public static readonly DEFAULT_CONFIG: FooConfig = {
        a: 1,
        b: 2
    }
    protected readonly config: FooConfig

    public constructor(...config: (FooConfigOverrides|null|undefined)[]) {
        this.config = extend(true, {}, Foo.DEFAULT_CONFIG, ...config);
    }

    public doStuff() {
        return config.a + config.b;
    }
}
export default Foo;
# ./config/default.yaml
foo
    a: 42
    b: 64767

# ./config/development.yaml
configProcessor
    obfuscator
        defaultAlg: DEV21
        algSettings:
            DEV21:
                name: DEV21
                base: DEFAULT
                password: ENV:DEV21_OBF_PASSWORD

# ./config/production.yaml
configProcessor
    obfuscator
        defaultAlg: PROD21
        algSettings:
            PROD21:
                name: PROD21
                base: DEFAULT
                password: ENV:PROD21_OBF_PASSWORD

Recommended package

API (core)

ConfigProcessor(data)

Constructs the config processor. data is the configuration to process. Note that data will be modified IN-PLACE when process() is called.

ConfigProcessor.process()

Processes the data passed into the constructor, returning the config object for chaining. Note that the object is modified IN-PLACE and is NOT cloned.

ConfigProcessor.obfuscateString(val, alg)

Obfuscates val using the configured obfucator. If alg is specified, it is used as the obfuscaion alogrithm.

API (extensions)

The following methods are intended for extending/customizing the module if needed. Subclass before using the config...

ConfigProcessor.processConfig()

Method to pre-process the config. The default implementation performs the full object processing, but does not allow the obfuscator to be used because it requires initialization from the config object.

The config to process can be found in this.config and it should be processed in-place.

ConfigProcessor.getObfuscator(): Obfuscator

Constructs an Obfuscator object to be used. Default implementation establishes a @msamblanet/node-obfuscator object using the configuration under configProcessor.obfuscator in the source data.

ConfigProcessor.processObject(data): any

Walks the data object and processes all of nodes. The default implementation uses deep-iterator to walk the tree and replaces the value with the value returned by processNode.

ConfigProcessor.processNode(nodeDesc, val): any

Processes a value for a single node. nodeDesc is a description of the node. If any errors are thrown, it should be stringified and used to display the context.

Readme

Keywords

none

Package Sidebar

Install

npm i @msamblanet/node-config-processor

Weekly Downloads

1

Version

0.3.1

License

Apache-2.0

Unpacked Size

24.7 kB

Total Files

6

Last publish

Collaborators

  • msamblanet