返回排行榜

af/envalid

TypeScript

Environment variable validation for Node, Bun, and other compatible JS runtimes

nodenodejsenvironmentvalidationjavascriptbun
Star 增长趋势
Star
1.6k
Forks
69
周增长
Issues
4
5001k1.5k
2013年3月2017年8月2022年2月2026年7月
制品库npmnpm install envalid
README

Envalid text logo with drop shadow

Envalid is a small library for validating and accessing
environment variables in Node.js programs

Current GitHub Build Status Badge

Envalid is a small library for validating and accessing environment variables in 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 from under you while the program is running

Why Envalid?

  • Type-safe: written completely in TypeScript, with great support for inference
  • Light: no dependencies!
  • Modular: customize behavior with custom validators, middleware, and reporters

API

envalid.cleanEnv(environment, validators, options)

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.

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.

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'] }),
})

// Read an environment variable, which is validated and cleaned during
// and/or filtering that you specified with cleanEnv().
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'

For an example you can play with, clone this repo and see the example/ directory.

git clone https://github.com/af/envalid
cd envalid
bun install
node example/server.js

Validator types

Node's process.env only stores strings, but sometimes you want to retrieve other types (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 a 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", "yes", "no", "on", "off" 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 admissible 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.
  • testDefault - A fallback value to use only when NODE_ENV=test. When provided, it takes priority over both devDefault and default in test environments. Unlike the testOnly() helper (which is wrapped around a devDefault and therefore can't coexist with a separate dev value), testDefault can be combined with default and devDefault to provide distinct values for production, development, and test.
  • 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.
  • requiredWhen - A function (env -> boolean) specifying when this env var is required. Use With default: undefined (optional value).

Custom validators

Basic usage

You can easily create your own validator functions with envalid.makeValidator(). It takes a function as its only parameter, and should either return a cleaned value, or throw if the input is unacceptable:

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 env = cleanEnv(process.env, {
  INITIALS: twochars(),
})

TypeScript users

You can use either one of makeValidator, makeExactValidator and makeStructuredValidator depending on your use case.

makeValidator<BaseT>

This validator has the output narrowed down to a subtype of BaseT (e.g. str). Example of a custom integer validator:

const int = makeValidator<number>((input: string) => {
  const coerced = parseInt(input, 10)
  if (Number.isNaN(coerced)) throw new EnvError(`Invalid integer input: "${input}"`)
  return coerced
})
const MAX_RETRIES = int({ choices: [1, 2, 3, 4] })
// Narrows down output type to '1 | 2 | 3 | 4' which is a subtype of 'number'

makeExactValidator<T>

This validator has the output widened to T (e.g. bool). To understand the difference with makeValidator, let's use it in the same scenario:

const int = makeExactValidator<number>((input: string) => {
  const coerced = parseInt(input, 10)
  if (Number.isNaN(coerced)) throw new EnvError(`Invalid integer input: "${input}"`)
  return coerced
})
const MAX_RETRIES = int({ choices: [1, 2, 3, 4] })
// Output type is 'number'

As you can see in this instance, the output type is exactly number, the parameter type of makeExactValidator. Also note that here, int is not parametrizable.

Error Reporting

By default, if any required environment variables are missing or have invalid values, Envalid will log a message and call process.exit(1). You can override this behavior by passing in your own function as options.reporter. For example:

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

Additionally, Envalid exposes EnvError and EnvMissingError, which can be checked in case specific error handling is desired:

const env = cleanEnv(process.env, myValidators, {
    reporter: ({ errors, env }) => {
        for (const [envVar, err] of Object.entries(errors)) {
            if (err instanceof envalid.EnvError) {
                ...
            } else if (err instanceof envalid.EnvMissingError) {
                ...
            } else {
                ...
            }
        }
    }
})

Custom Middleware (advanced)

In addition to cleanEnv(), as of v7 there is a new customCleanEnv() function, which allows you to completely replace the processing that Envalid applies after applying validations. You can use this custom escape hatch to transform the output however you wish.

envalid.customCleanEnv(environment, validators, applyMiddleware, options)

customCleanEnv() uses the same API as cleanEnv(), but with an additional applyMiddleware argument required in the third position:

  • applyMiddleware - A function 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.

FAQ

Can I call structuredClone() on Envalid's validated output?

Since by default Envalid's output is wrapped in a Proxy, structuredClone will not work on it. See #177.

  • dotenv is a very handy tool for loading env vars from .env files. It was previously used as a dependency of Envalid. To use them together, simply call require('dotenv').config() before you pass process.env to your envalid.cleanEnv().

  • react-native-config can be useful for React Native projects for reading env vars from a .env file

  • fastify-envalid is a wrapper for using Envalid within Fastify

  • nestjs-envalid is a wrapper for using Envalid with NestJS

  • nuxt-envalid is a wrapper for using Envalid with NuxtJS

Motivation

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

相关仓库
vercel/next.js

The React Framework

JavaScriptnpmMIT Licensereactserver-rendering
nextjs.org
141.1k31.5k
nodejs/node

Node.js JavaScript runtime ✨🐢🚀✨

JavaScriptnpmOthernodejsjavascript
nodejs.org
118.4k36.2k
nvm-sh/nvm

Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions

ShellMIT Licensenvmnodejs
94.2k10.3k
nestjs/nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀

TypeScriptnpmMIT Licensenestjavascript
nestjs.com
76.2k8.4k
sindresorhus/awesome-nodejs

:zap: Delightful Node.js packages and resources [BECAUSE OF TOO MUCH SPAM AND LOW-QUALITY SUBMISSIONS, SUBMISSIONS ARE PAUSED UNTIL JULY]

Creative Commons Zero v1.0 Universalawesomeawesome-list
node.cool
66.3k6.2k
withastro/astro

The web framework for content-driven websites. ⭐️ Star to support our work!

TypeScriptnpmOtherstatic-site-generatorblog
astro.build
61.2k3.6k
nuxt/nuxt

the full-stack Vue framework

TypeScriptnpmMIT Licensecsrfull-stack
nuxt.com
60.7k5.7k
coreybutler/nvm-windows

A node.js version management utility for Windows. Ironically written in Go.

GoGo ModulesMIT Licensenodeversioning
47.1k3.9k
Asabeneh/30-Days-Of-JavaScript

30 days of JavaScript programming challenge is a step-by-step guide to learn JavaScript programming language in 30 days. This challenge may take more than 100 days, please just follow your own pace. These videos may help too: https://www.youtube.com/channel/UC7PNRuno1rzYPb1xLa4yktw

JavaScriptnpm30daysofjavascriptjavascript-for-everyone
46.6k10.5k
Unitech/pm2

Node.js/Bun Production Process Manager with a built-in Load Balancer.

JavaScriptnpmOtherpm2nodejs
pm2.keymetrics.io/docs/usage/quick-start/
43.2k2.7k
directus/directus

The flexible backend for all your projects 🐰 Turn your DB into a headless CMS, admin panels, or apps with a custom UI, instant APIs, auth & more.

TypeScriptnpmOtherapicms
directus.com
36.7k4.9k
pnpm/pnpm

Fast, disk space efficient package manager

Rustcrates.ioMIT Licensenpmdependency-manager
pnpm.io
35.8k1.6k