Skip to content

Instantly share code, notes, and snippets.

@jeiea
Last active March 21, 2024 15:19
Show Gist options
  • Save jeiea/73f585b2d1d568f6e53978ab435aaef3 to your computer and use it in GitHub Desktop.
Save jeiea/73f585b2d1d568f6e53978ab435aaef3 to your computer and use it in GitHub Desktop.
/**
* Create a configuration getter that reads from command line arguments, environment variables,
* and a .env file in the priority.
* @param args Result of deno std's [parseArgs](https://deno.land/std/cli/parse_args.ts)
* @param getEnv Function to get environment variables
* @param dotEnv Record from a .env file
* @returns A function that returns the value for a configuration parameter
*/
export function configSource<T>(
{ args, getEnv, dotEnv }: {
args: Readonly<T>;
getEnv?: typeof Deno.env.get;
dotEnv?: Readonly<Record<string, string>>;
},
) {
return function getConfig<R>(
parameterName: R extends Exclude<keyof RemoveIndex<T>, "_"> ? R : never,
environmentKey: string,
) {
const name = parameterName;
const key = environmentKey;
return args[name] ?? getEnv?.(key) ?? dotEnv?.[key];
};
}
type RemoveIndex<T> = {
// https://stackoverflow.com/a/68261113/4197293
// deno-lint-ignore ban-types
[K in keyof T as {} extends Record<K, 1> ? never : K]: T[K];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment