60 lines
1.3 KiB
TypeScript
60 lines
1.3 KiB
TypeScript
function read<
|
|
const C extends readonly string[],
|
|
D extends Partial<Record<C[number], any>> & Record<Exclude<keyof D, C[number]>, never> = {},
|
|
>(columns: C, defaults: D): Record<C[number], any> {
|
|
const missing: string[] = []
|
|
|
|
const result: Record<string, any> = {}
|
|
|
|
for (const column of columns) {
|
|
let value: string | number | boolean | null | undefined = process.env[column]
|
|
|
|
if (value === undefined) {
|
|
value = defaults[column as keyof D] ?? null
|
|
missing.push(column)
|
|
} else {
|
|
if (typeof value === 'string') {
|
|
if (/^\d+$/.test(value)) {
|
|
value = Number(value)
|
|
} else if (['false', 'true', 'null', 'undefined'].includes(value)) {
|
|
// oxlint-disable-next-line no-eval
|
|
value = eval(value)
|
|
}
|
|
}
|
|
}
|
|
|
|
result[column] = value
|
|
}
|
|
|
|
if (missing.length) {
|
|
throw new Error(`Missing required env variables: ${missing.join(', ')}`)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
export default read(
|
|
[
|
|
'DOMAIN',
|
|
'PROTOCOL',
|
|
'HOSTNAME',
|
|
'PORT',
|
|
'FASTIFY_PORT',
|
|
'FASTIFY_HOST',
|
|
'LOG_LEVEL',
|
|
'LOG_STREAM',
|
|
'NODE_ENV',
|
|
'PGDATABASE',
|
|
'PGHOST',
|
|
'PGPASSWORD',
|
|
'PGPORT',
|
|
'PGUSER',
|
|
'REDIS_HOST',
|
|
] as const,
|
|
{
|
|
PGPASSWORD: null,
|
|
PGPORT: null,
|
|
PGUSER: null,
|
|
},
|
|
)
|