Repository URL to install this package:
|
Version:
1.3.3 ▾
|
/**
* @private
* @fileoverview loads .env files for the env
* @borrows https://github.com/motdotla/dotenv
*/
import { existsSync, readFileSync } from 'fs'
import { resolve } from 'path'
import {
AbsolutePathString,
DotEnvValues,
DotEnvConfigOptions,
} from './typings'
/**
* @private
* @description parses a string or buffer into an object
* @param src - source to be parsed
* @returns keys and values from src
*/
function parse(src: string | Buffer) {
const obj = {}
// convert Buffers before splitting into lines and processing
src
.toString()
.split('\n')
.forEach(line => {
// matching "KEY' and 'VAL' in 'KEY=VAL'
const keyValueArr = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/)
// matched?
if (keyValueArr !== null) {
const key = keyValueArr[1]
// default undefined or missing values to empty string
let value = keyValueArr[2] || ''
// expand newlines in quoted values
const len = value ? value.length : 0
if (
len > 0 &&
value.charAt(0) === '"' &&
value.charAt(len - 1) === '"'
) {
value = value.replace(/\\n/gm, '\n')
}
// remove any surrounding quotes and extra spaces
value = value.replace(/(^['"]|['"]$)/g, '').trim()
obj[key] = value
}
})
return obj
}
/**
* @private
* @param [options=undefined]
* @return path to .env file
*/
function getOptions(options: DotEnvConfigOptions): DotEnvConfigOptions {
let path = '.env'
let encoding = 'utf8'
if (options !== undefined) {
if (options.path) {
path = options.path
}
if (options.encoding) {
encoding = options.encoding
}
}
return { path, encoding }
}
// const DOT_ENV = []
process.env.DOT_ENV = '\n'
/**
* @private
* @description main entry point into dotenv. Allows configuration before loading .env
*
* @return {Object} parsed object or error
*/
function config(options: DotEnvConfigOptions) {
const { path, encoding } = getOptions(options)
try {
// specifying an encoding returns a string instead of a buffer
const content = readFileSync(path, { encoding })
const parsedObj = parse(content)
Object.keys(parsedObj).forEach(key => {
const value = parsedObj[key]
// if (hasOwnProp(process.env, key)) {
process.env[key] = value
process.env.DOT_ENV += `${key}=${value}\n`
// process.env.DOT_ENV[key] = value
// process.env.DOT_ENV.push([key, value])
})
return { parsed: parsedObj }
} catch (parseError) {
return { error: parseError }
}
}
/**
* @private
* @param envFileResolutionOrder
*/
function loadEnv(envFileResolutionOrder: AbsolutePathString[]): void {
// Find the first env file path match.
const envFilePath = envFileResolutionOrder.find(existsSync)
// console.log({ envFilePath })
// If we found an env file match the register it.
if (envFilePath) {
const message = `==> Registering environment variables from: ${envFilePath}`
// const colored = colors.bgBlue.white(message)
// console.log(colored)
console.log(message)
config({ path: envFilePath })
}
}
/**
* @private
* @see loadEnv
*
* @example @name env.data/LiquidAss
*/
function registerEnvFile(
envFile = '.env',
DEPLOYMENT = process.env.DEPLOYMENT
): void {
// This is the order in which we will try to resolve an environment configuration
// file.
const envFileResolutionOrder = [
// Is there an environment config file at the app root?
// This always takes preference.
// e.g. /projects/react-universally/.env
// resolve(appRootDir, envFile),
// Is there an environment config file at the app root for our target
// environment name?
// e.g. /projects/react-universally/.env.staging
]
const APP_ROOT_PATH = process.env.APP_ROOT_PATH
if (DEPLOYMENT) {
const DEPLOYMENT_DOT_ENV = resolve(
APP_ROOT_PATH,
`${envFile}.${DEPLOYMENT}`
)
// console.log(DEPLOYMENT_DOT_ENV)
// envFileResolutionOrder.push(DEPLOYMENT_DOT_ENV)
envFileResolutionOrder.unshift(DEPLOYMENT_DOT_ENV)
envFileResolutionOrder.unshift(`${DEPLOYMENT_DOT_ENV}/.env`)
}
// console.log({ envFileResolutionOrder })
loadEnv(envFileResolutionOrder)
}
/**
* @todo autofix here?
* @alias fromQueryStringToObj
*/
function loadFromDotEnvString(
DOT_ENV: string = process.env.DOT_ENV
): DotEnvValues {
const obj = {}
// could .reduce
DOT_ENV.split('\n')
.filter(String)
.map(string => string.split('='))
.forEach(([key, value]) => (obj[key] = value))
return obj
}
export { registerEnvFile }
export { loadFromDotEnvString }
export { loadEnv }