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

xenv-config

v1.3.1

Published

Load config from env, user config, or default spec

Downloads

507

Readme

NPM version Build Status Dependency Status devDependency Status

xenv-config

Load config from env, user config, or default spec.

Install

$ npm i xenv-config --save

Usage

const xenvConfig = require("xenv-config");
const spec = {
  fooOption: { env: "FOO_OPTION", default: false },
  barOption: { env: "BAR_OPTION", type: "number" },
  zooOption: { default: false, type: "truthy" },
  jsonOption: { env: "JSON_OPTION", type: "json" }
};

process.env.BAR_OPTION = "900";
process.env.JSON_OPTION = "{b:90}";
const config = xenvConfig(spec, { zooOption: true, jsonOption: { a: 50 } });

expect(config).to.deep.equal({
  fooOption: false,
  barOption: 900,
  zooOption: true,
  jsonOption: { a: 50, b: 90 }
});

expect(config.__$trace__).to.deep.equal({
  fooOption: { src: "default" },
  barOption: { src: "env", name: "BAR_OPTION" },
  zooOption: { src: "option" },
  jsonOption: { src: "env,option" }
});

API

xenvConfig(spec, userConfig, options);
  • spec - specification of the configs
  • userConfig - configuration from the user (use if not declared in env)
  • options - options

Returns config object.

  • Each key that exist has the value that's determined
  • A hidden field __$trace__ that contains data to indicate where each config key's value was determined from

options:

  • _env - Object that represents environment instead of process.env
  • merge - function to merge json object instead of using Object.assign

Spec

The spec is a JSON object with the following format:

{
  "<optionKey>": {
    env: "ENV_VAR_NAME",
    envMap: {},
    default: <default_value>,
    type: "<type>",
    post: (val, trace) => {}
  }
}
  • Each optionKey specifies the name of the option
  • Its value should be an object with the following fields:
    • env: the name (or array of names) of the environment varialbe(s) to check first. If it's true, then use optionKey as the env variable name.
    • envMap: an object of mapping env value to another value.
    • default: the default value or a function to return the default value.
    • type: indicate how to interpret and convert the string from process.env.
    • post: callback to post process value

All fields are optional, if they are all skipped, then the config option will be determined from userConfig only.

Without either default or type, the value from env will remain as a string.

If default is a function, then type must be defined or it will be string.

If env is an array, then the first one that finds a value in process.env will be used.

If env is true, then use optionKey as the name to look up from process.env.

Types

When loading from env, in order to indicate what value to convert the string into, the type can be one of.

  • string - no conversion
  • number - (integer) convert with parseInt(x,10)
  • float - (float) convert with parseFloat(x)
  • boolean - (boolean) convert with x === "true" || x === "yes" || x === "1" || x === "on"
  • truthy - (boolean from truthy check) convert with !!x
  • json - (JSON) parsed with JSON.parse

If type is not specified, and default exist and not a function, then typeof default will be used.

Trace

The hidden field __$trace__ contain data for each key to indicate where its value was determined from.

  • If the value's from env, then it's {src: "env", name: "ENV_OPTION_NAME"}
  • If the value's from user config, then it's {src: "option"}
  • If the value's from default, then it's {src: "default"}

json Type

json type is slightly different.

  • If default is an object like {}, then type is detected to be json, unless spec has type explicitly.
  • Values from all three sources are combined in the following order env, option, default.
  • It uses Object.assign to combine values unless you pass in a merge function in options. For example, merge from lodash.
  • trace.src would be a comma separate list of them. For example, "env,option", "env,option,default", or "option,default"

Option Orders

The order of source to check are:

  1. The env if it's defined in the spec and process.env contains the variable
  2. The value from userConfig directly if it contains the optionKey
  3. The default value from spec if it's declared
  4. Nothing