Skip to content

Commit

Permalink
Simplifications and markdown formatting for README
Browse files Browse the repository at this point in the history
  • Loading branch information
af committed Jan 10, 2023
1 parent 2ab6c22 commit 237c2ad
Showing 1 changed file with 63 additions and 90 deletions.
153 changes: 63 additions & 90 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<p align="center">
<strong>
Envalid is a small library for validating and accessing<br />
environment variables in Node.js (v8.12 or later) programs
environment variables in Node.js programs
</strong>
</p>

Expand All @@ -19,40 +19,18 @@
</p>

Envalid is a small library for validating and accessing environment variables in
Node.js (v8.12 or later) programs, aiming to:
Node.js programs, aiming to:

* ensure that your program only runs when all of its environment dependencies are met
* give you executable documentation about the environment your program expects to run in
* give you an immutable API for your environment variables, so they don't change
- ensure that your program only runs when all of its environment dependencies are met
- give you executable documentation about the environment your program expects to run in
- give you an immutable API for your environment variables, so they don't change
from under you while the program is running

## Changes in v7.x

Version 7 is a major update, with several breaking changes. Please review the breaking changes
below before upgrading:

* Rewritten in TypeScript
* Removed _all_ runtime dependencies except for [tslib](https://github.com/Microsoft/tslib)
* The mode-currently-known-as-`strict` is removed, and its behavior is enabled by default. This means:
* The env object will *only* contain the env vars that were specified by your `validators`.
* Any attempt to access an invalid/missing property on the env object will cause a thrown error.
* Any attempt to mutate the cleaned env object will cause a thrown error.
You can still opt-out of strict mode by disabling the `strictProxyMiddleware`, but it's not
recommended (see "Custom Middleware", below).
* The `dotenv` package is no longer shipped as part of this library. You can easily use it directly
by installing it and running `require('dotenv').config()` before you invoke envalid's `cleanEnv()`
* The `transformer` validator option is gone, replaced by the ability to add custom middleware
* The `host` and `ip` validators are now slightly less exhaustive. If you need these to be airtight, use
your own custom validator instead
* When you try to access an invalid property on the cleaned env object, the error will no longer
suggest an env variable that you may have intended. You can re-implement the old behavior with a custom
middleware if you wish
* `NODE_ENV` support is now less opinionated, and an error is no longer thrown if a value other
than `production`/`development`/`test` is passed in. You can provide your own validator for `NODE_ENV`
to get exactly the behavior you want. The `isDev`, `isProduction`, etc properties still work as
before, and are implemented as middleware so you can override their behavior as needed.
* `devDefault` values are no longer used if `NODE_ENV` was not set in the environment (a case where
Envalid otherwise assumes `'production'` mode). Fixes #65
## Why envalid?

- Type-safe: written completely in TypeScript, with great support for inference
- Light: no dependencies besides [tslib](https://github.com/Microsoft/tslib)
- Modular: customize behavior with custom validators, middleware, and reporters

## API

Expand All @@ -61,11 +39,11 @@ below before upgrading:
`cleanEnv()` returns a sanitized, immutable environment object, and accepts three
positional arguments:

* `environment` - An object containing your env vars (eg. `process.env`)
* `validators` - An object that specifies the format of required vars.
* `options` - An (optional) object, which supports the following key:
* `reporter` - Pass in a function to override the default error handling and
console output. See `src/reporter.ts` for the default implementation.
- `environment` - An object containing your env vars (eg. `process.env`)
- `validators` - An object that specifies the format of required vars.
- `options` - An (optional) object, which supports the following key:
- `reporter` - Pass in a function to override the default error handling and
console output. See `src/reporter.ts` for the default implementation.

By default, `cleanEnv()` will log an error message and exit (in Node) or throw (in browser) if any required
env vars are missing or invalid. You can override this behavior by writing your own reporter.
Expand All @@ -74,22 +52,21 @@ env vars are missing or invalid. You can override this behavior by writing your
import { cleanEnv, str, email, json } from 'envalid'

const env = cleanEnv(process.env, {
API_KEY: str(),
ADMIN_EMAIL: email({ default: 'admin@example.com' }),
EMAIL_CONFIG_JSON: json({ desc: 'Additional email parameters' }),
NODE_ENV: str({ choices: ['development', 'test', 'production', 'staging']}),
API_KEY: str(),
ADMIN_EMAIL: email({ default: 'admin@example.com' }),
EMAIL_CONFIG_JSON: json({ desc: 'Additional email parameters' }),
NODE_ENV: str({ choices: ['development', 'test', 'production', 'staging'] }),
})


// Read an environment variable, which is validated and cleaned during
// and/or filtering that you specified with cleanEnv().
env.ADMIN_EMAIL // -> 'admin@example.com'
env.ADMIN_EMAIL // -> 'admin@example.com'

// Envalid checks for NODE_ENV automatically, and provides the following
// shortcut (boolean) properties for checking its value:
env.isProduction // true if NODE_ENV === 'production'
env.isTest // true if NODE_ENV === 'test'
env.isDev // true if NODE_ENV === 'development'
env.isProduction // true if NODE_ENV === 'production'
env.isTest // true if NODE_ENV === 'test'
env.isDev // true if NODE_ENV === 'development'
```

For an example you can play with, clone this repo and see the `example/` directory.
Expand All @@ -107,30 +84,29 @@ Node's `process.env` only stores strings, but sometimes you want to retrieve oth
(booleans, numbers), or validate that an env var is in a specific format (JSON,
url, email address). To these ends, the following validation functions are available:

* `str()` - Passes string values through, will ensure an value is present unless a
`default` value is given. Note that an empty string is considered a valid value -
if this is undesirable you can easily create your own validator (see below)
* `bool()` - Parses env var strings `"1", "0", "true", "false", "t", "f"` into booleans
* `num()` - Parses an env var (eg. `"42", "0.23", "1e5"`) into a Number
* `email()` - Ensures an env var is an email address
* `host()` - Ensures an env var is either a domain name or an ip address (v4 or v6)
* `port()` - Ensures an env var is a TCP port (1-65535)
* `url()` - Ensures an env var is a url with a protocol and hostname
* `json()` - Parses an env var with `JSON.parse`
- `str()` - Passes string values through, will ensure an value is present unless a
`default` value is given. Note that an empty string is considered a valid value -
if this is undesirable you can easily create your own validator (see below)
- `bool()` - Parses env var strings `"1", "0", "true", "false", "t", "f"` into booleans
- `num()` - Parses an env var (eg. `"42", "0.23", "1e5"`) into a Number
- `email()` - Ensures an env var is an email address
- `host()` - Ensures an env var is either a domain name or an ip address (v4 or v6)
- `port()` - Ensures an env var is a TCP port (1-65535)
- `url()` - Ensures an env var is a url with a protocol and hostname
- `json()` - Parses an env var with `JSON.parse`

Each validation function accepts an (optional) object with the following attributes:

* `choices` - An Array that lists the admissable parsed values for the env var.
* `default` - A fallback value, which will be present in the output if the env var wasn't specified.
Providing a default effectively makes the env var optional. Note that `default`
values are not passed through validation logic, they are default *output* values.
* `devDefault` - A fallback value to use *only* when `NODE_ENV` is explicitly set and _not_ `'production'`.
This is handy for env vars that are required for production environments, but optional
for development and testing.
* `desc` - A string that describes the env var.
* `example` - An example value for the env var.
* `docs` - A url that leads to more detailed documentation about the env var.

- `choices` - An Array that lists the admissable parsed values for the env var.
- `default` - A fallback value, which will be present in the output if the env var wasn't specified.
Providing a default effectively makes the env var optional. Note that `default`
values are not passed through validation logic, they are default _output_ values.
- `devDefault` - A fallback value to use _only_ when `NODE_ENV` is explicitly set and _not_ `'production'`.
This is handy for env vars that are required for production environments, but optional
for development and testing.
- `desc` - A string that describes the env var.
- `example` - An example value for the env var.
- `docs` - A url that leads to more detailed documentation about the env var.

## Custom validators

Expand All @@ -142,15 +118,16 @@ input is unacceptable:

```js
import { makeValidator, cleanEnv } from 'envalid'
const twochars = makeValidator(x => {
if (/^[A-Za-z]{2}$/.test(x)) return x.toUpperCase()
else throw new Error('Expected two letters')
const twochars = makeValidator((x) => {
if (/^[A-Za-z]{2}$/.test(x)) return x.toUpperCase()
else throw new Error('Expected two letters')
})

const env = cleanEnv(process.env, {
INITIALS: twochars()
});
INITIALS: twochars(),
})
```

### TypeScript users

You can use either one of `makeValidator`, `makeExactValidator` and `makeStructuredValidator`
Expand Down Expand Up @@ -197,9 +174,9 @@ this behavior by passing in your own function as `options.reporter`. For example

```js
const env = cleanEnv(process.env, myValidators, {
reporter: ({ errors, env }) => {
emailSiteAdmins('Invalid env vars: ' + Object.keys(errors))
}
reporter: ({ errors, env }) => {
emailSiteAdmins('Invalid env vars: ' + Object.keys(errors))
},
})
```

Expand All @@ -221,7 +198,6 @@ const env = cleanEnv(process.env, myValidators, {
})
```


## Custom Middleware (advanced)

In addition to `cleanEnv()`, as of v7 there is a new `customCleanEnv()` function,
Expand All @@ -233,11 +209,10 @@ validations. You can use this custom escape hatch to transform the output howeve
`customCleanEnv()` uses the same API as `cleanEnv()`, but with an additional `applyMiddleware`
argument required in the third position:

* `applyMiddleware` - A functions that can modify the env object after it's
validated and cleaned. Envalid ships (and exports) its own default
middleware (see src/middleware.ts), which you can mix and match with your own
custom logic to get the behavior you desire.

- `applyMiddleware` - A functions that can modify the env object after it's
validated and cleaned. Envalid ships (and exports) its own default
middleware (see src/middleware.ts), which you can mix and match with your own
custom logic to get the behavior you desire.

## Utils

Expand All @@ -248,7 +223,7 @@ A helper function called `testOnly` is available, in case you need an default en

```js
const env = cleanEnv(process.env, {
SOME_VAR: envalid.str({devDefault: testOnly('myTestValue')})
SOME_VAR: envalid.str({ devDefault: testOnly('myTestValue') }),
})
```

Expand All @@ -260,22 +235,20 @@ For more context see [this issue](https://github.com/af/envalid/issues/32).

Since by default envalid's output is wrapped in a Proxy, structuredClone [will not work](https://bugzilla.mozilla.org/show_bug.cgi?id=1269327#c1) on it. See [#177](https://github.com/af/envalid/issues/177).


## Related projects

* [dotenv](https://www.npmjs.com/package/dotenv) is a very handy tool for loading env vars from
- [dotenv](https://www.npmjs.com/package/dotenv) is a very handy tool for loading env vars from
`.env` files. It was previously used as a dependency of Envalid's. To use them together, simply
call `require('dotenv').config()` before you pass `process.env` to your `envalid.cleanEnv()`.

* [react-native-config](https://www.npmjs.com/package/react-native-config) can be useful for React Native projects for reading env vars from a `.env` file

* [fastify-envalid](https://github.com/alemagio/fastify-envalid) is a wrapper for using Envalid within [Fastify](https://www.fastify.io/)
- [react-native-config](https://www.npmjs.com/package/react-native-config) can be useful for React Native projects for reading env vars from a `.env` file

* [nestjs-envalid](https://github.com/cobraz/nestjs-envalid) is a wrapper for using Envalid with [NestJS](https://nestjs.com/)
- [fastify-envalid](https://github.com/alemagio/fastify-envalid) is a wrapper for using Envalid within [Fastify](https://www.fastify.io/)

* [nuxt-envalid](https://github.com/manuelhenke/nuxt-envalid) is a wrapper for using Envalid with [NuxtJS](https://nuxtjs.org/)
- [nestjs-envalid](https://github.com/cobraz/nestjs-envalid) is a wrapper for using Envalid with [NestJS](https://nestjs.com/)

- [nuxt-envalid](https://github.com/manuelhenke/nuxt-envalid) is a wrapper for using Envalid with [NuxtJS](https://nuxtjs.org/)

## Motivation

http://www.12factor.net/config
http://www.12factor.net/config

0 comments on commit 237c2ad

Please sign in to comment.