function read< const C extends readonly string[], D extends Partial> & Record, never> = {}, >(columns: C, defaults: D): Record { const missing: string[] = [] const result: Record = {} 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, }, )