utils/src/loadConfig.ts

51 lines
1.4 KiB
TypeScript

import path from "path";
import {
convertCamelToUpperSnakeCase,
getDirname,
readJsonIfExists,
} from "./utils";
export default <T>(
opts: Partial<T>,
envKey: string,
localDefaultFilePath = ""
) => {
const { env } = process,
{ __dirname } = getDirname(),
def = readJsonIfExists(
path.join(__dirname, localDefaultFilePath || "./defaults.json5")
),
// gets value from ENV || options || defaults (in that order)
getVal = (envName: keyof T) => {
const snakeEnvName = `${envKey}_${convertCamelToUpperSnakeCase(
envName as string
)}`;
if (env[snakeEnvName]) return env[snakeEnvName];
if (opts[envName]) return opts[envName];
return def[envName];
},
// gets array from ENV || options || defaults (in that order)
getArray = (envName: keyof T, optName: keyof T | "" = "") => {
let newEnvName;
if (optName === "") {
optName = envName;
newEnvName = convertCamelToUpperSnakeCase(envName as string);
}
newEnvName = `${envKey}_${String(envName)}`;
if (env[newEnvName])
return env?.[newEnvName as keyof typeof env]?.split(path.delimiter);
if (Array.isArray(opts[optName]) && (opts[optName] as []).length)
return opts[optName];
return def[optName];
};
return {
...Object.keys(def).reduce((acc: Partial<typeof def>, curr) => {
if (Array.isArray(def[curr])) acc[curr] = getArray(curr as keyof T);
else acc[curr] = getVal(curr as keyof T);
return acc;
}, {}),
};
};