npm package: @fine-js/env
Description: Read env vars in a robust way.
Author: Aleksei Zabrodskii
Latest version: 1.0.0

# env

Read [environment variables](https://nodejs.org/dist/latest/docs/api/process.html#process_process_env)
in a robust way and finally stop getting `undefined`s everywhere across your config.

```
npm install @fine-js/env
```

# Basic Usage

```js
const env = require('@fine-js/env')

env.has('PORT') // => false
env.get('PORT') // => Error: env var "PORT" missing
env.get('PORT', {required: false, defaultsTo: 3000, parseFn: Number}) // => 3000

console.log(env) // Prints a nice represantation sorted alphabetically by key
```

# API

## `get(name, options)`

Returns the value of variable `name` or throws an `Error` based on following options:

  - **`required`** <sup>`bool` `[true]`</sup>

    When `true`, throw in case env var is not set.

  - **`defaultsTo`** <sup>`anything` `[undefined]`</sup>

    For non-required env vars, this value will be returned directly
    without parsing with `parseFn`.

  - **`parseFn`** <sup>`function` `[(x) => x]`</sup>

    Values that come from `process.env` will be passed to this function for parsing,
    e.g. for port numbers, you'd want `Number`;
    feel free to do any validations here, but note that `defaultsTo` is returned directly.

  - **`allowEmpty`** <sup>`bool` `[false]`</sup>

    By default, empty strings on `process.env` throw an error;
    note that setting `defaultsTo` to `''` is okay.

  - **`allowUndefined`** <sup>`bool` `[false]`</sup>

    Whether resulting value can be `undefined`.

  - **`allowNull`** <sup>`bool` `[false]`</sup>

    Whether resulting value can be `null`.

## `has(name)`

Returns `true` when the variable named `name` is set to _any_ value.

## `createEnv()`

Default export is an environment object based with the contents of `process.env`
at the time of the module being required. You can get an updated version
or create new environment from any other object:

```js
const {createEnv} = require('@fine-js/env')

// Defaults to using process.env at the moment of calling.
createEnv()

// Or you can pass any other object.
createEnv({
  my: 'custom',
  env: '42',
})
```

## Changes

### `1.0.0`

I had no need to change this package for years now,
seems like it's time for the first stable version
with tests, overhauled API and 0 dependencies 🎉

`Env` is no longer a class, but a plain object with 4 exports:

  - `get` is a main function for reading env
  - `has` will tell you if environment has a certain key
  - `keys` creates an iterator for all the environment variable names present
  - `createEnv` allows to create a new environment

Not being a class means no longer inherting from `Map`,
which makes it non-iterable except via `keys()`
(there is rarely a need to iterate over **values**).
Another bonus is being nicely printable with `console` methods
and serializable to JSON.

`oneOf` option is removed as being out of scope.
You'll get better validations and more options by putting
those kinds of things under `parseFn`.

```js
env.get('PORT', {
  required: false,
  defaultsTo: 3000,
  parseFn: (val) => {
    const port = Number(val)
    assert(Number.isSafeInteger(port) && port >= 0 && port <= 65535)
    return port
  }
})
```

### `0.0.2`

**Fixed**

  - Small codebase issues and typos.



### `0.0.1`

**Added**

  - Initial realease.