Skip to content

Instantly share code, notes, and snippets.

@OliverBrotchie
Created July 18, 2022 12:24
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 OliverBrotchie/a62d67bcd9dd8af80457888a985013da to your computer and use it in GitHub Desktop.
Save OliverBrotchie/a62d67bcd9dd8af80457888a985013da to your computer and use it in GitHub Desktop.
Enviroment Config
/**
* @file Environment variables & configuration utilities.
*/
import { EnvError } from "../errors/envError";
import dotenv from "dotenv";
dotenv.config();
export enum Env {
CLIENT_ID = "CLIENT_ID",
KINETIC_SECURE_URL = "KINETIC_SECURE_URL",
PRIVATE_KEY = "PRIVATE_KEY",
PUBLIC_KEY = "PUBLIC_KEY",
}
/**
* A config class that checks if a set of environment variables are present,
* garunteering that the variables will be present when they are retrieved.
*
* @example
* ```ts
* const TestConfig = new ConfigFactory(
* "Test Config",
* [Env.PUBLIC_KEY, Env.PRIVATE_KEY],
* { CUSTOM_CONST: "xyz" }
* );
*
* // Get config values
* TestConfig.get(Env.PUBLIC_KEY);
* TestConfig.get("CUSTOM_CONST");
* ```
*/
export class ConfigFactory<E extends Env, T extends string | number> {
private name: string;
private keys: Array<E>; // Used to vefify that the environment variables are present
stateChecked = false;
state: {
[key: string | number]: string;
};
/**
* Instanciate a new ConfigFactory.
* @param name The name of the configuration factory (to be thrown alongside errors).
* @param env The set of environment variables to check.
* @param constants An optional set of constants to include.
*/
constructor(name: string, env: Array<E>, constants?: Record<T, string>) {
// Do not Env check until first get() call
const result = env.reduce((acc, variable) => {
acc[variable] = process.env[variable] as string;
return acc;
}, {} as Record<E, string>);
this.state = { ...result, ...constants };
this.keys = env;
this.name = name;
}
/**
* Get a config value.
* @param env The key of the config value to get.
* @returns The config value.
* @throws EnvError if the environment variable is not present.
*/
get(env: E | T): string {
this.check();
if (typeof this.state[env] !== "string")
throw new EnvError("Runtime value was not a string", this.name);
return this.state[env];
}
/**
* Performs a one time check to if the environment variables are present.
* @throws {EnvError} if the environment variables are not present.
*/
check(): void {
if (this.stateChecked) return;
const missing = this.keys.reduce((acc, variable) => {
if (typeof process.env[variable] !== "string") acc.push(variable);
return acc;
}, [] as Array<E>);
if (missing.length !== 0) {
throw new EnvError(missing, this.name);
}
this.stateChecked = true;
return;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment