Socket
Socket
Sign inDemoInstall

read-env

Package Overview
Dependencies
2
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.3.0 to 2.0.0

dist/index.d.ts

129

package.json
{
"name": "read-env",
"version": "1.3.0",
"description": "Convert environment variables into JSON object",
"browser": "dist-browser/index.min.js",
"main": "dist-node/index.js",
"version": "2.0.0",
"description": "Transform environment variables into JSON object with sanitized values.",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"browser": "dist/index.umd.js",
"types": "dist/index.d.ts",
"repository": {

@@ -12,5 +14,6 @@ "type": "git",

"files": [
"dist-node/index.js",
"dist-browser/index.js",
"dist-browser/index.min.js"
"dist/",
"package.json",
"README.md",
"LICENCE"
],

@@ -22,2 +25,6 @@ "keywords": [

"JSON.parse",
"sanitize",
"process.env",
"config",
"conf",
"read"

@@ -32,85 +39,37 @@ ],

"scripts": {
"preversion": "npm test",
"prepublishOnly": "npm run build && npm test",
"eslint:fix": "eslint . --fix --color",
"eslint:check": "eslint . --color",
"build": "npm run build:node && npm run build:browser && npm run uglify:browser",
"build:node": "bnr build:node",
"build:browser": "bnr build:browser",
"uglify:browser": "bnr uglify:browser",
"compile": "bnr compile",
"test": "nyc ava --verbose",
"coveralls": "nyc npm run test && nyc report --reporter=text-lcov | coveralls"
"preversion": "npm run lint && npm test",
"prepublishOnly": "npm run lint && npm test && npm run build",
"prebuild": "rimraf dist",
"build": "rollup -c rollup.config.ts",
"lint": "eslint .",
"test": "jest",
"coveralls": "jest --coverage --coverageReporters=text-lcov | coveralls"
},
"betterScripts": {
"build:node": {
"command": "babel --presets env -d dist-node/ src/",
"env": {
"NODE_ENV": "production",
"BABEL_ENV": "production"
}
},
"build:browser": {
"command": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s read-env --node",
"env": {
"NODE_ENV": "production"
}
},
"uglify:browser": {
"command": "uglifyjs -m -o ./dist-browser/index.min.js ./dist-browser/index.js",
"env": {
"NODE_ENV": "production"
}
},
"compile": {
"command": "babel --presets env -d dist-node/ src/",
"env": {
"NODE_ENV": "development",
"BABEL_ENV": "development"
}
},
"test": {
"command": "babel --presets env -d dist-node/ src/",
"env": {
"NODE_ENV": "development",
"BABEL_ENV": "development"
}
}
},
"pre-push": {
"silent": false,
"run": [
"eslint:check"
]
},
"ava": {
"files": [
"test/**/*.spec.js"
],
"require": [
"babel-register",
"babel-polyfill"
],
"babel": "inherit"
},
"devDependencies": {
"ava": "^0.22.0",
"babel-cli": "^6.26.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-register": "^6.26.0",
"better-npm-run": "^0.1.0",
"browserify": "^16.2.2",
"coveralls": "^3.0.0",
"eslint": "^4.8.0",
"eslint-config-airbnb": "^15.1.0",
"eslint-plugin-ava": "^4.2.2",
"eslint-plugin-import": "^2.7.0",
"nyc": "^11.2.1",
"pre-push": "^0.1.1",
"uglify-es": "^3.3.9"
"@rollup/plugin-commonjs": "11.0.2",
"@rollup/plugin-node-resolve": "7.1.1",
"@types/jest": "25.1.4",
"@types/node": "13.9.8",
"@typescript-eslint/eslint-plugin": "2.26.0",
"@typescript-eslint/parser": "2.26.0",
"coveralls": "3.0.11",
"eslint": "6.8.0",
"eslint-config-airbnb-base": "14.1.0",
"eslint-plugin-import": "2.20.2",
"eslint-plugin-jest": "23.8.2",
"husky": "4.2.3",
"jest": "25.2.6",
"lint-staged": "10.1.1",
"prettier": "2.0.2",
"rimraf": "3.0.2",
"rollup": "2.3.2",
"rollup-plugin-terser": "5.3.0",
"rollup-plugin-typescript2": "0.27.0",
"ts-jest": "25.3.0",
"typescript": "3.8.3"
},
"dependencies": {
"camelcase": "5.0.0"
"@types/camelcase": "5.2.0",
"camelcase": "5.3.1"
}
}
# read-env
> Convert environment variables into JSON object with parsed values.
> Transform environment variables into JSON object with sanitized values.
[![NPM version](https://badge.fury.io/js/read-env.svg)](https://www.npmjs.com/package/read-env)
[![Build Status](https://travis-ci.org/yatki/read-env.svg?branch=master)](https://travis-ci.org/yatki/read-env)
[![npm](https://img.shields.io/npm/dt/read-env.svg)](https://www.npmjs.com/package/read-env)
[![Coverage Status](https://coveralls.io/repos/github/yatki/read-env/badge.svg?branch=master&)](https://coveralls.io/github/yatki/read-env?branch=master)
[![npm](https://img.shields.io/npm/dt/read-env.svg)](https://www.npmjs.com/package/read-env)
[![Dependencies](https://david-dm.org/yatki/read-env/status.svg)](https://david-dm.org/yatki/read-env)
> See docs for previous version [v1.3.x](https://github.com/yatki/read-env/tree/v1.3.0).
Main purpose of this library is to allow developers to configure their applications with environment variables. See: [a use case example](#use-case-example).
## What's New with v2.x 🚀
- Migrated to Typescript, Yay! 🎉
- Simplified API
- With new `separator` option,nested object constructions are possible.
- New `source` option allows you to use other objects, other than `process.env`
## Migrating from v1.x to v2.x
- `default` export is **deprecated**. Please use named export `readEnv` as below:
```js
const { readEnv } = require('read-env');
// Or
import { readEnv } from 'read-env';
// Or in browser
window.readEnv('EXAMPLE');
```
- `parse` option was renamed as `sanitize`.
- `transformKey` option was renamed as `format`.
- Deprecated options: `ignoreInvalidJSON`, `prefix`, `filter`,
## Install

@@ -15,3 +42,5 @@

```
or
```

@@ -21,151 +50,216 @@ yarn add read-env

## Basic Example
## Basic Usage
Let's say you have some environment variables starting with prefix "**EXAMPLE_**" like below:
Let's say you have some environment variables starting with prefix "**EXAMPLE\_**" like below:
```text
EXAMPLE_OBJECT='{"prop": "value"}'
EXAMPLE_ARRAY='[1,2,3, "string", {"prop": "value"}, 5.2]'
EXAMPLE_INVALID_OBJECT='{"prop": }"value"}'
EXAMPLE_INVALID_ARRAY='[1,2,3, "string", ]{"prop": "value"}, 5.2]'
EXAMPLE_TRUE='true'
EXAMPLE_FALSE='false'
EXAMPLE_INT='5'
EXAMPLE_NEGATIVE_INT='-11'
EXAMPLE_FLOAT='5.2456'
EXAMPLE_NEGATIVE_FLOAT='-2.4567'
EXAMPLE_INT_ZERO='0'
EXAMPLE_FLOAT_ZERO='0.00'
EXAMPLE_NEGATIVE_INT_ZERO='-0'
EXAMPLE_NEGATIVE_FLOAT_ZERO='-0.00'
EXAMPLE_STRING='example'
EXAMPLE_DEEP__OBJECT__PROPERTY='value'
```
EXAMPLE_OBJECT_KEY= '{"prop": "value"}',
EXAMPLE_ARRAY_KEY= '[1,2,3, "string", {"prop": "value"}, 5.2]',
EXAMPLE_TRUE_KEY= 'true',
EXAMPLE_FALSE_KEY= 'false',
EXAMPLE_INT_KEY= '5',
EXAMPLE_FLOAT_KEY= '5.2',
EXAMPLE_STRING_KEY= 'example',
```
your-app.js
```javascript
import readEnv from 'read-env';
app.js
const options = readEnv('EXAMPLE');
console.log(options);
```js
import { readEnv } from 'read-env';
const result = readEnv('EXAMPLE');
console.log(result);
```
Output:
```javascript
{
arrayKey: [ 1, 2, 3, 'string', { prop: 'value' }, 5.2 ],
falseKey: false,
floatKey: 5.2,
intKey: 5,
objectKey: { prop: 'value' },
stringKey: 'example',
trueKey: true
Result:
```json
{
"object": { "prop": "value" },
"array": [1, 2, 3, "string", { "prop": "value" }, 5.2],
"invalidObject": "{\"prop\": }\"value\"}",
"invalidArray": "[1,2,3, \"string\", ]{\"prop\": \"value\"}, 5.2]",
"true": true,
"false": false,
"int": 5,
"negativeInt": -11,
"float": 5.2456,
"negativeFloat": -2.4567,
"intZero": 0,
"floatZero": 0,
"negativeIntZero": -0,
"negativeFloatZero": -0,
"string": "example",
"deep": {
"object": {
"property": "value"
}
}
}
```
## Usage
## API
### `readEnv(prefix = null, transformKey = 'camelcase')`
You can pass a string prefix as first paremeter like below:
### `readEnv(prefix?: string, options: ReadEnvOptions = {})`
```javascript
const options = readEnv('EXAMPLE');
// Output:
/**
{
arrayKey: [ 1, 2, 3, 'string', { prop: 'value' }, 5.2 ],
falseKey: false,
floatKey: 5.2,
intKey: 5,
objectKey: { prop: 'value' },
stringKey: 'example',
trueKey: true
}
*/
**Input:**
const optionsLower = readEnv('EXAMPLE', 'lowercase');
// Output:
/**
{
array_key: [ 1, 2, 3, 'string', { prop: 'value' }, 5.2 ],
false_key: false,
float_key: 5.2,
int_key: 5,
object_key: { prop: 'value' },
string_key: 'example',
true_key: true
}
*/
- `prefix` (type: `string`, default: `undefined`): filters environment variables by prefix
- `options` (type: `ReadEnvOptions`, default: `{}`): options object to change function's behaviour
function ucfirst(string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
**Returns:** `object` (type: _Record<string,any>_), returns the instance, so add methods are chainable.
### Options
**Default Options:**
```js
{
"source": process.env,
"format": "camelcase",
"separator": "__",
"sanitize": {
"object": true,
"array": true,
"bool": true,
"int": true,
"float": true
},
"includePrefix": false
}
const optionsUcfirst = readEnv('EXAMPLE', ucfirst);
// Output:
/**
{
Array_key: [ 1, 2, 3, 'string', { prop: 'value' }, 5.2 ],
False_key: false,
Float_key: 5.2,
Int_key: 5,
Object_key: { prop: 'value' },
String_key: 'example',
True_key: true
}
*/
```
### `readEnv(config)`
You can pass whole config object:
- [`options.source`](#optionssource)
- [`options.format`](#optionsformat)
- [`options.separator`](#optionsseparator)
- [`options.sanitize`](#optionssanitize)
- [`options.includePrefix`](#optionsincludeprefix)
```javascript
function ucfirst(string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
#### `options.source`
- Type: `object`
- Default: `process.env`
The source object that will be filtered, sanitized and formatted.
**Type Signature:**
```ts
interface Source {
[key: string]: string | undefined;
}
```
const options = readEnv({
prefix: 'EXAMPLE',
includePrefix: false,
transformKey: ucfirst,
parse: {
array: false, //not gonna parse arrays
}, //still gonna parse object, int, float and boolean
#### `options.format`
- Type: `boolean | string | function`
- Default: `camelcase`
Format environment variable name.
It's value can be:
- a `boolean`, if set to `false`, formatting is disabled
- a `string`, one of which `camelcase`, `pascalcase`, `lowercase`, `uppercase`
- a `function`, with `(rawVarName: string) => string` type signature
#### `options.separator`
- Type: `boolean | string`
- Default: `__`
Allows you construct nested objects from environment variable name.
- If set to `false`, constructing nested objects is disabled
**Example:**
```js
const { readEnv } = require('read-env');
const testInput = {
EXAMPLE_DEEP__OBJECT_PROPERTY1: 'value1',
EXAMPLE_DEEP__OBJECT_PROPERTY2: 'value2',
};
const result = readEnv('EXAMPLE', {
source: testInput,
});
console.log(result);
```
You can also pass your own filter function:
```javascript
const options = readEnv({
filter: (envVarName) => envVarName.indexOf('EXAMPLE') > 0 && envVarName === 'ANOTHER_REQUIRED_KEY',
});
Result:
```json
{
"deep": {
"object": {
"property1": "value1",
"property2": "value2"
}
}
}
```
## Config
#### `options.sanitize`
Available Config Options:
- `prefix` (type: *string*, default: *null*): filters environment variables by prefix
- `includePrefix` (type: *bool*, default: *false*): set true if you want to keep prefix in property names.
- `transformKey` (type: *bool*|*string*|*function*, default: *'camelcase'*): transform environment variable name.
1. `false`, doesn't transform the environment variable name.
1. `camelcase`, transforms variable name to camelCase.
1. `lowercase`, transforms variable name to lowercase.
1. `uppercase`, transforms variable name to UPPERCASE.
1. `fn(varName)`, you can write your own transformer function (*varName* will be provided **with** prefix, **if** *includePrefix* is *true*)
- `parse` (type: *bool*|*object*, default: *object*):
1. `false`: returns raw environment variable value
1. `{}`: allows you to define which value types are going to be parsed.
- `object` (type: *bool*, default: *true*): parse stringified object (value must be valid JSON input, see: [JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_JSON.parse())).
- `array` (type: *bool*, default: *true*): parse stringified array (value must be valid JSON input, see: [JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_JSON.parse())).
- `int` (type: *bool*, default: *true*): parse numbers into integer (value must be consist of only digits).
- `float` (type: *bool*, default: *true*): parse numbers into float (value must be consist of only digits with decimal point).
- `bool` (type: *bool*, default: *true*): parse if value into bolean if it equals to *'true'* or *'false'* .
- `ignoreInvalidJSON` (type: *bool*, default: *true*): if set to false, throws exception when value is not a valid JSON input (parse.object or parse.array options must be set to true).
- `filter` (type: *null*|*function*, default: *null*): filters environment variables (overrides prefix rule).
1. `null`, don't filter varaibles.
1. `fn(envVarName, index)`, custom filter function (*envVarName* will be provided **without** any transformation).
- Type: `boolean | object`,
- Default: `{}`
Sanitize object consists of following properties which is used to
- `object` (type: _bool_, default: _true_): sanitize stringified object
> value must be valid JSON input, see: [JSON.parse](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_JSON.parse()>).
- `array` (type: _bool_, default: _true_): sanitize stringified array
> value must be valid JSON input, see: [JSON.parse](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_JSON.parse()>).
- `int` (type: _bool_, default: _true_): sanitize numbers into integer
> value must be consist of only digits.
- `float` (type: _bool_, default: _true_): sanitize numbers into float
> value must be consist of only digits with decimal point.
- `bool` (type: _bool_, default: _true_): sanitize value into boolean
> value must have case insensitive match with "true" or "false".
#### `options.includePrefix`
- Type: `boolean`
- Default: `false`
If set to true, keeps the given prefix in property names.
## Use Case Example
Recently, I used [Nightmare](https://github.com/segmentio/nightmare) for *acceptance testing* and had several environments which have different configurations.
Instead of writing a code like below:
```javascript
In past, I used [Nightmare](https://github.com/segmentio/nightmare) for _acceptance testing_ and tests had different configurations based on the
environment they were running on.
So, I simply used read-env, and nightmare is fully configurable with environment variables :)
```js
import Nightmare from 'nightmare';
import { readEnv } from 'read-env';
const nightmareConfig = readEnv('MY_NIGHTMARE');
const nightmare = Nightmare(nightmareConfig);
```
Instead of writing code like below:
```js
import Nightmare from 'nightmare';
const nightmare = Nightmare({
show: process.env.X_NIGHTMARE_SHOW || false,
width: process.env.X_NIGHTMARE_WIDTH || 1280,
height: process.env.X_NIGHTMARE_HEIGHT || 720,
typeInterval: process.env.X_NIGHTMARE_TYPE_INTERVAL || 50,
show: process.env.MY_NIGHTMARE_SHOW || false,
width: process.env.MY_NIGHTMARE_WIDTH || 1280,
height: process.env.MY_NIGHTMARE_HEIGHT || 720,
typeInterval: process.env.MY_NIGHTMARE_TYPE_INTERVAL || 50,
//... other properties go forever

@@ -175,19 +269,10 @@ });

I wrote this, and nightmare is fully configurable with environment variables :)
```javascript
import Nightmare from 'nightmare';
import readEnv from 'read-env';
const nightmareConfig = readEnv('X_NIGHTMARE');
const nightmare = Nightmare(nightmareConfig);
```
## Contribution
As always, I'm open to any contribution and would like to hear your feedback.
As always, I'm open to any contribution and would like to hear your feedback.
### Just an important reminder:
If you are planning to contribute to **any** open source project,
before starting development, please **always open an issue** and **make a proposal first**.
If you are planning to contribute to **any** open source project,
before starting development, please **always open an issue** and **make a proposal first**.
This will save you from working on features that are eventually going to be rejected for some reason.

@@ -197,2 +282,2 @@

MIT (c) 2017 Mehmet Yatkı
MIT (c) 2020 Mehmet Yatkı

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc