utils/src/loadConfig.ts

49 lines
1.6 KiB
TypeScript

import path from "path";
import { convertCamelToUpperSnakeCase, readJsonIfExists } from "./utils";
export default <T>(opts: Partial<T>, envKey: string, filePath = "") => {
const { env } = process,
defPath = filePath || path.join(process.cwd() ?? ".", "defaults.json5"),
def = readJsonIfExists(defPath),
// 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];
};
const retVal = {
...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;
}, {}),
};
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;
}, {}),
};
};