Skip to content

Instantly share code, notes, and snippets.

@nebez
Created September 4, 2018 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nebez/379627714ec80cc536fbba9d5d235da4 to your computer and use it in GitHub Desktop.
Save nebez/379627714ec80cc536fbba9d5d235da4 to your computer and use it in GitHub Desktop.
Type-safe config loading
// TODO: We need an overload for a default value so it doesn't throw
function env(name: string): string;
function env<T>(name: string, transformer: (dirty: string) => T): T;
function env<T>(name: string, transformer?: (dirty: string) => T): T | string {
const value = process.env[name];
if (value == undefined) {
// todo: should null be allowed? it might be a valid value for some
// consumers instead of defaulting to an empty string.
throw new Error(`Missing environment variable: ${name}`);
}
if (typeof transformer === 'function') {
return transformer(value);
}
return value;
}
interface ApplicationConfiguration {
environment: 'production' | 'development';
debug: boolean;
logLevel: false | number;
connection: Connection;
}
type Connection = RedisConnection | DynamoDbConnection | MemoryConnection
interface RedisConnection {
type: 'redis';
options: {
host: string;
port: number;
databaseId: number;
};
}
interface DynamoDbConnection {
type: 'dynamodb';
options: {
region: string;
accessKeyId: string;
secretAccessKey: string;
tableName: string;
};
}
interface MemoryConnection {
type: 'memory';
}
const config: ApplicationConfiguration = {
environment: env('NODE_ENV', getValidNodeEnvironment),
debug: true,
logLevel: env('LOG_LEVEL', getLogLevel),
connection: env('CONNECTION_DRIVER', getConnectionOptions),
};
function getValidNodeEnvironment(env: string) {
if (env === 'production' || env === 'development') {
return env;
}
throw new Error(`Bad NODE_ENV value: ${env}`);
}
function getLogLevel(level: string) {
const num = parseInt(level);
if (num === 0) {
return false;
}
return num;
}
function getConnectionOptions(driver: string): Connection {
if (driver === 'memory') {
return { type: 'memory' };
} else if (driver === 'dynamodb') {
return { type: 'dynamodb', options: {
region: env('DYNAMODB_REGION'),
accessKeyId: env('AWS_ACCESS_KEY_ID'),
secretAccessKey: env('AWS_SECRET_ACCESS_KEY'),
tableName: env('DYNAMODB_TABLE'),
}};
} else if (driver === 'redis') {
return { type: 'redis', options: {
host: env('REDIS_HOST'),
port: env('REDIS_PORT', parseInt),
databaseId: env('REDIS_DB', parseInt),
}};
}
throw new Error(`Invalid connection driver: ${driver}`);
}
export { config };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment