Package Exports
- ts-configurable
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (ts-configurable) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
TS-Configurable
✨ Make all properties of a class configurable using only one decorator! ✨
TS-Configurable implements the @Configurable() decorator to make any class configurable via environment variables and command line arguments! Additionally, the BaseConfig<T> class can be extended to allow the passing of an options (options: Partial<T>) object that can partially override the property defaults specified in the configuration class:
🏃 Get started
Install via npm i ts-configurable and create a config class with default values for each property:
// server-config.ts
import { Configurable } from 'ts-configurable';
@Configurable()
class ServerConfig {
host = 'localhost';
port = 3000;
}
console.log(new ServerConfig());Due to the @Configurable() decorator, the values for all properties can now be set via environment variables and command line arguments:
# Default config instance
$ ts-node server-config.ts
ServerConfig { host: 'localhost', port: 3000 }
# Change port via command line argument
$ ts-node server-config.ts --port=4200
ServerConfig { host: 'localhost', port: 4200 }
# Change host via environment variable
$ host=0.0.0.0 ts-node server-config.ts
ServerConfig { host: '0.0.0.0', port: 3000 }
# Throw an error if a value with a different type was assigned
$ port=random ts-node server-config.ts
Property 'ServerConfig.port' is of type number but a value of type string ('"random"') was assigned!🎉 Features
- Type safety for your configuration:
- No need to maintain a separate interface
- Types can be infered from the property's default value
- Enforce correct types for values passed by environment variables and command line arguments
- Take full advantage of having a configuration class:
- Calculate config values based on other config values (e.g.
urlfromhostandport) - Getter functions (e.g.
get debugPort() { return this.port + 1000; }) - Inherit from other (config) classes
- Calculate config values based on other config values (e.g.
- Enforce the configuration object to be read-only
- Load environment variables from a local file (using dotenv)
🔧 API
@Configurable([options])
▸ Configurable(options?: IDecoratorOptions)
Class decorator for marking a class configurable: The values of all class properties can be set using the following sources, listed by priority (1 = highest):
- Command line arguments
- Environment variables
- Constructor options on instantiation
- Defaults provided with the property definitions
The final values for the config instance's properties are calculated upon instantiation.
<Optional> options.enforceReadonly: boolean
Enforce that all properties are read-only by using Object.freeze() (default: true)
<Optional> options.loadEnvFromFile: false | DotenvConfigOptions
Apply environment variables from a file to the current process.env
<Optional> options.parseArgv: false | IArgvOptions
Whether to parse command line arguments (default: true)
<Optional> options.parseArgv.prefix: string
Prefix for command line arguments (default: no prefix)
<Optional> options.parseEnv: false | IEnvOptions
Whether to parse environment variables (default: true)
<Optional> options.parseEnv.lowerCase: boolean
Whether to lower-case environment variables (default: false)
<Optional> options.parseEnv.prefix: string
Prefix for environment variables (default: no prefix)
<Optional> options.parseEnv.separator: string
Seperator for environment variables (default: '__')
<Optional> options.parseValues: boolean
Attempt to parse well-known values (e.g. 'false', 'null', 'undefined' and JSON values) into their proper types (default: true)
<Optional> options.strictTypeChecking: boolean
Throw an error if a config entry is set to a value of a different type than the default value (e.g. assigning a number to a string property) (default: true)
Example: Nested Properties
import { Configurable, BaseConfig } from '@tfs/config';
type TOrder = Partial<{
recipient: string;
priceTotal: number;
delivered: boolean;
billing: Partial<{ address: string }>;
}>;
class BasePizzaConfig extends BaseConfig<BasePizzaConfig> {
id = 5;
topping = 'cheese';
rating = null;
ingredients = ['tomato', 'bread'];
order: TOrder = {
recipient: 'John Doe',
priceTotal: 6.2,
delivered: true,
billing: {
address: 'Jerkstreet 53a, 1234 Whatevertown',
},
};
}
const pizzaConfig = new PizzaConfig({ topping: 'bacon' });
console.log(JSON.stringify(pizzaConfig, null, 2));By adding the @Configurable() decorator to any class, all of its properties can be configured via environment variables and command line arguments:
export pizza_order__delivered=false
$ start pizza-app --order.recipient=Jonny"
{
"id": 5,
"topping": "bacon",
"rating": null,
"ingredients": [
"tomato",
"bread"
],
"order": {
"recipient": "Jonny",
"priceTotal": 6.2,
"delivered": false,
"billing": {
"address": "Jerkstreet 53a, 1234 Whatevertown"
}
}
}Negating Boolean Arguments
If you want to explicitly set a field to false instead of just leaving it undefined or to override a default you can add a no- before the key: --no-key.
$ start pizza-app --cash --no-paypal
{ cash: true, paypal: false }