Socket
Socket
Sign inDemoInstall

dotenv

Package Overview
Dependencies
0
Maintainers
3
Versions
86
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 14.3.2 to 15.0.0

20

CHANGELOG.md

@@ -5,4 +5,22 @@ # Changelog

## [Unreleased](https://github.com/motdotla/dotenv/compare/v14.3.2...master)
## [Unreleased](https://github.com/motdotla/dotenv/compare/v15.0.0...master)
## [15.0.0](https://github.com/motdotla/dotenv/compare/v14.3.2...v15.0.0) (2022-01-31)
`v15.0.0` is a major new release with some important breaking changes.
### Added
- _Breaking:_ Multiline parsing support (just works. no need for the flag.)
### Changed
- _Breaking:_ `#` marks the beginning of a comment (UNLESS the value is wrapped in quotes. Please update your `.env` files to wrap in quotes any values containing `#`. For example: `SECRET_HASH="something-with-a-#-hash"`).
..Understandably, (as some teams have noted) this is tedious to do across the entire team. To make it less tedious, we recommend using [dotenv cli](https://github.com/dotenv-org/cli) going forward. It's an optional plugin that will keep your `.env` files in sync between machines, environments, or team members.
### Removed
- _Breaking:_ Remove multiline option (just works out of the box now. no need for the flag.)
## [14.3.2](https://github.com/motdotla/dotenv/compare/v14.3.1...v14.3.2) (2022-01-25)

@@ -9,0 +27,0 @@

2

lib/cli-options.js

@@ -1,2 +0,2 @@

const re = /^dotenv_config_(encoding|path|debug|override|multiline)=(.+)$/
const re = /^dotenv_config_(encoding|path|debug|override)=(.+)$/

@@ -3,0 +3,0 @@ module.exports = function optionMatcher (args) {

@@ -20,6 +20,2 @@ // ../config.js accepts options via environment variables

if (process.env.DOTENV_CONFIG_MULTILINE != null) {
options.multiline = process.env.DOTENV_CONFIG_MULTILINE
}
module.exports = options
// TypeScript Version: 3.0
/// <reference types="node" />
export interface DotenvParseOptions {
/**
* Default: `false`
*
* Turn on logging to help debug why certain keys or values are not being set as you expect.
*
* example: `dotenv.parse('KEY=value', { debug: true })`
*/
debug?: boolean;
/**
* Default: `false`
*
* Turn on multiline line break parsing.
*
* example:
*
* MY_VAR="this
* is
* a
* multiline
* string"
*/
multiline?: boolean;
}
export interface DotenvParseOutput {

@@ -44,4 +18,3 @@ [name: string]: string;

export function parse<T extends DotenvParseOutput = DotenvParseOutput>(
src: string | Buffer,
options?: DotenvParseOptions
src: string | Buffer
): T;

@@ -85,17 +58,2 @@

override?: boolean;
/**
* Default: `false`
*
* Turn on multiline line break parsing.
*
* example:
*
* MY_VAR="this
* is
* a
* multiline
* string"
*/
multiline?: boolean;
}

@@ -113,3 +71,3 @@

*
* @param options - additional options. example: `{ path: './custom/path', encoding: 'latin1', debug: true, override: false, multiline: false }`
* @param options - additional options. example: `{ path: './custom/path', encoding: 'latin1', debug: true, override: false }`
* @returns an object with a `parsed` key if successful or `error` key if an error occurred. example: { parsed: { KEY: 'value' } }

@@ -116,0 +74,0 @@ *

@@ -5,74 +5,38 @@ const fs = require('fs')

function log (message) {
console.log(`[dotenv][DEBUG] ${message}`)
}
const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
const NEWLINE = '\n'
const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*("[^"]*"|'[^']*'|.*?)(\s+#.*)?$/
const RE_NEWLINES = /\\n/g
const NEWLINES_MATCH = /\r\n|\n|\r/
// Parses src into an Object
function parse (src, options) {
const debug = Boolean(options && options.debug)
const multiline = Boolean(options && options.multiline)
// Parser src into an Object
function parse (src) {
const obj = {}
// convert Buffers before splitting into lines and processing
const lines = src.toString().split(NEWLINES_MATCH)
// Convert buffer to string
let lines = src.toString()
for (let idx = 0; idx < lines.length; idx++) {
let line = lines[idx]
// Convert line breaks to same format
lines = lines.replace(/\r\n?/mg, '\n')
// matching "KEY' and 'VAL' in 'KEY=VAL'
const keyValueArr = line.match(RE_INI_KEY_VAL)
// matched?
if (keyValueArr != null) {
const key = keyValueArr[1]
// default undefined or missing values to empty string
let val = (keyValueArr[2] || '')
let end = val.length - 1
const isDoubleQuoted = val[0] === '"' && val[end] === '"'
const isSingleQuoted = val[0] === "'" && val[end] === "'"
let match
while ((match = LINE.exec(lines)) != null) {
const key = match[1]
const isMultilineDoubleQuoted = val[0] === '"' && val[end] !== '"'
const isMultilineSingleQuoted = val[0] === "'" && val[end] !== "'"
// Default undefined or null to empty string
let value = (match[2] || '')
// if parsing line breaks and the value starts with a quote
if (multiline && (isMultilineDoubleQuoted || isMultilineSingleQuoted)) {
const quoteChar = isMultilineDoubleQuoted ? '"' : "'"
// Remove whitespace
value = value.trim()
val = val.substring(1)
// Check if double quoted
const maybeQuote = value[0]
while (idx++ < lines.length - 1) {
line = lines[idx]
end = line.length - 1
if (line[end] === quoteChar) {
val += NEWLINE + line.substring(0, end)
break
}
val += NEWLINE + line
}
// if single or double quoted, remove quotes
} else if (isSingleQuoted || isDoubleQuoted) {
val = val.substring(1, end)
// Remove surrounding quotes
value = value.replace(/^(['"])([\s\S]+)\1$/mg, '$2')
// if double quoted, expand newlines
if (isDoubleQuoted) {
val = val.replace(RE_NEWLINES, NEWLINE)
}
} else {
// remove surrounding whitespace
val = val.trim()
}
// Expand newlines if double quoted
if (maybeQuote === '"') {
value = value.replace(/\\n/g, '\n')
value = value.replace(/\\r/g, '\r')
}
obj[key] = val
} else if (debug) {
const trimmedLine = line.trim()
// ignore empty and commented lines
if (trimmedLine.length && trimmedLine[0] !== '#') {
log(`Failed to match key and value when parsing line ${idx + 1}: ${line}`)
}
}
// Add to object
obj[key] = value
}

@@ -83,3 +47,7 @@

function resolveHome (envPath) {
function _log (message) {
console.log(`[dotenv][DEBUG] ${message}`)
}
function _resolveHome (envPath) {
return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath

@@ -94,7 +62,6 @@ }

const override = Boolean(options && options.override)
const multiline = Boolean(options && options.multiline)
if (options) {
if (options.path != null) {
dotenvPath = resolveHome(options.path)
dotenvPath = _resolveHome(options.path)
}

@@ -107,4 +74,4 @@ if (options.encoding != null) {

try {
// specifying an encoding returns a string instead of a buffer
const parsed = DotenvModule.parse(fs.readFileSync(dotenvPath, { encoding }), { debug, multiline })
// Specifying an encoding returns a string instead of a buffer
const parsed = DotenvModule.parse(fs.readFileSync(dotenvPath, { encoding }))

@@ -121,5 +88,5 @@ Object.keys(parsed).forEach(function (key) {

if (override === true) {
log(`"${key}" is already defined in \`process.env\` and WAS overwritten`)
_log(`"${key}" is already defined in \`process.env\` and WAS overwritten`)
} else {
log(`"${key}" is already defined in \`process.env\` and was NOT overwritten`)
_log(`"${key}" is already defined in \`process.env\` and was NOT overwritten`)
}

@@ -133,3 +100,3 @@ }

if (debug) {
log(`Failed to load ${dotenvPath} ${e.message}`)
_log(`Failed to load ${dotenvPath} ${e.message}`)
}

@@ -136,0 +103,0 @@

{
"name": "dotenv",
"version": "14.3.2",
"version": "15.0.0",
"description": "Loads environment variables from .env file",

@@ -5,0 +5,0 @@ "main": "lib/main.js",

@@ -31,22 +31,13 @@ <p align="center">

Usage is easy!
Create a `.env` file in the root of your project:
### 1. Create a `.env` file in the **root directory** of your project.
```dosini
# .env file
#
# Add environment-specific variables on new lines in the form of NAME=VALUE
#
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"
```
### 2. As early as possible in your application, import and configure dotenv.
As early as possible in your application, import and configure dotenv:
```javascript
// index.js
require('dotenv').config()
console.log(process.env) // remove this after you've confirmed it working

@@ -58,3 +49,2 @@ ```

```javascript
// index.mjs (ESM)
import 'dotenv/config' // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import

@@ -64,6 +54,4 @@ import express from 'express'

### 3. That's it! 🎉
That's it. `process.env` now has the keys and values you defined in your `.env` file:
`process.env` now has the keys and values you defined in your `.env` file.
```javascript

@@ -74,10 +62,78 @@ require('dotenv').config()

const db = require('db')
db.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS
})
s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {})
```
### Multiline values
If you need multiline variables, for example private keys, those are now supported (`>= v15.0.0`) with line breaks:
```dosini
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
...
Kh9NV...
...
-----END DSA PRIVATE KEY-----"
```
Alternatively, you can double quote strings and use the `\n` character:
```dosini
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\Kh9NV...\n-----END DSA PRIVATE KEY-----\n"
```
### Comments
Comments may be added to your file on their own line or inline:
```dosini
# This is a comment
SECRET_KEY=YOURSECRETKEYGOESHERE # comment
SECRET_HASH="something-with-a-#-hash"
```
Comments begin where a `#` exists, so if your value contains a `#` please wrap it in quotes. This is a breaking change from `>= v15.0.0` and on.
### Parsing
The engine which parses the contents of your file containing environment variables is available to use. It accepts a String or Buffer and will return an Object with the parsed keys and values.
```javascript
const dotenv = require('dotenv')
const buf = Buffer.from('BASIC=basic')
const config = dotenv.parse(buf) // will return an object
console.log(typeof config, config) // object { BASIC : 'basic' }
```
### Preload
You can use the `--require` (`-r`) [command line option](https://nodejs.org/api/cli.html#cli_r_require_module) to preload dotenv. By doing this, you do not need to require and load dotenv in your application code.
```bash
$ node -r dotenv/config your_script.js
```
The configuration options below are supported as command line arguments in the format `dotenv_config_<option>=value`
```bash
$ node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env dotenv_config_debug=true
```
Additionally, you can use environment variables to set configuration options. Command line arguments will precede these.
```bash
$ DOTENV_CONFIG_<OPTION>=value node -r dotenv/config your_script.js
```
```bash
$ DOTENV_CONFIG_ENCODING=latin1 DOTENV_CONFIG_DEBUG=true node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env
```
### Variable Expansion
You need to add the value of another variable in one of your variables? Use [dotenv-expand](https://github.com/motdotla/dotenv-expand).
### Syncing
You need to keep `.env` files in sync between machines, environments, or team members? Use [dotenv cli](https://github.com/dotenv-org/cli).
## Examples

@@ -101,2 +157,3 @@

* [express](https://github.com/dotenv-org/examples/tree/master/dotenv-express)
* [nestjs](https://github.com/dotenv-org/examples/tree/master/dotenv-nestjs)

@@ -170,23 +227,2 @@ ## Documentation

##### Multiline
Default: `false`
Turn on multiline line break parsing.
```js
require('dotenv').config({ multiline: true })
```
This allows specifying multiline values in this format:
```
PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIGT...
7ure...
-----END PRIVATE KEY-----"
```
Ensure that the value begins with a single or double quote character, and it ends with the same character.
### Parse

@@ -221,47 +257,4 @@

##### Multiline
Default: `false`
Turn on multiline line break parsing.
```js
require('dotenv').config({ multiline: true })
```
This allows specifying multiline values in this format:
```
PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIGT...
7ure...
-----END PRIVATE KEY-----"
```
## Other Usage
### Preload
You can use the `--require` (`-r`) [command line option](https://nodejs.org/api/cli.html#cli_r_require_module) to preload dotenv. By doing this, you do not need to require and load dotenv in your application code. This is the preferred approach when using `import` instead of `require`.
```bash
$ node -r dotenv/config your_script.js
```
The configuration options below are supported as command line arguments in the format `dotenv_config_<option>=value`
```bash
$ node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env dotenv_config_debug=true
```
Additionally, you can use environment variables to set configuration options. Command line arguments will precede these.
```bash
$ DOTENV_CONFIG_<OPTION>=value node -r dotenv/config your_script.js
```
```bash
$ DOTENV_CONFIG_ENCODING=latin1 DOTENV_CONFIG_DEBUG=true node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env
```
## FAQ

@@ -303,3 +296,3 @@

- lines beginning with `#` are treated as comments
- whitespace followed by `#` marks the beginning of an inline comment (unless when the value is wrapped in quotes)
- `#` marks the beginning of a comment (unless when the value is wrapped in quotes)
- empty values become empty strings (`EMPTY=` becomes `{EMPTY: ''}`)

@@ -329,4 +322,8 @@ - inner quotes are maintained (think JSON) (`JSON={"foo": "bar"}` becomes `{JSON:"{\"foo\": \"bar\"}"`)

React has dotenv built in but with a quirk. Preface your environment variables with `REACT_APP_`. See [this stack overflow](https://stackoverflow.com/questions/42182577/is-it-possible-to-use-dotenv-in-a-react-project) for more details.
Your React code is run in Webpack, where the `fs` module or even the `process` global itself are not accessible out-of-the-box. `process.env` can only be injected through Webpack configuration.
If you are using [`react-scripts`](https://www.npmjs.com/package/react-scripts), which is distributed through [`create-react-app`](https://create-react-app.dev/), it has dotenv built in but with a quirk. Preface your environment variables with `REACT_APP_`. See [this stack overflow](https://stackoverflow.com/questions/42182577/is-it-possible-to-use-dotenv-in-a-react-project) for more details.
If you are using other frameworks (e.g. Next.js, Gatsby...), you need to consult their documentation for how to inject environment variables into the client.
### Can I customize/write plugins for dotenv?

@@ -394,3 +391,3 @@

There are also 2 alternatives to this approach:
There are two alternatives to this approach:

@@ -397,0 +394,0 @@ 1. Preload dotenv: `node --require dotenv/config index.js` (_Note: you do not need to `import` dotenv with this approach_)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc