npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

environment-decoder

v1.3.0

Published

A decoder for the process.env

Downloads

1,502

Readme

environment decoder

Publish GitHub release

A decoder for the process.env

With environment-decoder you define a decoder for your environment variable names, and their corresponded types.

This library took a big inspiration from typescript-json-decoder, the main differences are that process.env is just a record type (no need for nested decoding) and since all process.env values default to string in environment-decoder you can cast the value to the desired type (see usage).

Idea (read struggle)

For most applications we have to trust that the environment flags are set correctly and often we see cases like:

server.listen(Number(process.env.PORT || 8080))

// or

// we are certain this is set by someone
if (process.env.FEATURE_FLAG!) {
    // ...
}

// or

// sure, this is fine
const baseURL = process.env.BASE_URL || ''
fetch(`${baseURL}/api`)
    .then(response => response.json())

This creates a lot of uncertainty: are the environment flags set? what are their "real" types?

Usage

Add it to your project

yarn add environment-decoder

// or

npm install environment-decoder

Since all environment variables are set as string, the decoder type primitives are written with asType as we will be casting (and validating) each variable.

Use .withDefault() to set default values for non-required environment variables.

import {environmentDecoder, asBoolean, asString, asNumber} from 'environment-decoder'

const myEnv = environmentDecoder({
    BASE_URL: asString,
    ENVIRONMENT: asStringUnion("dev","qa", "prod"),
    PORT: asNumber,
    FEATURE_FLAG: asBoolean,
    OPTIONAL_FLAG: asString.withDefault('OPTION_1')
})

// will output the process.env.BASE_URL value
console.log(myEnv.BASE_URL)

// will output the process.env.OPTIONAL_FLAG value if set, if not will output 'OPTION_1'
console.log(myEnv.OPTIONAL_FLAG) 

You can also use the output type created by environmentDecoder with DecodeType<typeof ...>:

import {environmentDecoder, asBoolean, asString, asNumber, DecodeType} from 'environment-decoder'

const myEnv = environmentDecoder({
    BASE_URL: asString,
    PORT: asNumber,
    FEATURE_FLAG: asBoolean
})

type MyEnvType = DecodeType<typeof myEnv>

const funWithEnv = (envParam: MyEnvType) => {
    console.log(envParam.FEATURE_FLAG)
}

Notes

environment-decoder will throw exceptions when:

  • the environment variable is not set and not using .withDefault() - all missing variables will be listed in the exception
  • the environment variable cannot be cast to type (ex: using asNumber on abcde)
  • using asStringUnion or asNumberUnion and the environment variable is not set to one of the allowed values

All exceptions will be thrown at run time, so it would be recommended to use environmentDecoder as close as possible to the entry point of the application in order to catch errors as early as possible.

Examples

Use it as React.js hook:

remember to use Error boundaries to handle exceptions thrown on your app

// useEnvironment.js
import {asString, environmentDecoder} from 'environment-decoder'

export const useEnvironment = function () {
    // if environment is not set will throw at this step
    return environmentDecoder({
        REACT_APP_MY_ENV_TEST: asString,
        NODE_ENV: asString
    })
}

// App.js
import {useEnvironment} from './useEnvironment'

function App() {
    const env = useEnvironment()
    return (
        <div>
            <h1>{env.REACT_APP_MY_ENV_TEST}</h1>
        </div>
    )
}

Use it in a Node.js application:

const fetch = require('node-fetch')
const {environmentDecoder, asString} = require('environment-decoder')

// if environment is not set will throw at this step
const config = environmentDecoder({
    FETCH_URL: asString,
    ACCESS_TOKEN: asString
})

const response = await fetch(config.FETCH_URL, {
    method: 'get',
    headers: {
        'Authorization': `Bearer ${config.ACCESS_TOKEN}`,
        'Content-type': 'application/json'
    }
})

const messageData = await response.json()